使用复合数据结构的最近点计算
Closest point computation using compound data structures
我正在读一本罗伯特·塞德威克算法(Robert Sedwick Algorithms)在C++的书。以下是书中给出的有关复合数据结构的示例。
问题陈述: 给定 "d",我们想知道单位平方中一组 N 个点中有多少对可以用一条长度小于 "d" 的直线连接。
以下程序使用逻辑将单位平方划分为一个网格,并维护一个链表的二维数组,每个网格正方形对应一个列表。网格的选择要足够精细,使距离"d"内的所有点都位于同一网格正方形或相邻的网格正方形中。
我的问题是
- 为什么作者在malloc2d(G+2, G+2)中分配G+2?
- 在网格插入函数中,为什么作者正在执行以下语句 int X = x*G+1; int Y = y*G+1; ?
- 在 for 循环中,为什么我们要将 i 初始化为 X-1 并将 j 初始化为 Y-1?
- 在代码中,我们在哪里维护距离 d 内相同网格正方形或相邻网格正方形中的点?
通过简单的示例请求您的帮助,以理解以下程序。
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
using namespace std;
float randFloat() {
return 1.0*rand()/RAND_MAX;
}
struct myPoint {
float x;
float y;
};
float myDistance(myPoint a, myPoint b) {
float dx = a.x - b.x, dy = a.y - b.y;
return sqrt(dx*dx + dy*dy);
}
struct node {
myPoint p; node *next;
node(myPoint pt, node* t) {
p = pt; next = t;
}
};
typedef node *link;
static link **grid = NULL;
link **malloc2d(int r, int c) {
link **t = new link*[r];
for (int i = 0; i < r; i++) {
t[i] = new link[c];
}
return t;
}
static int G, cnt = 0;
static float d;
void gridinsert(float x, float y) {
int X = x*G+1;
int Y = y*G+1;
myPoint p;
p.x = x; p.y = y;
link s, t = new node(p, grid[X][Y]);
for (int i = X-1; i <= X+1; i++)
for (int j = Y-1; j <= Y+1; j++)
for (s = grid[i][j]; s != 0; s = s->next)
if (myDistance(s->p, t->p) < d) cnt++;
grid[X][Y] = t;
}
int main(int argc, char *argv[]) {
int i;
int N = 10;
d = 0.25;
G = 1/d;
grid = malloc2d(G+2, G+2);
for (i = 0; i < G+2; i++)
for (int j = 0; j < G+2; j++)
grid[i][j] = 0;
for (i = 0; i < N; i++)
gridinsert(randFloat(), randFloat());
cout << cnt << " pairs within " << d << endl;
return 0;
}
-
这个想法是检查网格的所有相邻单元格。但是边界细胞没有相邻。因此,为了避免棘手的边界检查,我们将网格扩展了 2 个额外的单元格 - 在第一个单元格之前和最后一个单元格之后。这些单元格是"虚拟的",永远不会包含任何点 - 它们只是为了简化算法并为边界单元格提供相邻点。
-
(X,Y) - 包含此点的网格中单元格的坐标(索引)。根据第 1 页,我们必须从单元格 (1,1) 而不是 (0,0) 开始放置点。(0,0) 和任何其他边界点都是虚拟的。
-
因为我们检查网格的所有相邻单元格。(X,Y)的相邻单元格是(X-1,Y-1),(X,Y-1),(X+1,Y-1)等到(X+1,Y+1)。这就是为什么我们有从 X-1 到 X+1 和 Y-1 到 Y+1 的循环。
-
我们不维护它们,只是检查任何输入点与现有集合和增量计数器
cnt
每次匹配距离时。问题条件不需要保留此类对的列表。如果您需要保留点列表,则应修改gridinsert()
,例如将(s->p, t->p)
放置在循环内的某个容器中,而不是递增cnt++
。
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- 递归函数计算序列中的平方和(并输出过程)
- (C++)分析树以计算返回错误值的简单算术表达式
- 我的字符计数代码计算错误.为什么
- 在计算中使用二的幂有多有利可图
- 如何计算文件中的"columns"数?
- 计算排序向量的向量中唯一值的计数
- 如何使用 std::累积在 C++ 中计算总和立方体
- 使用Qt C++计算类似Git的SHA1哈希
- OpenCV C++.快速计算混淆矩阵
- cpp二进制搜索问题,计算给定数组中输入元素的出现次数
- C++如何计算用户输入的数字中的偶数位数
- 如何计算数据类型的范围,例如int
- 类似枚举的计算常量
- 计算每个节点的树高,帮助我解释这个代码解决方案
- 应该如何编写用于计算最近点距离的C++函数?
- C/C++编译器是否会通过重用最近计算的函数结果来优化代码?
- 使用复合数据结构的最近点计算
- 处理大数据网络文件的高效算法,用于计算n个最近节点
- 计算与通配符匹配的下一个最近日期时间