Az utazó eladó problémája a Java-ban

1. Bemutatkozás

Ebben az oktatóanyagban megismerhetjük a Szimulált annealing algoritmust, és bemutatjuk a megvalósító példát a Traveling Salesman Problem (TSP) alapján.

2. Szimulált hőkezelés

A szimulált annealing algoritmus heurisztikus a problémák megoldására nagy keresési területtel.

Az ihlet és a név a kohászatban történt megolvasztásból származott; ez egy technika, amely magában foglalja az anyag melegítését és szabályozott hűtését.

Általánosságban elmondható, hogy a szimulált hőkezelés csökkenti a rosszabb megoldások elfogadásának valószínűségét, mivel feltárja a megoldási teret és csökkenti a rendszer hőmérsékletét. Az alábbi animáció bemutatja a legjobb megoldás megtalálásának mechanizmusát a szimulált annealing algoritmus segítségével:

Amint megfigyelhetjük, az algoritmus szélesebb megoldástartományt alkalmaz a rendszer magas hőmérsékletén, a globális optimum keresésére. A hőmérséklet csökkentése közben a keresési tartomány egyre kisebb, amíg meg nem találja a globális optimumot.

Az algoritmusnak néhány paramétere van:

  • iterációk száma - a szimulációk leállási feltétele
  • kezdeti hőmérséklet - a rendszer induló energiája
  • hűtési sebesség paraméter - az a százalék, amellyel csökkentjük a rendszer hőmérsékletét
  • minimális hőmérséklet - opcionális megállási feltétel
  • szimulációs idő - opcionális megállási feltétel

Ezeknek a paramétereknek az értékeit gondosan kell kiválasztani - mivel ezek jelentősen befolyásolhatják a folyamat teljesítményét.

3. Utazó eladó problémája

A Traveling Salesman Problem (TSP) a legismertebb informatikai optimalizálási probléma a modern világban.

Egyszerű szavakkal, problémát jelent a grafikon csomópontjai közötti optimális útvonal megtalálása. A teljes utazási távolság lehet az egyik optimalizálási kritérium. A TSP-vel kapcsolatos további részletekért tekintse meg itt.

4. Java modell

A TSP probléma megoldásához két modellosztályra lesz szükségünk, nevezetesen Város és Utazás. Az elsőben a csomópontok koordinátáit tároljuk a grafikonon:

@Data nyilvános osztály City {private int x; magán int y; nyilvános város () {this.x = (int) (Math.random () * 500); ez.y = (int) (Math.random () * 500); } nyilvános kettős távolságToCity (városi város) {int x = Math.abs (getX () - város.getX ()); int y = Math.abs (getY () - város.getY ()); return Math.sqrt (Math.pow (x, 2) + Math.pow (y, 2)); }}

A kivitelező Város osztály lehetővé teszi számunkra, hogy véletlenszerű helyeket hozzunk létre a városokban. A distanceToCity (..) a logika felelős a városok közötti távolság kiszámításáért.

A következő kód felelős az utazó eladó túra modellezéséért. Kezdjük a városok kezdeti sorrendjének létrehozásával az utazás során:

public void generatorInitialTravel () {if (travel.isEmpty ()) new Travel (10); Gyűjtemények.sorsolás (utazás); }

A kezdeti sorrend előállítása mellett szükségünk van a véletlenszerű két város utazási sorrendben történő felcserélésére szolgáló módszerekre. Használni fogjuk a jobb megoldások keresésére a Szimulált Égesztés algoritmusban:

public void swapCities () {int a = generálRandomIndex (); int b = generálRandomIndex (); előzőTravel = utazás; X város = travel.get (a); Y város = utazás.get (b); utazás.halmaz (a, y); utazás.készlet (b, x); }

Továbbá szükségünk van egy módszerre az előző lépésben generált csere generálásának visszavonására, ha algoritmusunk nem fogadja el az új megoldást:

public void revertSwap () {utazás = előzőTravel; }

Az utolsó módszer, amelyet meg akarunk tenni, a teljes utazási távolság kiszámítása, amelyet optimalizálási kritériumként használunk:

public int getDistance () {int távolság = 0; for (int index = 0; index <utazás.méret (); index ++) {Város kezdő = getCity (index); Város rendeltetési helye; if (index + 1 <utazás.méret ()) {cél = getCity (index + 1); } else {cél = getCity (0); } távolság + = kezdő.távolságToCity (cél); } visszatérési távolság; }

Most összpontosítsunk a fő részre, a Szimulált Annealing algoritmus megvalósítására.

5. Szimulált hőkezelési megvalósítás

A következő Szimulált annealing megvalósításban megoldjuk a TSP problémát. Csak egy rövid emlékeztető, a cél az, hogy megtalálja a legrövidebb távolságot az összes város megtételéhez.

A folyamat elindításához három fő paramétert kell megadnunk, nevezetesen startTemperature, numberOfIterations és hűtési sebesség:

nyilvános kettős szimulációAnnealing (kettős indítási hőmérséklet, int számOfIterációk, kettős hűtési sebesség) {double t = kezdő hőmérséklet; travel.generateInitialTravel (); double bestDistance = utazás.getDistance (); Utazás currentSolution = utazás; // ...}

A szimuláció megkezdése előtt generáljuk a városok kezdeti (véletlenszerű) sorrendjét, és kiszámoljuk az utazás teljes távolságát. Mivel ez az első számított távolság, ezért a távolságon belül elmentjük bestDistance változó, a currentSolution.

A következő lépésben elindítunk egy fő szimulációs ciklust:

mert (int i = 0; i 0.1) {// ...} else {folytatás; }}

A ciklus megtartja az általunk megadott iterációk számát. Ezenkívül feltettünk egy feltételt a szimuláció leállítására, ha a hőmérséklet alacsonyabb vagy egyenlő, mint 0,1. Ez lehetővé teszi számunkra a szimulációk idejének megtakarítását, mivel alacsony hőmérsékleten az optimalizálási különbségek szinte nem látszanak.

Nézzük meg a Szimulált annealing algoritmus fő logikáját:

currentSolution.swapCities (); double currentDistance = currentSolution.getDistance (); if (currentDistance <bestDistance) {bestDistance = currentDistance; } else if (Math.exp ((bestDistance - currentDistance) / t) <Math.random ()) {currentSolution.revertSwap (); }

A szimuláció minden lépésében véletlenszerűen cserélünk két várost utazási sorrendben.

Továbbá kiszámoljuk a currentDistance. Ha az újonnan kiszámított currentDistance alacsonyabb, mint bestDistance, a legjobbként mentjük el.

Ellenkező esetben ellenőrizzük, hogy a valószínűségeloszlás Boltzmann-függvénye alacsonyabb-e, mint a véletlenszerűen kiválasztott érték, 0 és 0 közötti tartományban. Ha igen, akkor visszavonjuk a városok cseréjét. Ha nem, akkor megtartjuk a városok új rendjét, mivel ez segíthet elkerülni a helyi minimumokat.

Végül a szimuláció minden lépésében csökkentjük a hőmérsékletet hűtési ráta:

t * = hűtési sebesség;

A szimuláció után visszaküldjük a legjobb megoldást, amelyet a Szimulált hőkezelés segítségével találtunk.

Kérjük, vegye figyelembe a néhány tippet a legjobb szimulációs paraméterek kiválasztásához:

  • kicsi megoldási terek esetén jobb csökkenteni a kezdő hőmérsékletet és növelni a hűtési sebességet, mivel ez csökkenti a szimulációs időt a minőség romlása nélkül
  • nagyobb megoldási terek esetén kérjük, válassza a magasabb kezdő hőmérsékletet és a kis hűtési sebességet, mivel több helyi minimum lesz
  • mindig elegendő időt biztosítson a szimulációhoz a rendszer magas és alacsony hőmérséklete között

Ne felejtsen el eltölteni egy kis időt az algoritmus hangolásával a kisebb problémapéldánnyal, mielőtt elkezdené a fő szimulációkat, mivel ez javítani fogja a végeredményeket. A szimulált annealing algoritmus hangolását például ebben a cikkben mutattuk be.

6. Következtetés

Ebben a gyors bemutatóban megismerhettük a Szimulált Kihúzás algoritmust és megoldottuk az utazó eladó problémáját. Remélhetőleg ez megmutatja, mennyire hasznos ez az egyszerű algoritmus, ha bizonyos típusú optimalizálási problémákra alkalmazzák.

A cikk teljes megvalósítása a GitHub oldalon található.