| 1119 | sage: G = Graph(graphs.PetersenGraph(), implementation='c_graph') |
| 1120 | sage: G.shortest_path(0,1) |
| 1121 | [0, 1] |
| 1122 | """ |
| 1123 | |
| 1124 | if x==y: |
| 1125 | return 0 |
| 1126 | |
| 1127 | # The function being mostly symmetric in x and y |
| 1128 | # their roles are reversed at the end of each loop |
| 1129 | # For this reason is defined, for example, |
| 1130 | # two dictionaries dist_y and dist_x containing the |
| 1131 | # distances to x and y, and a dictionary |
| 1132 | # dist_current and dist_other, pointing toward the |
| 1133 | # previous two, alternatively. |
| 1134 | # |
| 1135 | # Besides, there is another difference in the fact |
| 1136 | # that for directed graphs we are interested in paths |
| 1137 | # leaving x toward y, so we are considering the out_neighbors |
| 1138 | # on x's side, and in_neighbors on y's side |
| 1139 | |
| 1140 | cdef int x_int = get_vertex(x, self.vertex_ints, self.vertex_labels, self._cg) |
| 1141 | cdef int y_int = get_vertex(y, self.vertex_ints, self.vertex_labels, self._cg) |
| 1142 | cdef int u = 0 |
| 1143 | cdef int v = 0 |
| 1144 | cdef int w = 0 |
| 1145 | |
| 1146 | # Each vertex knows its predecessors in the search, for each side |
| 1147 | cdef dict pred_x = {} |
| 1148 | cdef dict pred_y = {} |
| 1149 | cdef dict pred_current = pred_x |
| 1150 | cdef dict pred_other = pred_y |
| 1151 | |
| 1152 | # Stores the distances from x and y |
| 1153 | cdef dict dist_x = {} |
| 1154 | cdef dict dist_y = {} |
| 1155 | cdef dict dist_current = dist_x |
| 1156 | cdef dict dist_other = dist_y |
| 1157 | dist_x[x_int] = 0 |
| 1158 | dist_y[y_int] = 0 |
| 1159 | |
| 1160 | # Lists of vertices whose neighbors have not been explored yet |
| 1161 | cdef list next_x = [x_int] |
| 1162 | cdef list next_y = [y_int] |
| 1163 | cdef list next_current = next_x |
| 1164 | cdef list next_other = next_y |
| 1165 | cdef list next_temporary = [] |
| 1166 | |
| 1167 | cdef list shortest_path = [] |
| 1168 | |
| 1169 | # We are interested in edges leaving x and entering y, so we |
| 1170 | # are dealing with two different "neighbors" functions |
| 1171 | cdef int out = 1 |
| 1172 | |
| 1173 | # As long as the current side (x or y) is not totally explored ... |
| 1174 | while next_current: |
| 1175 | next_temporary = [] |
| 1176 | |
| 1177 | # Take the next vertex in the list, and study all of its neighbors |
| 1178 | # When a new neighbor is found, it is added into a temporary list |
| 1179 | # When all the vertices in the list are tested |
| 1180 | # and next_current is replaced by the temporary list |
| 1181 | # |
| 1182 | # After this, current and other are reversed, and the loop restarts |
| 1183 | for u in next_current: |
| 1184 | for v in (self._cg.out_neighbors(u) if out == 1 else self._cg.in_neighbors(u)): |
| 1185 | # If the neihgbor is new, updates the distances and adds to the list |
| 1186 | if not dist_current.has_key(v): |
| 1187 | dist_current[v] = dist_current[u] + 1 |
| 1188 | pred_current[v] = u |
| 1189 | next_current.append(v) |
| 1190 | |
| 1191 | # If the new neighbor is already known by the other side ... |
| 1192 | |
| 1193 | if dist_other.has_key(v): |
| 1194 | # build the shortest path and returns in. |
| 1195 | |
| 1196 | w = v |
| 1197 | |
| 1198 | while w != x_int: |
| 1199 | shortest_path.append(vertex_label(w, self.vertex_ints, self.vertex_labels, self._cg)) |
| 1200 | w = pred_x[w] |
| 1201 | |
| 1202 | shortest_path.append(x) |
| 1203 | shortest_path.reverse() |
| 1204 | |
| 1205 | if v == y_int: |
| 1206 | return shortest_path |
| 1207 | |
| 1208 | w=pred_y[v] |
| 1209 | while w != y_int: |
| 1210 | shortest_path.append(vertex_label(w, self.vertex_ints, self.vertex_labels, self._cg)) |
| 1211 | w = pred_y[w] |
| 1212 | shortest_path.append(y) |
| 1213 | |
| 1214 | return shortest_path |
| 1215 | |
| 1216 | next_current = next_temporary |
| 1217 | pred_current, pred_other = pred_other, pred_current |
| 1218 | dist_current, dist_other = dist_other, dist_current |
| 1219 | next_current, next_other = next_other, next_current |
| 1220 | out = -out |
| 1221 | |
| 1222 | return [] |