Unkarilainen algoritmi

Kokeneet kirjoittajat eivät ole vielä tarkistaneet sivun nykyistä versiota, ja se voi poiketa merkittävästi 4.3.2020 tarkistetusta versiosta . tarkastukset vaativat 6 muokkausta .

Unkarilainen algoritmi  on optimointialgoritmi , joka ratkaisee osoitusongelman polynomiajassa (katso operaatiotutkimus ). Sen kehitti ja julkaisi Harold Kuhn vuonna 1955 . Kirjoittaja antoi sille nimen "Unkarilainen menetelmä" johtuen siitä, että algoritmi perustuu suurelta osin kahden unkarilaisen matemaatikon König ja Egerváry

James Mancres havaitsi vuonna 1957, että algoritmi on (tiukka) polynomi. Siitä lähtien algoritmi on tunnettu myös Kuhn-Mankres- algoritmina tai Mankres-algoritmina osoitusongelman ratkaisemiseksi . Alkuperäisen algoritmin aikamonimutkaisuus oli, mutta Edmonds Karp samoin osoittivat, että sitä voitiin muokata käyntiajan saavuttamiseksi. Modifioitua unkarilaista algoritmia kutsutaan Hopcroft-Karp-algoritmiksi. Ford ja Fulkerson laajensivat menetelmän yleisiin kuljetusongelmiin. Vuonna 2006 havaittiin, että Jacobi oli löytänyt 1800-luvun ratkaisun toimeksiantoongelmaan, joka julkaistiin latinaksi vuoden 1890 postuumikokoelmassa. [1] [2]

Esimerkki

Oletetaan, että työntekijöitä on kolme: Ivan, Peter ja Andrey. On tarpeen jakaa heidän kesken kolmen tyyppisen työn suorittaminen (jota kutsumme A, B, C), jokaisen työntekijän on suoritettava vain yhden tyyppinen työ. Miten se tehdään niin, että työntekijöiden palkkoihin kuluu mahdollisimman vähän rahaa? Ensin sinun on rakennettava kustannusmatriisi .

A B C
Ivan 10 000 ruplaa. 20 000 ruplaa. 30 000 ruplaa.
Peter 30 000 ruplaa. 30 000 ruplaa. 30 000 ruplaa.
Andrew 30 000 ruplaa. 30 000 ruplaa. 20 000 ruplaa.

Yllä olevaan taulukkoon sovellettu unkarilainen algoritmi antaa meille vaaditun jakauman: Ivan tekee työn A, Peter tekee työn B, Andrey tekee työn C.

Ongelman selvitys

Annettu ei-negatiivinen n × n -matriisi , jossa i : nnen rivin ja j :nnen sarakkeen elementti vastaa kustannuksia, jotka aiheutuvat i : nnen työntekijän suorittamasta j - tyypin työstä . On tarpeen löytää tällainen työn vastaavuus työntekijöille, jotta työvoimakustannukset ovat alhaisimmat. Jos tavoitteena on löytää kohde, jolla on korkeimmat kustannukset, niin ratkaisu pelkistyy juuri muotoillun ongelman ratkaisemiseen korvaamalla kukin kustannus C maksimikustannusten ja C :n välisellä erolla . [3]

Tärkeimmät ideat

Algoritmi perustuu kahteen ajatukseen:

Algoritmi etsii arvoja vähennettäviksi jokaisen rivin ja jokaisen sarakkeen kaikista elementeistä (eri riveillä ja sarakkeilla eri tavalla), niin että kaikki matriisin elementit pysyvät ei-negatiivisina, mutta näkyviin tulee nollaratkaisu.

Määritelmät

Algoritmia on helpompi kuvata, jos ongelma muotoillaan käyttämällä kaksiosaista graafia . Annettu täydellinen kaksiosainen graafi G=(S, T; E) , jossa n pistettä vastaa työntekijöitä ( S ) ja n pistettä vastaa työtyyppejä ( T ); kunkin reunan c(i, j) hinta ei ole negatiivinen. On löydettävä täydellinen tai täydellinen yhteensopivuus halvimmalla hinnalla.

Kutsumme funktiopotentiaalia , jos jokaiselle . Potentiaaliarvo määritellään . On helppo nähdä, että täydellisen yhteensovittamisen hinta ei ole pienempi kuin minkään potentiaalin arvo. Unkarilainen menetelmä löytää täydellisen vastaavuuden ja potentiaalin samalla kustannus/arvolla, mikä osoittaa, että molemmat suureet ovat optimaalisia. Itse asiassa hän löytää täydellisen yhteensopivuuden jäykkien reunojen kanssa: reunan sanotaan olevan jäykkä mahdolliselle jos . Jäykkä reunaosakuvaaja merkitään nimellä . Täydellisen vastaavuuden hinta (jos sellainen on) on yhtä suuri kuin .

Algoritmi kaksiosaisten graafien suhteen

Algoritmi tallentaa muistiin jokaisen jäykän reunan potentiaalin ja orientaation (suunnan asettamisen), jolla on se ominaisuus, että reunat suuntautuvat muodostamaan sovituksen, jota merkitsemme . Suunnattua graafia, joka koostuu jäykistä reunoista tietyllä suuntauksella, on merkitty . Siten joka hetki on olemassa kolmenlaisia ​​reunoja:

Aluksi kaikkialla on 0, ja kaikki reunat on suunnattu kohteesta kohteeseen (siis tyhjä). Jokaisessa vaiheessa joko muutetaan niin, että seuraavassa kappaleessa määriteltyä kärkijoukkoa lisätään, tai suuntaa muutetaan, jotta saadaan sovitus suuremmalla määrällä reunoja; se on aina totta, että kaikki reunat ovat jäykkiä. Prosessi päättyy, jos  se sopii täydellisesti.

Olkoon jokaisessa vaiheessa ja oltava joukko kärkipisteitä, jotka eivät ole satunnaisia ​​reunoja osoitteesta (eli  pisteiden joukko , jotka eivät sisällä mitään reunaa, vaan  joukko kärkipisteitä kohteesta , josta ei reunaa tule ulos). Merkitään joukosta kärkijoukkoja, jotka ovat saavutettavissa välillä - (se löytyy leveyshaulla ).

Jos ei ole tyhjä, se tarkoittaa, että on vähintään yksi polku osoitteesta osoitteeseen . Valitsemme minkä tahansa näistä poluista ja muutamme sen kaikkien reunojen suunnan päinvastaiseksi. Vastaavuuden koko kasvaa yhdellä.

Todisteeksi huomautamme kaksi ilmeistä tosiasiaa:

Määritelmän mukaan tästä seuraa, että valitulla polulla kuuluvat ja kuulumattomat reunat vuorottelevat, ja ensimmäinen ja viimeinen reuna eivät kuulu , eli polku on nousussa, josta todistettava väite seuraa.

Jos tyhjä, laita . on positiivinen, koska ja välillä ei ole kovia reunoja .

Todellakin, olkoon sellainen reuna (i, j) olemassa. Koska , mutta , kärkipiste on saavutettavissa kohteesta - , mutta kärki ei ole tavoitettavissa.

Siksi se ei voi sisältää reunoja (i, j). Siksi mistä . Koska se on saavutettavissa osoitteesta , on polku johonkin osoitteeseen kuuluvasta kärjestä . Harkitse tämän polun viimeistä reunaa. Merkitse se (k, i). Koska se on tavoitettavissa välillä - , mutta tavoittamaton, . Koska , . Siksi on sattunut kahteen reunaan : ja , mikä on mahdotonta, koska  on täsmäys. Ristiriita.

Olkaamme lisätä on vertics alkaen ja vähentää klo vertics mukana . Uusi on edelleen potentiaalinen.

Todellakin, mille tahansa reunalle (i, j), , :

Kaavio muuttuu, mutta sisältää tästä huolimatta .

Todellakin, jotta jostain reunasta (i, j), , , jätetään pois, on tarpeen tehdä siitä ei-jäykkä, eli lisätä eroa c(i, j)-y(i)-y(j) . Kuten olemme nähneet, ero kasvaa vain, jos , , toisin sanoen, on saavuttamaton kohteesta , mutta on saavutettavissa. Mutta tässä tapauksessa reuna (j, i) ei voi kuulua ryhmään , joten reuna ei kuulu joukkoon .

Suuntaa uudet reunat kohdasta . Määritelmän mukaan pisteistä tavoitettavissa olevien kärkien joukko kasvaa (eikä jäykkien reunojen määrä välttämättä kasva).

Tämän väitteen todistamiseksi todistamme ensin, että mikään huippupiste ei katoa Z:sta. Olkoon . Sitten on polku jostakin V:stä V:hen kuuluvasta kärjestä. Kaikki tämän polun kärjet ovat saavutettavissa osoitteesta , eli ne kuuluvat Z:hen. Jokainen tämän polun reuna osuu kahteen kärkeen Z:stä. Kuten edellä näimme, tällaisilla reunoilla ero c(i, j )-y(i)-y(j) ei muutu. Tämä tarkoittaa, että kaikki polun reunat pysyvät jäykinä ja V on edelleen saavutettavissa osoitteesta . Todistetaan nyt, että vähintään yksi kärkipiste lisätään Z:hen. Tarkastellaan reunaa, jolla minimi saavutetaan . Tälle reunalle ero c(i, j)-y(i)-y(j) on nolla, joten siitä tulee jäykkä ja se suuntautuu S:stä T:hen, eli i:stä j:ään. Koska , j tulee myös tavoitettavissa kohteesta , eli se lisätään Z:hen.

Toistamme nämä vaiheet, kunnes siitä tulee täydellinen yhteensopivuus; tässä tapauksessa se antaa toimeksiannon halvimmalla hinnalla. Tämän algoritmiversion suoritusaika on : se täytetään kerran, ja siinä vaiheessa, kun se ei muutu, potentiaalisia muutoksia ei voi enää olla (koska se kasvaa joka kerta). Potentiaalin muuttamiseen tarvittava aika on .

Matriisitulkinta

Työntekijöille ja töille annetaan n × n -matriisi , joka määrittää kunkin työn kustannukset kullekin työntekijälle. Etsi minimikustannus työn tekemisestä siten, että jokainen työntekijä tekee täsmälleen yhden työn ja jokaisen työn tekee täsmälleen yksi työntekijä.

Seuraavassa toimeksiannolla ymmärrämme työntekijöiden ja töiden välisen vastaavuuden, jonka kustannukset ovat nolla, kun olemme tehneet muutoksia, jotka vaikuttavat vain työpaikkojen kokonaiskustannuksiin.

Ensinnäkin kirjoitetaan ongelma matriisimuodossa:

jossa a, b, c, d ovat työntekijöitä, joiden on suoritettava työt 1, 2, 3, 4. Kertoimet a1, a2, a3, a4 ilmaisevat kustannuksia, jotka aiheutuvat töiden 1, 2, 3, 4 suorittamisesta työntekijälle "a", vastaavasti. Muilla symboleilla on samanlainen merkitys. Matriisi on neliön muotoinen, joten jokainen työntekijä voi tehdä vain yhden työn.

Vaihe 1

Vähennämme elementtejä rivi riviltä. Etsitään ensimmäisen rivin alkioista pienin (a1, a2, a3, a4) ja vähennetään se kaikista ensimmäisen rivin elementeistä. Tässä tapauksessa ainakin yksi ensimmäisen rivin elementeistä asetetaan nollaan. Teemme samoin kaikille muille linjoille. Nyt jokaisella matriisin rivillä on vähintään yksi nolla. Joskus nollat ​​jo riittävät määränpään löytämiseen. Esimerkki on esitetty taulukossa. Punaiset nollat ​​osoittavat määrättyjä töitä.

0 a2' 0 a4'
b1' b2' b3' 0
0 c2' c3' c4'
d1' 0 d3' d4'

Suurella määrällä nollia voit löytää määränpään (nollahinta) käyttämällä algoritmia, joka etsii kaksiosaisten kaavioiden maksimivastineisuutta, esimerkiksi Hopcroft-Karp-algoritmia . Lisäksi, jos ainakin yhdessä sarakkeessa ei ole nollaelementtejä, osoitus ei ole mahdollista.

Vaihe 2

Usein ensimmäisessä vaiheessa ei ole tehtävää, kuten seuraavassa tapauksessa:

0 a2' a3' a4'
b1' b2' b3' 0
0 c2' c3' c4'
d1' 0 d3' d4'

Tehtävän 1 voivat tehdä tehokkaasti (nollakustannuksin) sekä työntekijä a että työntekijä c, mutta tehtävää 3 ei kukaan voi tehdä tehokkaasti.

Tällaisissa tapauksissa toistamme sarakkeille vaiheen 1 ja tarkistamme uudelleen, onko määritys mahdollista.

Vaihe 3

Monissa tapauksissa saavutamme halutun tuloksen vaiheen 2 jälkeen. Joskus näin ei kuitenkaan ole, esimerkiksi:

0 a2' a3' a4'
b1' b2' b3' 0
0 c2' c3' c4'
d1' 0 0 d4'

Jos työntekijä d tekee työtä 2, ei ole ketään tehtävää 3 ja päinvastoin.

Tällaisissa tapauksissa noudatamme alla kuvattua menettelyä.

Ensinnäkin, käyttämällä mitä tahansa algoritmia maksimivastaavuuden löytämiseksi kaksiosaisesta graafista, annamme mahdollisimman monta työtä niille työntekijöille, jotka voivat suorittaa ne nollakustannuksilla. Taulukossa on esimerkki, määrätyt työt on korostettu punaisella.

0 a2' a3' a4'
b1' b2' b3' 0
0 c2' c3' c4'
d1' 0 0 d4'

Merkitse muistiin kaikki rivit ilman tehtäviä (rivi 1). Huomaa kaikki näillä riveillä olevat sarakkeet, joissa on nolla (sarake 1). Huomaa kaikki rivit, joissa on "punaisia" nollia näissä sarakkeissa (rivi 3). Jatkamme, kunnes uusia rivejä ja sarakkeita ei enää merkitä.

×
0 a2' a3' a4' ×
b1' b2' b3' 0
0 c2' c3' c4' ×
d1' 0 0 d4'

Nyt piirrämme viivoja kaikkien merkittyjen sarakkeiden ja merkitsemättömien rivien läpi.

×
0 a2' a3' a4' ×
b1' b2' b3' 0
0 c2' c3' c4' ×
d1' 0 0 d4'

Kaikilla näillä toimilla oli vain yksi tavoite: piirtää mahdollisimman vähän viivoja (pystysuorat ja vaakasuuntaiset) niin, että ne peittävät kaikki nollat. Voit käyttää mitä tahansa muuta menetelmää kuvatun sijaan.

Vaihe 4

Etsi matriisielementeistä, joita viivat eivät kata (tässä tapauksessa a2', a3', a4', c2', c3', c4'), pienin. Vähennä se kaikista merkitsemättömistä riveistä ja lisää se kaikkiin merkittyjen rivien ja sarakkeiden leikkauspisteisiin. Joten esimerkiksi jos listan pienin elementti on a2', saamme

×
0 0 a3'-a2' a4'-a2' ×
b1'+a2' b2' b3' 0
0 c2'-a2' c3'-a2' c4'-а2' ×
d1'+a2' 0 0 d4'

Toista toimenpide (vaiheet 1-4), kunnes tapaaminen on mahdollista.

Bibliografia

Muistiinpanot

  1. Jacobi C. De investigando ordine systematis aequationum differentialum vulgarium cujuscunque, CGJ Jacobi's gesammelte Werke, fünfter Band, herausgegeben von K. Weierstrass. - 1890.
  2. (linkki ei saatavilla) politechnique.fr Arkistoitu 29. tammikuuta 2020 Wayback Machinessa 
  3. Arkistoitu kopio (linkki ei saatavilla) . Haettu 11. helmikuuta 2010. Arkistoitu alkuperäisestä 19. heinäkuuta 2011. 

Linkit