在一组点中找到距原点的最小距离

Finding the smallest distance in a set of points from the origin

我要找到一组给定的点和原点之间的最小距离。我有一个包含 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, :);

我不能使用任何包。我在网上找到了 geometry 包,但我要解决这个任务而不需要额外的包。

我将使用您的原始代码。首先,您要计算 all 个点的范数,并将它们作为单独的元素存储在数组中。您当前的代码没有这样做,而是覆盖了变量 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 循环的功能完全相同。然而,这(至少对我而言)更具可读性,而且我敢说更大尺寸的点更快。