如何在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部
(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