通常为了在一组点上找到连通分量,我从放置在二维欧几里德空间中的点构建一个图形,其中边缘由阈值确定。即,如果两点之间的距离比预定的截止半径更近,则我将它们视为邻居。然后,我在此图上进行深度优先搜索,以确定连接的组件。
这种方法的问题是我必须首先使用阈值来构建图形。我不是计算机科学家,所以我从未参加过算法课程。我想知道是否有一个算法,我可以找到最近的邻居或连接组件而不用阈值建立边缘?使阈值化如此可取的主要问题是这个盒子是周期性的。这就是为什么谷歌搜索对我没什么帮助。
我的代码看起来像这样:
// +++++
// Graph
// +++++
// ( Note that edges are lines connecting nodes or vertices )
class Graph
{
public:
Graph() {}
~Graph() {}
void setNumNodes( int nds );
int getNumNodes() { return numNodes; }
void addEdge( int nd_idx, set<int> dest );
map<int,set<int> > edges; // [node, destination]
void setThreshold( double cutoff, double carpan );
double getThreshold() { return threshold; }
private:
int numNodes;
double threshold;
};
void Graph::setNumNodes( int nds ){
numNodes = nds;
}
void Graph::addEdge( int nd_idx, set<int> dest ){
edges.insert( pair<int,set<int> >( nd_idx, dest ) );
}
void Graph::setThreshold( double cutoff, double carpan ){
threshold = 2*R + carpan*cutoff;
}
// +++++
// Function for depth-first search from a starting node
int dfsFromNode( Graph& graph, int i, stack<int>& S, vector<bool>& visited ){
int connected_comp = 0;
// Add the node to the stack
S.push( i );
// While there are nodes that are not visited
// (so as long as stack is not empty ..)
while( !S.empty() ){
// Remove the top of the stack (backtracking process)
S.pop();
if( !visited[i] ){
visited[i] = true;
connected_comp++;
set<int> neighbors;
neighbors = graph.edges[i];
for( auto j: neighbors ){
i = j;
S.push( i );
}
} // if the node is visited before, get out
} // while loop to check if the stack is empty or not
return connected_comp;
}
编辑:
重申一个问题,如何在不进行周期性边界设置的阈值处理的情况下找到最近邻居或连通分量?
答案 0 :(得分:1)
要查找连接的组件,可以使用kd-trees。 k-d树(缩写为k维树)是一种算法,在这种算法中,您可以在每个自由度中将数据点分成两个交替的正交方向。我发现following link对解释非常有用。
具体而言,在周期性边界条件的情况下,您可以在主框外部对像素进行重影/图像处理,并构建包含这些粒子的kd树。