Portál AbcLinuxu, 8. listopadu 2025 00:30
Nejvíc práce Vám dá podle mého "infrastruktura" - implementace datových struktur, loadování dat z disku, nějaký výstup (uživatelské rozhraní) - budete tu topologii skutečně graficky zobrazovat (případně i zadávat)? Až budete mít tohle hotovo, pak si můžete hrát s heuristikou algoritmu - ala "robot Karel"
Pokud by hrany byly rovnocenné, asi bych začal tím, že bych se snažil procházet graf "od buka do buka" (jako když na lyžích křižujete sjezdovku). Tj. začal bych třeba "jdi do sousedního uzlu, který je nejvíc vlevo z dosud nenavštívených" - a když bych narazil na koncový uzel (žádný další nenavštívený uzel), zkusil bych pátrat po nejbližším dalším dosud nenavštíveném uzlu (pátral bych 1,2,3... hopy okolo) nebo bych si pamatoval, ve kterém uzlu jsem naposledy zaznamenal víc než jednu možnost, kam se vydat, a tam bych se vrátil. A pokračoval bych doprava. Anebo dál doleva, ale pak by to nebylo "cik cak", ale "zvenčí dovnitř" (resp. zevnitř ven, podle toho kde jste začal). V dalším kroku bych mohl zkusit zohlednit v rozhodování cenu další hrany (nějakou váhou). Nebo bych mohl zkusit nějakou "shlukovou analýzu blízkého okolí (N hopů)" - abych si zbytečně nevytvářel "dlouhé slepé větve", nebo abych elegantně "vyčistil malé lokální smyčky bez únikových cest", třeba i s lokální dooptimalizací hrubou silou (všechny možnosti). Nebo bych v "blízkém okolí" detekoval cykly v grafu a vyhýbal bych se dražším hranám... Zkuste přemýšlet, jak byste problém řešil selským rozumem (za volantem s mapou v ruce) - a algoritmus zapsat jako program.
Tak mě napadá: je to rovinný (2D) graf, nebo amorfní chumel? (při zobrazení v 2D se hrany kříží a vedou klidně napříč celým grafem) Tam by pak neměly smysl pojmy "napravo a nalevo"
Nemám v oboru formální vzdělání - nicméně mám představu, že tohle nemá nějaké "jediné správné a přímo spočítatelné" řešení. Problém typu "obchodní cestující" má k Vašemu zadání skutečně nejblíž. Patrně velmi přesně Vaše zadání odpovídá praktickému problému různých kurýrních služeb (pošta, DHL/UPS/TNT/DPD/PPL/GP...). Četl jsem, že to někdo zkouší třeba pomocí genetických algoritmů. Taky mi to připomíná některá "témata" Xscreensaveru
Otrava...
Problém má určitou složitost. Takže sebelepší algoritmus nebude lepší, než je třída problému. Pokud je problém NP-úplný, tak na polynomickou složitost algoritmu zapoměňte.
Samozřejmě, když si odpostíme podmínku optimálnosti, tak se dají vymyslet heuristiky, které občas trochu pomůžou.
Tak som si určil, že tie body v krajine sú vrcholy grafu a hrany medzi nimi sú rôzne možné cesty ohodnotené počtom kilometrov medzi nimi. Lenže potom ma napadlo, že kritérium vzdialenosti nieje jediné, podľa ktorého sa človek v teréne rozhoduje. Tento algoritmus by ma totiž napríklad viedol z hrebeňa dole do doliny lebo je tam blízky bod a potom naspäť hore na hrebeň na nejaký ďalší bod, ktorý je trebars len o kúsok ďalej. Lenže človek by logicky dal prednosť prejsť najprv 2 body hore na hrebeni v jednej nadmorskej výške aj keď sú trebars dvojnásobne vzdialené ako bod v doline. A až potom by zišiel dole aby v kuse nechodil hore-dole čo by ma na biku vyčerpalo
Preto som z grafu urobil digraf (orientovaný graf) aby som smer AB (dolekopcom) mohol ohodniť inak ako opačný smer BA (horekopcom). Takto môžem hrane z bodu A do B dať hodnotu 4 (4 km) a naopak z B do A dať 6 (4 km + 2 ako penalizácia že to je hore kopcom). Túto penalizáciu budem dávať len tak subjektívne z hlavy podľa sklonu kopca. Určite by sa dal nájsť aj nejaký algoritmus ktorý by tu penalizáciu vypočítaval automaticky ako rozdiel nadmorskej výšky dvoch bodov...Ďalšia penalizácia môže byť či to je pekná/rozbitá cesta, atraktívne/neatraktívne okolie...No a výsledok je že mám ako som písal v prvom príspevku orientovaný graf s hranami ohodnotenými nejakými hodnotamy a chcem prejsť v grafe všetky vrcholy s najmenšou "vzdialenosťou" (v uvodzovkách pretože ako som písal, ohodnotenie hrán nevyjadruje len vzdialenosť).
Žiadne ďalšie obmedzenia niesu. Začať a skončiť môžem kde chcem. Ak to je výhodné tak vrcholom grafu môžem prejsť aj viackrát (ale minimálne raz). Po rovnakých hranách môžem prechádzať tiež viackrát, po nevýhodných hranách nemusím ísť ani raz...
for i in 1..1000: # or another big number instead of 1000
x = random_permutation()
if length(x) < best_length:
best_x = x;
best_length = length(x)
Tiskni
Sdílej:
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.