Esempio n. 1
0
def find_placement(pieces, resistors_as_components, cost_type):
    """
  Given a list of |pieces|, returns a placement of the pieces that requires
      comparatively small wiring. Finding the absolute best placement is too
      expensive. If the |pieces| cannot be placed so as to fit on a protoboard,
      returns None with a cost of float('inf').
  """
    assert isinstance(pieces, list), 'pieces must be a list'
    assert all(isinstance(piece, Circuit_Piece)
               for piece in pieces), ('all '
                                      'items in pieces must be Circuit_Pieces')
    pieces = deepcopy(pieces)
    if len(pieces) == 0:
        return [], 0
    # order pieces in decreasing number of nodes
    pieces.sort(key=lambda piece: -len(piece.nodes))
    queue = Queue()

    def add_to_queue(piece):
        if piece in pieces:
            queue.push(piece)
            pieces.remove(piece)

    placement = []
    placement_cost = float('inf')
    while pieces:
        add_to_queue(pieces[0])
        while queue:
            current_piece = queue.pop()
            # try inserting the current piece at all possible indicies in the current
            #     placement, consider both regular and inverted piece
            best_placement = None
            best_placement_cost = float('inf')
            # all indicies in which the piece can be inserted
            for i in xrange(len(placement) + 1):
                # both regular and inverted piece
                for piece in set([current_piece, current_piece.inverted()]):
                    for top_left_row in piece.possible_top_left_rows:
                        piece.top_left_row = top_left_row
                        new_placement = deepcopy(placement)
                        new_placement.insert(i, piece)
                        new_placement_cost = cost(new_placement,
                                                  resistors_as_components,
                                                  cost_type)
                        if new_placement_cost < best_placement_cost:
                            best_placement = deepcopy(new_placement)
                            best_placement_cost = new_placement_cost
            if best_placement is None:
                return None, float('inf')
            placement = best_placement
            placement_cost = best_placement_cost
            # add pieces connected to this piece to the queue
            for piece in reduce(
                    list.__add__,
                [[piece for piece in pieces if node in piece.nodes]
                 for node in current_piece.nodes], []):
                add_to_queue(piece)
    return placement, placement_cost
def find_placement(pieces, resistors_as_components, cost_type):
  """
  Given a list of |pieces|, returns a placement of the pieces that requires
      comparatively small wiring. Finding the absolute best placement is too
      expensive. If the |pieces| cannot be placed so as to fit on a protoboard,
      returns None with a cost of float('inf').
  """
  assert isinstance(pieces, list), 'pieces must be a list'
  assert all(isinstance(piece, Circuit_Piece) for piece in pieces), ('all '
      'items in pieces must be Circuit_Pieces')
  pieces = deepcopy(pieces)
  if len(pieces) == 0:
    return [], 0
  # order pieces in decreasing number of nodes
  pieces.sort(key=lambda piece: -len(piece.nodes))
  queue = Queue()
  def add_to_queue(piece):
    if piece in pieces:
      queue.push(piece)
      pieces.remove(piece)
  placement = []
  placement_cost = float('inf')
  while pieces:
    add_to_queue(pieces[0])
    while queue:
      current_piece = queue.pop()
      # try inserting the current piece at all possible indicies in the current
      #     placement, consider both regular and inverted piece
      best_placement = None
      best_placement_cost = float('inf')
      # all indicies in which the piece can be inserted
      for i in xrange(len(placement) + 1):
        # both regular and inverted piece
        for piece in set([current_piece, current_piece.inverted()]):
          for top_left_row in piece.possible_top_left_rows:
            piece.top_left_row = top_left_row
            new_placement = deepcopy(placement)
            new_placement.insert(i, piece)
            new_placement_cost = cost(new_placement, resistors_as_components,
                cost_type)
            if new_placement_cost < best_placement_cost:
              best_placement = deepcopy(new_placement)
              best_placement_cost = new_placement_cost
      if best_placement is None:
        return None, float('inf')
      placement = best_placement
      placement_cost = best_placement_cost
      # add pieces connected to this piece to the queue
      for piece in reduce(list.__add__, [[piece for piece in pieces if node
          in piece.nodes] for node in current_piece.nodes], []):
        add_to_queue(piece)
  return placement, placement_cost
Esempio n. 3
0
    def closest_vertex(self, frm, target_list):
        """ closest_vertex(frm, target_list) -> id Uses bfs-like
        algorithm to find closest vertex to frm in target_list

        """
        if frm in target_list:
            return frm
        target_list = set(target_list)
        visited = set([frm])
        parent = {}
        q = Queue()
        q.push(frm)
        while 1:
            try:
                current = q.pop()
            except q.EmptyQueue:
                raise GraphException("no vertices reachable: %s %s" %
                                     (frm, list(target_list)))
            efrom = self.edges_from(current)
            for (to, eid) in efrom:
                if to in target_list:
                    return to
                if to not in visited:
                    parent[to] = current
                    q.push(to)
                    visited.add(to)
Esempio n. 4
0
    def closest_vertex(self, frm, target_list):
        """ closest_vertex(frm, target_list) -> id Uses bfs-like
        algorithm to find closest vertex to frm in target_list

        """
        if frm in target_list:
            return frm
        target_list = set(target_list)
        visited = set([frm])
        parent = {}
        q = Queue()
        q.push(frm)
        while 1:
            try:
                current = q.pop()
            except q.EmptyQueue:
                raise GraphException("no vertices reachable: %s %s" % (frm, list(target_list)))
            efrom = self.edges_from(current)
            for (to, eid) in efrom:
                if to in target_list:
                    return to
                if to not in visited:
                    parent[to] = current
                    q.push(to)
                    visited.add(to)
Esempio n. 5
0
    def bfs(self, frm):
        """ bfs(frm:id type) -> dict(id type)
        Perform Breadth-First-Search and return a dict of parent id

        Keyword arguments:
        frm -- 'immutable' vertex id

        """
        visited = set([frm])
        parent = {}
        q = Queue()
        q.push(frm)
        while 1:
            try:
                current = q.pop()
            except q.EmptyQueue:
                break
            efrom = self.edges_from(current)
            for (to, eid) in efrom:
                if to not in visited:
                    parent[to] = current
                    q.push(to)
                    visited.add(to)
        return parent
Esempio n. 6
0
    def bfs(self, frm):
        """ bfs(frm:id type) -> dict(id type)
        Perform Breadth-First-Search and return a dict of parent id

        Keyword arguments:
        frm -- 'immutable' vertex id

        """
        visited = set([frm])
        parent = {}
        q = Queue()
        q.push(frm)
        while 1:
            try:
                current = q.pop()
            except q.EmptyQueue:
                break
            efrom = self.edges_from(current)
            for (to, eid) in efrom:
                if to not in visited:
                    parent[to] = current
                    q.push(to)
                    visited.add(to)
        return parent