Ejemplo n.º 1
0
 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)
Ejemplo n.º 3
0
 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]
Ejemplo n.º 8
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)
Ejemplo n.º 10
0
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))