假设我有一个圆形区域,并且在该区域中随机部署了n个对象。我想将圆圈从中心位置划分为K个组,使得同一区域中的对象被视为同一组的成员。另外,被指定从圈子中心的位置(特别是一个人一个人)访问K组的K人。现在,我希望将这样一种方式分组,即每个人的旅行距离彼此接近。
如果对象统一部署,则非常容易。只将区域划分为相等的角度,才能得到理想的结果。但是,对于对象的随机部署,我无法划分圆形区域(具体而言,无法固定角度),这使得每组中每个人的行进距离彼此接近
答案 0 :(得分:0)
正如评论中所提到的,在一个群体中找到最短路径的子问题是NP难的。因此,整体问题是NP难的。我将介绍一种动态编程算法,该算法既可以精确地解决问题(在指数时间内),也可以用启发式算法(在多项式时间内)近似。
两种变体都需要一个函数f(g)
来评估一个组的旅行距离。在确切的变体中,您需要解决TSP。在近似变体中,您使用启发式。您应该尝试几种启发式方法,看看哪种方法最合适。例如,对象的边界环区域可能是一个好的开始(加上最近的对象到中心的距离)。
实际算法如下所示:计算每个对象的角度位置,并根据该位置对它们进行排序。另外,计算到中心的距离。
现在,我们假设第一组从第一个对象开始。然后,我们希望找到最小化所有组f(g)
之和的分组。动态程序的状态通过到目前为止指定的组数和属于第一个下一组的对象进行参数化。这使得2D表格成为可能。您可以通过为结果组计算f()
来轻松初始化第一列:
groups | 1 2 3 4 5 6 ... K
next object |
--------------+------------------------
o2 | f(o1->o1)
o3 | f(o1->o2)
... | ...
on | f(o1->on-1)
o1 | f(o1->on)
然后,填写后续列。对于每个条目,您必须将该组与上一列中的所有组进行比较,并找到具有最小总和的组:
entry(column i, object j) = min_k (entry(i - 1, k) + f(ok->j-1))
实际上,您不必计算整个列。如果条目不允许适合K
组,则可以在开头和结尾处留空。例如。在第一列中,您只需要计算最多on-(K-1)
,因为您必须保留K-1
个对象未分配才能获得有效的分组。您可以缓存f
的结果以避免重复计算。
填好表后,您对entry(K, o1)
感兴趣。按照此条目中的路径返回到开头,您将获得第一组从o1
开始的最佳分组。在组开始时为第一个n-K
对象执行此操作,您将获得整体最佳值。
此算法的时间复杂度为O(n^3 * K * T(f))
,其中T(f)
是计算f(g)
的复杂性。