def find_paths(self): self.d = Dijkstra(_get_dbl_level_dict(self.G), len(self.nodes)) self.dijkPaths = {} for each in self.sampled: for e in each: if self.dijkPaths.get(e, -1) == -1: self.dijkPaths[e] = self.d.shortest_path(self.nodes, e)
def store_nodeLandmarks(self): dijk_obj = Dijkstra(_get_dbl_level_dict(self.G, self.noNodes), self.noNodes) for landmark in self.nodeLandmarks: if landmark in self.sp: continue self.sp[landmark] = dijk_obj.shortest_path(self.vertices, landmark)
def store(self, distance_hash, n): self.order = n self._dbl_lvl_dict = _get_dbl_level_dict(distance_hash) sp_dijkstra = Dijkstra(self._dbl_lvl_dict, self.order) for i in range(self.order): self.ub_matrix.append([1] * self.order) for i in range(self.order): nodes = list(range(self.order)) sp = sp_dijkstra.shortest_path(nodes, i) for index in range(self.order): # distance, node, parent self.ub_matrix[i][index] = sp[index][0] self.ub_matrix[index][i] = sp[index][0] self.search_started = [False] * n for i in range(n): self.lb_matrix.append([0] * n) if n - i - 1 != 0: self.uncalculated[i] = set(range(i + 1, n)) for k in distance_hash.keys(): x, y = k self.lb_matrix[x][y] = distance_hash[k] self.lb_matrix[y][x] = distance_hash[k] self.uncalculated[min(x, y)].remove(max(x, y)) if len(self.uncalculated[min(x, y)]) == 0: del self.uncalculated[min(x, y)] self.sparse_matrix = SparseMatrix(distance_hash, n) if self.max_path_length == 2: for i in range(n): for j in range(i + 1, n): self._update(i, j) else: for i in range(n): self._dfs(i)
def store_edgeLandmarks(self): dijk_obj = Dijkstra(_get_dbl_level_dict(self.G, self.noNodes), self.noNodes) for (x, y) in self.edgeLandmarks: if x not in self.sp: self.sp[x] = dijk_obj.shortest_path(self.vertices, x) if y not in self.sp: self.sp[y] = dijk_obj.shortest_path(self.vertices, y)
def __init__(self, edge_list, order_val, k): self.edge_list = edge_list self.k = k self.order_val = order_val self.dbl_dict = _get_dbl_level_dict(self.edge_list) self.d = Dijkstra(self.dbl_dict, self.order_val) self.landmarks = None self.dijk_dict = {}
def get_landmarks(self): assert self.k >= 1 # self.k_landmarks = [random.choice(self.vertices)] self.k_landmarks = [0] sum_node_to_landmark = {} select = self.k_landmarks[-1] import copy dup_nodes = copy.copy(self.vertices) while len(self.k_landmarks) < self.k + 1: # sum_node_to_landmark = {} for node in range(self.noNodes): if node in self.k_landmarks: continue u, v = min(select, node), max(select, node) if sum_node_to_landmark.get(node, -1) == -1: sum_node_to_landmark[node] = 0 if self.G.get((u, v), -1) == -1: dist_val = self.vanila_oracle(u, v) # self.update((u, v), dist_val) else: dist_val = self.G[(u, v)] self.G[(u, v)] = dist_val if len(self.edgeLandmarks) < self.k1: self.edgeLandmarks.add({ 'edge': (u, v), "length": dist_val }) # print("Val 53 here: {}, vals:{}".format((u, v), dist_val)) elif self.edgeLandmarks[0]['length'] < dist_val: del self.edgeLandmarks[0] self.edgeLandmarks.add({ 'edge': (u, v), "length": dist_val }) # print("Val 57 here: {}, vals:{}".format((u, v), dist_val)) sum_node_to_landmark[node] += dist_val select = select_the_new_landmark(sum_node_to_landmark) dup_nodes.remove(select) sum_node_to_landmark.pop(select) self.k_landmarks.append(select) del self.k_landmarks[-1] print("Landmarks(LSS): {}".format(self.k_landmarks)) self.collector = dict( zip(self.k_landmarks, [1] * len(self.k_landmarks))) for edge_details in self.edgeLandmarks: a, b = edge_details["edge"] a, b = min(a, b), max(a, b) if a in self.collector: self.collector[a] += 1 else: self.collector[a] = 1 if b in self.collector: self.collector[b] += 1 else: self.collector[b] = 1 dijk_obj = Dijkstra(_get_dbl_level_dict(self.G, self.noNodes), self.noNodes) # print("Keys of Collector {}".format(self.collector.keys())) # print("Node Landmarks: {}".format(self.k_landmarks)) for landmark in self.collector: if landmark in self.sp: continue self.sp[landmark] = dijk_obj.shortest_path(self.vertices, landmark)
def update(self, edge, val): # print("\nEdge: {}; val: {}\n\n".format(edge, val)) u, v = min(edge), max(edge) self.G[(u, v)] = val dijk_obj = Dijkstra(_get_dbl_level_dict(self.G, self.noNodes), self.noNodes) new_sp_u = dijk_obj.shortest_path(self.vertices, u) new_sp_v = dijk_obj.shortest_path(self.vertices, v) self.sp[u] = new_sp_u self.sp[v] = new_sp_v for key in self.sp.keys(): if key == u or key == v: continue if u not in self.sp[key] and v not in self.sp[key]: continue for node in self.vertices: if key in new_sp_u and node in new_sp_u: change_len_node = min( 1, new_sp_u[key][0] + new_sp_v[node][0] + val, new_sp_u[node][0] + new_sp_v[key][0] + val) if node in self.sp[key]: self.sp[key][node][0] = min(change_len_node, self.sp[key][node][0]) else: self.sp[key][node] = [change_len_node] local_total = SortedList([], key=lambda x: x['length']) for each in self.more_node_landmarks: total = 0 for key, val in self.sp[each].items(): total += val[0] local_total.add({'node': each, "length": total}) if u not in self.more_node_landmarks: total = 0 for key, val in new_sp_u.items(): total += val[0] local_total.add({'node': u, "length": total}) if v not in self.more_node_landmarks: total = 0 for key, val in new_sp_v.items(): total += val[0] local_total.add({'node': v, "length": total}) self.more_node_landmarks = list( map(lambda x: x['node'], local_total[:-2])) # print(local_total, self.more_node_landmarks) if u in self.collector: self.collector[u] += 2 else: self.collector[u] = 2 if v in self.collector: self.collector[v] += 2 else: self.collector[v] = 2 self.collector[local_total[-1]["node"]] -= 1 self.collector[local_total[-2]["node"]] -= 1 if self.collector[local_total[-1]["node"]] == 0: # print("Deleting {}".format(self.collector[local_total[-1]["node"]])) del self.collector[local_total[-1]["node"]] del self.sp[local_total[-1]["node"]] if self.collector[local_total[-2]["node"]] == 0: # print("Deleting {}".format(self.collector[local_total[-2]["node"]])) del self.collector[local_total[-2]["node"]] del self.sp[local_total[-2]["node"]] # Edge landmark update # print("Edge Landmarks: {}".format({'edge': (u, v), "length": self.G[(u, v)]})) self.edgeLandmarks.add({'edge': (u, v), "length": self.G[(u, v)]}) self.collector[self.edgeLandmarks[0]["edge"][0]] -= 1 self.collector[self.edgeLandmarks[0]["edge"][1]] -= 1 if self.collector[self.edgeLandmarks[0]["edge"][1]] == 0: # print("Deleting {}".format(self.collector[self.edgeLandmarks[-1]["edge"][1]])) del self.collector[self.edgeLandmarks[0]["edge"][1]] del self.sp[self.edgeLandmarks[0]["edge"][1]] if self.collector[self.edgeLandmarks[0]["edge"][0]] == 0: # print("Deleting {}".format(self.collector[self.edgeLandmarks[-2]["edge"][1]])) del self.collector[self.edgeLandmarks[0]["edge"][0]] del self.sp[self.edgeLandmarks[0]["edge"][0]] # print("Deleting Edge LM{}".format(self.edgeLandmarks[-1])) del self.edgeLandmarks[0]
def greedy_sampling(self, landmarks): """ This function greedily selects the edges from the known edges for our greedy algorithm :param landmarks: number of sample edges needed from the known edge set :return: """ file_writer = open(os.path.join("elm-results", 'intermediate.txt'), 'a+') file_writer.write("{}\n".format("*" * 50)) file_writer.write( "Value of Graph: {}\nValue of k: {}\nSampling State: {}\n{}\n". format(len(self.nodes), landmarks, self.Sampling, "*" * 50)) file_writer.flush() self.landmarks = landmarks previous = -1 out = [(-1, -1)] if self.landmarks < 1: pass for knownEdge in self.known: total = 0 for edge in self.sampled: total += max( 0, self.G[knownEdge] - self.dijkPaths[edge[0]][knownEdge[0]][0] - self.dijkPaths[edge[1]][knownEdge[1]][0], self.G[knownEdge] - self.dijkPaths[edge[0]][knownEdge[1]][0] - self.dijkPaths[edge[1]][knownEdge[0]][0]) if total > previous: previous = total out[-1] = knownEdge # net_total += previous if self.dijkPatishs.get(out[-1][0], -1) == -1: self.dijkPaths[out[-1][0]] = self.d.shortest_path( self.nodes, out[-1][0]) if self.dijkPaths.get(out[-1][1], -1) == -1: self.dijkPaths[out[-1][1]] = self.d.shortest_path( self.nodes, out[-1][1]) net_total = self.get_unknown_edge_estimates(out) print("Iteration 1: " + str(net_total)) file_writer.write("Iteration 1: " + str(net_total) + "\n") file_writer.flush() self.known.remove(out[-1]) representative = [out[-1]] * len(self.sampled) # import pdb # pdb.set_trace() for i in range(self.landmarks - 1): out.append((-1, -1)) previous = -1 for knownEdge in self.known: total = 0 for index, edge in enumerate(self.sampled): cost = max( 0, self.G[knownEdge] - self.dijkPaths[edge[0]][knownEdge[0]][0] - self.dijkPaths[edge[1]][knownEdge[1]][0], self.G[knownEdge] - self.dijkPaths[edge[0]][knownEdge[1]][0] - self.dijkPaths[edge[1]][knownEdge[0]][0]) repr = representative[index] cost_current = max( 0, self.G[repr] - self.dijkPaths[edge[0]][repr[0]][0] - self.dijkPaths[edge[1]][repr[1]][0], self.G[repr] - self.dijkPaths[edge[0]][repr[1]][0] - self.dijkPaths[edge[1]][repr[0]][0]) if cost > cost_current: total += cost - cost_current if total > previous: previous = total out[-1] = knownEdge # net_total += previous if self.dijkPaths.get(out[-1][0], -1) == -1: self.dijkPaths[out[-1][0]] = self.d.shortest_path( self.nodes, out[-1][0]) if self.dijkPaths.get(out[-1][1], -1) == -1: self.dijkPaths[out[-1][1]] = self.d.shortest_path( self.nodes, out[-1][1]) net_total = self.get_unknown_edge_estimates(out) print("Iteration " + str(i + 2) + ": " + str(net_total)) file_writer.write("Iteration " + str(i + 2) + ": " + str(net_total) + "\n") file_writer.flush() # print(previous) for index, edge in enumerate(self.sampled): cost = max( 0, self.G[out[-1]] - self.dijkPaths[edge[0]][out[-1][0]][0] - self.dijkPaths[edge[1]][out[-1][1]][0], self.G[out[-1]] - self.dijkPaths[edge[0]][out[-1][1]][0] - self.dijkPaths[edge[1]][out[-1][0]][0]) repr = representative[index] cost_current = max( 0, self.G[repr] - self.dijkPaths[edge[0]][repr[0]][0] - self.dijkPaths[edge[1]][repr[1]][0], self.G[repr] - self.dijkPaths[edge[0]][repr[1]][0] - self.dijkPaths[edge[1]][repr[0]][0]) if cost > cost_current: representative[index] = out[-1] self.known.remove(out[-1]) self.greedyK = out d = Dijkstra(_get_dbl_level_dict(self.G), len(self.nodes)) for each in self.greedyK: for e in each: if self.dijkPaths.get(e, -1) == -1: self.dijkPaths[e] = d.shortest_path(self.nodes, e) new_total = self.get_unknown_edge_estimates(self.greedyK) print(new_total) for i in range(len(self.nodes)): if i % 100 == 0: print(i) for j in range(i + 1, len(self.nodes)): edge = (i, j) some = 0 if self.G.get((i, j), -1) == -1: for repr in self.greedyK: some = max( some, self.G[repr] - self.dijkPaths[repr[0]][edge[0]][0] - self.dijkPaths[repr[1]][edge[1]][0], self.G[repr] - self.dijkPaths[repr[1]][edge[0]][0] - self.dijkPaths[repr[0]][edge[1]][0]) new_total += some print("\nEdge Landmark Sum: {} for k(Land Marks):{} ".format( new_total, self.landmarks)) file_writer.write("=" * 50 + "\n") file_writer.flush() file_writer.close() return new_total
def __init__(self, g, order_val): self.G = g self.noNodes = order_val self.vertices = [i for i in range(self.noNodes)] self._dbl_lvl_dict = _get_dbl_level_dict(self.G, order_val)
from dijkstra import Dijkstra from graph_maker import NlogNGraphMaker from helper import _get_dbl_level_dict order_val = 1000 graph_maker = NlogNGraphMaker(order_val) g = graph_maker.get_nlogn_edges() dbl_dict = _get_dbl_level_dict(g) d = Dijkstra(dbl_dict, order_val) print(d.shortest_path(list(range(order_val)), 0))