Algorithm 计算友元点的分治算法

Algorithm 计算友元点的分治算法,algorithm,Algorithm,我有一个问题需要用分而治之的办法来解决。 存在一个包含N个点的集合S。 如果有一个平行于轴的正方形,S中只包含两个点p1和p2,那么我们称之为p1和p2朋友点 现在,我需要使用分治算法来计算S中有多少个朋友点 我想了很久了。我没有办法。 我需要你的帮助。 我的英语不好,如果你有问题,请问我,我会补充。Thansks.以下(不一定是最优的)伪代码算法如何 List<Pair<Point, Point>> findFriends(List<Point> point

我有一个问题需要用分而治之的办法来解决。 存在一个包含N个点的集合S。 如果有一个平行于轴的正方形,S中只包含两个点p1和p2,那么我们称之为p1和p2朋友点

现在,我需要使用分治算法来计算S中有多少个朋友点

我想了很久了。我没有办法。 我需要你的帮助。 我的英语不好,如果你有问题,请问我,我会补充。Thansks.

以下(不一定是最优的)伪代码算法如何

List<Pair<Point, Point>> findFriends(List<Point> points)
{
    List<Pair<Point, Point>> friends = new List<Pair<Point, Point>>();

    if (points.Count > 1)
    {
        if (points.Count == 2)
        {
           friends.Add(new Pair<Point, Point>(points[0], points[1]);
        }
        else
        {
           int xMedian = getMedianX(points);
           int yMedian = getMedianY(points);
           List<Point> topLeftPoints = selectPoints(points, 0, xMedian-1, yMedian, yMax);
           List<Point> bottomLeftPoints = selectPoints(points, 0, xMedian-1, 0, yMedian-1);
           List<Point> topRightPoints = selectPoints(points, xMedian, xMax, yMedian, yMax);
           List<Point> bottomRightPoints = selectPoints(points, xMedian, xMax, yMedian, yMax);

           friends.Add(findFriends(topLeftPoints));
           friends.Add(findFriends(bottomLeftPoints));
           friends.Add(findFriends(topRightPoints));
           friends.Add(findFriends(bottomRightPoints));      
        }
    }

    return friends;
}
列出findFriends(列出点)
{
列出朋友=新建列表();
如果(点数>1)
{
如果(points.Count==2)
{
添加(新的一对(点数[0],点数[1]);
}
其他的
{
int xMedian=getMedianX(点);
int yMedian=getMedianY(点);
List topLeftPoints=选择点(点,0,xMedian-1,yMedian,yMax);
List bottomLeftPoints=selectPoints(点,0,xMedian-1,0,yMedian-1);
List topRightPoints=选择点(点、xMedian、xMax、yMedian、yMax);
列表右下角点=选择点(点、xMedian、xMax、yMedian、yMax);
添加(findFriends(topLeftPoints));
添加(findFriends(bottomLeftPoints));
添加(findFriends(topRightPoints));
添加(findFriends(bottomRightPoints));
}
}
回报朋友;
}

诀窍是以这样一种方式进行划分,即单个部分更小,并且可以独立处理。我们可以使用类似于快速排序的枢轴将点划分为两个集合。但这比听起来要困难得多,因为如果操作不正确,这些集合在特殊情况下可能不会收缩或不独立

添加好友:由于无法进一步区分而必须评估的集合大小为1(不做任何操作)、2(添加对)和3(添加2到3对,需要检查)

找到一个轴心点:计算平均值x和平均值y,并找到最接近该轴心点的点
p


划分:将点划分为4组a、b、c和d,如下所示。a、b为左下、右上分区,c、d为左上、右下分区,仅保留较好的一组(以a,b为例,如果a.size+b.size使用此实现,您将错过拆分后处于不同集合中的所有朋友。想象一下(-2,1);(-1,2);(1,2);(2,1);(2,-1);(1,-2);(-1,-2),(-2,-1)上的点。八角形,例如(-1,2)和(-1,-2)将被错过……非常棘手。@maraca:是的,这就是我所说的“非最优”的意思.有什么改进的建议吗?非常感谢你能让一个给定的点成为不止一个点的朋友吗?想象一下,在p1=(-1,0),p2=(0,0)和p3=(+1,0)处有一组三个点。这组点只有两个朋友点吗?还是会有两对朋友{p1,p2}和{p2,p3}因此有三个朋友点?一个给定点是多个其他点的朋友如果点可以是多个其他点的朋友,最好的算法是构造一个。一个给定点是位于相邻Voronoi区域的所有其他点的朋友。描述了一个分治算法。与Voronoi图密切相关的是.它连接相邻的Voronoi点,因此可视为“友谊图”。对不起。我不明白你的划分。你能举个例子吗?添加了一个例子分区b和c将计算两次。你将得到两个集合,其中约有3/4的点,所以是的,一些对会被检测两次,这都在上面,但集合是独立的,它们越来越小。如果你将朋友添加到集合中,那么一点也不重要LH,重复的将被自动丢弃。递归地做10次,集合的大小大约是总点数的百万分之二。
* * *    * * *    * * .   * * *
* * * => * p * => * * . , . * * bottom-left top-right partition
* * *    * * *    * * *   . * *

* * .    * * .    * * .   . . .
* * . => * p . => * * . , * * . top-left bottom-right partition
* * *    * * *    * . .   * * *

. . .    . . .    . . .   . . .
* * . => * * . => * . . , . * * bottom-left top-right partition
* * *    * p *    * * *   . * .
a | b    top-left bottom-right partition: 1st set: a, b, c, p; 2nd set: b, c, d, p.
- p -
c | d    bottom-left top-right partition: 1st set: a, c, d, p; 2nd set: a, b, d, p.