def solve(G): """ Args: G: networkx.Graph Returns: T: networkx.Graph """ g = GraphSolver(G) start = g.find_leaf_path() if start is None: start = first_heuristic(g) graph_choices = [] for v in g.neighbors(start): newG = G.copy() new_g = GraphSolver(newG) new_g.visit(start) new_g.visit(v, (start, v)) graph_choices.append(new_g) minT = G minCost = float('inf') for g_option in graph_choices: g_option.dijkstra_solve_graph(start, calculate_heuristic, first_heuristic) optimize_sorted(g_option, g_option.T, cycle_killer_fn=kill_cycle) cost = average_pairwise_distance(g_option.T) if cost < minCost: minCost = cost minT = g_option.T return minT
def solve(G): global saved_costs, solver_filenames g = GraphSolver(G) for v in list(g.G.nodes): if len( list(g.neighbors(v)) ) == g.n - 1: # Special case when one vertex is connected to all of them g.visit(v) return g.T solvers = [ import_module(solver_filename) for solver_filename in solver_filenames ] skipped_costs = [] skipped_solvers = [] # Don't calculate for inputs we already know costs for deterministically skip = [] if cacher is not None: for i in range(len(solvers)): # It turns out all of our algorithms are not deterministic so that condition is going to be deleted if cacher.is_cached(input_filename, solver_filenames[i]): # if getattr(solvers[i], 'isDeterministic', False) and cacher.is_cached(input_filename, solver_filenames[i]): skipped_costs.append( cacher.get_cost(input_filename, solver_filenames[i])) skip.append(i) skipped_solvers.append(solver_filenames[i]) solver_filenames = [ f for i, f in enumerate(solver_filenames) if i not in skip ] solvers = [s for i, s in enumerate(solvers) if i not in skip] trees = [] # to be populated ############### Parallelizing ######################## if len(solvers) > 0: pool = Pool(len(solvers)) async_solvers = [ pool.apply_async(solver.solve, [G]) for solver in solvers ] trees = [ async_solver.get(1000000000) for async_solver in async_solvers ] pool.close() pool.join() ################ Non - parallelizing #################### # trees = [solver.solve(G) for solver in solvers] ######################################################### # Cache costs costs = [average_pairwise_distance(t) for t in trees] if cacher is not None: for i in range(len(trees)): cacher.cache_if_better_or_none(input_filename, solver_filenames[i], costs[i], None, trees[i]) # Create lists with the same length all_trees = [None] * len(skipped_costs) + trees all_costs = skipped_costs + costs solver_filenames = skipped_solvers + solver_filenames # Sort all_trees = [ tree for c, tree in sorted(zip(all_costs, all_trees), key=lambda pair: pair[0]) ] solver_filenames = [ filename for c, filename in sorted(zip(all_costs, solver_filenames), key=lambda pair: pair[0]) ] all_costs = sorted(all_costs) # Print saved costs second_smallest = all_costs[1] individual_saved_costs = [ second_smallest - cost if second_smallest - cost > 0 else 0 for cost in all_costs ] saved_costs = [sum(x) for x in zip(saved_costs, individual_saved_costs)] print(saved_costs) # Get the tree to return min_tree = all_trees[0] if min_tree is None: out_file = join(OUTPUT_DIRECTORY, input_filename[:-3], solver_filenames[0] + '.out') if isfile(out_file): print('read outfile', out_file) min_tree = read_output_file(out_file, G) else: print( "WARNING: all_prev_outputs.txt is probably out of sync. {} was not found." .format(out_file)) print('Recalculating for input {}'.format(input_filename)) # Recalculate for this input prev_type = cacher.set_cache_type('none') min_tree = solve(G) cacher.set_cache_type(prev_type) return min_tree