0

この質問は以前に何度か回答されていることは知っていますが、状況を改善するために以前の回答をすべて確認しましたが、役に立ちませんでした。

私がする必要があるのは、ループを並列化して、各都市 (または内側のループ) が並列に処理されるようにすることです。しかし、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
4

2 に答える 2

0

あなたの問題は、A matrix を「スライス」していないという事実だと思います。

Matlab の parfor コンストラクトはプロセスを作成します。つまり、すべてのプロセスが競合して変数 A を同時に更新します。Matlab がプロセス間の共有メモリと適切な同期を実装しているかどうかはわかりません。そうではないようです。

Matlab がスレッドを作成していた場合、A へのアクセスを同期する方が簡単だったでしょう。これは、すべてのスレッドが単一のプロセスで A にアクセスしていたからです。プロセスを使用すると、より複雑になります。

あなたの問題は、 A がプロセス間で共有されていることです。この問題を回避するには、行列 A をn 個の変数 (プロセスの数に等しい) に分割し、各プロセスにスライスを与えてから、n 個のプロセスによって与えられた出力で A を再構築します。

n サブマトリックス (または n サブマトリックスの配列) を割り当てて、手動でスライスを行うのが最善です。実際、コンパイラはそれ自体でスライスできないため、エラーが発生します。それはあなたがそれをする必要があります。

同様の問題について説明している投稿を参照してください。

幸運を。

于 2014-10-21T10:50:38.117 に答える