运筹学__指派问题1
二 匈牙利算法
思路 算法原理 算法步骤
(一) 思路
匈牙利法基于这样一个明显的事实: 如果在m阶效率矩阵中,所有元素cij≥0, 而其中有m个位于不同行不同列的一组0元 素, 则在解矩阵中,只要令对应于这些0元素 位置的xij=1,其余的xij=0,就得到最优 解。 此时的最优解为0
•如效率矩阵为 •恰有4个不同行 不同列的0系数
利用这个性质,可使原系数矩阵变换为含有很多
0元素的新系数矩阵,而最优解保持不变,
在系数矩阵(bij)中,把位于不同行不同列的0元素, 简称为独立的0元素。
问题是:
能否找到位于不同行、不同列的m个0元素?
若能在系数矩阵(bij)中找出m个独立的0元素; 则令 解矩阵(xij)中对应这m个独立的0元素的xij 取值为1, 其他元素取值为0。
0 13 7 0
66 9 5 3 2
010 0
然后划去所在的列的其他0 元素,记作Ø,得
Ø 13 7 0 6 6 9 5 3 2 Ø1 0 0
➢给只有一个0元素的列的0 元素加圈,记,得
Ø 13 7 0 6 6 9 5 3 2 Ø 1 0
然后划去所在的行的其他0元 素,记作Ø,得
Ø 13 7 0 6 6 9 5 3 2 Ø 1 Ø
(三) 匈牙利算法的步骤
例7:
任务 人员
甲 乙 丙 丁
E
J
G
R
2 15 13 4
10 4 14 15
9 14 16 13
7
8 11 9
第一步:变换系数矩阵,使指派问题的 系数 矩阵经变换,在各行各列中都出现0元素: ➢从系数矩阵的每行元素减去该行的最小元素。 ➢再从所得系数矩阵的每列元素减去该列的最小元素。 若某行已经有0元素,就不必再减了。
将其代入目标函数中得到zb=0,它一定是最小值。 这就是以(bij)为系数矩阵的指派问题的最优解。
从而也就得到了原问题的最优解。
库恩(W.W.Kuhn)于1955年给出了指派 问题的 解法,
他引用匈牙利数学家狄·康尼格(d.konig)关于矩 阵中独立零元素的定理(即定理2):
系数矩阵中独立的“0”元素的最多个数等于覆盖 所有“0”元素的最少直线数
(i 1, ,n; j 1, ,m)
则指派问题的数学模型一般形式为:
mm
xij
为第
i
个人指派
min (或 max)z
cijxij
去做第 j 项任务;
i1 j1
m
xij 1 (i 1, ,n)
cij 为第 i 个人为完 成第 j 项任务时
j1
s.t.
n
xij 1
(j 1, ,m)
覆盖所有“0”元素的最少直线数 = 独立的“0”元素 的最多个数
推论1:覆盖所有“0”元素的直线数≥ 不同行不同列的“0”元素的最多个数(m)
推论2:覆盖所有“0”元素的最少直线数≥ 不同行不同列的“0”元素的个数
定理2说明: 1. 只要表中含有不同行或不同列的“0”元素,
都可以通过直线覆盖的方式来找到它们 2. 当覆盖直线的最少条数达到m条时,
➢给最后一个0元素加圈, 记,得
Ø 13 7 6 6 9 5 3 2 Ø 1 Ø
可得独立的0元素的个数就是矩阵的阶 数,即n=m=4, 故得到最优解:
0 0
1 0
0 0
0 0 0 1
指派问题的解矩阵应具有如下特点:
(1)解矩阵(xij)中各行各列的元素之和都是1; (2)可行解(最优解)中恰含有4个非零元,即4个1;
(3)可行解(最优解)矩阵中的1恰取于不同行不同列。
人 工作
甲
乙
丙
丁 人数
译成英文 2 10 9 7 1
译成日文 15 4 14 8 1
每件工作只有一个人去做。
▪ 已知第i个人去做第j 件工作的的效率( 时间或 费用)
为cij (i=1.2…m;j=1.2…m) ,并假设cij ≥0。 问应如何指派才能使总效率最高或总时间﹑ 总费用最低 ?
2. 指派问题数学模型—一般形式
设[cij]表示指派问题的效率矩阵,令
1, 分配第i个人去完成第j项任务 xij 0, 不分配第i个人去完成第j项任务
译成德文 13 14 16 11 1
译成俄文 4 15 13 9 1
任务 1
1ห้องสมุดไป่ตู้
1
1
可以看到指派问题既是0-1 规划问题,也是运输问题, 所以也可用整数规划,0-1 规划, 或运输问题的解法去求解。
(二)指派问题的数学模型
1. 指派问题的一般提法: ▪ 设m个人被指派去做m件工作,
规定每个人只做一件工作,
求解题时通常需引入0-1变量:
1, 分配第i个人去完成第j项任务 xij 0, 不分配第i个人去完成第j项任务
(i 1, ,4; j 1, ,4)
则该指派问题的数学模型为:
min z 2x11 15x12 13x13 4x14 L 11x43 9x44
4
xij
1
(i 1,L
, 4)
∑xij=1 (i=1,2,3,4) 表示第i人只能完成一项任务
2 15 13 4 2
10 4 14 15 4
(cij)= 9 14 16 13
9
7 8 11 9 7
0 13 7 0 606 9 053 2 010 0
0 13 11 2 6 0 10 11 057 4 014 2
42
▪ 第二步:圈出不同行且不同列的0元 素,进行试指派,以寻找最优解。
经第一步变换后,系数矩阵中每行每列都已有了0元素 但需找出m个独立的0元素。 若能找出,就以这些独立0元素对应解矩阵(xij)中 的元素为1,其余为0,这就得到最优解。 当m较小时,可用观察法、试探法去找出m个独立0元素。 若m较大时,就必须按一定的步骤去找, 常用的步骤为:
j1
s.t.
4
xij
1
( j 1,L
, 4)
i1
xij=1 (j=1,2,3,4) 表示第j 项任务只能由一人去完成。
x
ij 0或1
(i,j 1,L
, 4)
满足约束条件的解称为可行解, 可写成矩阵形式,叫作解矩阵。
如本例的一个可行解矩阵(但不一定是最优解)
0 1 0 0
xij
0 1
即m个值取为1,其余取为0, 是自然高度退化的。
指派问题是0-1 规划的特例, 也是运输问题的特例,所以可用整数规 划,0-1 规划或运输问题的解法去求解, 但这就如同用单纯形法去求解运输问题 一样,
是不合算的。 根据指派问题的特点可以有更简便的解 法, 就是匈牙利算法, 其重要依据是: 系数矩阵中独立 0 元素的最多个数等 于能覆盖所有 0 元素的最少直线数。
则[bij]的最优解的结构等价于[cij]的最优解的结构.
证明:将从[bij]中得到的解 代入分配问题模型的目标函数式,有
mm
mm
z
bijxij
(cij ui v j )xij
i1 j1
i1 j1
mm
m
m
m
m
cijxij
ui
xij
vj
xij
i1 j1
i1
j1
j1
i 1
▪ 其元素cij>0(i,j=1,2,…n),
▪ 表示指派第i人去完成第j 项任务时的效率(或时间、成
本等)
c11 c12 … c1n
效率
C=(cij)n×n= c21 c22 … c2n
矩阵 或
………………
系数
c c …c
矩阵
C=(cij )4×4=
2 15 13 4 10 4 14 15 9 14 16 13 7 8 11 9
4. 指派模型的标准形的特点: 含有m×m个决策变量,均为0-1变量 m+m=2m个约束方程
给定一个指派问题时,必须给出效率矩阵(系数矩阵) C=(cij)mxm,且cij0,因此必有最优解 。
mm
MinZ
cijxij 0
i1 j1
指派问题有2m个约束条件,
但可行解(即解矩阵)中有且只有m个是非零值,
➢从只有一个0元素的行(或列)开始, 给这个0元素加圈,记,
这表示对这行所 代表的人,只有一种任务可指派。 然后划去所在的列(或行)的其他0元素,记作Ø。 这表示这列所代表的任务已指派完,不必再考虑别人
0 13 7 0 6 6 9 5 3 2
01 0 0
➢给只有一个0元素的列(或行)中的0元素加圈, 记,
0 14 9 3
9
20
0
23
23 0 3 8
0
12 14
0
令x11=1,x23=1,x32=1,x44=1,即可得最优解,
其解矩阵为
min Z=Z*=0
1 0 0 0 0 0 1 0 0 1 0 0 0 0 0 1
问题是如何找到位于不同行、不同列的m个0元素?
匈牙利算法基本思想: 对同一工作i来说, 所有人的效率都提高或降低同一常数, 不会影响最优分配; 同样,对同一人j来说, 做所有工作的效率都提高或降低同一常数, 也不会影响最优分配。
然后划去所在的行(或列)的其他0元素,记作Ø。 这表示这行所代表的人已指派完, 不必再考虑他做别的任务了。
➢反复进行上述两步,直到所有的0元素都被圈出和 划掉为止。
➢从只有一个0元素的行(或列)开 始,给这个0元素加圈,记。
0 13 7 0
66 9
053 2 010 0
➢再给第三行的这个唯一的0元素 加圈,记,得
任务 E
J
G
R
运筹学课件ch5指派问题[全文]
运筹学课件ch5指派问题[全文] 指派问题assignment problem 运筹学课件一种特殊的线性规划问题,我们也经常遇到指派人员做某项工作的情况。
指派问题的许多应用都用来帮助管理人员解决如何为一项将要开展进行的工作指派人员的问题。
其他的一些应用如为一项任务指派机器、设备或者是工厂。
指派问题运筹学课件指派问题的形式表述:给定了一系列所要完成的任务(tasks)以及一系列完成任务的被指派者(assignees),所需要解决的问题就是要确定出哪一个人被指派进行哪一项任务。
指派问题模型运筹学课件指派问题的假设:被指派者的数量和任务的数量是相同的每一个被指派者只完成一项任务每一项任务只能由一个被指派者来完成每个被指派者和每项任务的组合有一个相关成本目标是要确定怎样进行指派才能使得总成本最小指派问题模型运筹学课件指派问题assignment problem 【例51></a>.14】人事部门欲安排四人到四个不同的岗位工作,每个岗位一个人(经考核四人在不同岗位的成绩(百分制)如表5-34所示,如何安排他们的工作使总成绩最好。
88809086丁90798382丙95788795乙90739285甲DCBA工作人员表5-34【解】设1 数学模型运筹学课件数学模型为:甲乙丙丁ABCD图5. 3指派问题assignment problem运筹学课件假设m个人恰好做m项工作,第i个人做第j项工作的效率为cij?0,效率矩阵为[cij](如表5-34),如何分配工作使效率最佳(min或max)的数学模型为指派问题assignment problem运筹学课件2 解指派问题的匈牙利算法匈牙利法的条件是:问题求最小值、人数与工作数相等及效率非负【定理5.1】如果从分配问题效率矩阵[cij]的每一行元素中分别减去(或加上)一个常数ui(被称为该行的位势),从每一列分别减去(或加上)一个常数vj(称为该列的位势),得到一个新的效率矩阵[bij],其中bij=cij,ui,vj,则[bij]的最优解等价于[cij]的最优解,这里cij、bij均非负(指派问题assignment problem【证】运筹学课件【定理5.2】若矩阵A的元素可分成“0”与非“0”两部分,则覆盖“0”元素的最少直线数等于位于不同行不同列的“0”元素(称为独立元素)的最大个数( 如果最少直线数等于m,则存在m个独立的“0”元素,令这些零元素对应的xij等于1,其余变量等于0,这时目标函数值等于零,得到最优解(两个目标函数相差一个常数 u+v,约束条件不变,因此最优解不变。
运筹学课件1.8工作指派问题
c1n c2 n cnn
关于模型的讨论
指派问题是运输问题的特殊情况 当n=m时,平衡指派问题 当 n m 时,不平衡指派问题,此时, 可设置虚工作或虚工作人员,将其化为 平衡指派问题。 对指派矩阵C,任意行(列)减去它的最 小元素后,所构成的指派问题最优解与 原指派问题相同。
45 0 40 65 45 55 55 0 0 5 0 45 0 55 60 55 45 45 0 45
0 20 40 60 95
45 0 40 65 45 55 55 0 0 5 0 45 0 55 60 55 45 45 0 45
回到第一步:圈零得新最优解
4 0 2 0 2 2 0 0 0 1 2 1 0 0 0 1 0 1 ( xij ) 0 0 0 0 0 1 1 0 0 0 0 0 1 0
最小的总工作时间:z=7+5+5+3=20。该问 题有多个最优解,请求出其它的最优解。
第八节 工作指派问题
工作指派问题及其数学模型 求解工作指派问题的匈牙利法 工作指派问题的应用举例
工作指派问题的数学模型
•例1-12
•指派问题数学模型 •指派矩阵 •对数学模型的讨论
匈牙利法
•匈牙利法的基本原理
•匈牙利法的计算步骤
•减数得零—求最优匹配
•圈零划线—查是否最大匹配
•找数调整—求新的最优匹配
ห้องสมุดไป่ตู้
指派问题一般模型
min z cij xij
j 1 i 1 n n
n xij 1, j 1,2, , n i n1 s.t. xij 1, i 1,2, , n j 1 xij 0,1
运筹学指派问题作业
作业:作业:问题1:书本P100第6题效率矩阵效率矩阵码头1 码头2 码头3 码头4货船A货船B货船C货船D目标函数:使总运输成本最小目标函数:使总运输成本最小约束条件约束条件: :码头1 码头2 码头3 码头4货船A 1 0 0 0 1 = 1 货船B 0 0 0 1 1 = 1 货船C 0 0 1 0 1 = 1 货船D 0 1 0 0 1= 11 1 1 1 ====1 1 1 1最少成本最少成本2100问题问题 2: 2: 2: 书本书本书本P101P101P101第第7题效率矩阵效率矩阵A B C D E甲乙丙丁目标函数:使总花费时间最小目标函数:使总花费时间最小约束条件约束条件: :方案矩阵方案矩阵AB C D E甲 2.22E-16 1 0 0 0 1 <= 1 <= 2 乙 0 0 1 1 2.22E-16 1 <=2 <= 2 丙 0 1.11E-16 0 0 1 1 <=1 <=2 丁 1 0 0 4.44E-16 0 1 <=1 <=2 1 11 1 1= == ==11 1 1 1时间最少时间最少131问题3:五人翻译五种外文的速度(印刷符号:五人翻译五种外文的速度(印刷符号//小时)如下表所示:小时)如下表所示: 语种语种语种 人 英 俄俄 日日 德德 法法 甲甲乙 丙 丁 戊900 400 600 800 500 800 500 900 1000 600 900 700 300 500 800400 800 600 900 5001000 500 300 600 800若规定每人专门负责一个语种的翻译工作,那么,试解答下列问题:若规定每人专门负责一个语种的翻译工作,那么,试解答下列问题: (1)应如何指派,使总的翻译效率最高?应如何指派,使总的翻译效率最高?效率矩阵效率矩阵英俄 日 德 法 甲 乙 丙 丁目标函数:使翻译效率最高目标函数:使翻译效率最高约束条件约束条件: :方案矩阵方案矩阵英俄 日 德 法甲0 011 =1乙0 1 0 0 0 1 = 1 丙0 0 0 1 0 1 = 1丁 1 0 0 0 0 1 = 1 戊0 0 1 0 0 1 = 11 1 1 1 1= = = = =1 1 1 1 1效率最高 2200效率最高若甲不懂德文,乙不懂日文,其他数字不变,则应如何指派?(2)若甲不懂德文,乙不懂日文,其他数字不变,则应如何指派?方案矩阵方案矩阵英俄日德法甲0 1 0 0 0 1 = 1 乙0 0 0 0 1 1 = 1 丙0 0 0 1 0 1 = 1 丁 1 0 0 0 0 1 = 1 戊0 0 1 0 0 1 = 11 1 1 1 1= = = = =1 1 1 1 1。
三类指派问题
三类指派问题1. 简介三类指派问题是运筹学中的一类经典问题,它的目标是找到一种最优分配方案,将若干个任务分配给若干个执行者,使得总体成本或效益达到最小或最大。
这类问题通常可以用线性规划模型来描述和求解。
三类指派问题包括: - 任务分配问题:将若干个任务分配给若干个执行者,使得总体成本最小或效益最大。
- 作业调度问题:将若干个作业安排在若干台机器上进行处理,使得总体完成时间最短或机器利用率最高。
- 设备调度问题:将若干个任务安排在若干台设备上进行处理,使得总体完成时间最短或设备利用率最高。
2. 任务分配问题2.1 模型描述假设有n个任务和n个执行者,每个任务只能由一个执行者完成,并且每个执行者只能处理一个任务。
每个任务与每个执行者之间都有一个成本或效益值。
我们的目标是找到一种分配方案,使得总体成本最小或效益最大。
可以使用二维数组C表示各任务与各执行者之间的成本或效益值,其中C[i][j]表示第i个任务分配给第j个执行者的成本或效益值。
定义一个二进制变量X[i][j],如果第i个任务分配给第j个执行者,则X[i][j]=1,否则X[i][j]=0。
任务分配问题可以用下面的线性规划模型来描述:minimize ∑(i=1 to n)∑(j=1 to n) C[i][j] * X[i][j]subject to∑(i=1 to n) X[i][j] = 1, for j = 1,2,...,n∑(j=1 to n) X[i][j] = 1, for i = 1,2,...,nX[i][j] ∈ {0, 1}, for i,j = 1,2,...,n2.2 求解方法常用的求解任务分配问题的方法有匈牙利算法和线性规划方法。
匈牙利算法是一种经典的图论算法,它通过构建增广路径来找到最优分配方案。
该算法的时间复杂度为O(n^3),适用于小规模问题。
线性规划方法则通过将任务分配问题转化为线性规划模型,并利用线性规划求解器进行求解。
运筹学运输与指派问题
5.2 运输单纯形法 Transportation Simplex Method
【解】
表5-7~5-9
Ai A1
A2
Bj
B1 9 × 7 × × 2 10 × 10 60
B2 3 10 6 20 10 10 60
B3 8
B4 4 × 5 30 9 2 × 30 1
产量
70 50 20 140
A3 销量
运量应大于或等于零(非负要求),即
ห้องสมุดไป่ตู้
xij 0, i 1,2,3;j 1,2,3,4
其系数矩阵为 : x11 1 0 0 1 0 0 0 x12 x13 x14 x 21 x 22 x 23 x 24 x 31 x 32 x 33 x 34 1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1
40
到一组基可行解可用矩阵
60 10 X 20 30 10 10
表示,矩阵X 中空白处对应的变量是非基变量,运量等于零, 这组解就是初始调运方案.总运费 Z=3×60+8×10+5×20+1×30+2×10+9×10=500
5.2 运输单纯形法 Transportation Simplex Method
运输问题具有如下特点:
1.运输问题存在可行解,也一定存在最优解 2.当供应量和需求量都是整数时,则一定存在整数最优解 3.有m+n个约束,mn个变量 4.约束条件系数矩阵的元素等于0或1 5.约束条件系数矩阵的每一列有两个非零元素,这对应于每一个变量在前 m个约束方程中出现一次,在后n个约束方程中也出现一次 6.所有约束方程都是等式方程 7.各产地产量之和等于各销地销量之和 8.有m+n-1个基变量,因为产销平衡,所以模型最多只有m+n-1个独立约 束方程,即系数矩阵的秩最多为m+n-1.
运筹学 指派问题共50页
运筹学 指派问题
6
、
露
凝
无
游
氛
,
天
高
风
景
澈
。
7、翩翩新 来燕,双双入我庐 ,先巢故尚在,相 将还旧居。
8
、
吁
嗟
身
后
名
,
于
我
若
浮
烟
。
9、 陶渊 明( 约 365年 —427年 ),字 元亮, (又 一说名 潜,字 渊明 )号五 柳先生 ,私 谥“靖 节”, 东晋 末期南 朝宋初 期诗 人、文 学家、 辞赋 家、散
1
0
、
Байду номын сангаас
倚
南
窗
以
寄
傲
,
审
容
膝
之
易
安
。
1、最灵繁的人也看不见自己的背脊。——非洲 2、最困难的事情就是认识自己。——希腊 3、有勇气承担命运这才是英雄好汉。——黑塞 4、与肝胆人共事,无字句处读书。——周恩来 5、阅读使人充实,会谈使人敏捷,写作使人精确。——培根
最新运筹学--第4章-运输问题和指派问题精品文档
i 1
j 1
i1 j1
n
xij ai
(i 1, 2,
,m)
(产 量 约 束 )
j1
m
s.t. xij b j ( j 1, 2, , n ) (销 量 约 束 )
i1
x
ij
0
(i 1, 2,
, m ; j 1, 2,
, n)
RUC, School of Information ,Ye Xiang
例4.1的电子表格模型
RUC, School of Information ,Ye Xiang
4.2 运输问题数学模型和电子表格模型
第4章 运输问题 和指派问题
需要注意的是:运输问题有这样一个性质 (整数解性质),只要它的供应量和需求 量都是整数,任何有可行解的运输问题必 然有所有决策变量都是整数的最优解。因 此,没有必要加上所有变量都是整数的约 束条件。
i1
x
ij
0
(i 1, 2 ,
, m ; j 1, 2 ,
, n)
RUC, School of Information ,Ye Xiang
4.2 运输问题数学模型和电子表格模型
第4章 运输问题 和指派问题
对于例4.1,其数学模型如下: 首先,三个产地A1、A2、A3的总产量为7+4+9=20;四 个销地B1、B2、B3、B4的总销量为3+6+5+6=20。由 于总产量等于总销量,故该问题是一个产销平衡的运输问 题。
例4.3 某公司从两个产地A1、A2将物品运往 三个销地 B1、B2、B3,各产地的产量、各 销地的销量和各产地运往各销地每件物品的 运费如表4-6所示。问应如何调运,可使得 总运输费最小?
表4-6 例4.3的运输费用表
运筹学指派问题的匈牙利法
运筹学课程设计指派问题的匈牙利法专业:姓名:学号:1.算法思想:匈牙利算法的基本思想是修改效益矩阵的行或列,使得每一行或列中至少有一个为零的元素,经过修正后,直至在不同行、不同列中至少有一个零元素,从而得到与这些零元素相对应的一个完全分配方案。
当它用于效益矩阵时,这个完全分配方案就是一个最优分配,它使总的效益为最小。
这种方法总是在有限步內收敛于一个最优解。
该方法的理论基础是:在效益矩阵的任何行或列中,加上或减去一个常数后不会改变最优分配。
2.算法流程或步骤:1.将原始效益矩阵C的每行、每列各元素都依次减去该行、该列的最小元素,使每行、每列都至少出现一个0元素,以构成等价的效益矩阵C’。
2.圈0元素。
在C’中未被直线通过的含0元素最少的行(或列)中圈出一个0元素,通过这个0元素作一条竖(或横)线。
重复此步,若这样能圈出不同行不同列的n个0元素,转第四步,否则转第三步。
3.调整效益矩阵。
在C’中未被直线穿过的数集D中,找出最小的数d,D中所有数都减去d,C’中两条直线相交处的数都加的d。
去掉直线,组成新的等价效益矩阵仍叫C’,返回第二步。
X=0,这就是一种最优分配。
最低总4.令被圈0元素对应位置的X ij=1,其余ij耗费是C中使X=1的各位置上各元素的和。
ij算法流程图:3.算法源程序:#include<iostream.h>typedef struct matrix{float cost[101][101];int zeroelem[101][101];float costforout[101][101];int matrixsize;int personnumber;int jobnumber;}matrix;matrix sb;int result[501][2];void twozero(matrix &sb);void judge(matrix &sb,int result[501][2]);void refresh(matrix &sb);void circlezero(matrix &sb);matrix input();void output(int result[501][2],matrix sb);void zeroout(matrix &sb);matrix input(){matrix sb;int m;int pnumber,jnumber;int i,j;float k;char w;cout<<"指派问题的匈牙利解法:"<<endl;cout<<"求最大值,请输入1;求最小值,请输入0:"<<endl;cin>>m;while(m!=1&&m!=0){cout<<"请输入1或0:"<<endl;cin>>m;}cout<<"请输入人数(人数介于1和100之间):"<<endl;cin>>pnumber;while(pnumber<1||pnumber>100){cout<<"请输入合法数据:"<<endl;cin>>pnumber;}cout<<"请输入工作数(介于1和100之间):"<<endl;cin>>jnumber;while(jnumber<1||jnumber>100){cout<<"请输入合法数据:"<<endl;cin>>jnumber;}cout<<"请输入"<<pnumber<<"行"<<jnumber<<"列的矩阵,同一行内以空格间隔,不同行间以回车分隔,以$结束输入:\n";for(i=1;i<=pnumber;i++)for(j=1;j<=jnumber;j++){cin>>sb.cost[i][j];sb.costforout[i][j]=sb.cost[i][j];}cin>>w;if(jnumber>pnumber)for(i=pnumber+1;i<=jnumber;i++)for(j=1;j<=jnumber;j++){sb.cost[i][j]=0;sb.costforout[i][j]=0;}else{if(pnumber>jnumber)for(i=1;i<=pnumber;i++)for(j=jnumber+1;j<=pnumber;j++){sb.cost[i][j]=0;sb.costforout[i][j]=0;}}sb.matrixsize=pnumber;if(pnumber<jnumber)sb.matrixsize=jnumber;sb.personnumber=pnumber;sb.jobnumber=jnumber;if(m==1){k=0;for(i=1;i<=sb.matrixsize;i++)for(j=1;j<=sb.matrixsize;j++)if(sb.cost[i][j]>k)k=sb.cost[i][j];for(i=1;i<=sb.matrixsize;i++)for(j=1;j<=sb.matrixsize;j++)sb.cost[i][j]=k-sb.cost[i][j];}return sb;}void circlezero(matrix &sb){int i,j;float k;int p;for(i=0;i<=sb.matrixsize;i++)sb.cost[i][0]=0;for(j=1;j<=sb.matrixsize;j++)sb.cost[0][j]=0;for(i=1;i<=sb.matrixsize;i++)for(j=1;j<=sb.matrixsize;j++)if(sb.cost[i][j]==0){sb.cost[i][0]++;sb.cost[0][j]++;sb.cost[0][0]++;}for(i=0;i<=sb.matrixsize;i++)for(j=0;j<=sb.matrixsize;j++)sb.zeroelem[i][j]=0;k=sb.cost[0][0]+1;while(sb.cost[0][0]<k){k=sb.cost[0][0];for(i=1;i<=sb.matrixsize;i++){if(sb.cost[i][0]==1){for(j=1;j<=sb.matrixsize;j++)if(sb.cost[i][j]==0&&sb.zeroelem[i][j]==0)break;sb.zeroelem[i][j]=1;sb.cost[i][0]--;sb.cost[0][j]--;sb.cost[0][0]--;if(sb.cost[0][j]>0)for(p=1;p<=sb.matrixsize;p++)if(sb.cost[p][j]==0&&sb.zeroelem[p][j]==0){sb.zeroelem[p][j]=2;sb.cost[p][0]--;sb.cost[0][j]--;sb.cost[0][0]--;}}}for(j=1;j<=sb.matrixsize;j++){if(sb.cost[0][j]==1){for(i=1;i<=sb.matrixsize;i++)if(sb.cost[i][j]==0&&sb.zeroelem[i][j]==0)break;sb.zeroelem[i][j]=1;sb.cost[i][0]--;sb.cost[0][j]--;sb.cost[0][0]--;if(sb.cost[i][0]>0)for(p=1;p<=sb.matrixsize;p++)if(sb.cost[i][p]==0&&sb.zeroelem[i][p]==0){sb.zeroelem[i][p]=2;sb.cost[i][0]--;sb.cost[0][p]--;sb.cost[0][0]--;}}}}if(sb.cost[0][0]>0)twozero(sb);elsejudge(sb,result);}void twozero(matrix &sb){int i,j;int p,q;int m,n;float k;matrix st;for(i=1;i<=sb.matrixsize;i++)if(sb.cost[i][0]>0)break;if(i<=sb.matrixsize){for(j=1;j<=sb.matrixsize;j++){st=sb;if(sb.cost[i][j]==0&&sb.zeroelem[i][j]==0){sb.zeroelem[i][j]=1;sb.cost[i][0]--;sb.cost[0][j]--;sb.cost[0][0]--;for(q=1;q<=sb.matrixsize;q++)if(sb.cost[i][q]==0&&sb.zeroelem[i][q]==0){sb.zeroelem[i][q]=2;sb.cost[i][0]--;sb.cost[0][q]--;sb.cost[0][0]--;}for(p=1;p<=sb.matrixsize;p++)if(sb.cost[p][j]==0&&sb.zeroelem[p][j]==0){sb.zeroelem[p][j]=2;sb.cost[p][0]--;sb.cost[0][j]--;sb.cost[0][0]--;}k=sb.cost[0][0]+1;while(sb.cost[0][0]<k){k=sb.cost[0][0];for(p=i+1;p<=sb.matrixsize;p++){if(sb.cost[p][0]==1){for(q=1;q<=sb.matrixsize;q++)if(sb.cost[p][q]==0&&sb.zeroelem[p][q]==0)break;sb.zeroelem[p][q]=1;sb.cost[p][0]--;sb.cost[0][q]--;sb.cost[0][0]--;for(m=1;m<=sb.matrixsize;m++)if(sb.cost[m][q]=0&&sb.zeroelem[m][q]==0){sb.zeroelem[m][q]=2;sb.cost[m][0]--;sb.cost[0][q]--;sb.cost[0][0]--;}}}for(q=1;q<=sb.matrixsize;q++){if(sb.cost[0][q]==1){for(p=1;p<=sb.matrixsize;p++)if(sb.cost[p][q]==0&&sb.zeroelem[p][q]==0)break;sb.zeroelem[p][q]=1;sb.cost[p][q]--;sb.cost[0][q]--;sb.cost[0][0]--;for(n=1;n<=sb.matrixsize;n++)if(sb.cost[p][n]==0&&sb.zeroelem[p][n]==0){sb.zeroelem[p][n]=2;sb.cost[p][0]--;sb.cost[0][n]--;sb.cost[0][0]--;}}}}if(sb.cost[0][0]>0)twozero(sb);elsejudge(sb,result);}sb=st;}}}void judge(matrix &sb,int result[501][2]){int i,j;int m;int n;int k;m=0;for(i=1;i<=sb.matrixsize;i++)for(j=1;j<=sb.matrixsize;j++)if(sb.zeroelem[i][j]==1)m++;if(m==sb.matrixsize){k=1;for(n=1;n<=result[0][0];n++){for(i=1;i<=sb.matrixsize;i++){for(j=1;j<=sb.matrixsize;j++)if(sb.zeroelem[i][j]==1)break;if(i<=sb.personnumber&&j<=sb.jobnumber)if(j!=result[k][1])break;k++;}if(i==sb.matrixsize+1)break;elsek=n*sb.matrixsize+1;}if(n>result[0][0]){k=result[0][0]*sb.matrixsize+1;for(i=1;i<=sb.matrixsize;i++)for(j=1;j<=sb.matrixsize;j++)if(sb.zeroelem[i][j]==1){result[k][0]=i;result[k++][1]=j;}result[0][0]++;}}else{refresh(sb);}}void refresh(matrix &sb){int i,j;float k;int p;k=0;for(i=1;i<=sb.matrixsize;i++){for(j=1;j<=sb.matrixsize;j++)if(sb.zeroelem[i][j]==1){sb.zeroelem[i][0]=1;break;}}while(k==0){k=1;for(i=1;i<=sb.matrixsize;i++)if(sb.zeroelem[i][0]==0){sb.zeroelem[i][0]=2;for(j=1;j<=sb.matrixsize;j++)if(sb.zeroelem[i][j]==2){sb.zeroelem[0][j]=1;}}for(j=1;j<=sb.matrixsize;j++){if(sb.zeroelem[0][j]==1){sb.zeroelem[0][j]=2;for(i=1;i<=sb.matrixsize;i++)if(sb.zeroelem[i][j]==1){sb.zeroelem[i][0]=0;k=0;}}}}p=0;k=0;for(i=1;i<=sb.matrixsize;i++){if(sb.zeroelem[i][0]==2){for(j=1;j<=sb.matrixsize;j++){if(sb.zeroelem[0][j]!=2)if(p==0){k=sb.cost[i][j];p=1;}else{if(sb.cost[i][j]<k)k=sb.cost[i][j];}}}}for(i=1;i<=sb.matrixsize;i++){if(sb.zeroelem[i][0]==2)for(j=1;j<=sb.matrixsize;j++)sb.cost[i][j]=sb.cost[i][j]-k;}for(j=1;j<=sb.matrixsize;j++){if(sb.zeroelem[0][j]==2)for(i=1;i<=sb.matrixsize;i++)sb.cost[i][j]=sb.cost[i][j]+k;}for(i=0;i<=sb.matrixsize;i++)for(j=0;j<=sb.matrixsize;j++)sb.zeroelem[i][j]=0;circlezero(sb);}void zeroout(matrix &sb){int i,j;float k;for(i=1;i<=sb.matrixsize;i++){k=sb.cost[i][1];for(j=2;j<=sb.matrixsize;j++)if(sb.cost[i][j]<k)k=sb.cost[i][j];for(j=1;j<=sb.matrixsize;j++)sb.cost[i][j]=sb.cost[i][j]-k;}for(j=1;j<=sb.matrixsize;j++){k=sb.cost[1][j];for(i=2;i<=sb.matrixsize;i++)if(sb.cost[i][j]<k)k=sb.cost[i][j];for(i=1;i<=sb.matrixsize;i++)sb.cost[i][j]=sb.cost[i][j]-k;}}void output(int result[501][2],matrix sb) {int k;int i;int j;int p;char w;float v;v=0;for(i=1;i<=sb.matrixsize;i++){v=v+sb.costforout[i][result[i][1]];}cout<<"最优解的目标函数值为"<<v;k=result[0][0];if(k>5){cout<<"解的个数超过了限制."<<endl;k=5;}for(i=1;i<=k;i++){cout<<"输入任意字符后输出第"<<i<<"种解."<<endl;cin>>w;p=(i-1)*sb.matrixsize+1;for(j=p;j<p+sb.matrixsize;j++)if(result[j][0]<=sb.personnumber&&result[j][1]<=sb.jobnumber)cout<<"第"<<result[j][0]<<"个人做第"<<result[j][1]<<"件工作."<<endl;}}void main(){result[0][0]=0;sb=input();zeroout(sb);circlezero(sb);output(result,sb);}4. 算例和结果:自己运算结果为:->⎥⎥⎥⎥⎦⎤⎢⎢⎢⎢⎣⎡3302102512010321->⎥⎥⎥⎥⎦⎤⎢⎢⎢⎢⎣⎡330110241200032034526635546967562543----⎥⎥⎥⎥⎦⎤⎢⎢⎢⎢⎣⎡可以看出:第1人做第4件工作;第2人做第1件工作;第3人做第3件工作;第4人做第2件工作。
《运筹学》胡运权清华版-5-05指派问题
任务 A
B
C
D
人员
甲
9
17 16
7
乙
12
7
14 16
丙
8
17 14 17
丁
7
9
11
9
解:设决策变量xij,i=1,2,3,4; j=1,2,3,4
xij 01
表示分派第i人做第j项工作 表示不分派第i人做第j项工作
任务 A
B
C
D
人员
甲
x11
x12
x13
x14
乙
x21
x22
x23
x24
丙
x31
③反复进行①、 ②两步,直到所有0元素都被圈出 或划掉为止。
注:若遇到在所有的行和列中,0元素都不止一个 时,可任选其中一个0元素加O;然后作一直线覆盖该 列元素(或该行元素)。
对于本例
用一直线覆 盖所在列
第一行只有 一个0元素
2 10 5 0
c'ij
5 0
0 9
3 9 2 9
0 2 0 2
x11
x21
...
xn1
1
...
x1n x2n ... xnn 1
若C=(cij)n×n的第一行各元素分别加上一个常数k, 得到一个新矩阵C’=(c’ij) n×n
c11 k
C'
c21
cn1
c12 k c22 ... cn2
... c1n k
17 7 17
16 14 14
7 16
-7 -7
17 -8
管理运筹(运输问题和指派问题)
实验四 运输问题和指派问题求解习题4.6习题1某公司要将一批货从三个产地运到四个销地,有关数据如下表所示。
现要求制定调运计划,且依次满足: (1)B 3的供应量不低于需要量; (2)其余销地的供应量不低于85%; (3)A 3给B 3的供应量不低于200; (4)A 2尽可能少给B 1;(5)销地B 2、B 3的供应量尽可能保持平衡。
(6)使总运费最小。
试建立该问题的目标规划数学模型。
123412341234min z 7379265116425A A A A B B B B C C C C x x x x x x x x x x x x =+++++++++++123412341234333111222444312223331234123min z 7379265116425480272204323200s..0222560A A A A B B B B C C C C A B C A B C A B C A B C C B A B C A B C A A A A B B B B x x x x x x x x x x x x x x x x x x x x x x x x x t x x x x x x xx x x x x x x x =+++++++++++++≥++≥++≥++≥≥=++=+++++≤+++()412344007500,,;1,2,3,4C C C C ij x x x x x i A B C J ⎧⎪⎪⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪≤⎪⎪+++≤⎪≥==⎪⎩案例4某市的菜篮子工程某市是一个人口不到15万人的小城市,根据该市的蔬菜种植情况,分别在A 、B 和C 设三个收购点,再由收购点分送到全市的8个菜市场。
按常年情况,A 、B 、C 三个收购点每天收购量分别为200、170和160(单位:100kg ),各菜市场的每天需求量及发生供应短缺时带来的损失见表 C -1。
从收购点至各菜市场的距离见表 C -2,设从收购点至各菜市场蔬菜调运费用为1元/(100kg.100m)。
