def max_degree_sample(graph: Graph, num_vertices: int, prev_state: DegreeWeightedSampleState, args: argparse.Namespace) -> SampleState: """Max-degree sampling. Simply samples the highest-degree vertices. 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 = MaxDegreeSampleState(graph.num_vertices(), prev_state) sample_num = int( (num_vertices * (args.sample_size / 100)) / args.sample_iterations) vertex_degrees = graph.get_total_degrees( np.arange(graph.num_vertices())) vertex_degrees[state.sample_idx] = 0 top_indices = np.argpartition(vertex_degrees, -sample_num)[-sample_num:] state.sample_idx = np.concatenate((state.sample_idx, top_indices)) return state
def examine_graph(graph: Graph, experiment: str, graphname: str, real: bool, directed: bool = True) -> Properties: vertices = graph.num_vertices() edges = graph.num_edges() total_degrees = graph.get_total_degrees(np.arange(vertices)) min_degree = np.min(total_degrees) max_degree = np.max(total_degrees) avg_degree = vertex_average(graph, "total")[0] largest_component = extract_largest_component( graph, directed=False).num_vertices() num_islands = np.sum(total_degrees == 0) cc = global_clustering(graph)[0] # _degrees, _counts = np.unique(total_degrees, return_counts=True) # log_degrees = np.log(_degrees) # log_counts = np.log(_counts) # regressor = LinearRegression() # regressor.fit(log_degrees.reshape(-1, 1), log_counts) # exponent = regressor.coef_[0] result = powerlaw.Fit(total_degrees, xmin=1, discrete=True, xmax=max_degree) exponent = -result.alpha percentile = np.percentile(total_degrees, 95) # print("Exponent for this graph is: ", exponent) # print("Using powerlaw package: e = {} xmin = {} xmax = {}".format( # exponent2, result.xmin, result.xmax)) # print("degrees: {}\ncounts: {}".format(_degrees[:20], _counts[:20])) return Properties(experiment, graphname, real, vertices, edges, min_degree, max_degree, avg_degree, largest_component, num_islands, cc, directed, exponent, percentile)
def create_sample(graph: Graph, old_true_block_assignment: np.ndarray, args: argparse.Namespace, prev_state: SampleState) -> 'Sample': """Performs sampling according to the sample type in args. TODO: either re-write how this method is used, or get rid of it - it seems to be a code smell. """ # get rid of 1-degree vertices degrees = graph.get_total_degrees(np.arange(graph.num_vertices())) degree_filter = degrees > 2 mapping = np.where(degrees > 2)[0] graph.set_vertex_filter( graph.new_vertex_property("bool", degree_filter)) filtered_graph = Graph(graph, prune=True) print(filtered_graph.num_vertices()) graph.clear_filters() # TODO: keep track of the mapping to original graph # TODO: below methods can return a SampleState, which we map back to original vertices here, then create the # sample before return. This is brilliant! I am genius! if args.sample_type == "degree_weighted": state = Sample.degree_weighted_sample(filtered_graph, graph.num_vertices(), prev_state, args) elif args.sample_type == "expansion_snowball": state = Sample.expansion_snowball_sample(filtered_graph, graph.num_vertices(), prev_state, args) elif args.sample_type == "forest_fire": state = Sample.forest_fire_sample(filtered_graph, graph.num_vertices(), prev_state, args) elif args.sample_type == "max_degree": state = Sample.max_degree_sample(filtered_graph, graph.num_vertices(), prev_state, args) elif args.sample_type == "random_jump": state = Sample.random_jump_sample(filtered_graph, graph.num_vertices(), prev_state, args) elif args.sample_type == "random_node_neighbor": state = Sample.random_node_neighbor_sample(filtered_graph, graph.num_vertices(), prev_state, args) elif args.sample_type == "random_walk": state = Sample.random_walk_sample(filtered_graph, graph.num_vertices(), prev_state, args) elif args.sample_type == "uniform_random": state = Sample.uniform_random_sample(filtered_graph, graph.num_vertices(), prev_state, args) else: raise NotImplementedError( "Sample type: {} is not implemented!".format(args.sample_type)) state.sample_idx = mapping[state.sample_idx] return Sample(state, graph, old_true_block_assignment)
def degree_weighted_sample(graph: Graph, num_vertices: int, prev_state: DegreeWeightedSampleState, args: argparse.Namespace) -> SampleState: """Degree-weighted sampling. The probability of selecting a vertex is proportional to its degree. 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 = DegreeWeightedSampleState(graph.num_vertices(), prev_state) sample_num = int( (num_vertices * (args.sample_size / 100)) / args.sample_iterations) vertex_degrees = graph.get_total_degrees( np.arange(graph.num_vertices())) vertex_degrees[state.sample_idx] = 0 state.sample_idx = np.concatenate( (state.sample_idx, np.random.choice(graph.num_vertices(), sample_num, replace=False, p=vertex_degrees / np.sum(vertex_degrees)))) return state
def deg_attack(g: GT.Graph): return IdNodes(g.get_total_degrees(g.get_vertices()))
def plot_degree_distribution(graph: Graph, file_name): degrees = graph.get_total_degrees(graph.get_vertices()) plt.hist(degrees) plt.savefig(file_name) plt.clf()
def passing_volume(g: Graph): vs = g.get_vertices() return np.asarray(g.get_total_degrees(vs, g.edge_properties['weight']))