def compute_estimated_cut(G, partition_dict, marked_nodes): """Compute overestimated cut value on a partial marked graph""" buffer_dict = dict(partition_dict) # cut marked nodes using strong minority gc.marked_nodes_could_be_cut(G, buffer_dict, marked_nodes) bk = set() # decided nodes in partition_dict m = set() # marked nodes in partition_dict for node in partition_dict: if partition_dict[node] == gc.MARKED: m.add(node) else: bk.add(node) b1k1 = set() # decided and undecided nodes in buffer_dict for node in m: if buffer_dict[node] != gc.MARKED: b1k1.add(node) nx.set_node_attributes(G, gc.PARTITION, buffer_dict) result = (G.subgraph(m).number_of_edges() + gc.cut_edges(G.subgraph(bk | b1k1)) - gc.cut_edges(G.subgraph(b1k1))) return result
def compute_estimated_cut(G, partition_dict, marked_nodes): """Compute overestimated cut value on a partial marked graph""" buffer_dict = dict(partition_dict) # cut marked nodes using strong minority gc.marked_nodes_could_be_cut(G, buffer_dict, marked_nodes) bk = set() # decided nodes in partition_dict m = set() # marked nodes in partition_dict for node in partition_dict: if partition_dict[node] == gc.MARKED: m.add(node) else: bk.add(node) b1k1 = set() # decided and undecided nodes in buffer_dict for node in m: if buffer_dict[node] != gc.MARKED: b1k1.add(node) nx.set_node_attributes(G, gc.PARTITION, buffer_dict) result = (G.subgraph(m).number_of_edges() + gc.cut_edges(G.subgraph(bk | b1k1)) - gc.cut_edges(G.subgraph(b1k1))) return result
def complete_cut(G, partition_dict, nodes_stack): """Compute the maximum cut from a partial partitioned graph.""" marked_nodes_stack = [] while gc.could_be_cut(G, partition_dict): pass # filter away the decided nodes for i in nodes_stack: if partition_dict[i] is gc.UNDECIDED or partition_dict[i] is gc.MARKED: marked_nodes_stack.append(i) if not marked_nodes_stack: return partition_dict, gc.cut_edges(G, partition_dict) candidate = marked_nodes_stack.pop() # Complete cut blue_cut, blue_cut_val = aux_local_consistent_max_cut( G, dict(partition_dict), list(marked_nodes_stack), int(candidate), gc.BLUE) black_cut, black_cut_val = aux_local_consistent_max_cut( G, dict(partition_dict), list(marked_nodes_stack), int(candidate), gc.BLACK) if blue_cut_val > black_cut_val: return blue_cut, blue_cut_val return black_cut, black_cut_val
def aux_pruning_local_consistent_max_cut(G, partition_dict, degree_node_seq, candidate, partition_attribute): """Helper function to pruning_local_consistent_max_cut""" partition_dict[candidate] = partition_attribute # check consistency in the candidate and its neighbors only check_nodes = nx.neighbors(G, candidate) if not gc.is_cut_consistent(G, partition_dict, check_nodes): return None, 0 if not degree_node_seq: return partition_dict, gc.cut_edges(G, partition_dict) while (gc.could_be_cut(G, partition_dict)): pass # pick a new candidate candidate = choose_new_candidate(partition_dict, degree_node_seq) blue_cut, blue_cut_val = aux_pruning_local_consistent_max_cut( G, dict(partition_dict), list(degree_node_seq), candidate, gc.BLUE) black_cut, black_cut_val = aux_pruning_local_consistent_max_cut( G, dict(partition_dict), list(degree_node_seq), candidate, gc.BLACK) if blue_cut is None and black_cut is None: return None, 0 # Choose best cut according to the effective cut value if blue_cut_val > black_cut_val: return blue_cut, blue_cut_val return black_cut, black_cut_val
def greedy_choice(G, candidate, blue_nodes, black_nodes, visited): """Helper function to greedy cut""" G.node[candidate][gc.PARTITION] = gc.BLUE blue_cut_val = gc.cut_edges(nx.subgraph(G, visited)) G.node[candidate][gc.PARTITION] = gc.BLACK black_cut_val = gc.cut_edges(nx.subgraph(G, visited)) if blue_cut_val > black_cut_val: G.node[candidate][gc.PARTITION] = gc.BLUE blue_nodes.add(candidate) else: black_nodes.add(candidate) return blue_nodes, black_nodes
def greedy_choice(G, candidate, blue_nodes, black_nodes, visited): """Helper function to greedy cut""" G.node[candidate][gc.PARTITION] = gc.BLUE blue_cut_val = gc.cut_edges(nx.subgraph(G, visited)) G.node[candidate][gc.PARTITION] = gc.BLACK black_cut_val = gc.cut_edges(nx.subgraph(G, visited)) if blue_cut_val > black_cut_val: G.node[candidate][gc.PARTITION] = gc.BLUE blue_nodes.add(candidate) else: black_nodes.add(candidate) return blue_nodes, black_nodes
def second_lemma(G): """Compute second lemma.""" cut_edges = gc.cut_edges(G) uncut_edges = G.number_of_edges() - cut_edges numerator = float(uncut_edges - cut_edges) denominator = float(G.number_of_edges()) return numerator / denominator
def second_lemma(G): """Compute second lemma.""" cut_edges = gc.cut_edges(G) uncut_edges = G.number_of_edges() - cut_edges numerator = float(uncut_edges - cut_edges) denominator = float(G.number_of_edges()) return numerator / denominator
def aux_pruning_local_consistent_max_cut(G, partition_dict, degree_node_seq, candidate, partition_attribute): """Helper function to pruning_local_consistent_max_cut""" partition_dict[candidate] = partition_attribute # check consistency in the candidate and its neighbors only check_nodes = nx.neighbors(G, candidate) if not gc.is_cut_consistent(G, partition_dict, check_nodes): return None, 0 if not degree_node_seq: return partition_dict, gc.cut_edges(G, partition_dict) while(gc.could_be_cut(G, partition_dict)): pass # pick a new candidate candidate = choose_new_candidate(partition_dict, degree_node_seq) blue_cut, blue_cut_val = aux_pruning_local_consistent_max_cut( G, dict(partition_dict), list(degree_node_seq), candidate, gc.BLUE) black_cut, black_cut_val = aux_pruning_local_consistent_max_cut( G, dict(partition_dict), list(degree_node_seq), candidate, gc.BLACK) if blue_cut is None and black_cut is None: return None, 0 # Choose best cut according to the effective cut value if blue_cut_val > black_cut_val: return blue_cut, blue_cut_val return black_cut, black_cut_val
def brute_force_max_cut(G): """Compute maximum cut of a graph considering all the possible cuts.""" max_cut_value = 0 max_cut_ind = 0 n = G.number_of_nodes() for i in range(1, 2**(n - 1)): cut_graph = nx.Graph(G) gc.binary_cut(cut_graph, i) value = gc.cut_edges(cut_graph) if value > max_cut_value: max_cut_value = value max_cut_ind = i gc.binary_cut(G, max_cut_ind) return gc.partition_dictionary(G), max_cut_value
def brute_force_max_cut(G): """Compute maximum cut of a graph considering all the possible cuts.""" max_cut_value = 0 max_cut_ind = 0 n = G.number_of_nodes() for i in range(1, 2 ** (n - 1)): cut_graph = nx.Graph(G) gc.binary_cut(cut_graph, i) value = gc.cut_edges(cut_graph) if value > max_cut_value: max_cut_value = value max_cut_ind = i gc.binary_cut(G, max_cut_ind) return gc.partition_dictionary(G), max_cut_value
def compare_cut_algorithm_results(cut_alg, results_graphs, test_name=''): graphs_dict = gg.read_from_file(results_graphs + '.dat') location = cut_alg.__name__ error_list = [] results_dict = defaultdict(list) print('Algorithm: ' + str(cut_alg.__name__)) print('Benchamark: ' + results_graphs) print('Starting..:)') print('Graph\Result Epsilon\tCurrent Epsilon') i = 0 for opt_eps in sorted(graphs_dict.iterkeys()): for A, c in graphs_dict[opt_eps]: G = nx.from_numpy_matrix(A) cut_alg(G) if gc.cut_edges(G) < G.number_of_edges() / 2: print('####### ERROR 1 #######') error_list.append(G) if gc.are_undecided_nodes(G): print('####### ERROR 2 #######') error_list.append(G) this_eps = gc.compute_epsilon(G) print(str(i) + '\t' + str(opt_eps) + '\t' + str(this_eps)) results_dict[opt_eps].append(this_eps) i += 1 gg.write_to_file(results_dict, test_name + 'results_' + results_graphs + '.dat', location) if len(error_list) != 0: gg.write_to_file(error_list, test_name + 'errors_' + results_graphs + '.dat', location)
def complete_cut(G, partition_dict, nodes_stack): """Compute the maximum cut from a partial partitioned graph.""" marked_nodes_stack = [] while gc.could_be_cut(G, partition_dict): pass # filter away the decided nodes for i in nodes_stack: if partition_dict[i] is gc.UNDECIDED or partition_dict[i] is gc.MARKED: marked_nodes_stack.append(i) if not marked_nodes_stack: return partition_dict, gc.cut_edges(G, partition_dict) candidate = marked_nodes_stack.pop() # Complete cut blue_cut, blue_cut_val = aux_local_consistent_max_cut( G, dict(partition_dict), list(marked_nodes_stack), int(candidate), gc.BLUE) black_cut, black_cut_val = aux_local_consistent_max_cut( G, dict(partition_dict), list(marked_nodes_stack), int(candidate), gc.BLACK) if blue_cut_val > black_cut_val: return blue_cut, blue_cut_val return black_cut, black_cut_val
def trevisan_approximation_alg(G): B, K = recursive_spectral_cut(G) # set blue and black nodes in graph G gc.set_partitions(G, B, K) return gc.cut_edges(G)
def trevisan_approximation_alg(G): B, K = recursive_spectral_cut(G) # set blue and black nodes in graph G gc.set_partitions(G, B, K) return gc.cut_edges(G)