经过两篇文章的篇幅,我们介绍了最小费用网络流模型以及解决的算法。今天我们介绍网络流模型的现实应用案例,并针对一些特殊的情景提出更高效的解决算法。
传送门:网络流与图(一)网络流与图(二)
1
运输与分配问题
运输问题是特殊的最小费用网络流模型,其中每个节点都是一个纯供给节点(所有弧都指出)或一个纯需求节点(所有弧都指入).
它的标准形式可以表示为:
举个贴近现实的例子——海军调动运输问题。
美国海军兵团的军官调动计划是一个真实的大规模运输问题。非常时期,会有上千名官军从他们日常岗位被调走或留在原有位置。然而并非每名军官在职级、经验或所接受的训练上都能满足分配需求。调动选择可以表示为如下面虚拟的有向图中。供给节点代表目前位于同一位置且可能满足分配要求的一组军官。例如第一个节点代表被训练为情报官的上尉;需求节点代表非常时期内活跃地区对具有特定资格的军官需求,例如节点2表示需要一个或多个服务于当地政府联络军官。
当一个供给节点所表示的军官具有填充一个需求节点所对应职位的资格时,两个节点间就会存在一个弧。因此,民政事务官会连接到当地政府联络员。对于处在任一源节点的军官,都可能有多种可行的分配,比如事务官也可以作为第一部队通信员。
海军需要首先考虑是填充所有所需的职位,但事实上总会留下一些职位无法被填充。此时我们用一个与所有需求相连的人工供给节点来表示无法填充职位的可能性,其弧上的高费用用在目标函数中作为无法填充职位的惩罚。一旦尽可能多的需求得以满足,第二个要考虑的则是令变动最小化。即尽量将军官分配到与调动前相同的单位,或至少通过最小化总路费而将他们分配到邻近的单位。
利用下列概念,将海军调动问题简化为标准形式。
分配问题(assignment problem)是另外一种特殊的最小费用网络流问题,用于获取两个不同集合中对象间的最优配对或匹配。
分配问题要用到离散决策变量进行建模:
用A表示可行的分配(i,j)的集合,我们可以将线性分配模型表示为双向流问题:
第一组约束方程通过对所有可能的分配j求和,保证每个i都恰好被分配了一次;第二组约束方程用同样的方式来确保每个j恰好被分配一次。
该公式为一个整数线性规划(ILP)问题,决策变量仅允许取离散值0或1。但我们会发现,计算最优解时可以忽略离散性。
举个真实的例子——CAM分配问题。
某计算机辅助制造(CAM)系统可以通过一个由电脑控制的工厂工作站来自动运行工作,而每项工作由所要求的一系列加工和装配操作构成。通过情况下,相同的操作可以在几个不同的工作站完成。因此电脑控制系统必须做出相应的运行决策。每当一项工作的某步骤已被完成,系统即必须从可实现其下步操作的几个工作站中选择一个来承接该项工作。完成这种控制决策的一种接近最优的方法即周期性的求解分配模型。为了进行说明,下表虚拟了8项工作i要么正在等待被移动到下一个工作站,要么会接下来的5min内完成当前的操作。同时,表中也列出了可能承接工作的10个工作站j。表中的项表示:运往站的时间+等待站变空的时间+在站中的操作处理时间。即它们将工作i分配给j的最短时间。缺失的数据表示不可行分配。
令集合A表示可行的(i,j)对,cij表示表里的时间。上面的问题可以转化为用最小化总时间的方法将工作分配给工作站。由于工作站数量多于工作,需要引入伪成员解决这一问题。
若分配问题中需要配对的两个集合大小不一致,则小的一个可以利用伪成员进行扩张。这些伪对象可以被分配给另一个集合里的所有成员,且相应费用为零。
CAM应用中,引入伪工作i=9,10.则其标准形式可表示为:
求解该问题,可以用到前两节提到的算法(消圈算法、单纯圈形法),也可以用线性规划的任一种算法(单纯形法、内点法、对偶法)。但对于这类分配问题,我们有一种更高效的算法求解——匈牙利算法(Hungarian Algorithm)
2
匈牙利算法
先直接给出算法步骤:
举个例子来消化这个算法。下表展示了源集I={1,2,3,4}四个对象需要配对给汇集J={5,6,7,8}对象的费用/权重:
初始化,先计算源集对偶值:
接着计算汇集对偶解:
计算边际减少费用:
然后构建相等子图:
进入解扩张,首先,标记为“偶”的根i=1被分配给未分配、未标记的j=5,将(1,5)加入解集;接着对“偶”的根i=2被分配给j=6,对根i=4被分配给j=7。由于5已分配,故根i=3不被分配。得到(红色粗线表示已分配):
然后进行树生长,只剩下“偶”节点i=3,指向已分配但未标记的节点j=5。故将(3,5)和分配给j=5的(1,5)插入树,标记j=5为“奇”,i=1为“偶”,得到(虚线表示被包含在树中):
转回步骤1,但此时不存在“偶”标记到未分配、未标记的节点。因此进入步骤2,也不存在满足条件的弧,进入步骤3.
A是源集到汇集的完整图={(1,5),(1,6),(1,7),(1,8),(2,5),(2,6),...,(4,7),(4,8)},根据定义,
接着更新对偶值及矩阵:
更新相等子图(绿色是新的边):
然后返回步骤1,节点5已被标记,故不满足“未标记”条件;节点6已被未配,也不满足“未分配”条件;因此进入步骤2,(3,6)满足条件,进行树生长及记录路径(3,6),(2,6):
然后返回步骤1,没有满足条件的情况,再次进入步骤2,记录路径(2,7)(4,7),得到:
返回步骤1,(4,8)满足条件,进行解集扩张:
至此,迭代结束。最优解已找到!