指派問題(Assignment problem)
在滿足特定指派要求條件下谅摄,使指派方案總體效果最佳服猪。(KM算法的另一種理解角度)
如:有若干項工作需要分配給若干人(或部門)來完成燕刻;有若干項合同需要選擇若干個投標者來承包:有若干班級需要安排在若干教室里上課等。
(結合參考一的代碼和案例觀看3氩洹W钔病!)
總架構
void HungarianAlgorithm::RunAssignment() {
(void)step_one();
(void)step_two();
int step = 3;
int path_zero[2];
while (true)
switch (step) {
case 3:
step = step_three();
break;
case 4:
step = step_four(path_zero);
break;
case 5:
step = step_five(path_zero);
break;
case 6:
step = step_six();
break;
case 7:
return;
default:
assert(false);
}
}
step 1
對于矩陣的每一行湿颅,找出最小的元素载绿,并將其從矩陣的每一行中減去;
step 2
在新矩陣中油航,
? 1.循環(huán)查找零點Z崭庸,且滿足行或列未被標定的話,Z點標星(M矩陣對應置1)谊囚,RowCover和ColCover置1怕享;
? 2.RowCover和ColCover數組分別置0;
step 3
計算標星點的列數镰踏,如果等于K(行數和列數的最小值)函筋,done;否則,step 4;
step 4
尋找cover行列之外的零點奠伪,設為斜點跌帐。(沒有的話取未覆蓋區(qū)域最小值,step 6)
? 1.如果該斜點的行中無星點绊率,step 5;
? 2.有星點谨敛,cover行,并uncover星點列即舌。以此類推佣盒,直到沒有uncover的零點。保存最小的uncover值顽聂,step 6;
step 5
構造一系列交替斜點和星點肥惭。
Z0表示step 4中最后發(fā)現的斜點盯仪,Z1表示Z0同列的星點,Z2表示Z1同行的斜點蜜葱,以此類推全景,直到終止于一個斜點;
清除路徑上的各個星點牵囤,斜點變星點爸黄,并擦除所有的線,返回step 3;
存在終止于星點的情況揭鳞,此時炕贵,該增廣路是不反置的
step 6
未覆蓋區(qū)域最小值min:覆蓋行各元素+min;未覆蓋列-min;
返回step 4,不改變斜點、星點和覆蓋線野崇;
參數列表
C
: cost matrix,m x n,成本矩陣;
k=min(m,n)
行列最小數称开;
Z
:矩陣零點;
M
: mask matrix,掩膜矩陣乓梨,與成本矩陣C同緯度鳖轰,用來標注C中的星點(1)和斜點(2);
RowCover
扶镀、ColCover
:標記成本矩陣C的行或列的記錄蕴侣;
path_row_0
、path_col_0
:step 4中最后一個斜點的行和列臭觉;
path_count
:路徑的長度昆雀;
path
:記錄增廣路徑上各點的行與列;