- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在尝试基于递归构建一个二维树。我可以将算法总结如下:
> ALGORITHM BuildKDTree(P,depth)
> 1. if P contains only one point
> 2. then return a leaf storing this point
> 3. else if depth is even
> 4. then split P with a vertical line through median x into P1 and P2 (left and right of the line, respectively)
> 5. else split P with a horizontal line through median y into P1 and P2 like before
> 6. RECURSION STEP -> v_left = BuildKDTree(P1,depth+1)
> 7. RECURSION STEP -> v_right = BuildKDTree(P2,depth+1)
> 8. Create a node v storing the line, make v_left the left child and v_right the right child
> 9. return the node v
由于这是我第一次实现递归,因此遇到了很多与之相关的问题。到目前为止,我编写的代码似乎处于无限循环中,直到抛出段错误。到目前为止,我无法在代码中找到错误,我将不胜感激。
// Point
struct Point{
int idx;
double xpos;
double ypos;
};
// Node in the k-d tree
struct Node{
char type;
Point coord;
Node* leftChild;
Node* rightChild;
double split;
};
// Function to find the median point
int findMedian( const vector<Point>& P, char line ){
vector<double> positions;
map<double,int> indices;
// Store the corresponding positions (vertical or horizontal splitting)
switch ( line ){
case 'x':
for( auto p: P ){
positions.push_back( p.xpos );
indices.insert( pair<double,int>(p.xpos,p.idx) );
}
break;
case 'y':
for( auto p: P ){
positions.push_back( p.ypos );
indices.insert( pair<double,int>(p.ypos,p.idx) );
}
break;
}
sort( positions.begin(), positions.end() );
cout << positions.size() << endl;
int middle_pt = (int)floor(positions.size()/2);
cout << indices[positions[middle_pt]] << "\t" << middle_pt << "\t" << positions[middle_pt] << endl;
return ( indices[positions[middle_pt]] );
}
// Function to build a k-d tree
Node buildKDTree( vector<Point> P, int depth ){
Node v;
// if P contains only one point, return a leaf storing this point;
// else if depth is even, split P with a vertical line through the median x ..
// .. into P1 (left of l) and P2 (right of l);
// when the depth is odd, do the vice versa.
if( P.size() == 1 ){
cout << "I am at the leaf!" << endl;
v.coord = P[0];
v.type = 'l';
return v;
}
else if( P.size() < 1 ){
cout << "Points size smaller than 1 " << P.size() << endl;
v.type = 'n';
return v;
}
else{
vector<Point> P1; // left of median
vector<Point> P2; // right of median
if( depth % 2 == 0 ) {
// Verical line through median x
char line = 'x';
v.type = line;
int mid_idx = findMedian( P, line );
v.split = P[mid_idx].xpos;
v.coord = P[mid_idx];
for( auto p: P ){
if( p.xpos < v.split ){
//cout << "Through x, left " << "\t" << p.xpos << "\t" << mid_coord << endl;
P1.push_back( p );
}
else{
//cout << "Through x, right " << "\t" << p.xpos << "\t" << mid_coord << endl;
P2.push_back( p );
}
}
}
else{
// Horizontal line through median y
char line = 'y';
v.type = line;
int mid_idx = findMedian( P, line );
v.split = P[mid_idx].ypos;
v.coord = P[mid_idx];
for( auto p: P ){
if( p.ypos < v.split ){
//cout << "Through y, left " << "\t" << p.ypos << "\t" << mid_coord << endl;
P1.push_back( p );
}
else{
//cout << "Through y, right " << "\t" << p.ypos << "\t" << mid_coord << endl;
P2.push_back( p );
}
}
}
cout << "depth is before at " << depth << endl;
Node temp1 = buildKDTree( P1, depth+1 );
depth = 2;
cout << "depth is after at " << depth << endl;
Node temp2 = buildKDTree( P2, depth+1 );
v.leftChild = &temp1;
v.rightChild = &temp2;
return v;
}
}
// +++++++
int main( int argc, char *argv[] ){
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//++ Get the data
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Choose the data to be used
const int nsamp = samplePostData; // Sampling interval
const double dtSamp = nsamp*dt; // Time units between two data points
// Instantiate the data structure
vector<Cell> cells( M );
// Set filenames
char * x_input_file = argv[1]; // Filename for the x data
char * y_input_file = argv[2]; // Filename for the y data
// Read the data to the cells
int sample_cnt = -1;
int sample_data = 1;
char getX = 'x';
readData( cells, x_input_file, getX, sample_cnt, sample_data );
sample_cnt = -1;
char getY = 'y';
readData( cells, y_input_file, getY, sample_cnt, sample_data );
// Set general simulation variables
Data simData;
simData.setNumStep( cells[0].xpos.size() );
simData.setNumDelay( sqrt( cells[0].xpos.size() ) );
simData.setNumTotalDelay();
const double T = simData.getNumStep(); // Total time
const double D = simData.getNumDelay(); // Last delay time
const double TD = simData.getNumTotalDelay(); // Total time - last delay time
// Set the box
Box box;
box.setWidth( boxSize_x );
box.setHeight( boxSize_y );
const double Lx = box.getWidth();
const double Ly = box.getHeight();
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//++ Do the analysis
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vector<Point> points;
int i = 1000;
for( int m = 0; m < M; m++ ){
Point point_temp;
point_temp.xpos = (cells[m].xpos[i] - Lx*ifloor(cells[m].xpos[i]/Lx));
point_temp.ypos = (cells[m].ypos[i] - Ly*ifloor(cells[m].ypos[i]/Ly));
point_temp.idx = m;
points.push_back( point_temp );
}
vector<Node> tree;
int depth = 2;
tree.push_back( buildKDTree( points, depth ) );
cout << tree.size() << endl;
// for( auto j: tree ){
// cout << j.type << " " << j.coord.idx << " " << j.coord.xpos << " " << j.coord.ypos << " " << j.leftChild->coord.idx << " " << j.rightChild->coord.idx << " " << j.leftChild->coord.xpos << " " << j.rightChild->coord.ypos << "\n";
// }
}
最佳答案
问题是您不检查是否将同一点标记为中位数两次。很容易出现这种情况(尤其是在密集系统中)中线上有多个点。如果您没有明确标记之前用作中位数的点,那么您将再次使用它们,这将在树中创建无限递归。
我的建议是为每个点创建一个 bool 数组,当你使用这些点作为中值时,只需标记它们,这样你以后就不会再使用它们了。
关于c++ - kd-tree 中的无限递归,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31534562/
假设您有一个对象列表,每个对象都需要计算距离它最近的对象以进行拍摄。这个对象有一个 x 和一个 y 值。物体也在移动。 kd树还有用吗?我不确定,因为如果物体在移动,你必须继续创建这个 kd 树。 我
我正在查看 KD 树的维基百科页面。例如,我在 python 中实现了用于构建列出的 kd 树的算法。 但是,使用 KD 树进行 KNN 搜索的算法会切换语言并且并不完全清楚。英文解释开始有意义,但它
Kd 算法首先通过划分基元数组(三角形、球体等)来创建根 BSP 节点,以便创建两个新数组(左基元和右基元),用于创建其两个基元子树。 左基元和右基元是通过将给定基元数组划分为两个数组来计算的。通过取
我(尝试)在Processing/Java中实现KD树,并遵循我在数十篇文章和维基百科文章中看到的逻辑,但我一定做错了什么,因为输出如下所示: 而不是这个: 显然有些东西不对劲,因为节点是重复的,而且
我有以下路径数据: id1 p1 p2 0 1 7.935 5.103 1 1 7.93
我正在阅读 C 中的 kd 树实现。这是其中的一些部分。问题出在 findmedian 函数中。我不明白 的实现 *md = start +(end-start)/2; ...... -> 其他不相关
给定一组数据点,kdtree是在它们之上创建的,但是这个 kdtree 是唯一的吗? 最佳答案 这似乎取决于您构建树的方式。维基百科文章提到中点的选择如何影响生成的树是否平衡。如果选择不同的点,那么树
警告:相当长的问题,也许太长了。如果是这样,我深表歉意。 我正在开发一个涉及 kd 树的最近邻搜索的程序(在本例中,它是一棵具有 3961 个独立点的 11 维树)。我们才刚刚了解它们,虽然我很好地掌
我目前正在尝试构建二维(纬度和经度)的 KD 树以查询最近的坐标。我将坐标(ID、纬度、经度)推送到一个 vector 中,并将该 vector 传递到我的 KD-Tree 的构造函数中。 但是当我在
我正在尝试为我的 C++ (DirectX) 项目实现一个 kd-tree 以加速我的碰撞检测。我的实现是一个非常原始的递归函数。第 nth_element 似乎工作正常(如果我将其注释掉,则只有 1
我为两组点构建了 kd 树,以便找到两组点之间最接近的双色配对: kd 树存储为 python 字典,可以在下面的代码中找到,并传递给一个函数('closest'),该函数旨在同时递归地分析两棵树以找
我正在尝试基于递归构建一个二维树。我可以将算法总结如下: > ALGORITHM BuildKDTree(P,depth) > 1. if P contains only one po
我想从平衡的 KD 树中删除一个元素,并且树在不重建整棵树的情况下保持平衡。这有可能在不重建整棵树的情况下平衡树吗?如果是那么怎么办? 最佳答案 对于标准的 k-d 树,您可以删除项目但没有重新平衡,
所以我们有一个无限的 3d 世界,我们需要查询最近的点。然而我们的点有标识符并且一直在移动。支持数据点的 KDtree\Octree 之类的数据结构是什么。连续移动并且在搜索+更新方面不会比 3d 情
你好,有人用 C++ 迭代实现了 Kd-Tree 吗?我试过了,但是当节点数为奇数时它失败了。到目前为止,这是我的代码。我指的是 http://ldots.org/kdtree/#buildingAk
我想扩展一个 kd-tree (2D) 类,以便能够删除节点(点)。这种移除应该在不必重建树的大部分的情况下进行。这些slides中描述的算法,在幻灯片 13 上似乎是我所追求的。但是,我无法理解幻灯
普通的kd-tree是通过递归地将超平面分成两半来构建的。并且用一个查询点做范围搜索,它只会搜索一小串点(对数)而不是所有(线性)。 我想知道 kd 树可以用点积构建吗? 例如,b 是一个 3d 向量
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我刚刚完成了一个 kd-tree 的实现用于进行快速最近邻搜索。除了 Euclidean distance 之外,我有兴趣使用不同的距离指标。 .我对 kd-tree 的理解是,如果度量是非欧几里德的
我使用了 kd-tree algoritham 和 make tree。 但是我发现树不平衡所以我的问题是如果我们使用 kd-tree algoritham 那棵树总是平衡的如果不是那么我们怎样才能使
我是一名优秀的程序员,十分优秀!