def shortest_path_cover_logn_apx(g: gt.Graph, weight: gt.EdgePropertyMap): started_with_directed = g.is_directed() if not g.is_directed(): reversed_edges = np.fliplr(g.get_edges()) g.set_directed(True) g.add_edge_list(reversed_edges) weight.a[-reversed_edges.shape[0]:] = weight.a[:reversed_edges. shape[0]] if weight.value_type() not in [ "bool", "int", "int16_t", "int32_t", "int64_t" ]: #min = np.min(weight.a) #min_second = np.min(weight.a[weight.a > min]) eps = 1 #min_second - min scaled_weight = (np.ceil(weight.a / eps) * (g.num_vertices() + 1)).astype(np.int) # ints >= 1 else: scaled_weight = weight.a * (g.num_vertices() + 1) summed_edge_weight = np.sum(scaled_weight) adjusted_weight = g.new_edge_property("long", vals=scaled_weight - 1) paths = [] covered_vertices = set() while len(covered_vertices) != g.num_vertices(): curr_paths = shortest_path_visiting_most_nodes(g, adjusted_weight, covered_vertices, summed_edge_weight) for path in curr_paths: paths.append(path) #if len(path) <= 2 switch to fast mode and just add single edges/vertices until done. path_vertices = set(path) for v in path_vertices.difference(covered_vertices): for w in g.get_in_neighbors(v): adjusted_weight[g.edge(w, v)] += 1 #.a[list()] -= 1 if adjusted_weight[g.edge( w, v)] % (g.num_vertices() + 1) != 0: exit(5) new_covered = path_vertices.difference(covered_vertices) covered_vertices = covered_vertices.union(path_vertices) print(len(new_covered), len(path), len(covered_vertices), path) if not started_with_directed: g.set_directed(False) for e in reversed_edges: g.remove_edge(g.edge(e[0], e[1])) return paths
def expansion_snowball_sample(graph: Graph, num_vertices: int, prev_state: ExpansionSnowballSampleState, args: argparse.Namespace) -> SampleState: """Expansion snowball sampling. At every iteration, picks a vertex adjacent to the current sample that contributes the most new neighbors. Parameters ---------- graph : Graph the filtered graph from which to sample vertices num_vertices : int number of vertices in the unfiltered graph prev_state : UniformRandomSampleState the state of the previous sample in the stack. If there is no previous sample, an empty SampleState object should be passed in here. args : argparse.Namespace the command-line arguments provided by the user Returns ------- state : SampleState the sample state with the sampled vertex ids (Note: these ids correspond to the filtered graph, and have to be mapped back to the unfiltered graph) """ state = ExpansionSnowballSampleState(graph.num_vertices(), prev_state) sample_num = int( (num_vertices * (args.sample_size / 100)) / args.sample_iterations) sample_num += len(state.sample_idx) if not state.neighbors: # If there are no neighbors, start with the state.start vertex state.index_flag[state.start] = True state.neighbors = set(graph.get_out_neighbors(state.start)) for neighbor in graph.get_out_neighbors(state.start): if neighbor == state.start: state.neighbors.remove(neighbor) else: state.neighbors_flag[neighbor] = True new_neighbors = 0 for _neighbor in graph.get_out_neighbors(neighbor): if not (state.index_flag[_neighbor] or state.neighbors_flag[_neighbor]): new_neighbors += 1 state.contribution[neighbor] += new_neighbors while len(state.index_set) == 0 or len( state.index_set) % sample_num != 0: if len(state.neighbors ) == 0: # choose random vertex not in index set vertex = np.random.choice( np.setxor1d(np.arange(graph.num_vertices()), state.index_set)) state.index_set.append(vertex) state.index_flag[vertex] = True for neighbor in graph.get_out_neighbors(vertex): if not (state.neighbors_flag[neighbor] or state.index_flag[neighbor]): Sample._add_neighbor(neighbor, state.contribution, state.index_flag, state.neighbors_flag, graph.get_out_neighbors(neighbor), graph.get_in_neighbors(neighbor), state.neighbors) continue elif np.max(state.contribution ) == 0: # choose random neighbors from neighbor set num_choices = min(len(state.neighbors), sample_num - len(state.index_set)) vertices = np.random.choice(np.fromiter( state.neighbors, int, len(state.neighbors)), num_choices, replace=False) for vertex in vertices: state.index_set.append(vertex) state.index_flag[vertex] = True state.neighbors.remove(vertex) for neighbor in graph.get_out_neighbors(vertex): if not (state.neighbors_flag[neighbor] or state.index_flag[neighbor]): Sample._add_neighbor( neighbor, state.contribution, state.index_flag, state.neighbors_flag, graph.get_out_neighbors(neighbor), graph.get_in_neighbors(neighbor), state.neighbors) continue vertex = np.argmax(state.contribution) state.index_set.append(vertex) state.index_flag[vertex] = True state.neighbors.remove(vertex) state.contribution[vertex] = 0 for neighbor in graph.get_in_neighbors(vertex): if not (state.neighbors_flag[neighbor] or state.index_flag[neighbor]): Sample._add_neighbor(neighbor, state.contribution, state.index_flag, state.neighbors_flag, graph.get_out_neighbors(neighbor), graph.get_in_neighbors(neighbor), state.neighbors) state.sample_idx = np.asarray(state.index_set) return state