【问题标题】:Finding the smallest distance in a set of points from the origin在一组点中找到距原点的最小距离
【发布时间】:2015-12-10 19:55:07
【问题描述】:

我要找到一组给定点与原点之间的最小距离。我有一个 2 列 10 行的矩阵。每行代表坐标。一个点由两个坐标组成,我想计算每个点与原点之间的最小距离。我还想确定哪个点给出了这个最小距离。

在 Octave 中,我使用 norm 计算这个距离,对于我的集合中的每个点,我都有一个与它们相关的距离,最小的距离显然是我正在寻找的距离。但是,我在下面编写的代码并没有按应有的方式工作。

function [dist,koor] = bonus4(S)     
 S= [-6.8667,  -44.7967; 
    -38.0136, -35.5284; 
     14.4552, -27.1413; 
     8.4996,   31.7294; 
    -17.2183,  28.4815; 
    -37.5100,  14.1941; 
    -4.2664,  -24.4428; 
    -18.6655,  26.9427; 
    -15.8828,  18.0170; 
     17.8440, -22.9164]; 
    for i=1:size(S) 
        L=norm(S(i, :)) 

     dist=norm(S(9, :)); 
          koor=S(9, :) ; 
end

i = 9 是正确答案,但我需要 Octave 来输入该数字。如何告诉 Octave 这是我想要的数字?具体来说:

 dist=norm(S(9, :));   
 koor=S(9, :);

我不能使用任何软件包。我在网上找到了几何包,但我要在没有额外包的情况下解决任务。

【问题讨论】:

  • 您不能使用软件包,但请记住,它都是免费软件,因此您可以查看源代码并进行研究。

标签: octave distance


【解决方案1】:

我会处理您的原始代码。首先,您要计算 所有 点的范数,并将它们作为单个元素存储在数组中。您当前的代码没有这样做,而是覆盖了变量 L,它在循环的每次迭代中都是一个值。

您需要将L 设为一个数组并在循环的每次迭代中存储规范。完成此操作后,您将需要找到位置以及最小距离本身。这可以通过调用min 来完成,其中第一个输出为您提供最小距离,第二个输出为您提供最小值的位置。您可以使用第二个输出切入 S 数组以检索实际点。

最后但同样重要的是,在调用此函数之前,您需要先定义 S。您在函数内部定义S,如果您想在每次调用时更改此函数的输入,这可能会给您带来意想不到的结果。因此,先定义S,再调用函数:

 S= [-6.8667,  -44.7967; 
    -38.0136, -35.5284; 
     14.4552, -27.1413; 
     8.4996,   31.7294; 
    -17.2183,  28.4815; 
    -37.5100,  14.1941; 
    -4.2664,  -24.4428; 
    -18.6655,  26.9427; 
    -15.8828,  18.0170; 
     17.8440, -22.9164];

function [dist,koor] = bonus4(S)             
    %// New - Create an array to store the distances
    L = zeros(size(S,1), 1);

    %// Change to iterate over number of rows
    for i=1:size(S,1) 
        L(i)=norm(S(i, :)); %// Change
    end

    [dist,ind] = min(L); %// Find the minimum distance
    koor = S(ind,:); %// Get the actual point
end

或者,确保将上述函数保存在名为 bonus4.m 的文件中,然后在 Octave 命令提示符下执行此操作:

octave:1> S= [-6.8667,  -44.7967; 
>         -38.0136, -35.5284; 
>          14.4552, -27.1413; 
>          8.4996,   31.7294; 
>         -17.2183,  28.4815; 
>         -37.5100,  14.1941; 
>         -4.2664,  -24.4428; 
>         -18.6655,  26.9427; 
>         -15.8828,  18.0170; 
>          17.8440, -22.9164];
octave:2> [dist,koor] = bonus4(S);

虽然这段代码有效,但我会争论它很慢,因为您使用的是for 循环。一种更快的方法是完全矢量化。因为对矩阵使用norm 与使用向量不同,所以您必须自己计算距离。因为您正在测量与原点的距离,所以您可以简单地将每一列单独平方,然后添加每一行的列。

因此,您可以这样做:

S= [-6.8667,  -44.7967; 
    -38.0136, -35.5284; 
     14.4552, -27.1413; 
     8.4996,   31.7294; 
    -17.2183,  28.4815; 
    -37.5100,  14.1941; 
    -4.2664,  -24.4428; 
    -18.6655,  26.9427; 
    -15.8828,  18.0170; 
     17.8440, -22.9164]; 

function [dist,koor] = bonus4(S)     
    %// New - Computes the norm of each point
    L = sqrt(sum(S.^2, 2));

    [dist,ind] = min(L); %// Find the minimum distance
    koor = S(ind,:); %// Get the actual point

end

函数sum 可用于独立地对维度求和。因此,通过执行S.^2,您正在对点矩阵中的每个项进行平方,然后通过使用sum 和第二个参数为2,您正在对每一行的所有列求和。取这个结果的平方根来计算每个点到原点的距离,这与for 循环的功能完全一样。然而,这(至少对我而言)更具可读性,我敢说对于更大尺寸的点来说更快。

【讨论】:

  • 非常感谢。对此,我真的非常感激!不过,我有 2 个小问题:如果我创建一个 m 文件并以八度音程运行这一行:[dist,koor] = bonus4(S) 我得到 dist = 24.01824 0.00000koor = -15.8828 18.0170 -6.8667 -44.7967 。我不应该只得到 dist 的标量吗?而且,似乎我得到了矩阵中最小范数加上第一行的位置。
  • @PhilippLoipolt 是的,自您上次发表评论以来,我进行了编辑。 L 矩阵未正确定义。请刷新此页面查看新的编辑。
  • @PhilippLoipolt - 如果上述解决方案适合您,请告诉我。如果确实如此并且您不再需要帮助,请考虑接受我的回答!这可以通过单击我帖子顶部的复选标记图标来完成,位于向上和向下投票箭头下方的左侧。祝你好运!
  • 它确实有效。我已经对其进行了测试,它似乎可以工作。我有最后一个问题:如果我重新启动 octave.exe 并导航到 m 文件所在的目录并运行它 - 八度会唠叨关于未定义的元素。所以我必须将S复制到octave.exe中,然后运行bonus4(S)。有没有办法让 taht octave 直接从 m 文件中获取 Matrix S?因为我需要放入其他矩阵并在不同的计算机上运行 mfile。非常感谢,非常感谢您的帮助,我会接受您的回答。
  • 只是两个小的性能说明。而不是sum (S.^2, 2),使用sumsq (S, 2) 会更快。此外,由于您实际上并不需要距离,您只需要按距离排序,根本不需要致电sqrtmin (sumsq (S, 2)) 会很好。
猜你喜欢
  • 1970-01-01
  • 2012-02-01
  • 2021-08-20
  • 1970-01-01
  • 1970-01-01
  • 2015-02-19
  • 1970-01-01
  • 2013-12-09
  • 1970-01-01
相关资源
最近更新 更多