【運籌學·轉載】指派問題的匈牙利算法

在這裏插入圖片描述

題目描述
有 n 件工作要分配給 n 個人做。第 i 個人做第 j 件工作產生的效益爲 c[i][j]​ 。試設計一個將 n 件工作分配給 n 個人做的分配方案,使產生的總效益最大。
輸入格式:
文件的第 1 行有 1 個正整數 n,表示有 n 件工作要分配給 n個人做。
接下來的n 行中,每行有 n 個整數 c[i][j]​​,表示第 i個人做第 j 件工作產生的效益爲 c[i][j]​。
輸出格式:
兩行分別輸出最小總效益和最大總效益。

求最小總效益就是經典的指派問題,最大總收益只要把c乘-1再求最小就可以。
這裏舉個例子
n = 5,c爲下表

12 7 9 7 9
8 9 6 6 6
7 17 12 14 9
15 14 6 6 10
4 10 7 10 9

第一步:每行減去該行最小的數,保證每行都有0。

5 0 2 0 2
2 3 0 0 0
0 10 5 7 2
9 8 0 0 4
0 6 3 6 5

第二步:每列減去該列最小的數,保證每行每列都有0。

5 0 2 0 2
2 3 0 0 0
0 10 5 7 2
9 8 0 0 4
0 6 3 6 5

第三步:
從單個0元素的行開始,給0加圈,記作O,然後劃去所在行的其它0元素,記爲X。
第四步:
從單個0元素的列開始,給0加圈,記作O,然後劃去所在列的其它0元素,記爲X。
重複三四,直到無法標記;
第五步:
若還存在沒有畫圈的0元素,則從剩餘的0元素最少的行(列)開始,選0元素畫圈,然後劃掉同行同列的其它0元素,反覆進行,直到所有0元素均被圈出或劃掉爲止;
檢驗:
若O的數目cnt=n,則該指派問題的最優解已經得到。
否則,進行調整。

5 O 2 X 2
2 3 X X O
O 10 5 7 2
9 8 O X 4
X 6 3 6 5

例子cnt = 4,少一個O
調整:找最少覆蓋所有0的直線

  1. 對沒有O的行打√
  2. 對已打√行中含X所在列打√
  3. 對已打√列中含O所在行打√
  4. 重複2~3, 直至沒有要打√的行和列爲止
  5. 對沒有打√的行劃橫線, 對打√的列劃豎線,得到最少覆蓋所有0的直線。
  6. 取未劃線的最小數,未劃線的減去這個數,線交點處加上這個數。
    返回第一步。

打√後

5 O 2 X 2
2 3 X X O
O 10 5 7 2 √3
9 8 O X 4
X 6 3 6 5 √1
√2

調整6後

7 0 2 0 2
4 3 0 0 0
0 8 3 5 0
11 8 0 0 4
0 4 1 4 3

正確性初步說明:同一行或同一列減去同一個數不影響最優分配方案

程序的一點說明:實際計算中, 第五步其實不需要dfs所有情況,模擬即可。相應調整5後可以這樣: 設直線數爲l,若l小於n,則轉調整6;若l=n,則轉第五步重新試探。程序直接枚舉到最好的情況了,所以省了這個判斷。

————————————————

版權聲明:本文爲CSDN博主「QASWINE」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/qq_33831360/article/details/94043097
————————————————

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章