(这不是我的问题,但它是同构的,我认为这个解释对其他人来说最容易理解。)
假设我在 n 维空间中有一组点。使用3个维度,例如:
A : [1,2,3]
B : [4,5,6]
C : [7,8,9]
我还有一组矢量来描述这个空间中可能的移动:
V1 : [+1,0,-1]
V2 : [+2,0,0]
现在,给定一个点 dest ,我需要找到一个起点 p 和一组向量移动,这将带我到 dest 以最有效的方式。效率定义为“移动次数最少”,不一定是“最小线性距离”:如果移动设置,允许选择 p 比 dest 更远离其他候选者 p 是这样你可以用更少的动作到达那里。 移动中的向量必须是可用向量的严格子集;除非在输入集中出现多次,否则不能多次使用同一个向量。
我的输入包含~100个起点和~10个矢量,我的维数是~20。起点和可用矢量将在应用程序的生命周期内得到修复,但我会找到许多不同 dest 点的路径。我想优化速度,而不是内存。算法失败是可以接受的(找不到 dest 的可能路径)。
我采用的解决方案非常类似于下面标记为“已接受”的解决方案。我遍历所有点和向量,并构建一个包含所有可到达点的列表以及到达它们的路径。我将此列表转换为< dest , p + vectors >的散列,为每个目标点选择最短的向量集。 (还有一些针对散列大小的优化,这与此处无关。)后续的 dest 查找在固定时间内发生。
答案 0 :(得分:6)
实际上,考虑到你有大约10个向量,对于给定的 dest 点,你可以从向量子集中仅计算 1024“目标” - 例如,每个可到达的空间,以及有关哪组动作的信息到达那里。根据上下文的不同,这可能是“慢”或“快”(如果在像GPU这样的并行计算设备上实现,它会非常快)。
拥有所有到达那里的集合你可以更快地计算路径,然后你可以选择从最少的移动到 dest 的点,从那些的子集中选择这是您的查询或更进一步。
(感谢Strilanc)
答案 1 :(得分:5)
我相信你能够对A *(又名A星)路径寻找算法进行广义应用。没有理由不能在第N个空间完成。如果你可以描述每次行动的成本,它会保证最佳路径。
答案 2 :(得分:5)
因此,您希望找到您的向量集的子集,以便子集求和到给定值。在1维中,这称为subset sum problem,并且是NP-Complete。
幸运的是,你只有~10个向量,所以你的问题大小实际上非常小且容易处理。首先尝试为每个起点尝试所有2 ^ 10个移动组合并选择最佳的一个。然后从那里寻找简单的优化。
可能有效的一些简单优化:
答案 3 :(得分:2)
鉴于您有起点和一组固定的向量,您是否可以计算所有可到达目的地的列表,然后只查找给定目的地?
答案 4 :(得分:1)
正如Kornel所说,你最多有2 ^ 10 = 1024个可达目的地。因此,您可以通过简单的递归生成在2 ^ N时间内生成所有可到达目的地(其中N是向量的数量)。当然,这将足够快。但是,我们假设您想要拉伸它。
您可以使用中间相遇解决方案将其优化为O(2 ^(N / 2 + 1))时间。您将矢量集拆分为两个子集,并为每个子集独立生成所有可到达的目标。然后,您遍历一组可到达的目标,并为每个位置找到它与目标目标之间的差异。如果该差异向量位于另一组可到达目的地中,则您有一个解决方案:将两者结合起来就完成了。这里的难点在于有效查询是否在另一组中有所需的向量:这可以使用哈希表在O(1)时间内完成。
每个子集的O(2 ^(N / 2))时间,两个子集的时间给出O(2 ^(N / 2 + 1))。要加入两个它是O(2 ^(N / 2))时间。所以这总给我们O(2 ^(N / 2 + 1))时间。
答案 5 :(得分:0)
这可能会在目的地周围振荡,但它会让你靠近。