零件穿过坦克。最短路径算法

时间:2014-07-31 15:22:33

标签: algorithm mathematical-optimization shortest-path

假设有一条带有8个储罐的生产线:每个储罐都装有不同的物质,用于浸入的部件。这些部件将通过起重机沿着储罐侧面落入储罐中。穿过坦克的每个部分都有与之相关的配方。也就是说,每个具有配方#1的部件必须在罐1中持续10秒并且在罐2中持续5秒,依此类推。每个部件也必须按照罐号1,2,3,4,5,6,7,8的顺序浸入每个罐中。

进一步假设每个部件不能在罐中放置超过该部件配方中规定的时间,并且起重机的行程时间是瞬时的。例如,如果一个部件在油箱2中持续10秒并且计划进入油箱1的下一个部件应该在油箱1中持续5秒钟,那么该部件将不会被放入油箱1中,因为它将不得不等待油箱1比指定的配方长5秒。相反,起重机必须等待在坦克1中放置一个新部件,直到确保没有任何等待时间在坦克之间移动。

现在,如果您说配方1的50个零件,配方2的50个,配方3的50个,那么将零件添加到油箱中的最佳方法是什么? 1,1,1,2,3,2,1,3...?或者可能是配方1的所有部件首先是第2部分和第3部分的混合?我最有希望解决这个问题的想法是使用最短路径算法(我没有多少经验),但Dijkstra的算法看起来很有希望。我会建一棵树,其中根节点是放在线上的第一部分,每个子节点代表要放入坦克的下一部分。如果从使用配方1的零件开始,那么您可以将其视为具有三个子项1,2,3的根节点(每种配方类型一个)。类似地,这些子节点中的每一个都有三个子节点1,2,3,依此类推,直到您用完了要添加到树中的部分为止。根据父母的食谱,父母与其子女之间的“距离”将是多长时间,孩子必须在坦克外等待才能进入并安全地穿过坦克而没有延误。

然而,这种方法的问题在于,有150!/(50!)^3 = 2*10^64个不同的部分顺序,这使得很难将其存储在任何类型的数据结构中或以合理的方式处理它。我可以采取哪些其他方法来解决这个问题?零件的确定最优顺序是否可以获得,还是我必须接近近似?

1 个答案:

答案 0 :(得分:2)

您可以将此转为最低成本流量问题。

  • 使用带有供应150的起始节点s(部件数量之和)
  • 为每个食谱添加节点
  • 将每个节点连接到s并为其提供50个容量(无论您需要多少部分)
  • 为每个食谱添加另一个节点,另加1个额外节点。
  • 将您的每个第一个配方节点连接到您刚刚创建的每个节点。
  • 为这些边缘(i,j)提供无限容量,以及在开始配方j之前必须等待食谱i继续的时间。 (对于我们特殊的额外节点0,任何边(i,0)都应该有0(就像我们从这个配方开始一样)。
  • 使用容量为50的边(或所需部分的数量)或1(在这种情况下)将这些最后节点中的每个节点连接到具有需求150(与源的供应相同)的接收器t我们特殊的0节点,因为只有1个部分可以先行。)

您可以使用线性编程解决此问题。这种方法有什么好处,你只需要2 * n + 3个节点和n *(n + 3)+ 1个边缘,无论你必须生成多少个部分。

修改

线性规划公式实际上比网络流程更简单(解释):

min sum(i in Recipes, sum(j in Recipes, t_(i,j)*n_(i,j)))
s.t. sum(j in Recipes n_(i,j)) = d_i for all i in Recipes
     sum(i in Recipes n_(i,j)) <= d_j for all j in Recipes
     sum(i in Recipes n_(i,0)) = 1
     n_(i,j) >= 0 for all i in Recipes, for all j in Recipes and 0

其中t_(i,j)是我们在开始食谱j之前等待食谱i继续进行的时间,而n_(i,j)是食谱类型i的部分数量跟随食谱类型j的一部分,而n_(i,0)代表食谱类型i中不遵循任何内容(先行)的部分数量。 d_i是应该制作的食谱i的部分数量。