| #------------------------------------------------------------- |
| # |
| # Licensed to the Apache Software Foundation (ASF) under one |
| # or more contributor license agreements. See the NOTICE file |
| # distributed with this work for additional information |
| # regarding copyright ownership. The ASF licenses this file |
| # to you under the Apache License, Version 2.0 (the |
| # "License"); you may not use this file except in compliance |
| # with the License. You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, |
| # software distributed under the License is distributed on an |
| # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| # KIND, either express or implied. See the License for the |
| # specific language governing permissions and limitations |
| # under the License. |
| # |
| #------------------------------------------------------------- |
| |
| # Computes the minimum distances (shortest-path) between a single source vertex and every other vertex in the graph. |
| # |
| # Grzegorz Malewicz, Matthew H. Austern, Aart J. C. Bilk, |
| # James C. Dehnert, Ikkan Horn, Naty Leiser and Grzegorz Czajkowski: |
| # Pregel: A System for Large-Scale Graph Processing, SIGMOD 2010 |
| # |
| # INPUT: |
| # ------------------------------------------------------------------------------------------- |
| # G adjacency matrix of the labeled graph: Such graph can be directed |
| # (G is symmetric) or undirected (G is not symmetric). |
| # The values of G can be 0/1 (just specifying whether the nodes |
| # are connected or not) or integer values (representing the weight |
| # of the edges or the distances between nodes, 0 if not connected). |
| # maxi Integer max number of iterations accepted (0 for FALSE, i.e. |
| # max number of iterations not defined) |
| # sourceNode node index to calculate the shortest paths to all other nodes. |
| # verbose flag for verbose debug output |
| # ------------------------------------------------------------------------------------------- |
| # |
| # OUTPUT: |
| # -------------------------------------------------------------------------------------- |
| # C Output matrix (double) of minimum distances (shortest-path) between |
| # vertices: The value of the ith row and the jth column of the output |
| # matrix is the minimum distance shortest-path from vertex i to vertex j. |
| # When the value of the minimum distance is infinity, the two nodes are |
| # not connected. |
| # -------------------------------------------------------------------------------------- |
| |
| m_shortestPath = function(Matrix[Double] G, Integer maxi = 0, Integer sourceNode, Boolean verbose = FALSE) |
| return (Matrix[Double] C) |
| { |
| if(verbose) |
| print("SHORTEST PATH CALCULATION:"); |
| |
| if(min(G) < 0) |
| stop("Shortest Path: All values in G must be positive.") |
| if(ncol(G) != nrow(G)) |
| stop("Shortest Path: input graph G must be a squared matrix.") |
| |
| # initialize the matrix of minimum distances with "infinity" values: |
| minDist = matrix(Inf, rows=nrow(G), cols=1); |
| |
| # update minimum distance from the sourceNode to itself to 0: |
| minDist[sourceNode, 1] = 0; |
| |
| iter = 1 |
| diff = Inf; |
| while( diff > 0 & (maxi==0 | iter<=maxi) ) { |
| # avoid densification of 'colMins(G + minDist)' via colMin-colMax transform |
| # (we exploit here that ^x with x!=0 is treated as sparse-safe and otherwise |
| # Inf or NaN and replaced with 0, which keeps large sparse graphs sparse) |
| Gp = (G + (G!=0) * minDist)^(-1); |
| Gp = replace(target=Gp, pattern=Inf, replacement=0); |
| Gp = replace(target=Gp, pattern=NaN, replacement=0); |
| u = min(t(1/colMaxs(Gp)), minDist); |
| diff = sum(u != minDist); |
| minDist = u; # update assignment |
| if( verbose ) |
| print("Shortest Path: iter = "+iter+", #diff = "+diff); |
| iter = iter + 1; |
| } |
| |
| C = minDist; |
| if(verbose) |
| print("Shortest Path: \n"+toString(C)); |
| } |