优化旅行和从工厂收集单位的成本 1. Dijkstra 算法最差2. A*搜索算法3.专业 A*最佳

问题描述

问题陈述 有'n'家工厂,位于arr[i]。条目位于 '0' ,退出 ID 位于 'exit-pos' 。从一个地方到另一个地方的移动时间就是两者之间的距离。

每个工厂都需要“处理”时间(所有工厂都一样)来处理。你必须从 '0' 开始,从 'exit-pos' 退出

此外,您必须生产“n”个单位,每个工厂只能生产 1 个单位。沿途您需要参观每个工厂并下达生产订单。然后将需要“处理”时间来生产它。您可以等待该单位生产并继续前进。或者您可以访问其他工厂给他们下订单。后者您需要再次访问工厂以选择订单。

旅行所需的时间是两个地方之间的距离。

问题:您需要说明生产“n”个单位并收集它们所需的最短时间。您的旅程从“0”开始,到“end-pos”结束。

输入:

number of units required to produce = number of factories = n
the location of factories in a array = arr
the exit position =  ext-pos
the processing time at each unit (it is same for each factory) = processing-time.

我的方法 我在测试时遇到了这个问题。测试已提交,但遗憾的是没有给出答案。在测试过程中,我尝试使用递归方法。它考虑了“收集的物品”、“时间”、“工厂-位置”。它失败了。它进入了一个时间循环。

对问题的清晰度有任何建议/问题,请随时发表评论。 谢谢

更新:0

解决方法

使用带有 A* 搜索的策略来解决

我已将解决方案上传到 GitHub repo
您可以看到 live demo here

以下是 README 的内容和截图:

Screenshot of the app

解决方案总结

0 < arr[i] < exit-pos 起,我们总是从第一个工厂开始最后完成。添加剩余时间很简单。

该解决方案包括三种不同的算法,可通过下拉菜单进行选择:

1. Dijkstra 算法(最差)

探索所有状态并找到到达最终状态的最短时间:

  • 一个状态包括当前位置所有工厂的状态(产品完成需要多长时间?是否已被取走?)。
  • 从每个状态等待直到生产完成,(向开始)或(向出口)移动。
  • 显然使用了 Dijkstra's algorithm

2. A*搜索算法

A* algorithm 与 Dijkstra 的算法基本相同,但使用启发式算法来支持更有希望的节点。

启发式无需等待即可计算最小行驶距离。它计算到最左边的未完成工厂以及从那里到出口的时间。

改进是显着的(即使对于小输入也是如此)。

3.专业 A*(最佳)

此版本使用与之前相同的搜索,但限制探索新状态:

它遵循的策略是一旦你从右转到左转就完成你剩下的一切。而且只允许在最左边的未完工工厂等待。

  1. 你可以向左移动,只有当你还剩下一个未完工的工厂时。
  2. 你可以等待,前提是你在最左边的未完工工厂。
  3. 您可以向右移动,前提是您正在进入未开发的区域或所有不适合您的事情都已完成。
  4. 如果您上一圈向左移动,请尽可能继续向左移动。
  5. 如果您上一圈左转,无法再左转,则只能等待。

为什么这样做(上面列出的参考文献)?

  1. 否则向左移动没有任何意义。只是不要。
  2. 无论如何,您都必须回到最左边的未完工工厂。在回来的路上,你会穿过右边的所有工厂。所以我们选择只在最左边等待,因为在别处等待可以转化为在这里等待。
  3. 向右移回接触区域不会更快,因为您必须回到最左边(参见 2.)。要么一开始往右边走,但只有在左边完成后才向右转。
  4. 你转身时选择了回去。其他选项通过在转弯前向右移动来探索。
  5. 同 4。

性能

这些是此输入的大致时间:
n = 14
arr = [2,3,5,7,11,13,17,19,23,29,31,37,41,43]
processingTime = 15

算法 时间
迪杰斯特拉 ~ 3000 毫秒
A* ~ 100 毫秒
战略 ~ 10 ms

如何获得此解决方案

首先,我选择将解决方案可视化并使用 Dijkstra 算法求解。

在检查各种输入的路径后,我注意到“策略”解决方案中描述的模式:向右走,转身然后完成这块工厂。

可能的改进

可以采取策略并将工厂数组分块。

每个块 [a1,a2,...,an] 需要 travelTime + waitTime = [3 * (an-a1)] + [min(0,processingTime - 2 * (an-a1))] 时间才能完成。
在块 [a1,an][b1,bm] 之间移动需要 b1 - an 时间。

现在必须确定块,以最小化总时间。


我在解决这个问题时玩得很开心。

而且我只能推荐可视化事物。

给我的一个提示:编码之前要三思而后行。只需拿一张纸,画出你会在没有电脑的情况下做的事情。