加快最佳路径功能

时间:2016-09-08 13:36:04

标签: matlab

我有一个脚本,可以找到从转换成本矩阵中的节点到所有其他节点的最佳路径(此处找到的函数文件夹中的DPA函数http://uk.mathworks.com/matlabcentral/fileexchange/39034-finding-optimal-path-on-a-terrain)。

我遇到的问题是这个功能正是我需要的,但我需要它运行在16641 x 16641矩阵(129 * 129 x 129 * 129)上。我目前正在运行它,但它正在按预期运行(目前仍在2小时运行!)。我将在最后发布整个函数,但我想知道是否有人可以阐明函数的以下更改是否会使它运行得更快。我认为创造这个过多时间的过程是

for fromNode = 1 : m
        for toNode = 1 : m
            aij = P(toNode, fromNode);
            dj = aij + prevStageCostMat(fromNode);
            if dj < stageCostMat(toNode)
                stageCostMat(toNode) = dj;
                predMat(toNode, stage) = fromNode;
            end         
        end % end toNode
    end % end fromNode

其中m = 16641。函数必须传播通过所有节点,而不是给出正确的结果(我想问题是,我是否正确理解函数正在做什么?)或者你认为有什么方法可以加速计算吗?

主要功能页面说

% Keep in mind that DPA propagates through all the nodes. Basically DPA
% tries to find optimal path from one nodes to all nodes

这是完整的功能,如果有人能给我任何见解我非常感激(如果你需要更多的澄清,请让我知道,因为我理解,如果我已经解释了这个令人困惑的),谢谢!

function [stageCostMat, predMat, converged] = dpa(P, startNode, endNode, maxIteration)

% This is the function that will perform the DPA.
%
% Assume we have n number of nodes. P matrix is the transition cost matrix
% with dimension of n x n(square matrix). P(toNode, fromNode) shows
% transition cost from fromNode to toNode.
%
% stageCostMat shows the cost at each node for current iteration.
% stageCostMat(c) = current stage cost matrix at node c.
%
% predMat shows parent/predecessor node of each node for every stage.
% predMat(c, s): parent of node c during stage s.
%
% manurung.auralius@gmail.com
% 17.11.2012
% -------------------------------------------------------------------------

% Is the algortihm converged?
converged = 0;

% Cost matrix is a square matrix, m = n
[m, n] = size(P);

% Assume we will probably converge after n stages
stageCostMat = ones(1, m) * inf;

% Initial cost, no initial cost
stageCostMat(startNode) = 0;

% Predecessor matrix to trace back the optimum path, we will record parent of
% each node on each iteration
predMat = zeros(m, maxIteration); 

% Stage-by-stage, we move from start node to terminal node
for stage = 2 : maxIteration    

    % Find connection from any nodes to any nodes, keep the smaller cost
    prevStageCostMat = stageCostMat;
    stageCostMat = ones(1, m) * inf;

    for fromNode = 1 : m
        for toNode = 1 : m
            aij = P(toNode, fromNode);
            dj = aij + prevStageCostMat(fromNode);
            if dj < stageCostMat(toNode)
                stageCostMat(toNode) = dj;
                predMat(toNode, stage) = fromNode;
            end         
        end % end toNode
    end % end fromNode

    % Termination
%     if (stageCostMat == prevStageCostMat)
%         converged = 1;
%         break;
%     end

    if (predMat(endNode, stage) == endNode) || (predMat(endNode, stage-1) > 0) && (predMat(endNode, stage) == predMat(endNode, stage-1))
        converged = 1;
        break;
    end

end

predMat = predMat(:, 1:stage);

1 个答案:

答案 0 :(得分:0)

更先进一点。 toNodeforNode的当前位置有关,您必须回避toNode超出矩阵维度的情况:

for fromNode = 1 : m 
    %relativ to fromNode bc its always on the diagonal
    for toNode = (fromNode-1) : (fromNode+1) 
        %for the first and alse fromNode toNode would be out of the array limits
        if toNode==0 | toNode==m+1
            continue 
        end
        aij = P(toNode, fromNode); 
        dj = aij + prevStageCostMat(fromNode); 
        if dj < stageCostMat(toNode) 
            stageCostMat(toNode) = dj; 
            predMat(toNode, stage) = fromNode; 
        end
    end % end toNode 
end % end fromNode

我建议你试试这个数据,你可以从旧循环中获得解决方案来检查洗脱液是否仍然相同。时间应该大大减少,因为你只计算16641个循环中的3个。