寻找尽可能多的对

时间:2013-03-07 08:47:58

标签: java algorithm graph

我正在尝试解决问题,但不幸的是,我的解决方案对于此任务来说并不是最好的。

任务:

在聚会上有N位客人(0

我的想法:我写了一个程序,从间隔创建一个连接图。从图中我搜索连接数最少的人。从关联人员中我也选择连接最少的人。然后在照片上选择这两个作为一对。两者都从图表中删除。算法运行直到没有连接。

此方法有效,但程序计算时间限为10秒。有1000个条目,它在2秒内运行,但即使有4000,也需要很长时间。此外,当我尝试使用25000个数据时,程序因内存不足而停止运行,因此我甚至无法正确存储连接。

我认为这里需要一种新的方法,但我找不到另一种方法来使这项工作。

任何人都可以帮我找出适合这项任务的算法吗?

非常感谢!

示例数据:

10
1 100
2 92
3 83
4 74
5 65
6 55
7 44
8 33
9 22
10 11

第一行是访客人数,其他数据是参加聚会的人的间隔时间。

6 个答案:

答案 0 :(得分:3)

这里不需要创建图形,这个问题可以在间隔结构上很好地解决。按离开时间(间隔结束点)的升序对人进行排序。然后按照排序顺序迭代它们:如果当前人没有与任何人交叉,那么他应该被删除。如果他与一个以上的人交叉,请将其中一个最早离开的人当作一对。在迭代期间,您应该仅将每个人与下一个人进行比较。

证明这种方法并不困难,所以我希望你能亲自证明一下。 关于运行时间,简单的解决方案将是O(N ^ 2),但我认为它可以减少到O(N * logN)。无论如何,O(N ^ 2)将在普通PC上适应10秒钟。

答案 1 :(得分:2)

对我来说似乎是一个经典的maximum matching问题。

您构建了一个图表,其中可能被合并在一起的人(他们的时间间隔相交)与边缘连接,然后找到最大匹配,例如Edmond's Blossom algorithm

我不想说,它很容易实现。但是,对于二分图表中的最大匹配,您可以使用Kuhn's algorithm得到相当好的近似值。这个很容易实现,但不会给你确切的解决方案。

答案 2 :(得分:1)

我有一些非常简单的想法:

假设,派对将采取Xh,每小时制作X套,为他们添加适当的人。当然,那些将在那里工作超过一小时的人将会在几集中。现在如果有两组“一起”和偶数个ppl,你可以为每组拍摄n / 2张照片。如果有两组奇数的人你正在寻找将会出现在这两组中的每一组的人,并将他移动到其中一组(所以你有两组偶数同一时间的人派对)。

请记住删除所有使用过的ppl(考虑一些class - Man并列出他/她的所有小时数。)

我的想法可能应该扩展到更先进的“移动人”算法,通过不止一个相邻的集合。

答案 3 :(得分:1)

我认为以下可以做到:

首先,读取所有客人的数据,并通过保持时间上升将其排序为数组。然后,获取数组的第一个元素并迭代下一个元素,直到找到第一个时间匹配(下一个访客的入口时间小于此访客的休假时间),如果找到,则从数组中删除两者,并在其他地方报告。如果没有,请删除访客,因为它根本无法配对。重复直到数组为空。

最糟糕的情况也是N ^ 2,因为派对可以像[1,2],[3,4],...,其中没有客人可以相互配对,算法将一直搜索所有30000位客人。所以我不认为这是最优算法,但它应该给出一个确切的答案。

答案 4 :(得分:0)

你说你已经有了图形结构表示。我假设你的顶点代表客人,他们留在聚会的间隔和边缘代表各个间隔的重叠。你需要解决的是图理论maximum matching problem,它之前已经解决了。

然而,正如我在上面的评论中指出的那样,我认为你可以利用问题的属性,尤其是传递性的“如果A在B离开之前离开而B在C到达之前离开,那么A和C将不会相遇,或者“像这样:

等到下一个尚未照相的客人即将离开的时候,然后拍下这张照片中剩下的那位照片。

答案 5 :(得分:-1)

您可能会想到拍摄照片的最早时间:这是第二个人到达聚会的时间。

因此,作为一名摄影师,将派对作为第一人并等待。每当一个人到达时,与他/她和聚会上的所有其他人拍照。由于一个人只出现过一次,因此不会有任何重复。

拍照时(即迭代客人名单),删除实际离开聚会的客人。