def Ai(self, k, r, X, i): T = SuitabilityGraph() while k > 0: TBEST = SuitabilityGraph() for kprime in range(1, k + 1): for v in self.__nodes: if i > 1: Tprime = self.Ai(kprime, v, X, i - 1) p = self.__paths[tuple(sorted([r, v]))] Tprime.append_path(p, self.__graph) else: dists = {} for t in self.__terminals: dists[t] = self.__dist[tuple(sorted([v, t]))] ord_term = sorted(dists.iteritems(), key=operator.itemgetter(1)) Tprime = SuitabilityGraph() for j in range(kprime): p = self.__paths[tuple(sorted([v, ord_term[j][0]]))] Tprime.append_path(p, self.__graph) if self.d(TBEST) > self.d(Tprime): TBEST = Tprime T.append_graph(TBEST) k -= len(set(TBEST.keys()).intersection(X)) X = set(X).difference(TBEST.keys()) return T
def __init__(self, graph, terminals, contract_graph=True, contracted_graph=None, within_convex_hull=False, dist_paths=None, nodes=None, use_medoid=False): # Check whether graph is node-weighted. if not graph.is_node_weighted(): raise (ValueError, "Dreyfus with IMRs algorithm only works with node-weighted graphs.") # Extract POI from the terminals list. if len(terminals) > 0: self.__poi = terminals[0] else: return # Set object variables. generator = SuitableNodeWeightGenerator() self.__original_graph = graph self.__terminals = terminals self.__contract_graph = contract_graph self.__use_medoid = use_medoid # Contracted graph... if contract_graph: if contracted_graph is not None: self.__graph = contracted_graph.copy() else: self.__graph = SuitabilityGraph() self.__graph.append_graph(graph) self.__graph.contract_suitable_regions(generator, excluded_nodes=terminals, get_centroid_medoid=use_medoid) else: self.__graph = SuitabilityGraph() self.__graph.append_graph(graph) # if nodes is not None: self.__nodes = list(nodes) else: if within_convex_hull: pass # self.__nodes = self.__graph.get_suitable_nodes_within_convex_set(terminals, generator, dist_paths) else: self.__nodes = self.__graph.get_suitable_nodes(generator, excluded_nodes=terminals) # for t in terminals: self.__nodes.append(t) # print(self.__nodes) # self.__dist = {} self.__paths = {} if dist_paths is not None: self.__dist = dict(dist_paths[0]) self.__paths = dict(dist_paths[1]) else: self.__dist, self.__paths = self.__graph.get_dist_paths(origins=self.__nodes, destinations=self.__nodes) # self.__s_d = {}
def steiner_tree(self): subtrees = [] _, paths = dijkstra(self.__graph, self.__poi, self.__terminals) for t in self.__terminals: path = paths[t] subtree = SuitabilityGraph() # j = 0 # for i in range(len(path_to_poi)): # if path_to_poi[i] in self.__graph.contracted_regions: # region_id = path_to_poi[i] # subtree.append_from_path(path_to_poi[j:i], self.__original_graph) # closest_node = self.__find_closest_node_to_poi_within_region(region_id) # path_endpoint_1 = self.__dist_paths_node_within_region_node[closest_node][1][path_to_poi[i - 1]] # subtree.append_from_path(path_endpoint_1, self.__original_graph) # path_endpoint_2 = self.__dist_paths_node_within_region_node[closest_node][1][path_to_poi[i + 1]] # subtree.append_from_path(path_endpoint_2, self.__original_graph) # j = i + 1 # subtree.append_from_path(path_to_poi[j:], self.__original_graph) subtree.append_path(path, self.__graph) subtrees.append(subtree) steiner_tree = self.__merge_subtrees(subtrees) self.__prune_steiner_tree(steiner_tree) if self.__contract_graph: self.__decontract_steiner_tree(steiner_tree) return steiner_tree
def __build_steiner_forest(self): forest = SuitabilityGraph() dist = cost = occupancy = 0 for t, dest in self.__confirmed.iteritems(): if dest is None: dest = self.__medoids[t] self.__confirmed[t] = dest for t_ in self.__term_tree[t]: self.__detour[t_] += self.__graph.dist[tuple( sorted([t, dest]))] # # Print groups of terminals that travel together. # if dest in self.__pois: # print self.__term_tree[t] # print t, dest self.__graph.compute_dist_paths(origins=[t], destinations=[dest], recompute=True) try: forest.append_path( self.__graph.paths[tuple(sorted([t, dest]))], self.__graph) dist = self.__graph.dist[tuple(sorted([t, dest]))] cost += dist except KeyError: # pdb.set_trace() print 'key error:', t, dest # Who is driver? # if t in self.__terminals and (dist > max_wd or dest == self.__medoids[t]): # print "Driver:", t, "Meeting point:", dest occupancy += len(self.__term_tree[t]) * dist # print "Num. terms:", len(self.__term_tree[t]), "Shared distance:", dist return forest, cost, occupancy / cost
def __build_steiner_tree_bactracking(self, node, subset): steiner_tree = SuitabilityGraph() next_node = self.__s_d[node][tuple(subset)][1] if self.__contract_graph: print(node, self.__s_d[node][tuple(subset)]) # pdb.set_trace() if next_node is not None: steiner_tree.append_path(self.__paths[tuple(sorted([node, next_node]))], self.__graph) (best_e, best_f) = self.__s_d[node][tuple(subset)][2] # pdb.set_trace() steiner_branch_e = SuitabilityGraph() if best_e is not None and best_e != [next_node]: steiner_branch_e = self.__build_steiner_tree_bactracking(next_node, best_e) steiner_branch_f = SuitabilityGraph() if best_f is not None and best_f != [next_node] and len(best_f) > 0: steiner_branch_f = self.__build_steiner_tree_bactracking(next_node, best_f) steiner_tree.append_graph(steiner_branch_e) steiner_tree.append_graph(steiner_branch_f) return steiner_tree
def get_suitability_graph_from_session(request): graph = request.session['graph'] suitability_graph = SuitabilityGraph() for node_id, (node_weight, adj_dict, data) in graph.iteritems(): new_adj_dict = { int(neighbour): edge_cost for neighbour, edge_cost in adj_dict.iteritems() } suitability_graph[int(node_id)] = (node_weight, new_adj_dict, data) return suitability_graph
def enclosing_region(self): enclosing = SuitabilityGraph() paths = [] paths.append(self.__paths[tuple(sorted([323287670, 2392803740]))]) paths.append(self.__paths[tuple(sorted([2392803740, 127578100]))]) paths.append(self.__paths[tuple(sorted([127578100, 3109398450]))]) paths.append(self.__paths[tuple(sorted([3109398450, 342909685]))]) paths.append(self.__paths[tuple(sorted([342909685, 323287670]))]) for path in paths: enclosing.append_path(path, self.__original_graph) return enclosing
def __init__(self, graph): # Init some instance variables. self.__graph = SuitabilityGraph() self.__graph.append_graph(graph) self.__edges = graph.get_edges() self.__congestion = {} l_G = float(0) for e, le in self.__edges.iteritems(): self.__congestion[e] = 0 l_G += le self.__costs = {e: le / l_G for e, le in self.__edges.iteritems()}
def __build_steiner_tree(self, node, subset): steiner_tree = SuitabilityGraph() next_node = self.__s_d[node][subset][0][3] print(node, self.__s_d[node][subset]) # pdb.set_trace() if next_node is not None: try: steiner_tree.append_path( self.__paths[tuple(sorted([node, next_node]))], self.__graph) except KeyError: _, paths = dijkstra(self.__graph, node, [next_node]) steiner_tree.append_path(paths[next_node], self.__graph) (set_e, set_f) = self.__s_d[node][subset][0][4] steiner_branch_e = SuitabilityGraph() if set_e is not None and set_e != [next_node]: steiner_branch_e = self.__build_steiner_tree(next_node, set_e) steiner_branch_f = SuitabilityGraph() if set_f is not None and set_f != [next_node] and len(set_f) > 0: steiner_branch_f = self.__build_steiner_tree(next_node, set_f) steiner_tree.append_graph(steiner_branch_e) steiner_tree.append_graph(steiner_branch_f) return steiner_tree
def __build_steiner_tree_bactracking(self, node, subset): steiner_tree = SuitabilityGraph() next_node = self.__steiner_distances[node][tuple(subset)][3] # pdb.set_trace() if next_node is not None: try: steiner_tree.append_path( self.__paths[tuple(sorted([node, next_node]))], self.__graph) except KeyError: _, paths = dijkstra(self.__graph, node, [next_node]) steiner_tree.append_path(paths[next_node], self.__graph) (best_e, best_f) = self.__steiner_distances[node][tuple(subset)][4] steiner_branch_e = SuitabilityGraph() if best_e is not None and best_e != [next_node]: steiner_branch_e = self.__build_steiner_tree_bactracking( next_node, best_e) steiner_branch_f = SuitabilityGraph() if best_f is not None and best_f != [next_node] and len(best_f) > 0: steiner_branch_f = self.__build_steiner_tree_bactracking( next_node, best_f) steiner_tree.append_graph(steiner_branch_e) steiner_tree.append_graph(steiner_branch_f) return steiner_tree
def __init__(self, graph, terminals): # Check whether graph is node-weighted. if not graph.is_node_weighted(): raise ( ValueError, "Cluster-based algorithm only works with node-weighted graphs." ) # Extract POI from the terminals list. if len(terminals) > 0: self.__poi = terminals[0] else: return # generator = SuitableNodeWeightGenerator() # Set object variables. self.__graph = SuitabilityGraph() self.__graph.append_graph(graph) self.__terminals = terminals # # self.__regions = self.__graph.get_suitable_regions(generator, excluded_nodes=terminals, # get_border_internal_nodes=True, get_centroid_medoid=True, # get_characteristic_nodes=True) self.__regions = self.__graph.get_suitable_regions( generator, excluded_nodes=terminals, get_border_internal_nodes=True, get_centroid_medoid=True) # self.__nodes = [] for id_r in self.__regions: # # characteristic_nodes = self.__regions[id_r][6] # self.__nodes.extend(characteristic_nodes) border_nodes = self.__regions[id_r][1] self.__nodes.extend(border_nodes) # # if len(characteristic_nodes) == 0: # medoid = self.__regions[id_r][4] # # print(medoid) # self.__nodes.append(medoid) for t in terminals: self.__nodes.append(t) # self.__dist, self.__paths = self.__graph.get_dist_paths( origins=self.__nodes, destinations=self.__nodes)
def get_suitability_graph_from_session(request): graph = request.session['graph'] suitability_graph = SuitabilityGraph() for node_id, (node_weight, adj_dict, data) in graph.iteritems(): new_adj_dict = {int(neighbour): edge_cost for neighbour, edge_cost in adj_dict.iteritems()} suitability_graph[int(node_id)] = (node_weight, new_adj_dict, data) dist = {} for k, v in request.session['dist'].iteritems(): k_ = k.split(",") dist[(long(k_[0]), long(k_[1]))] = v suitability_graph.dist = dist pairs = set() for k in request.session['pairs_dist_paths']: k_ = k.split(",") pairs.add((long(k_[0]), long(k_[1]))) suitability_graph.pairs_dist_paths = pairs return suitability_graph
def __init__(self, graph, terminals, poi, max_level_attraction=2, contract_graph=True, contracted_graph=None, within_convex_hull=False, dist_paths_suitable_nodes=None): if not graph.is_node_weighted(): raise ( ValueError, "Gravitation algorithm only works with node-weighted graphs.") # Store class variables for future references. self.__original_graph = graph self.__terminals = terminals self.__poi = poi self.__contract_graph = contract_graph # terminals_poi = list(terminals) terminals_poi.append(poi) generator = SuitableNodeWeightGenerator() # Contracted graph... if contract_graph: if contracted_graph is not None: self.__graph = contracted_graph.copy() else: self.__graph = SuitabilityGraph() self.__graph.append_graph(graph) self.__graph.contract_suitable_regions( generator, excluded_nodes=terminals_poi) else: self.__graph = SuitabilityGraph() self.__graph.append_graph(graph) # # # ngh = NetworkXGraphHelper(self.__original_graph) # ngh.draw_graph(nodes_1=terminals, # nodes_2=[poi], # subgraphs_1=[r for _, (r, _, _) in self.__graph.contracted_regions.iteritems()], # node_weight_generator=generator, # node_size=25) # # # ngh = NetworkXGraphHelper(self.__graph) # ngh.draw_graph(node_weight_generator=generator, node_size=25, node_labels=True) # Copy distances and paths dictionary since it will be changed. dist_paths = None if dist_paths_suitable_nodes is not None: dist_paths = dict(dist_paths_suitable_nodes) for e in terminals_poi: dist_paths[e] = dijkstra(self.__graph, e) # Get the suitable nodes. if within_convex_hull: self.__suitable_nodes = self.__graph.get_suitable_nodes_within_convex_set( terminals_poi, generator, dist_paths) else: self.__suitable_nodes = self.__graph.get_suitable_nodes( generator, excluded_nodes=terminals_poi) # print(self.__suitable_nodes) # self.__dist_paths_node_node = {} if dist_paths is not None: self.__dist_paths_node_node = { n: dist_paths[n] for n in self.__suitable_nodes } else: self.__dist_paths_node_node = \ {n: dijkstra(self.__graph, n) for n in self.__suitable_nodes} for e in terminals_poi: if e not in self.__dist_paths_node_node: self.__dist_paths_node_node[e] = dijkstra(self.__graph, e) # max_distances = [ max(self.__dist_paths_node_node[n][0].values()) for n in self.__suitable_nodes if len(self.__dist_paths_node_node[n][0].values()) > 0 ] if len(max_distances) > 0: self.__max_dist = max(max_distances) else: self.__max_dist = 0 # # # max_level_attraction_poi = 0 # for t in terminals: # max_level_attraction_poi = max(max_level_attraction_poi, len(self.__dist_paths_node_node[poi][1][t])) # mass = self.__calculate_mass_suitable_node(poi) # self.__attract_nodes_to(poi, mass, poi, max_level_attraction_poi, 0, []) # dist_to_poi = {} for n in self.__suitable_nodes: try: dist_to_poi[n] = self.__dist_paths_node_node[n][0][poi] except KeyError: dist_to_poi[n] = sys.maxint # dist_to_poi = {n: self.__dist_paths_node_node[n][0][poi] for n in self.__suitable_nodes} # ord_suit_nodes = sorted(dist_to_poi.iteritems(), key=operator.itemgetter(1), reverse=True) ord_suit_nodes = sorted(dist_to_poi.iteritems(), key=operator.itemgetter(1)) for n, _ in ord_suit_nodes: mass = self.__calculate_mass_suitable_node(n) self.__attract_nodes_to(n, mass, n, max_level_attraction, 0, [])
def __init__(self, graph, terminals, poi, contract_graph=True, contracted_graph=None, within_convex_hull=False, dist_paths_suitable_nodes=None): # Check whether graph is node-weighted. if not graph.is_node_weighted(): raise (ValueError, "Spiders algorithm only works with node-weighted graphs.") # Store class variables for future references. self.__original_graph = graph self.__terminals = terminals self.__poi = poi self.__contract_graph = contract_graph terminals_poi = list(terminals) terminals_poi.append(poi) generator = SuitableNodeWeightGenerator() # Contracted graph... if contract_graph: if contracted_graph is not None: self.__graph = contracted_graph.copy() else: self.__graph = SuitabilityGraph() self.__graph.append_graph(graph) self.__graph.contract_suitable_regions( generator, excluded_nodes=terminals_poi) else: self.__graph = SuitabilityGraph() self.__graph.append_graph(graph) # Copy distances and paths dictionary since it will be changed. dist_paths = None if dist_paths_suitable_nodes is not None: dist_paths = dict(dist_paths_suitable_nodes) for e in terminals_poi: dist_paths[e] = dijkstra(self.__graph, e) # Get the suitable nodes. if within_convex_hull: self.__suitable_nodes = self.__graph.get_suitable_nodes_within_convex_set( terminals_poi, generator, dist_paths) else: self.__suitable_nodes = self.__graph.get_suitable_nodes( generator, excluded_nodes=terminals_poi) # POI will be included in this list. self.__suitable_nodes.append(poi) # Calculate distances and paths between nodes. IMPORTANT: Only suitable nodes are regarded as start nodes. self.__dist_paths_node_node = {} # self.__dist_paths_node_within_region_node = {} if dist_paths is not None: self.__dist_paths_node_node = { n: dist_paths[n] for n in self.__suitable_nodes } # for n in self.__suitable_nodes: # self.__dist_paths_node_node[n] = dist_paths[n] # if n in self.__graph.contracted_regions: # region = self.__graph.contracted_regions[n][0] # for w in region: # self.__dist_paths_node_within_region_node[w] = \ # dijkstra(self.__original_graph, w, consider_node_weights=False) else: self.__dist_paths_node_node = \ {n: dijkstra(self.__graph, n) for n in self.__suitable_nodes} # for n in self.__suitable_nodes: # self.__dist_paths_node_node[n] = dijkstra(self.__graph, n, consider_node_weights=False) # if n in self.__graph.contracted_regions: # region = self.__graph.contracted_regions[n][0] # for w in region: # self.__dist_paths_node_within_region_node[w] = \ # dijkstra(self.__original_graph, w, consider_node_weights=False) for e in terminals_poi: if e not in self.__dist_paths_node_node: self.__dist_paths_node_node[e] = dijkstra(self.__graph, e) # For every terminal create a subtree which has such terminal as the only node. Each subtree is digraph. self.__subtrees = {} for s in terminals: subtree = SuitabilityGraph() subtree[s] = (self.__graph[s][0], {}) self.__subtrees[s] = subtree # IMPORTANT: This method calculates the distances and paths from suitable nodes only. self.__calculate_distances_paths_to_subtrees()
def __merge_subtrees(subtrees): result = SuitabilityGraph() for subtree in subtrees: result.append_graph(subtree) return result
def __init__(self, graph, terminals, hot_spots=None, generator=None, distances=None): # Check whether graph is node-weighted. if not graph.is_node_weighted(): raise (ValueError, "Lazy Steiner Tree only works with node-weighted graphs.") # Extract POI from the terminals list. if len(terminals) > 0: self.__poi = terminals[0] else: return # Set object variables. self.__graph = SuitabilityGraph() self.__graph.append_graph(graph) self.__terminals = terminals self.__hot_spots = None self.__nodes = None self.__s_d = {} self.__paths = {} self.__refs = {} # Set hot spots. if hot_spots is None: if generator is None: generator = SuitableNodeWeightGenerator() self.__hot_spots = self.__graph.get_suitable_nodes( generator, excluded_nodes=terminals) else: self.__hot_spots = list(hot_spots) # Set nodes = hot spots + terminals. self.__nodes = list(self.__hot_spots) for t in terminals: self.__nodes.append(t) # Set distances. if distances is None: len_hot_spots = len(self.__hot_spots) self.__distances = {} for t in self.__terminals: dist, paths = dijkstra(self.__graph, t, self.__nodes) for n in self.__nodes: try: self.__distances[tuple(sorted([t, n]))] = (dist[n], 'N') self.__paths[tuple(sorted([t, n]))] = paths[n] except KeyError: self.__distances[tuple(sorted([t, n]))] = (sys.maxint, 'N') self.__paths[tuple(sorted([t, n]))] = [] for h1 in self.__hot_spots: for i in range(self.__hot_spots.index(h1), len_hot_spots): h2 = self.__hot_spots[i] distance = 0 d_type = 'E' if h1 == h2: d_type = 'N' else: distance = haversine(self.__graph[h1][2]['lat'], self.__graph[h1][2]['lon'], self.__graph[h2][2]['lat'], self.__graph[h2][2]['lon']) self.__distances[tuple(sorted([h1, h2]))] = (distance, d_type) else: self.__distances = dict(distances)
results = [] generator = SuitableNodeWeightGenerator() # try: for seed in seeds: print("seed:", seed) for msns in range(len(ms)): print("nodes:", ms[msns] * ns[msns]) graph = GridDigraphGenerator().generate( ms[msns], ns[msns], node_weighted=True, node_weight_generator=generator, seed=seed) suitability_graph = SuitabilityGraph() suitability_graph.append_graph(graph) hotspots = suitability_graph.get_suitable_nodes(generator) start_time = time.clock() suitability_graph.compute_dist_paths(origins=hotspots, destinations=hotspots, compute_paths=False) print "compute", time.clock() - start_time, "# hotspots:", len( hotspots) for num_seats in capacity: # suitability_graph.extend_suitable_regions(seed, generator) # hotspots = suitability_graph.get_suitable_nodes(generator) # print i, "# hotspots:", len(hotspots) for num_terminals in nums_terminals:
def generate_graph(results, generator, cost_type="distance", capacitated=False): graph = SuitabilityGraph(capacitated=capacitated) # prev_way_id = None prev_node_id = None hotspots = set() pois = set() for r in results: way_id = r[0] node_id = r[1] type_ = r[3] stype = r[4] poi_name = r[5] lat = float(r[6]) lon = float(r[7]) sa1_code = r[8] sa2_code = r[9] hw_type = r[10] if node_id not in graph: if type_ == "hotspot": graph[node_id] = (generator.weights["VERY_SUITABLE"][0], {}, {'lat': lat, 'lon': lon, 'sa1': sa1_code, 'sa2': sa2_code, 'subtype': stype}) hotspots.add(node_id) else: if type_ == "poi": pois.add(node_id) graph[node_id] = (generator.weights["WARNING"][0], {}, {'lat': lat, 'lon': lon, 'sa1': sa1_code, 'sa2': sa2_code, 'subtype': stype, 'name': poi_name}) if prev_way_id == way_id: prev_lat = graph[prev_node_id][2]['lat'] prev_lon = graph[prev_node_id][2]['lon'] # Cost estimation cost = 0 distance = haversine(lat, lon, prev_lat, prev_lon) if cost_type == "distance": cost = distance elif cost_type == "travel_time": cost = osm_avg(distance, hw_type) # graph[node_id][1][prev_node_id] = cost graph[prev_node_id][1][node_id] = cost prev_way_id = way_id prev_node_id = node_id # # pdb.set_trace() isolated = [] # Both dictionaries will INCLUDE HOT SPOTS AND POIs. nodes_by_sa1_code = {} nodes_by_sa2_code = {} # for node_id, info in graph.iteritems(): if len(info[1]) == 0 or (len(info[1]) == 1 and info[1].keys()[0] == node_id): isolated.append(node_id) else: sa1_code = info[2]['sa1'] sa2_code = info[2]['sa2'] if sa1_code in nodes_by_sa1_code: nodes_by_sa1_code[sa1_code].append(node_id) else: nodes_by_sa1_code[sa1_code] = [node_id] if sa2_code in nodes_by_sa2_code: nodes_by_sa2_code[sa2_code].append(node_id) else: nodes_by_sa2_code[sa2_code] = [node_id] for node_id in isolated: del graph[node_id] if node_id in hotspots: hotspots.remove(node_id) if node_id in pois: pois.remove(node_id) # print "h:", len(hotspots), "p:", len(pois) return graph, list(hotspots), list(pois), nodes_by_sa1_code, nodes_by_sa2_code
generator = SuitableNodeWeightGenerator() results = [] try: for seed in range(num_seeds): for size in sizes: graph = GridDigraphGenerator().generate( size, size, node_weighted=True, node_weight_generator=generator, seed=seed) suitability_graph = SuitabilityGraph() suitability_graph.append_graph(graph) total_num_suitable_nodes = len( suitability_graph.get_suitable_nodes(generator)) for num_terminals in nums_terminals: for sample in range(num_samples): line = [ seed, size * size, total_num_suitable_nodes, num_terminals, sample + 1 ] terminals = np.random.choice(a=size * size,
def generate(self, m, n, nodes=None, edge_weighted=True, node_weighted=False, node_weights=None, node_weight_generator=None, capacitated=False, capacities_range=(1, 100), seed=0): if m <= 1 or n <= 1: return if node_weighted: self.graph = SuitabilityGraph(capacitated=capacitated) else: self.graph = Graph(capacitated=capacitated) if edge_weighted or node_weighted or capacitated: np.random.seed(seed) for i in range(m * n): node = i if nodes is not None: node = nodes[i] if node_weighted: if node_weights is not None: self.graph[node] = (node_weights[i], {}, {}) elif node_weight_generator is not None: self.graph[node] = (node_weight_generator.generate(), {}, {}) else: raise (RuntimeError, "Grid Digraph: Can't generate a node-weighted grid digraph without a node-weight generator.") else: self.graph[node] = {} if i / n == 0: # First row if nodes is not None: node_b = nodes[i + n] else: node_b = i + n if node_weighted: if edge_weighted: self.graph[node][1][node_b] = np.random.uniform() else: self.graph[node][1][node_b] = 1 else: if edge_weighted: self.graph[node][node_b] = np.random.uniform() else: self.graph[node][node_b] = 1 self.__set_left_right_nodes(node, i, n, nodes, edge_weighted, node_weighted) elif i / n == m - 1: # Last row if nodes is not None: node_a = nodes[i - n] else: node_a = i - n if node_weighted: self.graph[node][1][node_a] = self.graph[node_a][1][node] else: self.graph[node][node_a] = self.graph[node_a][node] self.__set_left_right_nodes(node, i, n, nodes, edge_weighted, node_weighted) else: if nodes is not None: node_b = nodes[i + n] node_a = nodes[i - n] else: node_b = i + n node_a = i - n if node_weighted: self.graph[node][1][node_a] = self.graph[node_a][1][node] if edge_weighted: self.graph[node][1][node_b] = np.random.uniform() else: self.graph[node][1][node_b] = 1 else: self.graph[node][node_a] = self.graph[node_a][node] if edge_weighted: self.graph[node][node_b] = np.random.uniform() else: self.graph[node][node_b] = 1 self.__set_left_right_nodes(node, i, n, nodes, edge_weighted, node_weighted) if capacitated: edges = self.graph.get_edges() capacities = {e: np.random.randint(capacities_range[0], capacities_range[1]) for e in edges} self.graph.set_capacities(capacities) return self.graph