我试图解决一个问题,该问题是关于最小化一组n个实体的行进距离,这些实体必须按给定的顺序通过一组x点。
n个实体都从相同的位置(1,1)开始,然后我给出了队列中的x个点,并且必须回答"按正确的顺序。但是,我希望距离最小。
到目前为止,我对算法的处理方法是按照与下一个x的距离递增的顺序对实体进行排序。然后,我将检查距离最远的那些距离最远的那个距离,如果到达下一个的那个距离大于到达之后的那个距离以最小化距离。最接近不符合这一条件的人去回答。如果所有这些都接近后来的x,我会按照与之后的距离递增的顺序对它们进行重新排序,然后将距离最远的那个发送给它以回答x。由于这是一个测试问题,我作为比赛的练习,我知道我的测试用例应该是什么结果,而且似乎我做错了。
我应该如何实现这样一种算法来保证距离最小?
答案 0 :(得分:0)
您描述的算法听起来像greedy search algorithm。贪婪算法不能保证找到最佳解决方案,除非在特定情况下似乎没有。
这似乎是dynamic programming制定的候选人。或者,您可以使用启发式搜索,例如A* search algorithm。如果我参加比赛,我会选择后者。请参阅链接以获取有关算法如何工作,如何实现以及如何将其应用于您的问题的说明。
答案 1 :(得分:0)
虽然由于需要按顺序访问这些点,但是可能的安排数量有限,我想不出比下面的公式更有效的方法。设f(ns, i)
表示直到i
点的最佳排列,其中ns
是每个至少有一个点的实体的最后选择点的列表。然后我们最多有两个选择:如果我们还没有用完就开始一个新实体,或者尝试将当前点作为每个实体的下一次访问。
Python递归:
import math
def d(p1, p2):
return math.sqrt(math.pow(p1[0] - p2[0], 2) + math.pow(p1[1] - p2[1], 2))
def f(ps, n):
def g(ns, i):
if i == len(ps):
return 0
# start a new entity if we haven't run out
best = d((0,0), ps[i]) + g(ns[:] + [i], i + 1) if len(ns) < n else float('inf')
# try the current point as the next visit for each entity
for entity_idx, point_idx in enumerate(ns):
_ns = ns[:]
_ns[entity_idx] = i
best = min(best, d(ps[point_idx], ps[i]) + g(_ns, i + 1))
return best
return d((0,0), ps[0]) + g([0], 1)
输出:
"""
p5
p3
p1
(0,0) p4 p6
p2
"""
points = [(0,1), (0,-1), (0,2), (2,0), (0,3), (3,0)]
print f(points, 3) # 7.0