Reppuongelma (myös reppuongelma ) on NP-täydellinen kombinatorinen optimointiongelma . Se on saanut nimensä lopullisesta tavoitteesta: laittaa reppuun mahdollisimman paljon arvokasta tavaraa, mikäli repun kapasiteetti on rajallinen. Reppuongelmasta voi kohdata erilaisia muunnelmia taloustieteessä , sovelletussa matematiikassa , kryptografiassa ja logistiikassa .
Yleisesti ottaen ongelma voidaan muotoilla seuraavasti: annetusta kohteiden joukosta , joilla on ominaisuudet "kustannus" ja "paino", on valittava osajoukko , jolla on enimmäiskokonaiskustannukset, samalla kun otetaan huomioon kokonaispainon rajoitus.
Olkoon joukko objekteja, joilla jokaisella on kaksi parametria - massa ja arvo. Siellä on myös reppu, jolla on tietty kantavuus. Tehtävänä on rakentaa reppu, jonka sisällä olevien esineiden enimmäisarvo on reppujen kokonaismassarajaa kunnioittaen.
Matemaattisesti ongelma on muotoiltu seuraavasti: rahtia on. Jokaista kuormaa varten määritetään sen massa ja arvo . Reppussa olevien tavaroiden kokonaispainon rajan määrää kantokyky . Välttämätön
maksimoida rajoituksin ja [1] .Ongelmanselvitys sallii suuren määrän yleistyksiä, riippuen reppulle, esineille tai niiden valinnasta asetetuista ehdoista. Suosituimmat lajikkeet ovat seuraavat:
Yksi reppuongelman yleisimmistä muunnelmista on epälineaarinen . Se voidaan muotoilla seuraavasti:
Anna vektorin määrittää kunkin repun esineen esiintymien lukumäärä. Sitten ongelmana on löytää funktion minimi
,
tietyllä rajoituksella:
.
Funktioiden oletetaan olevan jatkuvia ja differentioituvia . on kokonaislukuvakio , joukko ei ole tyhjä [7] .
Lineaaristen funktioiden tapauksessa ongelma rajoittuu johonkin klassisista formulaatioista riippuen joukosta :
Vapaus toimintojen valinnassa mahdollistaa laajemman luokan tehtävien ratkaisemisen, mukaan lukien tuotantolaitosten organisoinnin, näytteiden optimaalinen jakautuminen alueellisessa otoksessa tai neliöllisen reppuongelman ratkaisu [7] .
Kuten edellä mainittiin, reppuongelma kuuluu luokkaan NP-complete , eikä sille ole toistaiseksi löydetty polynomialgoritmia , joka ratkaisee sen kohtuullisessa ajassa. Siksi reppuongelmaa ratkaistaessa on valittava tarkkojen algoritmien välillä, jotka eivät sovellu "suuriin" reppuihin, ja likimääräisistä algoritmeista, jotka toimivat nopeasti, mutta eivät takaa optimaalista ongelman ratkaisua.
Kuten muutkin erilliset ongelmat , reppuongelma voidaan ratkaista luettelemalla tyhjentävästi kaikki mahdolliset ratkaisut.
Ongelman tilanteen mukaan on esineitä, jotka voidaan laittaa reppuun, ja sinun on määritettävä kuorman enimmäishinta, jonka paino ei ylitä .
Jokaiselle tuotteelle on 2 vaihtoehtoa: tavara laitetaan reppuun tai esinettä ei sijoiteta reppuun. Tällöin kaikkien mahdollisten vaihtoehtojen luettelointi on ajallisesti monimutkainen , mikä mahdollistaa sen käytön vain pienelle määrälle kohteita [8] . Kohteiden määrän kasvaessa ongelma tulee ratkeamattomaksi tällä menetelmällä hyväksyttävässä ajassa.
Kuvassa on iteraatiopuu kolmelle alkiolle. Jokainen lehti vastaa jotakin esineiden alajoukkoa. Puun kokoamisen jälkeen on löydettävä lehti, jolla on suurin arvo niiden joukosta, joiden paino ei ylitä [9] .
Haara ja sidottu menetelmä on muunnelma raakavoiman menetelmästä sillä erolla, että raa'an voiman puun tietoisesti epäoptimaaliset oksat jätetään pois. Kuten raa'an voiman menetelmä, sen avulla voit löytää optimaalisen ratkaisun ja kuuluu siksi täsmällisiin algoritmeihin.
Alkuperäinen Peter Kolesarin vuonna 1967 ehdottama algoritmi ehdottaa kohteiden lajittelua niiden yksikkökustannusten (arvon ja painon suhteen) mukaan ja raa'an voiman puun rakentamista . Sen parannus on siinä, että jokaiselle solmulle rakennettaessa puuta estimoidaan ratkaisun arvon yläraja ja puun rakentaminen jatkuu vain maksimiestimaatin solmun kohdalla [10] . Kun suurin yläraja on puun lehdellä, algoritmi lopettaa työnsä.
Haara- ja sidotun kyky vähentää iteraatioiden määrää riippuu suuresti syöttötiedoista. On suositeltavaa käyttää sitä vain, jos kohteiden erityisarvot eroavat merkittävästi [11] .
Esineiden painojen lisärajoituksella selkäreppuongelma voidaan ratkaista pseudopolynomiaalisessa ajassa dynaamisilla ohjelmointimenetelmillä .
Olkoon kunkin kohteen paino positiivinen kokonaisluku. Sitten ongelman ratkaisemiseksi on tarpeen laskea optimaaliset ratkaisut kaikille , missä on annettu kantavuus. Määritellään tavaroiden enimmäisarvo, joka voidaan sijoittaa reppuun, jonka kantavuus on .
Sillä voit kirjoittaa rekursiivisia kaavoja :
missä ovat vastaavasti -:nnen kohteen arvo ja paino , ja tyhjän joukon maksimiarvo on katsottava nollaksi.
Itse asiassa viimeinen yhtälö on R. Bellmanin funktionaalinen yhtälö tai dynaamisen ohjelmoinnin funktionaalinen yhtälö. Tässä tapauksessa sen ratkaisemiseksi riittää laskea kaikki arvot alkaen [12] ja asti . Jos tallennamme jokaiseen vaiheeseen lisäksi joukon kohteita, jotka toteuttavat maksimiarvon, niin algoritmi antaa myös optimaalisen kohteiden joukon.
Koska jokaisessa vaiheessa on tarpeen löytää alkioiden maksimi , algoritmin laskennallinen monimutkaisuus on . Koska se voi riippua eksponentiaalisesti syötteen koosta, algoritmi on pseudopolynomiaalinen . Siksi tämän algoritmin tehokkuus määräytyy arvon . Algoritmi antaa erinomaiset tulokset kohteelle , mutta ei kovin hyviä [13] .
Reppuongelma 0-10-1 reppuongelman ratkaisu on lähellä edellisen tehtävän ratkaisua, mutta on otettava huomioon, että jokainen esine on yhtenä kappaleena. Antaa olla ensimmäisistä saatavilla olevista kohteista saatujen tavaroiden enimmäisarvo , joiden kokonaispaino on enintään .
Laskemalla voit löytää tarkan ratkaisun. Jos matriisi mahtuu koneen muistiin, tämä algoritmi on luultavasti yksi tehokkaimmista [12] .
// Syöte: // Nimikkeiden arvot (ladattu taulukkoon v) // Nimikkeiden painot (ladataan taulukkoon w) // Tavaroiden lukumäärä (n) // Kantavuus (W) j : lle 0 - W tee : m [ 0 , j ] := 0 minulle 1 - n tehdä : _ _ j : lle 0 - W tee : jos w [ i ] > j niin : m [ i , j ] : = m [ i - 1 , j ] muuta : m [ i , j ] := max ( m [ i -1 , j ], m [ i -1 , j - w [ i ]] + v [ i ])Ratkaisu voidaan havainnollistaa dynaamisella ohjelmoinnilla seuraavasti: kaksiulotteisessa tasossa objektien lukumäärä piirretään akselille ja niiden paino akselille. Ensimmäisessä vaiheessa rakennetaan kaksi viivaa koordinaattien origosta: vaakasuuntainen, joka vastaa sitä tosiasiaa, että ensimmäistä objektia ei otettu, ja kalteva, joka vastaa ensimmäistä otettua objektia. Niiden projektiot akselilla ovat yhtä suuret kuin kohteen paino. Toisessa vaiheessa rakennetaan jälleen 2 viivaa, vaakasuora (toinen kohde ei otettu) tai vino (toinen kohde otettiin). Asetetaan vaakakaarien pituudeksi nolla ja vinojen kaarien pituudeksi kohteen arvo [14] . Siten mikä tahansa ongelman ratkaisu vastaa jotakin polkua rakennetussa puussa . Ongelma rajoittuu maksimipituisen polun löytämiseen [14] . Anna kapasiteettireppu .
Tuotenumero | Arvo | Paino |
---|---|---|
yksi | 3 | 5 |
2 | 5 | kymmenen |
3 | neljä | 6 |
neljä | 2 | 5 |
Kuvasta voidaan nähdä, että optimaalisen ratkaisun kokonaisarvo on 7, koska tämä on rakennetun puun maksimiarvo.
Dynaaminen ohjelmointi nimikkeiden arvojen yliToistuvuussuhteet voidaan kirjoittaa paitsi esineiden painon, myös arvon suhteen. Tätä varten merkitsemme kohteiden vähimmäispainoa kokonaisarvolla , joka voidaan saada ensimmäisistä kohteista. Jos vaadittua painoa ei saada, merkitse se muodossa .
Sen jälkeen ratkaisemme toiminnallisen dynaamisen ohjelmoinnin yhtälön :
,
alkuehdoilla : _
Kuten useimmissa NP-täydellisissä ongelmissa, ei aina tarvitse saada tarkkaa ratkaisua, koska optimaalisen lähellä olevia ratkaisuja voidaan soveltaa sovellettaviin ongelmiin.
Ongelman ratkaisemiseksi ahneella algoritmilla on tarpeen lajitella asiat niiden tietyn arvon mukaan (eli tavaran arvon ja sen painon suhteen) ja sijoittaa reppuun tavarat, joilla on suurin ominaisarvo [10] .
Tämän algoritmin ajoaika on lajitteluajan ja pinoamisajan summa. Kohteiden lajittelun monimutkaisuus on . Seuraavaksi se laskee kuinka monta esinettä mahtuu reppuun kokonaisajassa [10] . Tuloksena oleva monimutkaisuus , kun lajittelua tarvitaan ja kun tiedot on jo lajiteltu [10] .
Esimerkki . Anna kapasiteettireppu . Tuotteet on jo lajiteltu yksikön arvon mukaan. Käytetään ahneita algoritmeja.
i | paino | hinta | hinta/paino |
---|---|---|---|
yksi | viisitoista | 60 | neljä |
2 | kolmekymmentä | 90 | 3 |
3 | viisikymmentä | 100 | 2 |
Laitoimme ensimmäisen esineen reppuun ja sen jälkeen toisen. Kolmas esine ei mahdu reppuun. Repun tavaroiden yhteisarvo on 150. Jos toinen ja kolmas esine otettaisiin, kokonaisarvo olisi 190. Siten olemme saaneet jonkinlaisen ei-optimaalisen ratkaisun.
On ymmärrettävä, että ahne algoritmi voi johtaa vastaukseen, joka on mielivaltaisen kaukana optimaalisesta. Jos esimerkiksi yhden kohteen paino on 1 ja hinta 2 ja toisen paino on W ja hinta W, ahne algoritmi saa kokonaishinnaksi 2, kun optimaalinen vastaus on W. samaan aikaan sama algoritmi rajoittamattomalle reppu-ongelmalle johtaa vastaukseen, joka on vähintään 50 % optimaalisen arvosta [10] .
George Danzig [16] ehdotti ensimmäisenä ahnetta algoritmia rajoittamattoman selkäreppu-ongelman ratkaisemiseksi.
Koska tarkkaa algoritmia ongelman ratkaisemiseksi polynomiajassa ei löytynyt, syntyi ongelma saada polynomiratkaisu taatulla tarkkuudella . Tätä varten on olemassa useita likimääräisiä kaavioita täysin polynomisesta ajasta , eli joiden monimutkaisuus on polynomi ja .
Klassisen mallin ideana on vähentää tarkkuusarvojen antamista. Yhdistämällä samanarvoisia kohteita yhdeksi ryhmäksi voit vähentää eri kohteiden määrää. Algoritmi kirjoitetaan seuraavasti [15] :
On olemassa monia erilaisia approksimaatiomalleja. Ne riippuvat kuitenkin voimakkaasti reppuongelman muotoilusta. Jos esimerkiksi toinen epäyhtälötyyppinen rajoite (kaksiulotteinen selkäreppu) esiintyy ehdossa, ongelmalla ei ole enää tunnettua polynomiaikakaaviota [17] .
Kuten muissakin NP-kovissa optimointiongelmissa, reppuongelman ratkaisemiseen käytetään geneettisiä algoritmeja . Ne eivät takaa optimaalisen ratkaisun löytämistä polynomiajassa eivätkä anna arviota ratkaisun läheisyydestä optimaaliseen, mutta niillä on hyvät aikaindikaattorit, joiden avulla voit löytää melko hyvän ratkaisun nopeammin kuin muut tunnetut deterministiset tai heuristiset menetelmiä. [kahdeksantoista]
Jokainen yksilö ( genotyyppi ) on osa tavaroista, jotka haluamme pakata laukkuun (niiden kokonaispaino voi ylittää sallitun kantokyvyn). Mukavuussyistä tiedot tallennetaan binäärisinä merkkijonoina, joissa jokainen bitti määrittää, mahtuuko tämä kohde laukkuun [19] .
Kuntotoiminto määrittää ratkaisun läheisyyden optimaaliseen ratkaisuun. Esimerkiksi tavaroiden kokonaisarvo voi toimia sellaisena, mikäli kokonaispaino ei ylitä kantokykyä.
Sukupolvenvaihdosten sarjan jälkeen, joissa vahvimmat yksilöt risteytetään ja loput jätetään huomiotta, algoritmin oletetaan parantavan alkuperäisiä ratkaisuja [19] .
Osajoukon summaongelman ratkaiseminenReppu 0-1 - tehtävän erikoistapaus on osajoukon summa - tehtävä . Olkoon reppun kantokyky, olkoon -:nnen esineen paino ja sen hinta . Tehtävänä on siis ladata reppu mahdollisimman tiukasti tai kuluttaa resurssit kokonaan pois:
Sen ratkaisemiseksi voit käyttää mainittua geneettistä algoritmia . Yksilö on vektori . Kuntotoimintona tulisi käyttää esineiden kokonaispainon läheisyyttä kohtaan , ainoana ominaisuutena on, että reppuun mahtuvat sarjat ovat parempia (esineiden kokonaispaino on pienempi kuin ) [19] .
Määritelkäämme muodollisesti kuntofunktio . Antaa olla kaikkien kohteiden painojen summa. Sitten - repussa olevien esineiden painon suurin mahdollinen poikkeama .
Antaa olla kohteen kokonaispaino tietylle vektorille. Sitten laitamme:
[19]
Yleisen algoritmin avulla voimme löytää likimääräisen ratkaisun:
Suoritus keskeytyy joko ratkaisun löytyessä tai tietyn iteraatiomäärän jälkeen [19] .
Ei tiedetä varmasti, kuka ensimmäisenä antoi reppuongelman matemaattisen muotoilun. Yksi ensimmäisistä viittauksista siihen löytyy George Ballard Matthewsin artikkelista[20] [21] päivätty 1897. Tämän ongelman intensiivinen tutkimus alkoi sen jälkeen , kun D. B. Dantzig julkaisi vuonna 1957 kirjan “ Englanti. Discrete Variable Extreum Problem » [22] , erityisesti 1900-luvun 70-90-luvuilla, sekä teoreetikot että harjoittajat [2] . Kiinnostuksen aiheutti monella tapaa ongelman melko yksinkertainen muotoilu, suuri määrä sen lajikkeita ja ominaisuuksia sekä samalla niiden ratkaisun monimutkaisuus. Vuonna 1972 tämä ongelma sisällytettiin M. Karpin NP-täydellisten ongelmien luetteloon ( englanninkielinen artikkeli "Reducibility among Combinatorial Problems" ) [23] .
Reppuongelman visuaalinen tulkinta on johtanut siihen, että sille on löydetty käyttöä useilla tiedon aloilla: matematiikassa, tietojenkäsittelytieteessä ja näiden tieteiden risteyksessä kryptografiassa . Yhdessä laskennallista lingvistiikkaa käsittelevässä teoksessa [24] ehdotetaan tekstien automaattisen yhteenvedon ongelman muotoilua , jonka erikoistapaus vastaa reppuongelman muotoilua.
Selkäreppuongelman perusteella luotiin ensimmäinen epäsymmetrinen salausalgoritmi . Whitfield Diffie ja Martin Hellman esittelivät idean julkisen avaimen salauksesta ensimmäisen kerran vuoden 1976 kansallisessa tietokonekonferenssissa [25] [26] .
Myös reppuongelma voi toimia mallina useille teollisille ongelmille [2] [27] :
Vuonna 1978 Ralph Merkle ja Martin Hellman kehittivät ensimmäisen algoritmin yleiselle julkisen avaimen salaukselle , Merkle-Hellmanin salausjärjestelmän , joka perustuu reppuongelmaan. He julkaisivat yksivaiheisia ( englanniksi singly-iterated ) ja monivaiheisia ( englanninkielisiä multiply-iterated ) versioita, ja algoritmia voitiin käyttää vain salaukseen. Mutta Adi Shamir mukautti sen käytettäväksi digitaalisissa allekirjoituksissa [28] .
Myöhemmin ehdotettiin muita selkäreppuongelmaan perustuvia salausjärjestelmiä, joista osa on muunnelmia Merkle-Hellmanin kryptosysteemistä. Tunnetut kryptojärjestelmät [29] :
Koska yleistä reppuongelmaa ei voida ratkaista täsmälleen kohtuullisessa ajassa, sitä voidaan käyttää kryptografisissa ongelmissa. Tätä varten esitämme viestin julkisesti tunnetuilla kohteilla lähetettyjen kohteiden joukkona ja lähetämme niiden kokonaispainon [28] .
Määritelmä. Reppuvektori on n:n esineen järjestetty joukko, jossa on -: nnen esineen paino [30] .
Reppuvektori on julkinen avain . Selkeän tekstin salaamiseksi se jaetaan bitin pituisiin lohkoihin, jolloin jokainen bitti määrittää esineen läsnäolon repussa (esimerkiksi selväteksti vastaa neljän ensimmäisen kuudesta mahdollisesta esineestä repussa). Uskotaan, että yksi ilmaisee esineen läsnäolon repussa ja nolla sen puuttumista [28] .
Tämän jälkeen lasketaan reppussa olevien tavaroiden kokonaispaino annetulle selväkieliselle tekstille ja lähetetään salatekstinä [28] .
Esimerkki salauksesta tällä algoritmilla:
Olkoon reppuvektori , jonka pituus on annettu .
pelkkää tekstiä | 1 1 1 1 1 0 | 0 0 1 1 0 0 | 0 0 0 0 0 0 | 0 0 0 0 0 1 |
---|---|---|---|---|
Tavarat repussa | 3 4 6 7 10 | 6 7 | yksitoista | |
Salateksti | 3 + 4 + 6 + 7 + 10 = 30 | 6 + 7 = 13 | 0 | yksitoista |
Reppu-ongelma | |
---|---|
Sovellukset | |
Selkäreppuongelmaan perustuvat kryptojärjestelmät |
|
Lisäksi |
NP-täydellisiä ongelmia | |
---|---|
Pinoamisen (pakkauksen) maksimointiongelma |
|
graafiteorian joukkoteoria | |
Algoritmiset ongelmat | |
Logiikkapelejä ja pulmia | |