C++ 两点之间的最近距离(不相交集)
这个问题是两个不相交集之间的一种最近对。 上面的图片表示了这个问题。有两种不相交的集合,-x平面上的蓝点,+x平面上的红点 我想计算一个蓝点和一个红点之间的最小距离(距离是| y2-y1 |+| x2-x1 |),我想使用二进制搜索来查找距离。如何使用二进制搜索这类问题? 我只在表示两个不相交集的二进制搜索上挣扎。我已经知道一个集合的情况,但我不知道两个不相交集合的情况 ++)它可以在线性时间内使用Delaunay三角剖分吗?(啊,这只是我的好奇心,我想用二进制搜索) 下面的代码,我已经编码了一个集合案例(使用问题解决技术,divide和qonquer)并转换为两个不相交的集合。我不知道如何分两组。 例如,提示。可以谁能帮帮我C++ 两点之间的最近距离(不相交集),c++,algorithm,computational-geometry,C++,Algorithm,Computational Geometry,这个问题是两个不相交集之间的一种最近对。 上面的图片表示了这个问题。有两种不相交的集合,-x平面上的蓝点,+x平面上的红点 我想计算一个蓝点和一个红点之间的最小距离(距离是| y2-y1 |+| x2-x1 |),我想使用二进制搜索来查找距离。如何使用二进制搜索这类问题? 我只在表示两个不相交集的二进制搜索上挣扎。我已经知道一个集合的情况,但我不知道两个不相交集合的情况 ++)它可以在线性时间内使用Delaunay三角剖分吗?(啊,这只是我的好奇心,我想用二进制搜索) 下面的代码,我已经编码了一
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <cmath>
/**
test input
10
-16 -4
-1 -3
-9 -1
-4 -10
-11 -6
-20 4
-13 6
-3 -10
-19 -1
-12 -4
10
8 2
10 3
10 10
20 -3
20 3
16 2
3 -5
14 -10
8 -2
14 0
10
-3 39
-2 -28
-1 20
-3 11
-3 45
-2 -44
-1 -47
-5 -35
-5 -19
-5 -45
10
27 5
28 0
28 5
21 5
2 3
13 -1
16 -2
20 -2
33 -3
27 1
**/
using namespace std;
const int MAX = 10001;
struct point{
int x,y;
};
bool xCompare(struct point, struct point);
bool yCompare(struct point, struct point);
int dis(struct point, struct point);
int absd(int);
int trace(int,int,int,int);
point p[MAX], q[MAX], tmp[MAX];
int main(){
int left;
int right;
scanf("%d\n", &left);
memset(p,0,sizeof(p));
memset(q,0,sizeof(q));
memset(tmp,0,sizeof(tmp));
for(int i=0; i<left; i++){
cin >> p[i].x >> p[i].y;
}
scanf("%d\n", &right);
for(int j=0; j<right; j++){
cin >> q[j].x >> q[j].y;
}
sort(p, p+left, xCompare);
sort(q, q+right, xCompare);
int min = trace(0,0, left-1, right-1);
printf("%d\n", min);
/** this is one set case.
while(true){
cin >> n;
if(n == 0) break;
memset(p,0,sizeof(p));
memset(tmp,0,sizeof(tmp));
for(int i= 0;i<n;i++)
cin >> p[i].x >> p[i].y;
sort(p,p+n,xCompare);
int min = trace(0,n-1);
if(min < 10000 && n > 1){
cout << fixed;
cout << setprecision(4) << min << endl;
}
else
cout << "INFINITY" << endl;
}
**/
return 0;
}
int trace(int low1, int low2, int high1, int high2){
if(high1 - low1 < 3){
int value = dis(p[low1],q[low2+1]);
int nextValue;
if(high1 - low1 == 2){
nextValue = dis(p[low1],q[low2+2]);
if(value > nextValue)
value = nextValue;
nextValue = dis(p[low1+1],q[low2+2]);
if(value > nextValue)
value = nextValue;
}
return value;
}
else{
/* DIVIDE & QONQUER */
int mid1 = (low1 + high1) >> 1;
int mid2 = (low2 + high2) >> 1;
int cnt = 0;
int leftValue = trace(low1,low2,mid1,mid2); // left trace
int rightValue = trace(mid1+1,mid2+1,high1,high2); // right trace
// min value find
int value = leftValue < rightValue ? leftValue : rightValue;
/* Middle Condition Check : Y Line */
// saving left
for(int i = low1;i<=mid1;i++){
if(abs(p[i].x - q[mid2].x) <= value)
tmp[cnt++] = p[i];
}
// saving right
for(int i = mid1+1;i<=high1;i++){
if(absd(p[i].x - q[mid2+1].x) <= value)
tmp[cnt++] = p[i];
}
sort(tmp,tmp+cnt,yCompare);
for(int i = 0;i<cnt;i++){
int count = 0;
for(int j = i-3;count < 6 && j < cnt;j++){
if(j >= 0 && i != j){
int distance = dis(tmp[i],tmp[j]);
if(value > distance)
value = distance;
count++;
}
}
}
return value;
}
}
int absd(int x){
if( x < 0)
return -x;
return x;
}
int dis(struct point a, struct point b){
return (abs(a.x-b.x) + abs(a.y-b.y));
}
bool xCompare(struct point a, struct point b){
return a.x < b.x;
}
bool yCompare(struct point a, struct point b){
return a.y < b.y;
}
#包括
#包括
#包括
#包括
/**
测试输入
10
-16 -4
-1 -3
-9 -1
-4 -10
-11 -6
-20 4
-13 6
-3 -10
-19 -1
-12 -4
10
8 2
10 3
10 10
20 -3
20 3
16 2
3 -5
14 -10
8 -2
14 0
10
-3 39
-2 -28
-1 20
-3 11
-3 45
-2 -44
-1 -47
-5 -35
-5 -19
-5 -45
10
27 5
28 0
28 5
21 5
2 3
13 -1
16 -2
20 -2
33 -3
27 1
**/
使用名称空间std;
常数int MAX=10001;
结构点{
int x,y;
};
boolxcompare(结构点,结构点);
bool yCompare(结构点,结构点);
int dis(结构点,结构点);
int absd(int);
int跟踪(int,int,int,int);
点p[MAX]、q[MAX]、tmp[MAX];
int main(){
int左;
国际权利;
scanf(“%d\n”,左)(&L);
memset(p,0,sizeof(p));
memset(q,0,sizeof(q));
memset(tmp,0,sizeof(tmp));
对于(inti=0;i>p[i].x>>p[i].y;
}
scanf(“%d\n”,右(&R));
对于(intj=0;j>q[j].x>>q[j].y;
}
排序(p,p+左,X比较);
排序(q,q+右,xCompare);
int min=轨迹(0,0,左-1,右-1);
printf(“%d\n”,最小值);
/**这是一个固定的案例。
while(true){
cin>>n;
如果(n==0)中断;
memset(p,0,sizeof(p));
memset(tmp,0,sizeof(tmp));
对于(inti=0;i>p[i].x>>p[i].y;
排序(p,p+n,xCompare);
int min=跟踪(0,n-1);
如果(最小值<10000&&n>1){
cout1;
int-cnt=0;
int leftValue=trace(low1,low2,mid1,mid2);//左跟踪
int rightValue=跟踪(mid1+1,mid2+1,high1,high2);//右跟踪
//最小值查找
int value=leftValue 对于(int i=low1;i我曾处理过一个类似的问题,我必须找到一个最近的成员来确定一个成员是否属于集群中的集群。我试图确定集群中的集群。下面是代码,这可能会帮助您开始
/**
* Find the nearest neighbor based on the distance threshold.
* TODO:
* @param currentPoint current point in the memory.
* @param threshold dynamic distance threshold.
* @return return the neighbor.
*/
private double nearestNeighbor(double currentPoint) {
HashMap<Double, Double> unsorted = new HashMap<Double, Double>();
TreeMap<Double, Double> sorted = null;
double foundNeighbor = 0.0;
for (int i = 0; i < bigCluster.length; i++) {
if (bigCluster[i] != 0.0 && bigCluster[i] != currentPoint) {
double shortestDistance = Math.abs(currentPoint - bigCluster[i]);
if (shortestDistance <= this.getDistanceThreshold())
unsorted.put(shortestDistance, bigCluster[i]);
}
}
if (!unsorted.isEmpty()) {
sorted = new TreeMap<Double, Double>(unsorted);
this.setDistanceThreshold(avgDistanceInCluster());
foundNeighbor = sorted.firstEntry().getValue();
return foundNeighbor;
} else {
return 0.0;
}
}
/**
* Method will check if a point belongs to a cluster based on the dynamic
* threshold.
*/
public void isBelongToCluster() {
for (int i=0; i < tempList.size(); i++) {
double aPointInCluster = tempList.get(i);
cluster.add(aPointInCluster);
double newNeighbor = nearestNeighbor(aPointInCluster);
if ( newNeighbor != 0.0) {
cluster.add(newNeighbor);
if (i + 1 > tempList.size() && (visited[i] != true)) {
isBelongToCluster();
}
}
}
for (int i=0; i < cluster.size(); i++) {
if (cluster.get(i) != 0.0)
System.out.println("whats in the cluster -> " + cluster.get(i));
}
}
/**
*根据距离阈值查找最近的邻居。
*待办事项:
*@param currentPoint内存中的当前点。
*@param threshold动态距离阈值。
*@返回邻居。
*/
专用双近邻(双电流点){
HashMap unsorted=新HashMap();
TreeMap sorted=null;
双近邻=0.0;
对于(int i=0;i”+cluster.get(i));
}
}
如果您想对空间数据进行二进制搜索,可以使用空间数据结构,如四叉树或k-d树。此问题通常称为最近双色对问题。以下是几种方法
Delaunay三角剖分。(这当然适用于L2(=欧几里德)距离;我认为步骤可以推广到L1。)对于每个Delaunay三角剖分(退化情况下可能不止一个),存在一个最小生成树,它的边都属于三角剖分。反过来,这个最小生成树包含一条最短的边,该边穿过颜色类之间的切割
最近邻数据结构
如果给定红色点与蓝色点在x方向上分开,则您可能能够调整Shamos–Hoey分治算法的O(n)合并步骤,以解决所述的最近(单色)对问题
这里还有一个解决方案。它基本上是将两个点集加载到两个kd树实例中(这两个kd树实例构建了在x轴和y轴上切片树的机制)然后通过检查每个节点在两棵树中的导航,如果两个节点之间的距离小于先前节点之间的距离,则继续,直到找不到相互距离小于任何其他节点的两个节点
下面的代码打印在节点之间导航时找到的距离并打印它们。这两组点也可以可视化,以查看算法的正确性
此代码可以正确地找到最近的节点,而不管一个集合是嵌套的,在另一个集合的右侧、左侧、上方还是下方
#include <iostream>
using namespace std;
int const k=2; // the number of dimensions
double min_distance = 10000; // set a large default value, in this example all distance will be shorter than this.
double distance(int arr[], int arr2[])
{
return sqrt(pow(arr2[0] - arr[0], 2) + pow(arr2[1] - arr[1], 2));
}
struct Node {
int point[k];
Node *left, *right;
Node()
{
left = right = NULL;
}
};
// A method to create a node of K D tree
struct Node* newNode(int arr[])
{
struct Node* temp = new Node;
for (int i = 0; i<k; i++) temp->point[i] = arr[i];
return temp;
}
Node * insertNode(Node * node, int arr[], int d)
{
if (node == NULL)
return newNode(arr);
int dim = d%k;
if (node->point[dim] > arr[dim])
{
node->left = insertNode(node->left, arr, dim + 1);
}
else
{
node->right = insertNode(node->right, arr, dim + 1);
}
return node;
}
Node * Nearest=NULL;
Node * FindnearestNode(Node * head1, int arr[], int d)
{
// if empty tree, return
if (head1 == NULL)
return NULL;
// check for each tree.
if (min_distance > distance(head1->point, arr))
{
min_distance = distance(head1->point, arr);
Nearest = head1;
}
if (head1->left == NULL && head1->right == NULL)
return head1;
// findout current dimension, in this case it either x or y i.e. 0 or 1
int dim = d%k;
// navigate through the tree as if inserting to a new member (to remain to the nearest member in closeness). in the path for insert it will find the nearest member.
if (head1->right && head1->point[dim] < arr[dim]) return FindnearestNode(head1->right, arr, d+1);
else if(head1->left && head1->point[dim] > arr[dim] )
return FindnearestNode(head1->left, arr, d+1);
return Nearest;
}
int main()
{
int const an = 10;
int const bn = 10;
int ax[an] = { 34,55,11,79,77,65,3,9,5,66 };
int ay[an] = { 5, 6, 7, 9, 32,3,15,7,10,35 };
int bx[bn] = { 5,35,4,41,32,64,41,54,87,3 };
int by[bn] = { 23,33,17,15,32,22,33,23,21,32 };
Node * head1=NULL;
Node * head2 = NULL;
double Final_Min_Distance = min_distance;
// fill the K-D trees with the two dimensional data in two trees.
for (int i = 0; i < an; i++)
{
int temp[k];
temp[0] = ax[i];
temp[1] = ay[i];
head1=insertNode(head1, temp, 0);
temp[0] = bx[i];
temp[1] = by[i];
head2=insertNode(head2, temp, 0);
}
Node * AnearB=NULL;
Node * BnearA = NULL;
min_distance = 1000;
Final_Min_Distance = min_distance;
for (int i = 0; i < an; i++) { int temp[k]; temp[0] = bx[i]; temp[1] = by[i]; Node * Nearer2 = FindnearestNode(head1, temp, 0); if (Final_Min_Distance > min_distance)
{
BnearA = Nearer2;
Final_Min_Distance = min_distance;
}
cout << " distance of B (" << temp[0] << "," << temp[1] << ") to nearest A (" << BnearA->point[0] << "," << BnearA->point[1] << ") distance:" << Final_Min_Distance << endl;
min_distance = 1000;
}
cout << "Minimum Distance is " << Final_Min_Distance<<endl<<endl;
min_distance = 1000;
Final_Min_Distance = min_distance;
for (int i = 0; i < an; i++) { int temp[k]; temp[0] = ax[i]; temp[1] = ay[i]; Node * Nearer2 = FindnearestNode(head2, temp, 0); if (Final_Min_Distance > min_distance)
{
AnearB = Nearer2;
Final_Min_Distance = min_distance;
}
cout << " distance of A (" << temp[0] << "," << temp[1] << ") to nearest B (" << AnearB->point[0] << "," << AnearB->point[1] << ") distance:" << Final_Min_Distance << endl;
min_distance = 1000;
}
cout << "Minimum Distance is " << Final_Min_Distance;
system("pause");
}
#包括
使用名称空间std;
int const k=2;//维数
double min_distance=10000;//设置一个较大的默认值,在本例中,所有距离都将小于此值。
双倍距离(int arr[],int arr2[]
{
返回sqrt(pow(arr2[0]-arr[0],2)+pow(arr2[1]-arr[1],2));
}
结构节点{
int点[k];
节点*左,*右;
节点()
{
左=右=空;
}
};
//一种创建kdtre节点的方法