在3d空间中针对n个最近的邻居实施knn实现

时间:2019-04-15 19:17:36

标签: c struct 3d knn

我是c的新手。我有n个结构,其中包含4个成员,第一个的唯一索引和代表3D空间中特殊坐标的三个浮点数。我需要根据欧几里得距离找到k个最近的结构。

//struct for input csv data
struct oxygen_coordinates
{
    unsigned int index; //index of an atom
    //x,y and z coordinates of atom 
    float x;
    float y;
    float z;
};

struct oxygen_coordinates atom_data[n];

//我需要编写类似的函数,

 knn(atom_data[i], atom_data, k); // This should return to 4 closest struct based on Euclidian distances. 
 //I have already written a function to get distances.

 //Distance function for two pints in a struct
 float getDistance(struct oxygen_coordinates a, struct oxygen_coordinates b)
 {
    float distance;
    distance = sqrt((a.x - b.x) * (a.x - b.x) + (a.y-b.y) *(a.y-b.y) + (a.z - b.z) * (a.z - b.z));
    return distance;
 }

在这一点上我完全迷失了,算法上的任何线索都将非常有帮助。特别是,在我的数据集中只有3d坐标,因此我真的需要对点进行分类吗?先感谢您。

2 个答案:

答案 0 :(得分:0)

以下一些代码可能会对您有所帮助。这段代码只是为了让人们对问题的解决方案有所了解。

// declare a global array that will hold the 4 nearest atom_data...
struct oxygen_coordinates nearestNeighbours[4];

// This function adds the structure passed to it until it becomes full, after that it replaces the structure added from the first...
    void addStructure(struct oxygen_coordinates possibleNeighbour) {
         static int counter = 0;
         int length = sizeof(nearestNeighbour)/sizeof(possibleNeighbour);
         if(length < 3) {
            nearestNeighbours[length] = possibleNeighbour;
         }
         else {
            nearestNeighbours[counter%4] = possibleNeighbour;
            counter++;
        }
    }

给定原子是要查找其邻居的原子的atom_data,而原子数据是整个数组。 现在,我们创建一个新的float变量,该变量存储到目前为止找到的最小距离,并使用很高的值对其进行初始化。 之后,我们遍历atomic_data,如果找到距离小于存储的最小值的候选对象,我们将更新最小值,并通过上面创建的add方法将结构添加到我们的NearestNeighbours数组中。 一旦遍历整个结构,我们将在NearestNeighbour数组中拥有4个最近的atom_data。

knn(given_atom, atom_data, k) {
        float minDistance = 10000; // Some large value...
        for(int i=0; i<n; i++) {
            int tempDistance = getDistance(given_atom, atom_data[i])
            if(tempDistance<minDistance) {
                addStructure(atom_data[i])
            }
        }
    }

时间复杂度将取决于atom_data的长度,即n。如果以排序方式存储数组,则可以大大降低时间复杂度。

答案 1 :(得分:0)

您可能要使用空间索引,例如boost R-Tree。还有其他一些,但是据我所知,这是唯一一个带有增强功能的。

其他(更简单)的空间索引是quadtreeskD-trees