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 b  
    12271227            out = -out
    12281228
    12291229        return []
     1230
     1231    def bidirectional_dijkstra(self,x,y):
     1232        r"""
     1233        Returns the shortest path between x and y using
     1234        a bidirectional version of Dijkstra
     1235 
     1236        EXAMPLE::
     1237 
     1238            sage: G = Graph(graphs.PetersenGraph(), implementation='c_graph')
     1239            sage: for (u,v) in G.edges(labels=None):
     1240            ...      G.set_edge_label(u,v,1)
     1241            sage: G.shortest_path(0,1,by_weight=True)
     1242            [0, 1]
     1243        """
     1244
     1245        if x==y:
     1246            return 0
     1247
     1248        # ****************** WARNING **********************
     1249        # Use Python to maintain a heap...
     1250        # Rewrite this in Cython as soon as possible !
     1251        # *************************************************
     1252        from heapq import heappush, heappop
     1253
     1254
     1255        # As for shortest_path, the roles of x and y are symmetric, hence we define
     1256        # dictionaries like pred_current and pred_other, which represent alternatively
     1257        # pred_x or pred_y according to the side studied
     1258        cdef int x_int = get_vertex(x, self.vertex_ints, self.vertex_labels, self._cg)
     1259        cdef int y_int = get_vertex(y, self.vertex_ints, self.vertex_labels, self._cg)
     1260        cdef int u = 0
     1261        cdef int v = 0
     1262        cdef int w = 0
     1263        cdef int pred
     1264        cdef float distance
     1265        cdef float edge_label
     1266        cdef int side
     1267
     1268        # Each vertex knows its predecessors in the search, for each side
     1269        cdef dict pred_x = {}
     1270        cdef dict pred_y = {}
     1271        cdef dict pred_current
     1272        cdef dict pred_other
     1273
     1274        # Stores the distances from x and y
     1275        cdef dict dist_x = {}
     1276        cdef dict dist_y = {}
     1277        cdef dict dist_current
     1278        cdef dict dist_other
     1279
     1280        # Lists of vertices who are left to be explored
     1281        # they are represented as 4-uples : (distance, side, predecessor ,name)
     1282        # 1 indicates x's side, -1 indicates y's, the distance being
     1283        # defined relatively
     1284        cdef list queue = [(0,1,x_int,x_int),(0,-1,y_int,y_int)]
     1285
     1286        cdef list shortest_path = []
     1287
     1288        # As long as the current side (x or y) is not totally explored ...
     1289        while queue:
     1290            (distance, side, pred, v) = heappop(queue)
     1291
     1292            if side == 1:
     1293                dist_current, dist_other = dist_x, dist_y
     1294                pred_current, pred_other = pred_x, pred_y
     1295            else:
     1296                dist_current, dist_other = dist_y, dist_x
     1297                pred_current, pred_other = pred_y, pred_x
     1298           
     1299            if not dist_current.has_key(v):
     1300                pred_current[v] = pred
     1301                dist_current[v] = distance
     1302
     1303                if dist_other.has_key(v):
     1304                   
     1305                    # build the shortest path and returns in.
     1306
     1307                    w = v
     1308
     1309                    while w != x_int:
     1310                        shortest_path.append(vertex_label(w, self.vertex_ints, self.vertex_labels, self._cg))
     1311                        w = pred_x[w]
     1312
     1313                    shortest_path.append(x)
     1314                    shortest_path.reverse()
     1315
     1316                    if v == y_int:
     1317                        return shortest_path
     1318
     1319                    w=pred_y[v]
     1320                    while w != y_int:
     1321                        shortest_path.append(vertex_label(w, self.vertex_ints, self.vertex_labels, self._cg))
     1322                        w = pred_y[w]
     1323                    shortest_path.append(y)
     1324
     1325                    return shortest_path
     1326           
     1327       
     1328                for w in (self._cg.out_neighbors(v) if side == 1 else self._cg.in_neighbors(v)):
     1329                    # If the neihgbor is new, adds its non-found neighbors to the queue
     1330                    if not dist_current.has_key(w):
     1331                        edge_label = self.get_edge_label(v,w) if side == 1 else self.get_edge_label(w,v)
     1332                        heappush(queue,(distance + edge_label,side,v,w))
     1333   
     1334
     1335        return []
     1336
  • sage/graphs/graph.py

    diff -r 58c7514ffc5b -r 52f5564eafee sage/graphs/graph.py
    a b  
    62276227        if by_weight:
    62286228            if bidirectional:
    62296229                try:
    6230                     L = networkx.bidirectional_dijkstra(self.networkx_graph(copy=False), u, v)[1]
    6231                 except:
    6232                     L = False
     6230                    L = self._backend.bidirectional_dijkstra(u,v)
     6231                except AttributeError:
     6232                    try:
     6233                        L = networkx.bidirectional_dijkstra(self.networkx_graph(copy=False), u, v)[1]
     6234                    except:
     6235                        L = False
    62336236            else:
    62346237                L = networkx.dijkstra_path(self.networkx_graph(copy=False), u, v)
    62356238        else: