def combined_solve_layout(circuit, verbose=True): """ Creates a layout for the given |circuit| by using a combination of methods. Returns None on failure. """ partially_solved = [] for cost_type in (COST_TYPE_BLOCKING, COST_TYPE_DISTANCE): if verbose: print 'Cost type: %s' % cost_type placement, resistor_node_pairs = get_piece_placement(circuit, resistors_as_components=True, cost_type=cost_type, verbose=verbose) if placement is None: if verbose: print '\tToo many components.' continue for order_sign in (-1, 1): proto_board, nodes, loc_pairs = _setup(placement, resistor_node_pairs) if verbose: print proto_board loc_pairs.sort(key=lambda (loc_1, loc_2, resistor, node): order_sign * dist(loc_1, loc_2)) if verbose: print 'Order: %d' % order_sign failed_loc_pairs = [] for loc_pair in loc_pairs: loc_1, loc_2, resistor, node = loc_pair if verbose: print 'Connecting %s -- %s' % (loc_1, loc_2) wired_proto_board = _wire_loc_pair(loc_pair, proto_board) if wired_proto_board: proto_board = wired_proto_board if verbose: print proto_board print 'Success' else: failed_loc_pairs.append(loc_pair) if verbose: print 'Fail' if not failed_loc_pairs: return proto_board.prettified() else: partially_solved.append((proto_board, failed_loc_pairs)) if not partially_solved: return None def cost((proto_board, failed_loc_pairs)): return sum(dist(loc_1, loc_2) ** 2 for loc_1, loc_2, resistor, node in failed_loc_pairs) proto_board, failed_loc_pairs = min(partially_solved, key=cost) if verbose: print 'Using terrible wirer for: %s' % [(loc_1, loc_2) for (loc_1, loc_2, resistor, node) in failed_loc_pairs] terrible_proto_board = find_terrible_wiring(failed_loc_pairs, proto_board) if terrible_proto_board is not None: return terrible_proto_board.prettified() return None
def solve_layout(circuit, resistors_as_components, cost_type, mode, order, best_first, filter_wire_lengths, verbose=True): """ Attempts to produce a layout for the given |circuit| and returns a dictionary containing data corresponding to the solution, most importantly the key 'proto_board' mapped to the produced layout. The value will be None if no layout could be found. |cost_type| is a parameter for which placement cost to use, see circuit_piece_placement.py. |mode| and |order| are parameters for how the wiring should be solved, see find_proto_board_wiring.py. """ if verbose: print 'Resistors as components: %s' % resistors_as_components print 'Placement cost type: %s' % cost_type print 'Wiring mode: %s, order: %s' % (mode, order) print 'Search: %s' % ('Best First' if best_first else 'A*') print 'Filter wire lengths: %s' % filter_wire_lengths print solve_data = defaultdict(lambda: None) try: placement_start = clock() placement, resistor_node_pairs = get_piece_placement(circuit, resistors_as_components, cost_type, verbose) solve_data['placement_time'] = clock() - placement_start solve_data['placement'] = placement solve_data['resistor_node_pairs'] = resistor_node_pairs if placement is None: print "Pieces don't fit on the board." return solve_data proto_board, nodes, loc_pairs = _setup(placement, resistor_node_pairs) solve_data['nodes'] = nodes solve_data['loc_pairs'] = loc_pairs wiring_start = clock() proto_board, num_expanded = find_wiring(loc_pairs=loc_pairs, start_proto_board=proto_board, mode=mode, order=order, best_first=best_first, filter_wire_lengths=filter_wire_lengths, verbose=verbose) solve_data['wiring_time'] = clock() - wiring_start solve_data['proto_board'] = proto_board solve_data['num_expanded'] = num_expanded except: print_exc(file=stdout) return solve_data