def optimize_removal(solver: GraphSolver, tree: Graph, orig_cost: float): candidates = [ v for v in tree.nodes if not solver.is_required(v) and is_leaf(tree, v) ] while candidates: # print(candidates) # random.seed(0) node = random.choice(candidates) candidates.remove(node) edge = (node, list(tree.neighbors(node))[0]) solver.unvisit(node) new_cost = average_pairwise_distance(tree) if new_cost < orig_cost: # print('removed', node) return optimize_removal(solver, tree, new_cost) else: solver.add_edge(edge) return orig_cost
def optimize_removal_sorted(solver: GraphSolver, tree: Graph, orig_cost: float): candidates = [ v for v in tree.nodes if not solver.is_required(v) and is_leaf(tree, v) ] while candidates: # print(candidates) # random.seed(0) candidates.sort(key=lambda x: closeness_centrality(solver.T, x)) node = candidates.pop(0) edge = (node, list(tree.neighbors(node))[0]) solver.unvisit(node) new_cost = average_pairwise_distance(tree) if new_cost < orig_cost: # print('removed', node) return optimize_removal_sorted(solver, tree, new_cost) else: solver.add_edge(edge) return orig_cost
def optimize_additions(solver: GraphSolver, tree: Graph, orig_cost: float = None): graph = solver.G if orig_cost is None: orig_cost = average_pairwise_distance(tree) # get all edges to consider edges = [] for node in tree.nodes: for neighbor in graph.neighbors(node): if not edge_exists(tree.edges, (node, neighbor)) and not edge_exists( edges, (node, neighbor)): edges.append((node, neighbor)) # for each edge (consider order randomly) while edges: # random.seed(0) added_edge = random.choice(edges) edges.remove(added_edge) weight = graph[added_edge[0]][added_edge[1]]['weight'] # if added edge creates a cycle if added_edge[1] in tree.nodes: solver.add_edge(added_edge) while (True): try: cycle: list = find_cycle(tree, added_edge[0]) except: # No cycle break try: cycle.remove(added_edge) except ValueError: cycle.remove(added_edge[::-1]) replaced_edge, new_cost = kill_cycle(solver, cycle, orig_cost) # print("replaced_edge:", replaced_edge) # print("cost:", new_cost) if replaced_edge: orig_cost = new_cost solver.remove_edge(replaced_edge) else: solver.remove_edge(added_edge) # if other vertex not in tree else: v = added_edge[1] solver.visit(v, added_edge) # add_edge(tree, added_edge, weight) new_cost = average_pairwise_distance(tree) if new_cost < orig_cost: orig_cost = new_cost add_neighbors(solver, edges, v) else: solver.unvisit(v) # remove considered edge return orig_cost