Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/selenium/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在MATLAB中创建矩阵中两个已知点之间的随机路径_Matlab_Matrix_Path - Fatal编程技术网

如何在MATLAB中创建矩阵中两个已知点之间的随机路径

如何在MATLAB中创建矩阵中两个已知点之间的随机路径,matlab,matrix,path,Matlab,Matrix,Path,如果有一个矩阵和两个已知点,如何在这两个点之间创建一条随机路径(无需最短): 可能有一定偏差的路径 路径可以是完全随机的(但不是必需的) 下一步只能从4个邻居开始 前。 具有两个已知点的5x5矩阵:(2,1)和(5,5) 输入后:pt1=[2,1];pt2=[5,5] 如何使用参数中记录的路径获得如下模式,例如path=[2,1;2,2-;3,2;4,2;4,3;4,4;4,5] X X X X X o o X X X X o X X X X o o o o X X X X o 第A部

如果有一个矩阵和两个已知点,如何在这两个点之间创建一条随机路径(无需最短):

  • 可能有一定偏差的路径
  • 路径可以是完全随机的(但不是必需的)
  • 下一步只能从4个邻居开始
  • 前。 具有两个已知点的5x5矩阵:
    (2,1)
    (5,5)

    输入后:
    pt1=[2,1];pt2=[5,5]

    如何使用参数中记录的路径获得如下模式,例如
    path=[2,1;2,2-;3,2;4,2;4,3;4,4;4,5]

    X X X X X
    
    o o X X X
    
    X o X X X
    
    X o o o o
    
    X X X X o
    

    第A部分-的目的是找到连接二维域上两点的线/路径的坐标,这样就不会有两个相邻坐标彼此成对角线,即仅左/右/上/下

    功能代码

    function pts_array = points_array(pt1,pt2)
    
    if pt1(1)==pt2(1)
        if pt2(2)>pt1(2)
            pts_array = [repmat(pt1(1),(pt2(2)-pt1(2)+1),1) (pt1(2):pt2(2))'];
        elseif pt2(2)<pt1(2)
            pts_array = flipud([repmat(pt1(1),(pt1(2)-pt2(2)+1),1) (pt2(2):pt1(2))']);
        else
            pts_array = pt1;
        end
    elseif pt1(2)==pt2(2)
        if pt2(1)>pt1(1)
            pts_array = [(pt1(1):pt2(1))' repmat(pt1(2),(pt2(1)-pt1(1)+1),1)];
        elseif pt2(1)<pt1(1)
            pts_array = flipud([(pt2(1):pt1(1))' repmat(pt1(2),(pt1(1)-pt2(1)+1),1)]);
        else
            pts_array = pt1;
        end
    else
    
        gslope1_org = (pt2(2)-pt1(2))/(pt2(1)-pt1(1));
        if gslope1_org <1
            pt1 = fliplr(pt1);
            pt2 = fliplr(pt2);
        end
        gslope1 = (pt2(2)-pt1(2))/(pt2(1)-pt1(1));
    
        off1 = 1;
    
        pts_array = [pt1];
        gpt1 = pt1;
        while 1
            slope1 = (pt2(2)-gpt1(2))/(pt2(1)-gpt1(1));
            if (slope1<gslope1)
                gpt1 = [gpt1(1)+off1 gpt1(2)];
                pts_array = [pts_array; gpt1];
            else
                new_y = floor(gpt1(2)+slope1);
                range_y = (gpt1(2)+1 : floor(gpt1(2)+slope1))';
                gpt1 = [gpt1(1) new_y];
                pts_array = [pts_array ; [repmat(gpt1(1),[numel(range_y) 1]) range_y]];
            end
            if isequal(gpt1,pt2)
                break;
            end
        end
    
        if gslope1_org <1
            pts_array = fliplr(pts_array);
        end
    end
    
    function pts_array = points_array_wrap(pt1,pt2) %%// Please remember that this needs points_array.m
    
    x1 = pt1(1);
    y1 = pt1(2);
    x2 = pt2(1);
    y2 = pt2(2);
    
    quad4 = y2<y1 & x2>x1; %% when pt2 is a lower height than pt1 on -slope
    quad3 = y2<y1 & x2<x1; %% when pt2 is a lower height than pt1 on +slope
    quad2 = y2>y1 & x2<x1; %% when pt2 is a higher height than pt1 on -slope
    
    if quad4
        y2 = y2+ 2*(y1 - y2);
    end
    
    if quad2
        y2 = y2 - 2*(y2 - y1);
        t1 = x1;t2 = y1;
        x1 = x2;y1 = y2;
        x2 = t1;y2 = t2;
    end
    
    if quad3
        t1 = x1;t2 = y1;
        x1 = x2;y1 = y2;
        x2 = t1;y2 = t2;
    end
    
    pts_array = points_array([x1 y1],[x2 y2]);
    
    if quad4
        offset_mat = 2.*(pts_array(:,2)-pt1(2));
        pts_array(:,2) = pts_array(:,2) - offset_mat;
    end
    
    if quad3
        pts_array = flipud(pts_array);
    end
    
    if quad2
        offset_mat = 2.*(pt1(2)-pts_array(:,2));
        pts_array(:,2) = pts_array(:,2) + offset_mat;
        pts_array = flipud(pts_array);
    end
    
    return;
    
    输出

    pt1 = [2 1];
    pt2 = [5 5];
    
    pts_array = points_array_wrap(pt1,pt2);
    
    plot(pts_array(:,1),pts_array(:,2),'o'), grid on, axis equal
    for k = 1:size(pts_array,1)
        text(pts_array(k,1),pts_array(k,2),strcat('[',num2str(pts_array(k,1)),',',num2str(pts_array(k,2)),']'),'FontSize',16)
    end
    
    pts_array =
    
         2     1
         2     2
         3     2
         3     3
         4     3
         4     4
         4     5
         5     5
    
    绘图

    pt1 = [2 1];
    pt2 = [5 5];
    
    pts_array = points_array_wrap(pt1,pt2);
    
    plot(pts_array(:,1),pts_array(:,2),'o'), grid on, axis equal
    for k = 1:size(pts_array,1)
        text(pts_array(k,1),pts_array(k,2),strcat('[',num2str(pts_array(k,1)),',',num2str(pts_array(k,2)),']'),'FontSize',16)
    end
    
    pts_array =
    
         2     1
         2     2
         3     2
         3     3
         4     3
         4     4
         4     5
         5     5
    

    第二部分-目标是通过给定空间找到连接二维域上两点的线/路径的坐标

    在这种特殊情况下,我们假设存在一些空间,并且只有通过这些空间才能连接路径。OP并没有问这个问题,但我觉得分享会很有趣。所以,对于这个,空格应该是o,如OP的问题所示

    代码

    function your_path = path_calc(mat1,starting_pt,final_pt)
    
    [x1,y1] = find(mat1);
    pt1 = [x1 y1];
    d1 = pdist2(pt1,final_pt,'euclidean');
    [~,ind1] = sort(d1,'descend');
    path1 = pt1(ind1,:);
    your_path =  path1(find(ismember(path1,starting_pt,'rows')):end,:);
    
    return;
    
    运行-1

    %%// Data
    mat1 = zeros(5,5);
    mat1(2,1:2) = 1;
    mat1(3,2) = 1;
    mat1(4,2:5) = 1;
    mat1(5,5) = 1;
    
    starting_pt = [2 1];
    final_pt = [5 5];
    
    %%// Path traces
    path = path_calc(mat1,starting_pt,final_pt);
    
    Gives -
    mat1 =
    
    0     0     0     0     0
    1     1     0     0     0
    0     1     0     0     0
    0     1     1     1     1
    0     0     0     0     1
    
    
    path =
    
    2     1
    2     2
    3     2
    4     2
    4     3
    4     4
    4     5
    5     5
    
    运行-2

    %%// Data
    mat1 = zeros(5,5);
    mat1(2,1:2) = 1;
    mat1(3,2) = 1;
    mat1(4,2:5) = 1;
    mat1(5,5) = 1;
    mat1 = fliplr(mat1');
    
    %%// Notice it starts not from the farthest point this time
    starting_pt = [2 3];
    final_pt = [5 1];
    
    %%// Path traces
    path = path_calc(mat1,starting_pt,final_pt);
    
    Gives
    
    mat1 =
    
         0     0     0     1     0
         0     1     1     1     0
         0     1     0     0     0
         0     1     0     0     0
         1     1     0     0     0
    
    
    path =
    
         2     3
         2     2
         3     2
         4     2
         5     2
         5     1
    

    第A部分-的目的是找到连接二维域上两点的线/路径的坐标,这样就不会有两个相邻坐标彼此成对角线,即仅左/右/上/下

    功能代码

    function pts_array = points_array(pt1,pt2)
    
    if pt1(1)==pt2(1)
        if pt2(2)>pt1(2)
            pts_array = [repmat(pt1(1),(pt2(2)-pt1(2)+1),1) (pt1(2):pt2(2))'];
        elseif pt2(2)<pt1(2)
            pts_array = flipud([repmat(pt1(1),(pt1(2)-pt2(2)+1),1) (pt2(2):pt1(2))']);
        else
            pts_array = pt1;
        end
    elseif pt1(2)==pt2(2)
        if pt2(1)>pt1(1)
            pts_array = [(pt1(1):pt2(1))' repmat(pt1(2),(pt2(1)-pt1(1)+1),1)];
        elseif pt2(1)<pt1(1)
            pts_array = flipud([(pt2(1):pt1(1))' repmat(pt1(2),(pt1(1)-pt2(1)+1),1)]);
        else
            pts_array = pt1;
        end
    else
    
        gslope1_org = (pt2(2)-pt1(2))/(pt2(1)-pt1(1));
        if gslope1_org <1
            pt1 = fliplr(pt1);
            pt2 = fliplr(pt2);
        end
        gslope1 = (pt2(2)-pt1(2))/(pt2(1)-pt1(1));
    
        off1 = 1;
    
        pts_array = [pt1];
        gpt1 = pt1;
        while 1
            slope1 = (pt2(2)-gpt1(2))/(pt2(1)-gpt1(1));
            if (slope1<gslope1)
                gpt1 = [gpt1(1)+off1 gpt1(2)];
                pts_array = [pts_array; gpt1];
            else
                new_y = floor(gpt1(2)+slope1);
                range_y = (gpt1(2)+1 : floor(gpt1(2)+slope1))';
                gpt1 = [gpt1(1) new_y];
                pts_array = [pts_array ; [repmat(gpt1(1),[numel(range_y) 1]) range_y]];
            end
            if isequal(gpt1,pt2)
                break;
            end
        end
    
        if gslope1_org <1
            pts_array = fliplr(pts_array);
        end
    end
    
    function pts_array = points_array_wrap(pt1,pt2) %%// Please remember that this needs points_array.m
    
    x1 = pt1(1);
    y1 = pt1(2);
    x2 = pt2(1);
    y2 = pt2(2);
    
    quad4 = y2<y1 & x2>x1; %% when pt2 is a lower height than pt1 on -slope
    quad3 = y2<y1 & x2<x1; %% when pt2 is a lower height than pt1 on +slope
    quad2 = y2>y1 & x2<x1; %% when pt2 is a higher height than pt1 on -slope
    
    if quad4
        y2 = y2+ 2*(y1 - y2);
    end
    
    if quad2
        y2 = y2 - 2*(y2 - y1);
        t1 = x1;t2 = y1;
        x1 = x2;y1 = y2;
        x2 = t1;y2 = t2;
    end
    
    if quad3
        t1 = x1;t2 = y1;
        x1 = x2;y1 = y2;
        x2 = t1;y2 = t2;
    end
    
    pts_array = points_array([x1 y1],[x2 y2]);
    
    if quad4
        offset_mat = 2.*(pts_array(:,2)-pt1(2));
        pts_array(:,2) = pts_array(:,2) - offset_mat;
    end
    
    if quad3
        pts_array = flipud(pts_array);
    end
    
    if quad2
        offset_mat = 2.*(pt1(2)-pts_array(:,2));
        pts_array(:,2) = pts_array(:,2) + offset_mat;
        pts_array = flipud(pts_array);
    end
    
    return;
    
    输出

    pt1 = [2 1];
    pt2 = [5 5];
    
    pts_array = points_array_wrap(pt1,pt2);
    
    plot(pts_array(:,1),pts_array(:,2),'o'), grid on, axis equal
    for k = 1:size(pts_array,1)
        text(pts_array(k,1),pts_array(k,2),strcat('[',num2str(pts_array(k,1)),',',num2str(pts_array(k,2)),']'),'FontSize',16)
    end
    
    pts_array =
    
         2     1
         2     2
         3     2
         3     3
         4     3
         4     4
         4     5
         5     5
    
    绘图

    pt1 = [2 1];
    pt2 = [5 5];
    
    pts_array = points_array_wrap(pt1,pt2);
    
    plot(pts_array(:,1),pts_array(:,2),'o'), grid on, axis equal
    for k = 1:size(pts_array,1)
        text(pts_array(k,1),pts_array(k,2),strcat('[',num2str(pts_array(k,1)),',',num2str(pts_array(k,2)),']'),'FontSize',16)
    end
    
    pts_array =
    
         2     1
         2     2
         3     2
         3     3
         4     3
         4     4
         4     5
         5     5
    

    第二部分-目标是通过给定空间找到连接二维域上两点的线/路径的坐标

    在这种特殊情况下,我们假设存在一些空间,并且只有通过这些空间才能连接路径。OP并没有问这个问题,但我觉得分享会很有趣。所以,对于这个,空格应该是o,如OP的问题所示

    代码

    function your_path = path_calc(mat1,starting_pt,final_pt)
    
    [x1,y1] = find(mat1);
    pt1 = [x1 y1];
    d1 = pdist2(pt1,final_pt,'euclidean');
    [~,ind1] = sort(d1,'descend');
    path1 = pt1(ind1,:);
    your_path =  path1(find(ismember(path1,starting_pt,'rows')):end,:);
    
    return;
    
    运行-1

    %%// Data
    mat1 = zeros(5,5);
    mat1(2,1:2) = 1;
    mat1(3,2) = 1;
    mat1(4,2:5) = 1;
    mat1(5,5) = 1;
    
    starting_pt = [2 1];
    final_pt = [5 5];
    
    %%// Path traces
    path = path_calc(mat1,starting_pt,final_pt);
    
    Gives -
    mat1 =
    
    0     0     0     0     0
    1     1     0     0     0
    0     1     0     0     0
    0     1     1     1     1
    0     0     0     0     1
    
    
    path =
    
    2     1
    2     2
    3     2
    4     2
    4     3
    4     4
    4     5
    5     5
    
    运行-2

    %%// Data
    mat1 = zeros(5,5);
    mat1(2,1:2) = 1;
    mat1(3,2) = 1;
    mat1(4,2:5) = 1;
    mat1(5,5) = 1;
    mat1 = fliplr(mat1');
    
    %%// Notice it starts not from the farthest point this time
    starting_pt = [2 3];
    final_pt = [5 1];
    
    %%// Path traces
    path = path_calc(mat1,starting_pt,final_pt);
    
    Gives
    
    mat1 =
    
         0     0     0     1     0
         0     1     1     1     0
         0     1     0     0     0
         0     1     0     0     0
         1     1     0     0     0
    
    
    path =
    
         2     3
         2     2
         3     2
         4     2
         5     2
         5     1
    

    要查找从起点到目标的纯随机路径,此函数将选择一个随机方向,检查该方向是否存在有效的邻居,如果存在,则移动到该新邻居并将其添加到路径中

    例如,如果我们在最左边的列中并尝试向左移动,则方向可能无效。我们可以事先检查,只选择随机的方向,从而导致有效的邻居,但这将使代码复杂化,选择有效邻居的几率最坏为50/50

    function path = random_path(start, goal, board_size)
    
        m = board_size(1);
        n = board_size(2);
        isInBounds = @(x) x(1) >= 1 && x(1) <= m && x(2) >= 1 && x(2) <= n;
    
        neighbor_offset = [ 0, -1;    % Neighbor indices:
                           -1,  0;    %        2
                            0,  1;    %    1   x   3
                            1,  0];   %        4
    % Edit: get the actual size of our neighbor list
        [possible_moves, ~] = size(neighbor_offset);
    
        current_position = start;
        path = current_position;
    
        while sum(current_position ~= goal) > 0
            valid = false;
            while ~valid
    % Edit: "magic numbers" are bad; fixed below
    %           move = randi(4);
                move = randi(possible_moves);
                candidate = current_position + neighbor_offset(move, :);
                valid = isInBounds(candidate);
            end
            current_position = candidate;
            path = [path; current_position];
        end
    end
    
    sum
    goal
    的至少一个坐标不同时继续。我相信这可以写得更简洁,所以如果有任何关于如何改进的建议,我将不胜感激

    同样地,
    isInBounds
    匿名函数似乎也有点笨拙,因此任何建议都将不胜感激

    无论如何,这里有一个输出示例。由于路径是完全随机的,其中一些路径可能会变得相当长:

    random_path([2,1], [5,5], [5,5])
    
    ans = 
    
       2   1 
       3   1 
       2   1 
       3   1 
       3   2 
       4   2 
       4   1 
       5   1 
       4   1 
       4   2 
       3   2 
       3   1 
       2   1 
       1   1 
       2   1 
       3   1 
       3   2 
       4   2 
       4   3 
       4   4 
       4   3 
       4   2 
       4   3 
       5   3 
       4   3 
       3   3 
       4   3 
       4   2 
       4   1 
       4   2 
       4   1 
       4   2 
       4   3 
       4   2 
       5   2 
       5   3 
       5   2 
       4   2 
       3   2 
       3   3 
       3   4 
       3   5 
       3   4 
       2   4 
       3   4 
       4   4 
       5   4 
       5   3 
       4   3 
       3   3 
       3   2 
       4   2 
       4   3 
       4   4 
       5   4 
       5   5 
    

    要查找从起点到目标的纯随机路径,此函数将选择一个随机方向,检查该方向是否存在有效的邻居,如果存在,则移动到该新邻居并将其添加到路径中

    例如,如果我们在最左边的列中并尝试向左移动,则方向可能无效。我们可以事先检查,只选择随机的方向,从而导致有效的邻居,但这将使代码复杂化,选择有效邻居的几率最坏为50/50

    function path = random_path(start, goal, board_size)
    
        m = board_size(1);
        n = board_size(2);
        isInBounds = @(x) x(1) >= 1 && x(1) <= m && x(2) >= 1 && x(2) <= n;
    
        neighbor_offset = [ 0, -1;    % Neighbor indices:
                           -1,  0;    %        2
                            0,  1;    %    1   x   3
                            1,  0];   %        4
    % Edit: get the actual size of our neighbor list
        [possible_moves, ~] = size(neighbor_offset);
    
        current_position = start;
        path = current_position;
    
        while sum(current_position ~= goal) > 0
            valid = false;
            while ~valid
    % Edit: "magic numbers" are bad; fixed below
    %           move = randi(4);
                move = randi(possible_moves);
                candidate = current_position + neighbor_offset(move, :);
                valid = isInBounds(candidate);
            end
            current_position = candidate;
            path = [path; current_position];
        end
    end
    
    sum
    goal
    的至少一个坐标不同时继续。我相信这可以写得更简洁,所以如果有任何关于如何改进的建议,我将不胜感激

    同样地,
    isInBounds
    匿名函数似乎也有点笨拙,因此任何建议都将不胜感激

    无论如何,这里有一个输出示例。由于路径是完全随机的,其中一些路径可能会变得相当长:

    random_path([2,1], [5,5], [5,5])
    
    ans = 
    
       2   1 
       3   1 
       2   1 
       3   1 
       3   2 
       4   2 
       4   1 
       5   1 
       4   1 
       4   2 
       3   2 
       3   1 
       2   1 
       1   1 
       2   1 
       3   1 
       3   2 
       4   2 
       4   3 
       4   4 
       4   3 
       4   2 
       4   3 
       5   3 
       4   3 
       3   3 
       4   3 
       4   2 
       4   1 
       4   2 
       4   1 
       4   2 
       4   3 
       4   2 
       5   2 
       5   3 
       5   2 
       4   2 
       3   2 
       3   3 
       3   4 
       3   5 
       3   4 
       2   4 
       3   4 
       4   4 
       5   4 
       5   3 
       4   3 
       3   3 
       3   2 
       4   2 
       4   3 
       4   4 
       5   4 
       5   5 
    


    什么样的房产?有最大长度吗?允许两次访问同一点?你是指随机路径还是通过o的最短路径?@Danial:没有限制。@Divakar:它不一定是最短路径,而是随机路径enough@user1687617该死我以为我在解决一些有趣的问题,但没关系:)@Divakar很抱歉:什么样的属性?有最大长度吗?允许两次访问同一点?你是指随机路径还是通过o的最短路径?@Danial:没有限制。@Divakar:它不一定是最短路径,而是随机路径enough@user1687617该死我以为我在解决一些有趣的问题,但没关系:)@Divakar对此很抱歉:PIt在我听来好像任何通过矩阵的路径都是允许的,OP正在寻找一条随机选择的路径。无论哪种情况,答案都很好!大卫是对的。在您的例子中,它将是:mat1=零(5,5);启动=mat1(2);结束=mat1(25);如何找到连接这两点的路径?@user1687617连接两点的路径案例在a部分解决,试试看@Divakar几乎完成了,但我希望所有点都连接起来。也就是说,它不能成对角线。下一步只能是右/左/上/下。@user1687617查看A部分中编辑的代码!唷,真了不起!在我看来,任何通过矩阵的路径都是允许的,OP正在寻找一条随机选择的路径。无论哪种情况,答案都很好!大卫是对的。在您的例子中,它将是:mat1=零(5,5);启动=mat1(2);结束=mat1(25);如何找到连接这两点的路径?@user168