Documente Academic
Documente Profesional
Documente Cultură
ALGORITMUL UNGAR
Suport teoretic
Matematica oferă modele ce se pot aplica în cele mai diverse probleme ale naturii. Se pot studia
probleme legate de teoria grafurilor , teoria jocurilor, teoria stocurilor, probleme de repartiţie.
În general, fiecare asociere posibilă xi yj aduce un anumit efect cij (profit, cost etc) care poate fi
calculat,vom presupune că este cunoscut şi îl vom reprezenta printr-o matrice C=( cij)p,q.
Cele două mulţimi X şi Y reprezintă partiţionarea mulţimii nodurilor unui graf şi realizarea unui
graf bipartit complet.
Reprezentarea geometrică a situaţiei de mai sus este un graf de forma:
x1
y1
x2
y2
yq
xp
Definiţie: Se numeşte graf bipartit un graf G = (X, U) în care mulţimea nodurilor, X poate fi
partiţionată în două mulţimi disjuncte A şi B astfel încât orice arc are extremitatea iniţială în A şi
cea finală în B şi orice nod din mulţimea A este adiacent cu orice nod din mulţimea B.
Definiţie: Se numeşte cuplaj maxim un cuplaj cu proprietatea că orice arc care nu face parte din
cuplaj este adiacent cu un arc din cuplaj (posedă un număr maxim de arce.
În 1931 apare:
Teorema lui König (numărul de arce ale unui cuplaj maxim): Numărul maxim de arce ale unui
cuplaj într-un graf bipartit G = (AB, ) este egal cu min A C C
C A
Este interesant de văzut însă cât de mare este el efectiv şi în ce condiţii este egal chiar cu min
(A,B).
Observaţie: Putem presupune că întotdeauna AB, în caz contrar inversăm sensul tuturor
arcelor grafului, problema rămânând aceeaşi. În acest caz:
max
C A
C C = 0 C C oricare ar fi C A
sau altfel spus, pentru orice submulţime C a lui A, mulţimea nodurilor atinse de arcele care pleacă
din nodurile sale, adică (C), are cel puţin atâtea elemente cât C.
Presupunem, în continuare, că s-a asociat fiecărui arc (xi, yj) o valoare cij.
Definiţie: Se numeşte valoare a unui cuplaj suma valorilor arcelor care îl formează.
Dintre problemele întâlnite în practica economică, ce se reduc matematic la găsirea unui cuplaj
maxim de valoare optimă, amintim:
Pe baza Teoremei lui König, în anul 1955, H.W. Kuhn elaborează un algoritm, cunoscut în
literatura de specialitate sub denumirea de algoritmul ungar. Cu ajutorul acestui algoritm se poate
determina un cuplaj maxim de valoare minimă într-un graf bipartit complet pentru care |A| = |B| =n
2
Algoritmul ungar prof. Maria şi Adrian NIŢĂ
El se bazează pe observaţia că, dacă se adună (sau scade) aceeaşi număr la toate valorile
arcelor, nu se modifică ierarhia cuplajelor maxime, în ceea ce priveşte valoarea lor.
Fie matricea C = (cij)p,q, unde cij ≥ 0, reprezintă valoarea cuplajului (xi, yj).
Pentru fiecare coloană se va scădea elementul cel mai mic al ei (minimul) din toate celelalte
elemente ale ei; în matricea obţinută se va proceda la fel pentru linii: se va scădea elementul cel mai
mic (minimul) din toate celelalte elemente ale ei.
Cu zerourile obţinute la prima etapă, se caută o soluţie de valoare zero (adică o repartiţie în care toţi
(cij) corespunzători să fie zero) astfel:
se alege linia cu cele mai puţine zerouri şi se încadrează unul din zerouri;
se barează zerourile care se găsesc pe aceeaşi linie sau coloană cu zeroul încadrat.
se procedează la fel pe toate liniile.
Dacă nu s-a obţinut o soluţie de valoare zero (au fost alese toate valorile pentru cuplaj) se trece la
etapa III.
Se elimină (logic, nu vor fi luate în calcule) liniile nemarcate şi coloanele marcate la etapa III.
În tabloul parţial obţinut se alege minimul. Se scade această valoare din coloanele care nu sunt
eliminate şi se adună liniilor care sunt eliminate la etapa anterioară. Cu tabloul nou obţinut se repetă
procedeul începând tot cu etapa I, până când etapa a II va da o soluţie optimă.
3
Algoritmul ungar prof. Maria şi Adrian NIŢĂ
Exemple:
1. Şase localităţi (x) sunt aprovizionate de şase depozite (y).Costurile sunt date de tabloul de mai
jos. Ştiind că aprovizionarea fiecărei localităţi se face de către un singur depozit, să se determine
repartiţia depozitelor pe localităţi, astfel încât costul să fie minim.
y1 y2 y3 Y4 y5 y6
x1 17 43 27 14 39 52
x2 29 24 69 90 23 13
x3 18 90 62 12 16 70
x4 58 14 6 18 73 64
x5 15 41 38 36 40 60
x6 25 44 18 44 13 50
y1 y2 y3 y4 y5 y6
x1 2 29 21 2 26 39
x2 14 10 63 78 10 0
x3 3 76 56 0 3 57
x4 43 0 0 6 60 51
x5 0 27 32 24 27 47
x6 10 30 12 32 0 37
Se caută minimul pe linii şi se scade. Teoretic se vor produce modificări doar pe liniile care nu au
nici un element zero, deoarece pe celelalte linii care au zero acesta va fi minimul şi prin scădere nu
se va modifica linia respectivă. În cazul exemplului vom modifica doar linia 1.
y1 y2 y3 y4 y5 y6
x1 -0 27 19 -0 24 37
x2 14 10 63 78 10 *0
x3 3 76 56 *0 3 57
x4 43 *0 -0 6 60 51
x5 *0 27 32 24 27 47
x6 10 30 12 32 *0 37
Etapa II:
linia cu cele mai puţine zerouri, prima găsită:
linia 2, deci se încadrează c26,
linia 3, deci c34 (se va tăia c14),
apoi linia 5, deci c51 (se taie c11),
linia 6, deci c65.
S-a marcat cu (*) elementele încadrate şi cu (-) cele tăiate (barate).
linia 4 are 2 zerouri, se încadrează primul (c42 ) se taie al doilea (c43 )
Toate zerourile sunt încadrate sau tăiate. Nu s-a obţinut soluţie deoarece sunt doar 5 zerouri
încadrate.
Etapa III.
Nici un zero încadrat pe linia 1; coloanele 1 şi 4, deci se marchează (conform b) de la această etapă.
Se marchează liniile 3 şi 5 (conform c), cu câte un zero încadrat.
S-au marcat: liniile: 1, 3, 5 şi coloanele: 1, 4
4
Algoritmul ungar prof. Maria şi Adrian NIŢĂ
Etapa IV.
Se elimină liniile 2, 4, 6 şi coloanele 1 şi 4 (linii nemarcate şi coloane marcate).
Se obţine:
y2 y3 y5 y6
X1 27 19 24 37
X3 76 56 3 57
X5 27 32 27 47
Etapa V.
Se caută elementul minim (3), Se scade din coloanele netăiate: 2, 3, 5, 6 şi se adună la liniile tăiate,
2, 4, 6. (caracterele italic) Se obţine:
y1 y2 y3 y4 y5 y6
x1 -0 24 16 *0 21 34
x2 17 10 63 78 10 *0
x3 3 73 53 -0 -0 54
x4 46 *0 -0 9 60 51
x5 *0 24 29 24 24 44
x6 13 30 12 35 *0 37
Se reîncepe direct cu etapa a II, pentru că pe fiecare linie minimul este zero, deci nu are rost să
exemplific etapa I, în care minimul de pe linie se scade...:
linia cu cele mai puţine zerouri, prima găsită:
linia 2, deci se încadrează c26,
linia 5, deci c51 (se taie c11),
linia 6, deci c65. (se taie c35)
linia 1, deci c14 , deoarece c11 este tăiat (se taie c34)
linia 4, deci c42 se taie al doilea (c43 )
Deci toate zerourile sunt încadrate (*) sau tăiate (-).
Încadrate sunt 5 zerouri deci nu s-a obţinut repartiţia minimă.
Etapa III:
Se marchează linia 3 (conform a, nu are zero încadrat) şi coloanele 4 şi 5 (conform b, în linia
marcată 3 are zerouri barate). Se marchează apoi liniile 1 şi 6 (conform c, are zero încadrat în
coloanele marcate, 4,5). Apoi se marchează coloana 1 ( are zero tăiat în linia 1 marcată, conform b).
Deci s-au marcat folosind b, c:
liniile: 1, 3, 6;
coloanele: 1, 4, 5.
Etapa IV:
Se taie liniile nemarcate: 2, 4, 5 şi coloanele marcate: 1, 4, 5.
y2 Y3 y6
x1 24 16 34
x3 73 53 54
x6 30 12 37
5
Algoritmul ungar prof. Maria şi Adrian NIŢĂ
Elementul minim va fi c63=12 . Se scade 12 din coloanele netăiate (2, 3, 6) şi se adună din liniile
tăiate (2, 4, 5). Se lucrează în tabelul mare, şi se obţine:
y1 y2 y3 y4 y5 y6
x1 0 12 4 0 21 22
x2 29 10 63 93 22 0
x3 3 61 41 0 0 42
x4 58 0 0 21 72 51
x5 12 24 29 36 36 44
x6 13 18 0 35 0 25
Se reia etapa I, există linie cu toate elementele diferite de zero, linia 5 care are minimul egal cu 12.
Acest minim se va scădea din elementele liniei 5. Se va obţine:
y1 y2 y3 y4 y5 y6
x1 -0 12 4 *0 21 22
x2 29 10 63 93 22 *0
x3 3 61 41 -0 *0 42
x4 58 *0 -0 21 72 51
x5 *0 12 17 24 24 32
x6 13 18 *0 35 -0 25
adică
x1 y1
14 15
x2 y2
14
13
x3 y3
x4 y4
16
x5 18 y5
x6 y6
6
Algoritmul ungar prof. Maria şi Adrian NIŢĂ
În întreprinderile (x) se fabrică oricare dintre produsele (y). În funcţie de capacităţile tehnice ale
fiecărei întreprinderi preţul la desfacere diferă (conform tabloului). Dacă un produs nu se poate
realiza într-o întreprindere, elementul corespunzător va fi: -∞.
Să se realizeze repartizarea celor cinci produse pentru ca preţul total de desfacere să fie maxim.
y1 y2 y3 y4 y5
x1 -∞ 5 2 7 9
x2 3 -∞ 8 6 2
x3 7 3 -∞ 9 9
x4 8 8 11 -∞ 5
x5 3 6 4 6 -∞
Pentru a se aplica algoritmul ungar se va folosi matricea obţinută din cea iniţială în care fiecare
element este ( max din matrice minus elementul corespunzător).
Deci lucrăm cu tabloul:
y1 y2 y3 y4 y5
x1 ∞ 6 9 4 2
x2 8 ∞ 3 5 9
x3 4 8 ∞ 2 2
x4 3 3 0 ∞ 6
x5 8 5 7 5 ∞
Etapa I:
Pe fiecare coloană se caută minimul şi se scade din elementele coloanei.
y1 y2 y3 y4 y5
x1 ∞ 3 9 2 0
x2 5 ∞ 3 3 7
x3 1 5 ∞ 0 0
x4 0 0 0 ∞ 4
x5 5 2 7 3 ∞
Există liniile 2 şi 5, fără nici un element zero, se alege minimul şi la fel se scade din elementele
liniei:
y1 y2 y3 y4 y5
x1 ∞ 3 9 2 *0
x2 2 ∞ *0 -0 4
x3 1 5 ∞ *0 -0
x4 *0 -0 -0 ∞ 4
x5 3 *0 5 1 ∞
7
Algoritmul ungar prof. Maria şi Adrian NIŢĂ
Etapa II:
Se caută soluţia optimă:
linia 1, deci c15 (se taie c35),
linia 5, deci c52 (se taie c42),
linia 2, deci c23 (se taie c43 şi c24),
linia 3, deci c34,
linia 4, deci c41.
adică
x1 y1
9
x2 8 8 y2
x3 9 y3
x4 y4
6
x5 y5
Exemplul 3:
Din tabelul de mai jos să se extragă numere situate pe linii şi coloane diferite, astfel încât suma lor
să fie minimă.
1 2 3 4 5 6
1 2 1 3 9 5 8
2 3 4 2 0 0 6
3 0 0 6 5 3 2
4 5 4 9 8 7 5
Tabloul nefiind pătratic, algoritmul ungar nu se poate aplica. Un mod simplu este de a adăuga atâtea
linii până devine pătratic, linii cu elemente zero care nu vor influenţa rezultatul. Deci vom obţine:
1 2 3 4 5 6
1 2 1 3 9 5 8
2 3 4 2 0 0 6
3 0 0 6 5 3 2
4 5 4 9 8 7 5
5 0 0 0 0 0 0
6 0 0 0 0 0 0
8
Algoritmul ungar prof. Maria şi Adrian NIŢĂ
Etapa I:
Pe fiecare coloană există minimul 0, deci căutăm liniile care nu au elemente zero: liniile 1şi 4, unde
minimele au valorile: 1 şi 4 (coincidenţă nefericită, întâmplătoare).
1 2 3 4 5 6
1 1 *0 2 8 4 7
2 3 4 2 *0 -0 6
3 *0 -0 6 5 3 2
4 1 -0 5 4 3 1
5 -0 -0 *0 -0 -0 -0
6 -0 -0 -0 -0 *0 -0
Etapa II:
linia 1, deci c12 (se taie c32, c42, c52, c62),
linia 2, deci c24 (se taie c25, c54, c64),
linia 3, deci c31 (se taie c51, c61),
linia 5, deci c53 (se taie c55, c56, c63),
linia 6, deci c65 (se taie c66),
Am marcat 5 elemente, deci nu avem soluţie.
Etapa III:
se marchează linia 4 (conform a, nu are zero încadrat);
se marchează coloana 2 (conform b, are 0 tăiat în linia 4);
se marchează linia 1 (conform c, are 0 marcat în coloana 2)
Deci s-au marcat liniile: 1, 4 şi coloana 2.
Etapa IV:
se taie liniile nemarcate: 2, 3, 5, 6 şi coloana marcată 2
Etapa V:
Elementul minim netăiat este 1.
1 3 4 5 6
1 1 2 8 4 7
4 1 5 4 3 1
1 2 3 4 5 6
1 0 0 1 7 3 6
2 3 5 2 0 0 6
3 0 1 6 5 3 2
4 0 0 4 3 2 0
5 0 1 0 0 0 0
6 0 1 0 0 0 0
Etapa I:
9
Algoritmul ungar prof. Maria şi Adrian NIŢĂ
Nu se realizează, deoarece fiecare coloană are un zero care va fi minimul dintre elemente, deci scad
0.
Etapa II:
1 2 3 4 5 6
1 -0 *0 1 7 3 6
2 3 5 2 *0 -0 6
3 *0 1 6 5 3 2
4 -0 -0 4 3 2 *0
5 -0 1 *0 -0 -0 -0
6 -0 1 -0 -0 *0 -0
Din alegerea elementelor se poate observa că linia 2 oferă două soluţii, amândouă ar trebui să ofere
suma minimă.
Soluţia 1:
linia 3, deci c31 (se taie c11, c41, c51, c61),
linia 1, deci c12 (se taie c42),
linia 2, deci c24 (se taie c25, c54, c64),
linia 4, deci c46 (se taie c56, c66),
linia 5, deci c53 (se taie c63),
linia 6, deci c65
1 2 3 4 5 6
1 -0 *0 1 7 3 6
2 3 5 2 -0 *0 6
3 *0 1 6 5 3 2
4 -0 -0 4 3 2 *0
5 -0 1 *0 -0 -0 -0
6 -0 1 -0 *0 -0 -0
Soluţia 2:
linia 3, deci c31 (se taie c11, c41, c51, c61),
linia 1, deci c12 (se taie c42),
linia 2, deci c25 (se taie c24, c55, c65),
linia 4, deci c46 (se taie c56, c66),
linia 5, deci c53 (se taie c54, c63),
linia 6, deci c64
10
Algoritmul ungar prof. Maria şi Adrian NIŢĂ
Observaţie: Alegerea algoritmului ungar este o alegere bună şi din punct de vedere al timpului de
executare, care pentru date de test mari (p=100, q=100) are timp de executare la nivelul unei
secunde. Implementarea algoritmului necesită o muncă mai laborioasă.
Program Algoritm_Ungar;
Const NMax=500;
Fi = 'input.in';
Fo = 'output.out';
{ CITIREA DATELOR }
Procedure CitesteMatrice;
Var i, j : integer;
Begin
Assign(fin, fi);
Reset(fin);
Readln(fin, n);
For i := 1 To n Do
Begin
New(a[i]);
For j := 1 To n Do
Read(Fin, a[i]^[j]);
New(a1[i]);
a1[i]^ := a[i]^;
{ Se reţine matricea iniţială pentru rezultatele finale, deoarece
matricea a va fi modificată în fiecare etapă }
End;
Close(fin);
End;
{ ETAPA 1 }
11
Algoritmul ungar prof. Maria şi Adrian NIŢĂ
Procedure Etapa1;
Var i, j, min : Integer;
Begin
For i := 1 To n Do
Begin
min := a[i]^[1];
For j := 1 To n Do
If a[i]^[j] < min Then min := a[i]^[j];
For j := 1 To n Do
a[i]^[j] := a[i]^[j] - min;
End;
For j := 1 To n Do
Begin
min := a[1]^[j];
For i := 1 To n Do
If a[i]^[j] < min Then min := a[i]^[j];
For i := 1 To n Do
a[i]^[j] := a[i]^[j] - min;
End;
End;
{ ETAPA 2 }
{ Se caută o soluţie optimă:
- se alege linia cu cele mai puţine zerouri si se încadrează
unul din ele;
- se barează zerourile care se găsesc în aceeaşi linie sau în
aceeaşi coloana cu zeroul încadrat;
- se procedeaza la fel cu toate celelalte linii.
Daca nu s-a obtinut o solutie (adică au fost alese n elemenete) se
trece la ETAPA3.}
Procedure Etapa2;
Var NrZerouri, linie : integer;
NrZ : Array [1..NMax] Of Integer;
Procedure NumaraZerouri;
Var i, j : Integer;
Begin
NrZerouri := 0;
For i := 1 To n Do
Begin
NrZ[i] := 0;
For j := 1 To n Do
If a[i]^[j] = 0 Then NrZ[i] := NrZ[i] + 1;
NrZerouri := NrZerouri + NrZ[i];
End;
12
Algoritmul ungar prof. Maria şi Adrian NIŢĂ
End;
Procedure AlegeLinie;
Var i, min : Integer;
Begin
For i := 1 To n Do
If NrZ[i] = 0 Then NrZ[i] := n + 1;
min := NrZ[1];
linie := 1;
For i := 2 To n Do
If NrZ[i] < min Then
Begin
min := NrZ[i];
linie:=i;
End;
End;
Procedure IncadreazaSiTaie;
Var k, i, j : Integer;
Begin
k := 1;
While a[linie]^[k] <> 0 Do k := k + 1;
a[linie]^[k] := -1;
{ 0 încadrat se marchează cu -1, cel tăiat cu -2}
For j := k + 1 To n Do
If a[linie]^[j] = 0 Then a[linie]^[j] := -2;
For i := 1 To n Do
If a[i]^[k] = 0 Then a[i]^[k] := -2;
End;
{ ETAPA 3 }
{ a)se vor marca toate liniile care nu conţin nici un zero
încadrat;
b)se va marca fiecare coloana care are unul sau mai multe
zerouri barate în una din liniile marcate;
c)se va marca fiecare linie care are un zero încadrat intr-o
coloana marcata;
d)se repeta operatiile b) si c) până când nu mai este posibil
să se obţină alte linii sau coloane marcate.}
Procedure Etapa3;
13
Algoritmul ungar prof. Maria şi Adrian NIŢĂ
Procedure InitMarcaj;
Var i:Integer;
Begin
For i := 1 To n Do
KM[i] := false;
End;
Procedure MarcLFaraZIncadrat;
Var i, j : Integer;
Begin
For i := 1 To n Do
Begin
LM[i] := true;
For j := 1 To n Do
If a[i]^[j] = -1 Then LM[i] := false;
End;
NrMarcaje := 0;
For i := 1 To n Do
If LM[i] { = TRUE } Then NrMarcaje := NrMarcaje + 1;
End;
Procedure MarcKCuZTaiat;
Var i, j : Integer;
Begin
NrMarcaje := 0;
For j := 1 To n Do
If not KM[j] Then
For i := 1 To n Do
If LM[i] And (a[i]^[j] = -2) Then
Begin
KM[j] := true;
NrMarcaje := NrMarcaje + 1;
End;
End;
Procedure MarcLCuZIncadrat;
Var i, j : Integer;
Begin
NrMarcaje := 0;
For i := 1 To n Do
If not LM[i] Then
For j:= 1 To n Do
If KM[j] And(a[i]^[j] = -1) Then
Begin
LM[i] := true;
NrMarcaje := NrMarcaje + 1;
End;
End;
Begin
InitMarcaj;
MarcLFaraZIncadrat;
While NrMarcaje > 0 Do
Begin
MarcKCuZTaiat;
If NrMarcaje > 0 Then
MarcLCuZIncadrat;
End;
End;
{ ETAPA 4 }
{ Se evidenţiază fiecare linie nemarcată si fiecare coloana
marcată.
În matricea elementelor care nu au fost evidenţiate, se va
alege minimul.
Se scade acest minim din elementele coloanelor neevidenţiate şi
se va aduna la elementele liniilor evidenţiate.
Cu matricea astfel obţinută se repetă procedeul(toate etapele)
până se va obţine soluţia optimă.}
Procedure Etapa4;
Var LT, KT : array [1..NMax] of Boolean;
i, j, min : Integer;
Begin
For i:= 1 To n Do
Begin
LT[i] := not LM[i];
KT[i] := KM[i];
End;
min := MaxInt;
For i := 1 To n Do
If not LT[i] Then
For j := 1 To n Do
If not KT[j] Then
If a[i]^[j] < min Then min := a[i]^[j];
For i := 1 To n Do
For j := 1 To n Do
Begin
If a[i]^[j] < 0 Then a[i]^[j] := 0;
If LT[i] AND KT[j] Then
a[i]^[j] := a[i]^[j] + min
Else
If not LT[i] And not KT[j] Then
a[i]^[j] := a[i]^[j] - min;
End;
End;
{ TESTUL DE OPTIM }
Function SolutieOptima : Boolean;
15
Algoritmul ungar prof. Maria şi Adrian NIŢĂ
{ AFISARE REZULTAT }
Procedure AfiseazaSolutie;
Var i, j : Integer;
total : LongInt;
Begin
Assign(fout, fo);
ReWrite(fout);
total := 0;
For i := 1 To n Do
For j := 1 To n Do
If a[i]^[j] = -1 Then
Begin
WriteLn(Fout, a1[i]^[j]);
total := total + a1[i]^[j];
End;
WriteLn(Fout, total);
Close(Fout);
End;
{ PROGRAMUL PRINCIPAL }
Begin
CitesteMatrice;
Etapa1;
Etapa2;
While not SolutieOptima Do
Begin
Etapa3;
Etapa4;
Etapa2;
End;
AfiseazaSolutie;
End.
16
Algoritmul ungar prof. Maria şi Adrian NIŢĂ
În anul 2003, pe planeta Marte s-a terminat construcţia unei "oaze", în care viaţa oamenilor putea fi
posibilă. În vederea colonizării, fiecare ţară de pe glob, a trimis un reprezentant. Ştiind că, pentru a
transporta un individ se foloseşte câte un avion special şi că fiecare deplasare are un cost bine
stabilit, dat intr-o matrice de forma:
se cere să se determine o repartiţie a persoanelor pe avioane, astfel încât costul total de transport să
fie minim.
Intrare:
Datele de intrare se citesc din fişierul MARTE.IN, având structura:
Ieşire:
Datele de ieşire se scriu în fişierul MARTE.OUT, având structura:
Exemplu:
MARTE.IN MARTE.OUT
6 27
17 43 27 14 39 52 13
29 24 69 90 23 13 16
18 90 62 12 16 70 14
58 14 6 18 73 64 15
15 41 38 36 40 60 18
25 44 18 44 13 50 90
17
Algoritmul ungar prof. Maria şi Adrian NIŢĂ
Pentru problema dată a fost propusă o soluţie care se apropie de algoritmul Greedy:
{$A+,B-,D+,E-,F-,G-,I-,L-,N-,O-,P-,Q-,R-,S-,T-,V-,X+}
Begin
Assign(fi,'MARTE.IN'); Reset(fi);
Readln(fi, n);
For i:=1 to n do
Begin min:=256;
For j:=1 to n do
Begin Read(fi,c[i,j]);
If c[i,j]<min Then Begin
min:=c[i,j]; y[i]:=j
{ se calculeaza minimul pe fiecare linie si se retine in vectorul
y care este coloana pentru care s-a asigurat minimul}
End
End;
Inc(x[y[i]]); Readln(fi);
{ x este un vector care sesizeaza de cate ori a fost folosita o
coloana pentru minim, este solutie daca x este format doar din
valori 1 }
End;
Close(fi);
a:=c; Flag:=true;
While Flag do
Begin
f:=ff;
j:=1;
While (j<=n) and (x[j]<=1) do Inc(j);
{ caut prima pozitie care are valoare mai mare ca 1, adica o coloana
folosita de mai multe ori, in continuare se cauta o alta coloana
pentru linia respectiva care sa conduca la acelasi minim pe care
l-am realizat prima data }
If j>n Then Flag:=false;
If Flag Then Begin
f[j]:=true; fl:=true;
While fl do
Begin
mi:=256;
For i:=1 to n do
if f[y[i]] Then
Begin
min:=256;
For j:=1 to n do
if not(f[j]) and (a[i,j]<min) Then
Begin min:=a[i,j]; co:=j End;
if mi>min-a[i,y[i]] Then
Begin mi:=min-a[i,y[i]];
ii:=i; pr:=co End;
18
Algoritmul ungar prof. Maria şi Adrian NIŢĂ
Assign(fo,'MARTE.OUT'); Rewrite(fo);
min:=0;
For i:=1 to n do
Begin writeln(fo,c[i,y[i]]); Inc(min,c[i,y[i]]) End;
Writeln(fo,min);
Close(fo);
End.
17 43 27 14 39 52
29 24 69 90 23 13
18 90 62 12 16 70
58 14 6 18 73 64
15 41 38 36 40 60
25 44 18 44 13 50
17 43 27 17 39 52
29 24 69 93 23 13
18 90 62 15 16 70
58 14 6 21 73 64
15 41 38 39 40 60
19
Algoritmul ungar prof. Maria şi Adrian NIŢĂ
25 44 18 47 13 50
18 43 27 18 39 52
30 24 69 94 23 13
19 90 62 16 16 70
59 14 6 22 73 64
16 41 38 40 40 60
26 44 18 48 13 50
23 43 27 23 44 52
35 24 69 99 28 13
24 90 62 21 21 70
64 14 6 27 78 64
21 41 38 45 45 60
31 44 18 53 18 50
Vectorul f={ true, false, true, true, true, false}. Următoare valoare minimă creaza diferenţa egală cu
8, care se va aduna la coloanele 1, 3, 4, 5. Se va obţine:
31 43 35 31 52 52
43 24 77 107 36 13
32 90 70 29 29 70
72 14 14 35 86 64
29 41 46 53 53 60
39 44 26 61 26 50
31 43 35 31 52 52
43 24 77 107 36 13
32 90 70 29 29 70
72 14 14 35 86 64
29 41 46 53 53 60
39 44 26 61 26 50
deci y={4, 6, 4, 2, 1, 3 } iar vectorul x={1, 1, 1, 2, 0, 1 }, şi deoarece pe linia 3 există un alt minim
de aceeşi valoare de pe o coloană nefolosită se va alege acesta. Deci se va obţine:
20
Algoritmul ungar prof. Maria şi Adrian NIŢĂ
31 43 35 31 52 52
43 24 77 107 36 13
32 90 70 29 29 70
72 14 14 35 86 64
29 41 46 53 53 60
39 44 26 61 26 50
21