我从dijkstra算法的每个输出得到NaN

时间:2017-04-13 18:40:45

标签: matlab graph path distance dijkstra

我在某处分发了一些节点。我想使用dijkstra算法来查找它们之间的距离和路径。这是代码:

function varargout = q43223243(N, TRSH, MAX_DST)
if nargin == 0
%% DEFINITIONS:
N = 50;
TRSH = 100*sqrt(5);  % If the distance between nodes is less than this, they can  communicate;
MAX_DST = 1000;
end
%% The rest...
xyNode=randi([1,100],N,2);
xyNode2=[xyNode;[100*sqrt(N)/2,100*sqrt(N)/2]];
ID = 1:N+1;
nodes = [ID(:),xyNode2(:,1),xyNode2(:,2)];
% Find pairwise distance:
D = pdist2(xyNode2,xyNode2); % symmetric, so we only take the bottom. %tril
D(D > TRSH | D == 0) = NaN;
% Find positions of valid edges:
[I,J] = ind2sub(size(D), find(~isnan(D)));
% Finally construct the segments array:
segments = [I, J, D(~isnan(D))];
% Outputs
if nargout > 0
  varargout{1} = nodes;
  varargout{2} = segments;
% else
%   figure();
%   line(xyNode(:,1),xyNode(:,2),'LineStyle','none','Marker','o'); hold on;
%   gplot(~isnan(D),xyNode,'-r');
end
end

这些是使用的功能:

function [dist,path] = dijkstra(nodes,segments,start_id,finish_id)

[Inf NaN]

我认为节点之间没有连接,因为所有输出都是function varargout = q43223243(N, TRSH, MAX_DST)

我该怎么做才能获得正确的输出?

另一个错误是使用函数segments[ID,N1,N2]输出必须采用以下格式:IDsegments必须增加并从中排序有序整数但是我的号码没有分类。

正确A=q43223243(16, 100*sqrt(5), 200); A = 1 90 36 2 96 84 3 55 59 4 14 55 5 15 92 6 26 29 7 85 76 8 26 76 9 82 39 10 25 57 11 93 8 12 35 6 13 20 54 14 26 78 15 62 94 16 48 13 17 200 200

的示例
segments =
    2.0000    1.0000   93.4345
    3.0000    1.0000  117.1537
    4.0000    1.0000   16.0312
    5.0000    1.0000   64.8460
    6.0000    1.0000   68.5930
    7.0000    1.0000   15.0000
    8.0000    1.0000   22.1359
    9.0000    1.0000   78.7718
   10.0000    1.0000   83.8153
   11.0000    1.0000   63.8905
   12.0000    1.0000   70.4557
   13.0000    1.0000   53.9351
   14.0000    1.0000   80.9506
   15.0000    1.0000   55.3173
   16.0000    1.0000   92.3959
   17.0000    1.0000    9.4868
    1.0000    2.0000   93.4345
    3.0000    2.0000   84.0536
    4.0000    2.0000   95.3362
    5.0000    2.0000   92.6553
    6.0000    2.0000   25.0000
    7.0000    2.0000   93.1933
    8.0000    2.0000   72.0278
    9.0000    2.0000  106.0424
   10.0000    2.0000   36.4005
   11.0000    2.0000   66.6033
   12.0000    2.0000  116.0431
   13.0000    2.0000  103.6002
   14.0000    2.0000   98.4733
   15.0000    2.0000  102.6158
   16.0000    2.0000    7.2801
   17.0000    2.0000   84.2140
   18.0000    2.0000  161.5947
    1.0000    3.0000  117.1537
    2.0000    3.0000   84.0536
    4.0000    3.0000  106.7801
    5.0000    3.0000   63.3246
    6.0000    3.0000   86.8332
    7.0000    3.0000  127.2792
    8.0000    3.0000  107.1681
    9.0000    3.0000   63.0079
   10.0000    3.0000   50.9902
   11.0000    3.0000   53.2635
   12.0000    3.0000   82.1523
   13.0000    3.0000   82.9699
   14.0000    3.0000   53.0848
   15.0000    3.0000   80.7775
   16.0000    3.0000   91.0055
   17.0000    3.0000  112.4500
    1.0000    4.0000   16.0312
    2.0000    4.0000   95.3362
    3.0000    4.0000  106.7801
    5.0000    4.0000   50.4777
    6.0000    4.0000   71.5122
    7.0000    4.0000   31.0161
    8.0000    4.0000   30.4795
    9.0000    4.0000   63.5610
   10.0000    4.0000   79.5110
   11.0000    4.0000   54.1202
   12.0000    4.0000   54.4518
   13.0000    4.0000   38.0789
   14.0000    4.0000   66.5733
   15.0000    4.0000   39.5601
   16.0000    4.0000   95.5196
   17.0000    4.0000   20.6155
    1.0000    5.0000   64.8460
    2.0000    5.0000   92.6553
    3.0000    5.0000   63.3246
    4.0000    5.0000   50.4777
    6.0000    5.0000   77.5242
    7.0000    5.0000   78.5493
    8.0000    5.0000   65.4905
    9.0000    5.0000   16.1245
   10.0000    5.0000   60.7454
   11.0000    5.0000   26.2488
   12.0000    5.0000   24.1868
   13.0000    5.0000   19.6469
   14.0000    5.0000   16.1245
   15.0000    5.0000   17.4642
   16.0000    5.0000   96.5401
   17.0000    5.0000   64.1950
    1.0000    6.0000   68.5930
    2.0000    6.0000   25.0000
    3.0000    6.0000   86.8332
    4.0000    6.0000   71.5122
    5.0000    6.0000   77.5242
    7.0000    6.0000   68.2642
    8.0000    6.0000   47.0425
    9.0000    6.0000   92.5743
   10.0000    6.0000   36.0555
   11.0000    6.0000   53.4883
   12.0000    6.0000   99.2018
   13.0000    6.0000   84.8999
   14.0000    6.0000   86.7295
   15.0000    6.0000   84.2912
   16.0000    6.0000   24.0416
   17.0000    6.0000   59.3043
   18.0000    6.0000  179.4314
    1.0000    7.0000   15.0000
    2.0000    7.0000   93.1933
    3.0000    7.0000  127.2792
    4.0000    7.0000   31.0161
    5.0000    7.0000   78.5493
    6.0000    7.0000   68.2642
    8.0000    7.0000   22.4722
    9.0000    7.0000   93.0054
   10.0000    7.0000   89.4427
   11.0000    7.0000   74.4110
   12.0000    7.0000   85.3756
   13.0000    7.0000   68.7314
   14.0000    7.0000   94.5410
   15.0000    7.0000   70.0357
   16.0000    7.0000   91.0055
   17.0000    7.0000   15.0000
    1.0000    8.0000   22.1359
    2.0000    8.0000   72.0278
    3.0000    8.0000  107.1681
    4.0000    8.0000   30.4795
    5.0000    8.0000   65.4905
    6.0000    8.0000   47.0425
    7.0000    8.0000   22.4722
    9.0000    8.0000   81.2219
   10.0000    8.0000   67.1193
   11.0000    8.0000   55.5698
   12.0000    8.0000   78.0897
   13.0000    8.0000   61.0000
   14.0000    8.0000   80.6040
   15.0000    8.0000   61.6604
   16.0000    8.0000   70.5762
   17.0000    8.0000   12.6491
   18.0000    8.0000  217.9354
    1.0000    9.0000   78.7718
    2.0000    9.0000  106.0424
    3.0000    9.0000   63.0079
    4.0000    9.0000   63.5610
    5.0000    9.0000   16.1245
    6.0000    9.0000   92.5743
    7.0000    9.0000   93.0054
    8.0000    9.0000   81.2219
   10.0000    9.0000   72.1803
   11.0000    9.0000   39.6611
   12.0000    9.0000   19.4165
   13.0000    9.0000   27.0185
   14.0000    9.0000   10.1980
   15.0000    9.0000   25.0000
   16.0000    9.0000  110.4355
   17.0000    9.0000   79.0759
    1.0000   10.0000   83.8153
    2.0000   10.0000   36.4005
    3.0000   10.0000   50.9902
    4.0000   10.0000   79.5110
    5.0000   10.0000   60.7454
    6.0000   10.0000   36.0555
    7.0000   10.0000   89.4427
    8.0000   10.0000   67.1193
    9.0000   10.0000   72.1803
   11.0000   10.0000   34.8855
   12.0000   10.0000   84.9058
   13.0000   10.0000   75.3923
   14.0000   10.0000   63.7024
   15.0000   10.0000   73.9256
   16.0000   10.0000   42.4500
   17.0000   10.0000   76.3217
   18.0000   10.0000  195.9042
    1.0000   11.0000   63.8905
    2.0000   11.0000   66.6033
    3.0000   11.0000   53.2635
    4.0000   11.0000   54.1202
    5.0000   11.0000   26.2488
    6.0000   11.0000   53.4883
    7.0000   11.0000   74.4110
    8.0000   11.0000   55.5698
    9.0000   11.0000   39.6611
   10.0000   11.0000   34.8855
   12.0000   11.0000   50.2195
   13.0000   11.0000   40.8044
   14.0000   11.0000   33.2415
   15.0000   11.0000   39.2173
   16.0000   11.0000   70.8025
   17.0000   11.0000   59.4643
    1.0000   12.0000   70.4557
    2.0000   12.0000  116.0431
    3.0000   12.0000   82.1523
    4.0000   12.0000   54.4518
    5.0000   12.0000   24.1868
    6.0000   12.0000   99.2018
    7.0000   12.0000   85.3756
    8.0000   12.0000   78.0897
    9.0000   12.0000   19.4165
   10.0000   12.0000   84.9058
   11.0000   12.0000   50.2195
   13.0000   12.0000   17.1172
   14.0000   12.0000   29.0689
   15.0000   12.0000   16.4924
   16.0000   12.0000  119.5199
   17.0000   12.0000   73.0068
    1.0000   13.0000   53.9351
    2.0000   13.0000  103.6002
    3.0000   13.0000   82.9699
    4.0000   13.0000   38.0789
    5.0000   13.0000   19.6469
    6.0000   13.0000   84.8999
    7.0000   13.0000   68.7314
    8.0000   13.0000   61.0000
    9.0000   13.0000   27.0185
   10.0000   13.0000   75.3923
   11.0000   13.0000   40.8044
   12.0000   13.0000   17.1172
   14.0000   13.0000   33.0151
   15.0000   13.0000    2.2361
   16.0000   13.0000  106.4049
   17.0000   13.0000   56.0089
    1.0000   14.0000   80.9506
    2.0000   14.0000   98.4733
    3.0000   14.0000   53.0848
    4.0000   14.0000   66.5733
    5.0000   14.0000   16.1245
    6.0000   14.0000   86.7295
    7.0000   14.0000   94.5410
    8.0000   14.0000   80.6040
    9.0000   14.0000   10.1980
   10.0000   14.0000   63.7024
   11.0000   14.0000   33.2415
   12.0000   14.0000   29.0689
   13.0000   14.0000   33.0151
   15.0000   14.0000   30.8058
   16.0000   14.0000  103.2473
   17.0000   14.0000   80.0562
    1.0000   15.0000   55.3173
    2.0000   15.0000  102.6158
    3.0000   15.0000   80.7775
    4.0000   15.0000   39.5601
    5.0000   15.0000   17.4642
    6.0000   15.0000   84.2912
    7.0000   15.0000   70.0357
    8.0000   15.0000   61.6604
    9.0000   15.0000   25.0000
   10.0000   15.0000   73.9256
   11.0000   15.0000   39.2173
   12.0000   15.0000   16.4924
   13.0000   15.0000    2.2361
   14.0000   15.0000   30.8058
   16.0000   15.0000  105.5509
   17.0000   15.0000   57.0789
    1.0000   16.0000   92.3959
    2.0000   16.0000    7.2801
    3.0000   16.0000   91.0055
    4.0000   16.0000   95.5196
    5.0000   16.0000   96.5401
    6.0000   16.0000   24.0416
    7.0000   16.0000   91.0055
    8.0000   16.0000   70.5762
    9.0000   16.0000  110.4355
   10.0000   16.0000   42.4500
   11.0000   16.0000   70.8025
   12.0000   16.0000  119.5199
   13.0000   16.0000  106.4049
   14.0000   16.0000  103.2473
   15.0000   16.0000  105.5509
   17.0000   16.0000   83.0241
   18.0000   16.0000  157.9060
    1.0000   17.0000    9.4868
    2.0000   17.0000   84.2140
    3.0000   17.0000  112.4500
    4.0000   17.0000   20.6155
    5.0000   17.0000   64.1950
    6.0000   17.0000   59.3043
    7.0000   17.0000   15.0000
    8.0000   17.0000   12.6491
    9.0000   17.0000   79.0759
   10.0000   17.0000   76.3217
   11.0000   17.0000   59.4643
   12.0000   17.0000   73.0068
   13.0000   17.0000   56.0089
   14.0000   17.0000   80.0562
   15.0000   17.0000   57.0789
   16.0000   17.0000   83.0241
    2.0000   18.0000  161.5947
    6.0000   18.0000  179.4314
    8.0000   18.0000  217.9354
   10.0000   18.0000  195.9042
   16.0000   18.0000  157.9060

在我的代码中,我得到了这个:

function [dist,path] = dijkstra(nodes,segments,start_id,finish_id)

%DIJKSTRA Calculates the shortest distance and path between points on a map

%   using Dijkstra's Shortest Path Algorithm

% 

% [DIST, PATH] = DIJKSTRA(NODES, SEGMENTS, SID, FID)

%   Calculates the shortest distance and path between start and finish nodes SID and FID

% 

% [DIST, PATH] = DIJKSTRA(NODES, SEGMENTS, SID)

%   Calculates the shortest distances and paths from the starting node SID to all

%     other nodes in the map

% 

% Note:

%     DIJKSTRA is set up so that an example is created if no inputs are provided,

%       but ignores the example and just processes the inputs if they are given.

% 

% Inputs:

%     NODES should be an Nx3 or Nx4 matrix with the format [ID X Y] or [ID X Y Z]

%       where ID is an integer, and X, Y, Z are cartesian position coordinates)

%     SEGMENTS should be an Mx3 matrix with the format [ID N1 N2]

%       where ID is an integer, and N1, N2 correspond to node IDs from NODES list

%       such that there is an [undirected] edge/segment between node N1 and node N2

%     SID should be an integer in the node ID list corresponding with the starting node

%     FID (optional) should be an integer in the node ID list corresponding with the finish

% 

% Outputs:

%     DIST is the shortest Euclidean distance

%       If FID was specified, DIST will be a 1x1 double representing the shortest

%         Euclidean distance between SID and FID along the map segments. DIST will have

%         a value of INF if there are no segments connecting SID and FID.

%       If FID was not specified, DIST will be a 1xN vector representing the shortest

%         Euclidean distance between SID and all other nodes on the map. DIST will have

%         a value of INF for any nodes that cannot be reached along segments of the map.

%     PATH is a list of nodes containing the shortest route

%       If FID was specified, PATH will be a 1xP vector of node IDs from SID to FID.

%         NAN will be returned if there are no segments connecting SID to FID.

%       If FID was not specified, PATH will be a 1xN cell of vectors representing the

%         shortest route from SID to all other nodes on the map. PATH will have a value

%         of NAN for any nodes that cannot be reached along the segments of the map.

% 

% Example:

%     dijkstra; % calculates shortest path and distance between two nodes

%               % on a map of randomly generated nodes and segments

% 

% Example:

%     nodes = [(1:10); 100*rand(2,10)]';

%     segments = [(1:17); floor(1:0.5:9); ceil(2:0.5:10)]';

%     figure; plot(nodes(:,2), nodes(:,3),'k.');

%     hold on;

%     for s = 1:17

%         if (s <= 10) text(nodes(s,2),nodes(s,3),[' ' num2str(s)]); end

%         plot(nodes(segments(s,2:3)',2),nodes(segments(s,2:3)',3),'k');

%     end

%     [d, p] = dijkstra(nodes, segments, 1, 10)

%     for n = 2:length(p)

%         plot(nodes(p(n-1:n),2),nodes(p(n-1:n),3),'r-.','linewidth',2);

%     end

%     hold off;

% 

% Author: Joseph Kirk

% Email: jdkirk630 at gmail dot com

% Release: 1.3

% Release Date: 5/18/07



if (nargin < 3) % SETUP

    % (GENERATE RANDOM EXAMPLE OF NODES AND SEGMENTS IF NOT GIVEN AS INPUTS)

    % Create a random set of nodes/vertices,and connect some of them with

    % edges/segments. Then graph the resulting map.

    num_nodes = 40; L = 100; max_seg_length = 30; ids = (1:num_nodes)';

    nodes = [ids L*rand(num_nodes,2)]; % create random nodes

    h = figure; plot(nodes(:,2),nodes(:,3),'k.') % plot the nodes

    text(nodes(num_nodes,2),nodes(num_nodes,3),'num2str(ids(num_nodes))','Color','b','FontWeight','b')

    hold on

    num_segs = 0; segments = zeros(num_nodes*(num_nodes-1)/2,3);

    for i = 1:num_nodes-1 % create edges between some of the nodes

        text(nodes(i,2),nodes(i,3),[' ' num2str(ids(i))],'Color','b','FontWeight','b')

        for j = i+1:num_nodes

            d = sqrt(sum((nodes(i,2:3) - nodes(j,2:3)).^2));

            if and(d < max_seg_length,rand < 0.6)

                plot([nodes(i,2) nodes(j,2)],[nodes(i,3) nodes(j,3)],'k.-')

                % add this link to the segments list

                num_segs = num_segs + 1;

                segments(num_segs,:) = [num_segs nodes(i,1) nodes(j,1)];

            end

        end

    end

    segments(num_segs+1:num_nodes*(num_nodes-1)/2,:) = [];

    axis([0 L 0 L])

    % Calculate Shortest Path Using Dijkstra's Algorithm

    % Get random starting/ending nodes,compute the shortest distance and path.

    start_id = ceil(num_nodes*rand); disp(['start id = ' num2str(start_id)]);

    finish_id = ceil(num_nodes*rand); disp(['finish id = ' num2str(finish_id)]);

    [distance,path] = dijkstra(nodes,segments,start_id,finish_id);

    disp(['distance = ' num2str(distance)]); disp(['path = [' num2str(path) ']']);

    % If a Shortest Path exists,Plot it on the Map.

    figure(h)

    for k = 2:length(path)

        m = find(nodes(:,1) == path(k-1));

        n = find(nodes(:,1) == path(k));

        plot([nodes(m,2) nodes(n,2)],[nodes(m,3) nodes(n,3)],'ro-','LineWidth',2);

    end

    title(['Shortest Distance from ' num2str(start_id) ' to ' num2str(finish_id) ' = ' num2str(distance)])

    hold off



else %--------------------------------------------------------------------------

    % MAIN FUNCTION - DIJKSTRA'S ALGORITHM



    % initializations

    node_ids = nodes(:,1);

    [num_map_pts,cols] = size(nodes);

    table = sparse(num_map_pts,2);

    shortest_distance = Inf(num_map_pts,1);

    settled = zeros(num_map_pts,1);

    path = num2cell(NaN(num_map_pts,1));

    col = 2;

    pidx = find(start_id == node_ids);

    shortest_distance(pidx) = 0;

    table(pidx,col) = 0;

    settled(pidx) = 1;

    path(pidx) = {start_id};

    if (nargin < 4) % compute shortest path for all nodes

        while_cmd = 'sum(~settled) > 0';

    else % terminate algorithm early

        while_cmd = 'settled(zz) == 0';

        zz = find(finish_id == node_ids);

    end

    while eval(while_cmd)

        % update the table

        table(:,col-1) = table(:,col);

        table(pidx,col) = 0;

        % find neighboring nodes in the segments list

        neighbor_ids = [segments(node_ids(pidx) == segments(:,2),3);

            segments(node_ids(pidx) == segments(:,3),2)];

        % calculate the distances to the neighboring nodes and keep track of the paths

        for k = 1:length(neighbor_ids)

            cidx = find(neighbor_ids(k) == node_ids);

            if ~settled(cidx)

                d = sqrt(sum((nodes(pidx,2:cols) - nodes(cidx,2:cols)).^2));

                if (table(cidx,col-1) == 0) || table(cidx,col-1) > (table(pidx,col-1) + d)

                    table(cidx,col) = table(pidx,col-1) + d;

                    tmp_path = path(pidx);

                    path(cidx) = {[tmp_path{1} neighbor_ids(k)]};

                else

                    table(cidx,col) = table(cidx,col-1);

                end

            end

        end

        % find the minimum non-zero value in the table and save it

        nidx = find(table(:,col));

        ndx = find(table(nidx,col) == min(table(nidx,col)));

        if isempty(ndx)

            break

        else

            pidx = nidx(ndx(1));

            shortest_distance(pidx) = table(pidx,col);

            settled(pidx) = 1;

        end

    end

    if (nargin < 4) % return the distance and path arrays for all of the nodes

        dist = shortest_distance';

        path = path';

    else % return the distance and path for the ending node

        dist = shortest_distance(zz);

        path = path(zz);

        path = path{1};

    end

end

用于N = 16个节点加上一个汇聚节点。

这是dijkstra算法:

SELECT DISTINCT reg.id, reg.key_recordID, reg.regType
FROM Vegas_Annual_Dinner_2017.reg reg1
LEFT JOIN Vegas_Annual_Dinner_2017.reg reg2 ON reg1.id=reg2.main_ID
WHERE reg.status = 'Invited' AND reg.registrationType = 'Student'

1 个答案:

答案 0 :(得分:1)

似乎segments构造错误。您正在使用

segments = [I, J, D(~isnan(D))];

其中I,J是节点,D是距离。为了使它成为[ID,N1,N2]你想要做类似

的事情
IDs = [1:numel(I)].';   % generate unique IDs for each segment
segments = [IDs, I, J];