从起始节点到结束节点的所有可能路径

时间:2013-03-20 13:15:00

标签: matlab

我有一个加权图,其中包含用户定义的节点数'n'。我想要一个代码,给定图中的两个唯一节点,它将显示连接两个节点的所有路径。 Graph Example

wt=zeros(n,n);
while(1)
i=input('enter the starting node:(0 to quit):');
if (i==0)    
    break;
end
j=input('enter the destination node:');
wt(i,j)=input('Enter the cost: '); 
end
disp('Adjacency Matrix');
for i=1:n
fprintf('           %d',i);
end
for i=1:n
fprintf('\n%d          ',i);
for j=1:n
fprintf('%d          ',wt(i,j));
end
end
Adjacency Matrix
   1           2           3           4           5
1          0          1          1          0          0          
2          0          0          0          0          0          
3          1          0          0          1          0          
4          0          0          1          0          0          
5          0          0          0          0          0     

矩阵wt显示任意两个给定节点之间的连接。这意味着节点(1,2)(1,3)(3,4)(4,3)连接。

fprintf('\nEnter the source');
s=input(':');
fprintf('\nEnter the destination');
de=input(':');

for i=1:n
m=s;
if(m~=i)
   for j=i:n
    if(m~=j)
        if(M(m,j)>0)
            p(i,j)=j;
            m=j;
        end
    end
    if(p(i,j)==de)
        d(i)=1;
        break;
    end
end
if(d(i)~=1)
    for k=1:j
        p(i,k)=0;
    end
    m=s;
    for k=n : -1 : i
        if(M(m,k)>0)
            p(i,n-k+2)=k;
            m=k;
        end
        if(p(i,n-k+2)==de)
            d(i)=1;
            break;
        end
    end
end
end
end


for i=1:n
j=1;
if(d(i)==1)
    for j=1:n
        if (j==1)
            fprintf('\n path: %d',s);
            kk=s;


        elseif (p(i,j)>0)
            fprintf('->%d',p(i,j));

            plot([nodes(kk, 2) nodes(p(i,j), 2)], [nodes(kk, 3) nodes(p(i,j), 3)], 'k.--')
            kk=p(i,j);
        end
    end
end
fprintf('\t\t hopcount of path %d:  %d',i,count);
count=0;
end

这是我编写的代码,用于查找从源到目标的可能路径。 'p'矩阵保存从源到目的地的最终路径。 输出:

 enter the starting node:(0 to quit):1
 enter the destination node:2
 Enter the cost: 1
 enter the starting node:(0 to quit):1
 enter the destination node:3
 Enter the cost: 1
 enter the starting node:(0 to quit):2
 enter the destination node:3
 Enter the cost: 1
 enter the starting node:(0 to quit):0

Enter the source:1

Enter the destination:3


     hopcount of path 1:  0
 path 2: 1->2->3         hopcount of path 2:  2
 path 3: 1->3        hopcount of path 3:  1??? 
 Attempt to reference field of      non-structure array.

如果我将源输入为3,目标为1,则代码不起作用。

1 个答案:

答案 0 :(得分:1)

这是一种更好的矢量化方法(我假设你不能两次跨越同一个节点)。您希望尽可能地最小化嵌套的for循环。尽可能使用矢量和矩阵运算。

我们的想法是构建所有路径的列表,同时将所有可能的下一个节点添加到列表中的每个元素上。 此函数返回Mx2单元阵列,其中M是最长(访问最多节点)路径。 第一列中的每个单元格包含一个矩阵,其中每一行都是长度为i的不同路径。第二列中的每个单元格都包含一个列向量,其中包含每条路径的相应成本。

function [paths] = allpaths(wt, startnode, endnode)
    lastpath = [startnode]; #We begin with the path containing just the startnode
    costs = [0]; #The cost of this path is zero because we haven't yet crossed any edges
    paths = {zeros(0,1),zeros(0,1)}; #The set of solution paths is empty (I'm assuming startnode!=endnode)
    N = size(wt,1); #Obtain the number of nodes in the graph
    assert(N==size(wt,2)); #Assert that the adjacency matrix is a square matrix
    for i = 2 : N
        #Creates a matrix with a row for each path and a 1 in a column where there's a possible move from the last visited node in a path to this column
        nextmove = wt(lastpath(:, i - 1), :) != 0;

        #Zero out any nodes we've already visited
        d = diag(1:size(lastpath,1));
        nrows = d * ones(size(lastpath));
        inds = sub2ind(size(nextmove), reshape(nrows,[],1), reshape(lastpath,[],1));
        nextmove(inds) = false;

        # If there are no more available moves we're done 
        if nextmove == 0
            break;
        endif

        #For each true entry in our nextmove matrix, create a new path from the old one together with the selected next move
        nextmoverow = d * nextmove;
        nextmovecol = nextmove * diag(1:N);
        rowlist = reshape(nonzeros(nextmoverow),[],1);
        collist = reshape(nonzeros(nextmovecol),[],1);
        nextpath = [lastpath(rowlist,:), collist];

        # Compute the costs of the new set of paths by adding the old ones to the cost of each newly traversed edge
        inds = sub2ind([N,N],nextpath(:, i-1),nextpath(:,i));
        costs = costs(rowlist) + wt(inds);

        # For any path finishing on the end node, add it to the return list (and it's corresponding cost)
        reachedend = nextpath(:,i) == endnode;
        paths = [paths; {nextpath(reachedend, :)},{costs(reachedend)}];

        #Then remove it from the list of paths still being explored
        lastpath = nextpath(~reachedend, :);
        costs = costs(~reachedend);

        #If there are no more paths, we're done
        if isempty(lastpath)
            break;
        endif
    endfor
endfunction


paths = allpaths(wt, startnode, endnode);
for i = 1:size(paths,1)
    mpath = paths{i,1};
    mcost = paths{i,2};
    for j = 1:length(mcost)
        p = mpath(j,:);
        first = true;
        for n = p
            if first
                first = false;
            else
                printf(' -> ');
            endif
            printf('%d', n);
        endfor
        printf('  cost: %d\n',mcost(j));
    endfor
endfor

编辑:添加了如何打印路径