# Ticket #7673: trac_7673.patch

File trac_7673.patch, 5.2 KB (added by rlm, 11 years ago)

rebased on 4.3.rc0 + #7640

• ## sage/graphs/base/c_graph.pyx

```# HG changeset patch
# User Nathann Cohen <nathann.cohen@gmail.com>
# Date 1260639709 -3600
# Node ID 52f5564eafee5bdca2dbd815c2b34ff77d35a7e8
# Parent  58c7514ffc5ba1c1cea93899f163333594205595
Bidirectional Dijkstra in c_graphs

diff -r 58c7514ffc5b -r 52f5564eafee sage/graphs/base/c_graph.pyx```
 a out = -out return [] def bidirectional_dijkstra(self,x,y): r""" Returns the shortest path between x and y using a bidirectional version of Dijkstra EXAMPLE:: sage: G = Graph(graphs.PetersenGraph(), implementation='c_graph') sage: for (u,v) in G.edges(labels=None): ...      G.set_edge_label(u,v,1) sage: G.shortest_path(0,1,by_weight=True) [0, 1] """ if x==y: return 0 # ****************** WARNING ********************** # Use Python to maintain a heap... # Rewrite this in Cython as soon as possible ! # ************************************************* from heapq import heappush, heappop # As for shortest_path, the roles of x and y are symmetric, hence we define # dictionaries like pred_current and pred_other, which represent alternatively # pred_x or pred_y according to the side studied cdef int x_int = get_vertex(x, self.vertex_ints, self.vertex_labels, self._cg) cdef int y_int = get_vertex(y, self.vertex_ints, self.vertex_labels, self._cg) cdef int u = 0 cdef int v = 0 cdef int w = 0 cdef int pred cdef float distance cdef float edge_label cdef int side # Each vertex knows its predecessors in the search, for each side cdef dict pred_x = {} cdef dict pred_y = {} cdef dict pred_current cdef dict pred_other # Stores the distances from x and y cdef dict dist_x = {} cdef dict dist_y = {} cdef dict dist_current cdef dict dist_other # Lists of vertices who are left to be explored # they are represented as 4-uples : (distance, side, predecessor ,name) # 1 indicates x's side, -1 indicates y's, the distance being # defined relatively cdef list queue = [(0,1,x_int,x_int),(0,-1,y_int,y_int)] cdef list shortest_path = [] # As long as the current side (x or y) is not totally explored ... while queue: (distance, side, pred, v) = heappop(queue) if side == 1: dist_current, dist_other = dist_x, dist_y pred_current, pred_other = pred_x, pred_y else: dist_current, dist_other = dist_y, dist_x pred_current, pred_other = pred_y, pred_x if not dist_current.has_key(v): pred_current[v] = pred dist_current[v] = distance if dist_other.has_key(v): # build the shortest path and returns in. w = v while w != x_int: shortest_path.append(vertex_label(w, self.vertex_ints, self.vertex_labels, self._cg)) w = pred_x[w] shortest_path.append(x) shortest_path.reverse() if v == y_int: return shortest_path w=pred_y[v] while w != y_int: shortest_path.append(vertex_label(w, self.vertex_ints, self.vertex_labels, self._cg)) w = pred_y[w] shortest_path.append(y) return shortest_path for w in (self._cg.out_neighbors(v) if side == 1 else self._cg.in_neighbors(v)): # If the neihgbor is new, adds its non-found neighbors to the queue if not dist_current.has_key(w): edge_label = self.get_edge_label(v,w) if side == 1 else self.get_edge_label(w,v) heappush(queue,(distance + edge_label,side,v,w)) return []
• ## sage/graphs/graph.py

`diff -r 58c7514ffc5b -r 52f5564eafee sage/graphs/graph.py`
 a if by_weight: if bidirectional: try: L = networkx.bidirectional_dijkstra(self.networkx_graph(copy=False), u, v)[1] except: L = False L = self._backend.bidirectional_dijkstra(u,v) except AttributeError: try: L = networkx.bidirectional_dijkstra(self.networkx_graph(copy=False), u, v)[1] except: L = False else: L = networkx.dijkstra_path(self.networkx_graph(copy=False), u, v) else: