Floyd-Warshall算法在matlab中的并行化

Floyd-Warshall算法在matlab中的并行化,matlab,parallel-processing,parfor,floyd-warshall,Matlab,Parallel Processing,Parfor,Floyd Warshall,我知道这个问题以前已经被回答过好几次了,但是我检查了所有以前的答案来补救我的情况,但是没有任何帮助 我需要做的是并行化我的循环,这样每个城市或内部循环都可以并行处理。但是当使用parfor时,我得到一个错误,parfor中的变量A不能被分类。2d矩阵的大小固定为n X n。我不知道,我看不出问题所在。请帮帮我 提供给我的c实现是使用mpi.h完成的。使用mpicc。我需要实现的是,应该有n个进程,每个进程负责找到从其本地城市到所有其他城市的最短路径 每种情况都不同。就我而言: my_first_

我知道这个问题以前已经被回答过好几次了,但是我检查了所有以前的答案来补救我的情况,但是没有任何帮助

我需要做的是并行化我的循环,这样每个城市或内部循环都可以并行处理。但是当使用parfor时,我得到一个错误,parfor中的变量A不能被分类。2d矩阵的大小固定为n X n。我不知道,我看不出问题所在。请帮帮我

提供给我的c实现是使用mpi.h完成的。使用mpicc。我需要实现的是,应该有n个进程,每个进程负责找到从其本地城市到所有其他城市的最短路径

每种情况都不同。就我而言:

my_first_city=2;
my_last_city=n;
parpool(n-1);

parfor (int_city=2:n,n-1)
% broadcast all --  create threads to handle each city
  for local_city=my_first_city:n
    for city2=2:n
          A(local_city,city2)=min(A(local_city,city2),A(local_city,int_city)+A(int_city,city2));
    end
  end
end
下面是我计算最短路径的函数:

function [ A,init ] = floydWarshall(input_matrix, n )
%% Floyd_Warshall algorithm is an analytical algorithm for finding shortest paths in weighted graph ,
%  for example an adjacency matrix or a map graph.
% Floyd_Warshall algorithm compares all possible paths through a graph between each pair of vertices,
% The complexity of this algorithm is O(n^3) where n is the number of vertices, or nodes.
%% Floyd_Warshall
% inputs : 
%       n          = number of vertices to initialize an adjacency matrix.
%    input_matrix  = the input matrix of initial weights or path costs. a nXn matrix
% outputs: 
%       A  = the matrix after floydWarshall algo is applied and the matrix contains the shortest
%            paths from each node to each other node
%     init = The original matrix with all the costs from each node to each other node.
if(nargin<2)
  n=size(input_matrix);
elseif (nargin<1)
   n=size(input_matrix);
   A=magic(n);
end


for i=1:n    % marking the border rows and columns with cities
    A(i,1)=i-1;
    A(1,i)=i-1;
end

for i=1:n    % making sure that the distance from a city i to city i is 0
    A(i,i)=0;
end

for i=2:n   
    for j=2:n
        A(i,j)=input_matrix(i,j);  % input matrix, values 
    end
end


init=A;   % temp variable to store the old matrix
for int_city=2:n
    for city1=2:n
        for city2=2:n
            A(city1,city2)=min(A(city1,city2),A(city1,int_city)+A(int_city,city2));
        end  % floyd-warshall
    end
end

下面是MATLAB中实现Floyd Warshall算法的代码

%%%%% Step 0: Initialization and Parameters %%%%%

N = size(D,1); 
INF =  1000*max(max(D))*N;  %% effectively infinite distance
Y.coords = cell(length(dims),1); 
R = zeros(1,length(dims)); 

%%%%% Step 1: Construct neighborhood graph %%%%%
disp('Constructing neighborhood graph...'); 

K = n_size;
if n_fcn == 'k'
     [~, ind] = sort(D); % For matrices, sort(X) sorts each column of X in ascending order.
     for i=1:N % N is number of points
          D(i,ind((2+K):end,i)) = INF; %setting to infinity distances that more far number of neighborhoods
     end                               %two because we need to have at least one neighbor???
elseif n_fcn == 'epsilon'
     warning off    %% Next line causes an unnecessary warning, so turn it off
     D =  D./(D<=epsilon); 
     D = min(D,INF); 
     warning on
end

D = min(D,D');    %% Make sure distance matrix is symmetric


% Finite entries in D now correspond to distances between neighboring points. 
% Infinite entries (really, equal to INF) in D now correspond to 
%   non-neighoring points. 

%%%%% Step 2: Compute shortest paths %%%%%
disp('Computing shortest paths...'); 

tic; 
for k=1:N
     D = min(D,  repmat(D(:,k),[1 N])  +  repmat(D(k,:),[N 1])  ); % compares each matrix element
     if rem(k,100) == 0 % rem    Remainder after division.
          disp([' Iteration: ', num2str(k), '     Estimated time to completion: ', num2str((N-k)*toc/k/60), ' minutes']); 
     end
end

%%%%% Remove outliers from graph %%%%%
disp('Checking for outliers...'); 
n_connect = sum(~(D==INF));        %% number of points each point connects to 1xN
[~, firsts] = min(D==INF);       %% first point each point connects to
[comps, ~, ~] = unique(firsts);    %% represent each connected component once
size_comps = n_connect(comps);     %% size of each connected component
[~, comp_order] = sort(size_comps);  %% sort connected components by size
comps = comps(comp_order(end:-1:1)); %%move upside down   
size_comps = size_comps(comp_order(end:-1:1)); 
n_comps = length(comps);               %% number of connected components
comp=1;                              %% default: use largest component

disp(['  Number of connected components in graph: ', num2str(n_comps)]); 
disp(['  Embedding component ', num2str(comp), ' with ', num2str(size_comps(comp)), ' points.']); 
Y.index = find(firsts==comps(comp)); 

D = D(Y.index, Y.index); 
N = length(Y.index); 
我知道你可能会问一些问题。顺便说一句,寻找距离的最快算法是Dijkstra算法,但您应该用C实现它


希望它能帮助你!我也是新手,但我以前也做过类似的工作,代码100%正确。

我相信你的问题在于你没有切割矩阵

Matlab中的parfor构造创建进程。这意味着所有进程将同时竞争更新变量A。我不知道Matlab是否实现了进程之间的共享内存和适当的同步。看起来没有

如果Matlab正在创建线程,那么同步对线程的访问会更容易,因为所有可以访问它的线程都在一个进程中。使用过程更为复杂

因此,您的问题是进程之间共享一个。为了避免这个问题,您可以将A矩阵拆分为等于进程数的n个变量,给每个进程一个切片,然后用n个进程给出的输出重构A

最好是手动执行切片,方法是指定n个子矩阵或n个子矩阵数组。实际上,编译器会给出错误,因为它无法自己对其进行切片。这需要你去做

请参见此处,描述了一个类似的问题


祝你好运。

A的初始值是多少?A=magic5;n=5;A是一个5行5列的2乘2矩阵。如何并行更新A?不能并行更新矩阵。在代码中,locality1应该是locality,反之亦然。谢谢。当我在这里复制代码时,这是一个输入错误。对不起,我是一个新手,我刚刚被要求计算平行城市之间的最短路径。它的floyd-warshal算法用最短路径填充邻接矩阵。您是否尝试在matlab中用多线程实现floyd-warshall?如果有,请告诉我。我也不明白你为什么这么做,comps=compscomp\u orderend:-1:1;%上下移动我实现了floyd warshall,但实际上我需要在这里实现的是多线程,每个城市都由一个线程处理,该线程只负责自己城市的路线和距离。之后,每个线程更新最短路径的矩阵。这只会使comps的顺序增加。谢谢。这真的很有帮助。我从来没有想过要切片;如果你能解释另一个问题,我将不胜感激。。如果我将A切片为n,我将手动进行,然后手动将矩阵重新调整到正确的位置,还是在完成切片后,我将以某种方式离开过程以将切片放回原位,如果我不是手动操作的话,我将如何确保被切割的部分在处理后会在i-e行1返回其位置之前准确地合并。添加了一个编辑。你需要手动操作。编译器会给你错误,因为它自己不能做。