# Ticket #7640: trac_7640.patch

File trac_7640.patch, 5.7 KB (added by ncohen, 11 years ago)
• ## sage/graphs/base/c_graph.pyx

```# HG changeset patch
# User Nathann Cohen <nathann.cohen@gmail.com>
# Date 1260639709 -3600
# Node ID 3ec89745ecddf37560738c9bdf6dda103b85dc16
# Parent  2e4cf9d12539d2e3acc4e4b82e794f86b8918345
Shortest path in c_graphs

diff -r 2e4cf9d12539 -r 3ec89745ecdd sage/graphs/base/c_graph.pyx```
 a self.vertex_labels = new_vx_labels def shortest_path(self,x,y): r""" Returns the shortest path between x and y EXAMPLE:: sage: G = Graph(graphs.PetersenGraph(), implementation='c_graph') sage: G.shortest_path(0,1) [0, 1] """ if x==y: return 0 # The function being mostly symmetric in x and y # their roles are reversed at the end of each loop # For this reason is defined, for example, # two dictionaries dist_y and dist_x containing the # distances to x and y, and a dictionary # dist_current and dist_other, pointing toward the # previous two, alternatively. # # Besides, there is another difference in the fact # that for directed graphs we are interested in paths # leaving x toward y, so we are considering the out_neighbors # on x's side, and in_neighbors on y's side 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 # Each vertex knows its predecessors in the search, for each side cdef dict pred_x = {} cdef dict pred_y = {} cdef dict pred_current = pred_x cdef dict pred_other = pred_y # Stores the distances from x and y cdef dict dist_x = {} cdef dict dist_y = {} cdef dict dist_current = dist_x cdef dict dist_other = dist_y dist_x[x_int] = 0 dist_y[y_int] = 0 # Lists of vertices whose neighbors have not been explored yet cdef list next_x = [x_int] cdef list next_y = [y_int] cdef list next_current = next_x cdef list next_other = next_y cdef list next_temporary = [] cdef list shortest_path = [] # We are interested in edges leaving x and entering y, so we # are dealing with two different "neighbors" functions cdef int out = 1 # As long as the current side (x or y) is not totally explored ... while next_current: next_temporary = [] # Take the next vertex in the list, and study all of its neighbors # When a new neighbor is found, it is added into a temporary list # When all the vertices in the list are tested # and next_current is replaced by the temporary list # # After this, current and other are reversed, and the loop restarts for u in next_current: for v in (self._cg.out_neighbors(u) if out == 1 else self._cg.in_neighbors(u)): # If the neihgbor is new, updates the distances and adds to the list if not dist_current.has_key(v): dist_current[v] = dist_current[u] + 1 pred_current[v] = u next_current.append(v) # If the new neighbor is already known by the other side ... 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 next_current = next_temporary pred_current, pred_other = pred_other, pred_current dist_current, dist_other = dist_other, dist_current next_current, next_other = next_other, next_current out = -out return []
• ## sage/graphs/graph.py

`diff -r 2e4cf9d12539 -r 3ec89745ecdd sage/graphs/graph.py`
 a L = networkx.dijkstra_path(self.networkx_graph(copy=False), u, v) else: if bidirectional: L = networkx.shortest_path(self.networkx_graph(copy=False), u, v) # If the graph is a C_graph, use shortest_path from its backend ! try: L = self._backend.shortest_path(u,v) except AttributeError: L = networkx.shortest_path(self.networkx_graph(copy=False), u, v) else: try: L = networkx.single_source_shortest_path(self.networkx_graph(copy=False), u)[v]