我是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坐标,因此我真的需要对点进行分类吗?先感谢您。
答案 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。还有其他一些,但是据我所知,这是唯一一个带有增强功能的。