如何在向量中的所有点之间绘制连线?

8

我有一个包含2-D空间中一些点的向量。我希望MATLAB可以绘制这些点,从每个点到其他每个点都画一条线。基本上,我想要一个连接所有顶点的图形。您可以使用plot实现吗?如果可以,该如何实现?

2个回答

8

一种解决方案是使用MESHGRID函数为每个点的组合创建一组索引。然后,您可以使用LINE函数绘制每条线(它会根据给定的数据列绘制一条线):

N = 10;                               %# Number of points
x = rand(1,N);                        %# A set of random x values
y = rand(1,N);                        %# A set of random y values
[I,J] = meshgrid(1:N);                %# Create all the combinations of indices
index = [I(:) J(:)].';               %'# Reshape the indices
line(x(index),y(index),'Color','k');  %# Plot the lines
hold on
plot(x,y,'r*');                       %# Plot the points

编辑:

你可能会注意到上面的解决方案将为每个连接绘制一条线,这意味着它将绘制零长度的线连接点与自身,并将为每个连接绘制2条线(即从点A到点B 从点B到点A)。 这里是另一个解决方案(使用函数HANKELFIND),它不会绘制冗余或不必要的线:

N = 10;                               %# Number of points
x = rand(1,N);                        %# A set of random x values
y = rand(1,N);                        %# A set of random y values
[r,c,v] = find(hankel(2:N));          %# Create unique combinations of indices
index = [v c].';                     %'# Reshape the indices
line(x(index),y(index),'Color','k');  %# Plot the lines
hold on
plot(x,y,'r*');                       %# Plot the points

以上两种解决方案创建的图形在视觉上完全相同:

alt text

关于时间的说明...

出于好奇心,我想测试一下我的HANKEL解决方案,并将其与Amro非常简洁的NCHOOSEK解决方案进行比较。对于N = 10,没有明显的差异。然而,当我增加N到更大的值时,我开始看到NCHOOSEK解决方案变得非常缓慢:

  • N = 200

    >> tic; [r,c,v] = find(hankel(2:N)); index = [v c].'; toc; %'
    Elapsed time is 0.009747 seconds.
    
    >> tic; pairs = nchoosek(1:N,2).'; toc; %'
    Elapsed time is 0.063982 seconds.
    
  • N = 1000

    >> tic; [r,c,v] = find(hankel(2:N)); index = [v c].'; toc; %'
    Elapsed time is 0.175601 seconds.
    
    >> tic; pairs = nchoosek(1:N,2).'; toc; %'
    Elapsed time is 12.523955 seconds.
    

我有点惊讶,直到我查看了NCHOOSEK的代码(通过在MATLAB命令窗口中键入type nchoosek)。不仅变量在循环内部增长而不是预先分配(正如Amro在评论中指出的那样),而且使用的算法也是递归的,这意味着会进行许多函数调用。我还注意到NCHOOSEK帮助文本末尾有这样一行:

此语法仅适用于N小于约15的情况。


1
你甚至可以添加测试:N=1000; pairs=zeros(2,499500); k=0; for i=1:N, for j=i+1:N, k =k+1; pairs(:,k)=[j;i]; end, end 来展示与非矢量化版本的区别(HANKEL 解法仍然更快!) - Amro

8

基于gnovice的示例,更简单、直观的生成所有对的方法是使用nchoosek函数:

%# random points
N = 10;
x = rand(1,N);
y = rand(1,N);

%# all possible combinations of the elements of [1:N] taken 2 at a time
pairs = nchoosek(1:N, 2)';

%'# plot points and lines
plot(x(pairs), y(pairs), '-bs', 'MarkerFaceColor','g', 'MarkerSize',10)

screenshot


+1:非常棒!我没有意识到 NCHOOSEK 可以这样使用。 - gnovice
1
我记得在这篇优秀的《组合数学导论》博客文章中读到过这个内容:http://blinkdagger.com/matlab/matlab-a-introduction-to-combinatorics/ - Amro
出于好奇,我对我们解决方案在更大的 N 下进行了一些计时。我将其添加到我的答案中,结果有点让我惊讶。你有注意到同样的事情吗? - gnovice
1
你说得对。我进行了一些分析,结果发现在循环内部有变量的大小在改变(没有预先分配)[第113行],导致了瓶颈。 - Amro
很奇怪他们在NCHOOSEK中没有预先分配内存。即便如此,我仍然期望HANKEL解法比较慢,因为它实际上构建了一个比必要更大的矩阵,然后再找到非零元素。 - gnovice

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接