Excel精英培训网

 找回密码
 注册
数据透视表40+个常用小技巧,让你一次学会!
12
返回列表 发新帖
楼主: wm06606

[已解决]任务指派问题:N个人执行M个任务的分配方案求解(M >N)

[复制链接]
发表于 2014-7-29 13:26 | 显示全部楼层
wm06606 发表于 2014-7-29 10:28
http://www.excelpx.com/forum.php?mod=attachment&aid=MzMyMTA0fDRiZjE4ZTljNGYwYzdkYTMxOTQ0MmVmODg1Y2M3ODUxfDE3MTUwODE3ODE%3D&request=yes&_f=.rar


25个人执行30个任务:k=2.76007084168187E+31

60个人执行70个任务:k=1.13767067826725E+42

25个人执行25个任务:k=1.27699013117527E+28


由于任务数的组合k已经非常巨大……所以穷举计算已经毫无意义。
excel精英培训的微信平台,每天都会发送excel学习教程和资料。扫一扫明天就可以收到新教程
回复

使用道具 举报

 楼主| 发表于 2014-7-29 13:40 | 显示全部楼层
本帖最后由 wm06606 于 2014-7-29 13:41 编辑

传说中KM算法可以搞定,但是研究良久,不得章法!


//带权的二分图的最优匹配KM算法
//适用于有优先度任务的最佳分配方案的实现过程
//KeyWord:虚拟点,松弛量(slack),完美匹配,最大权匹配,增广路,相等子图,匈牙利算法,KM(Kuhn_Munkras)算法,ACM

//算法引入:
//给定一个完全二分图G=(X∪Y,X×Y),其中边(x,y)有权w(x,y);
//要找一个从X到Y具有最大权和的匹配M,即为二分图的最优匹配问题;
//KM(Kuhn_Munkras)算法求的是完备匹配下的最大权匹配;

//算法思想:
//KM算法是通过给每个顶点一个标号(叫做顶标)来把求最大权匹配的问题转化为求完备匹配的问题的;
//设顶点Xi的顶标为A,顶点Yi的顶标为B,顶点Xi与Yj之间的边权为w[i,j];
//在算法执行过程中的任一时刻,对于任一条边(i,j),A+B[j]>=w[i,j]始终成立;
//初始A为与Xi相连的边的最大边权,B[j]=0;

//KM算法的正确性基于以下定理:
//设G(V,E)为二分图,G//(V,E//)为该二分图的子图;
//如果对于G //中的任何边<x,y>满足, A(x)+ B(y)==W[x,y];
//则称G //(V,E//)为G(V,E)的等价子图或相等子图(是G的生成子图);
//若由二分图中所有满足A+B[j]=w[i,j]的边(i,j)构成的子图(称做相等子图)有完备匹配;
//那么这个完备匹配就是二分图的最大权匹配;

//因为对于二分图的任意一个匹配,如果它包含于相等子图;
//那么它的边权和等于所有顶点的顶标和;
//如果它有的边不包含于相等子图,那么它的边权和小于所有顶点的顶标和(即不是最优匹配);
//所以相等子图的完备匹配一定是二分图的最大权匹配;

//相等子图包含原图的所有的点,相等子图一定可以找到完备匹配;
//相等子图的完备匹配只需加一些虚拟点可以扩充为完美匹配(记为M);
//完美匹配是包含了所有点的匹配,那么所有点的顶点的标号值都包括进来了;
//虽然有些点是0,在这个状态下,把相等子图的标号一一对应的标到原图上去;
//原图的任意一个匹配最多只能包含原图的所有顶点;
//即任何匹配的权和不可能超过所有标号的和,所以M的和必然是最优的;

//补充内容
//初始时为了使A+B[j]>=w[i,j]恒成立,令A为所有与顶点Xi关联的边的最大权,B[j]=0。
//如果当前的相等子图没有完备匹配,就按下面的方法修改顶标以使扩大相等子图,直到相等子图具有完备匹配为止。
//我们求当前相等子图的完备匹配失败了,是因为对于某个X顶点,我们找不到一条从它出发的交错路。
//这时我们获得了一棵交错树,它的叶子结点全部是X顶点。
//现在我们把交错树中X顶点的顶标全都减小某个值d,Y顶点的顶标全都增加同一个值d,那么我们会发现:
//两端都在交错树中的边(i,j),A+B[j]的值没有变化。也就是说,它原来属于相等子图,现在仍属于相等子图。
//两端都不在交错树中的边(i,j),A和B[j]都没有变化。也就是说,它原来属于(或不属于)相等子图,现在仍属于(或不属于)相等子图。
//X端不在交错树中,Y端在交错树中的边(i,j),它的A+B[j]的值有所增大。它原来不属于相等子图,现在仍不属于相等子图。
//X端在交错树中,Y端不在交错树中的边(i,j),它的A+B[j]的值有所减小。
//也就说,它原来不属于相等子图,现在可能进入了相等子图,因而使相等子图得到了扩大。
////现在的问题就是求d值了。为了使A+B[j]>=w[i,j]始终成立,且至少有一条边进入相等子图,
//d应该等于min{A+B[j]-w[i,j]|Xi在交错树中,Yi不在交错树中。

//算法改进:
//给每个Y顶点一个"松弛量"函数slack;
//每次开始找增广路时初始为无穷大;
//在寻找增广路的过程中,检查(i,j)时,如果它不在相等子图中;
//则让slack[j]=min(原值,A+B[j]-W[i,j]);
//这样在修改顶标时,取所有的不在交错树中的Y顶点的slack值中的最小值作为d值即可;

//补充内容
//但是朴素的实现方法,时间复杂度为O(n4)——需要找O(n)次增广路,每次增广最多需要修改O(n)次顶 标,
//每次修改顶标时由于要枚举边来求d值,复杂度为O(n2)。实际上KM算法的复杂度是可以做到O(n3)的。
//我们给每个Y顶点一个“松弛量”函数 slack,每次开始找增广路时初始化为无穷大。
//在寻找增广路的过程中,检查边(i,j)时,如果它不在相等子图中,则让slack[j]变成原值与A +B[j]-w[i,j]的较小值。
//这样,在修改顶标时,取所有不在交错树中的Y顶点的slack值中的最小值作为d值即可。
//但还要注意一点:修改顶标后,要把所有的slack值都减去d。

//算法过程:
//①初始化可行顶标的值;
//②用匈牙利算法寻找完备匹配;
//③若未找到完备匹配则修改可行顶标的值;
//④重复②③直到找到相等子图的完备匹配;
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|Excel精英培训 ( 豫ICP备11015029号 )

GMT+8, 2024-5-7 19:36 , Processed in 0.285910 second(s), 9 queries , Gzip On, Yac On.

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表