Per il percorso più breve, inizia dal noto algoritmo di Dijkstra.
When you're on E, according to certain values and variable states, only G may be available...
Una soluzione semplice, che voglio incoraggiare a implementare, è implementare dijkstra in modo tale che chiami una funzione per ottenere i collegamenti in uscita da un determinato nodo. Puoi quindi fare i tuoi controlli lì. Quando cambiano le condizioni, invaliderei i risultati della ricerca e eseguirli di nuovo.
Nota : è ancora meglio se puoi contrassegnare i nodi come non validi. In questo modo l'algoritmo può memorizzare nella cache gli elenchi di collegamenti e rivalutare solo per i nodi invalidati.
Il fatto che un dato collegamento o nodo possa non essere disponibile non rappresenta un problema se il grafico non può cambiare mentre viene utilizzato. Basta calcolarlo per il grafico come lo hai.
Poiché questa è una preoccupazione, suppongo che ci sia qualcosa che attraverserà il grafico e potrebbe scoprire che è cambiata da un momento all'altro ... quando ciò accade, questo qualcosa ha avanzato una certa distanza sul grafico e ha senso calcolare il percorso dalla posizione corrente al bersaglio sul grafico modificato.
Non sono sicuro di come si desidera definire il percorso più lungo ...
Forse, una buona definizione per il percorso più lungo è: il percorso più breve che massimizza il numero di nodi visitati. Sotto questa definizione, camminare su un loop infinito non è vantaggioso.
Cercheremo il percorso più breve ... ma abbiamo bisogno di una nuova metrica per chiamare "distanza". La mia intuizione iniziale è di usare una metrica che non aumenta quando visitiamo un nuovo nodo.
Se la distanza non aumenta né diminuisce quando si visita un nuovo nodo, i seguenti percorsi hanno la stessa lunghezza:
A -> B
A -> C -> F -> G -> I -> B
Tuttavia, vogliamo che il secondo percorso sia migliore (intendo, "più breve", intendo, per avere un valore inferiore nella metrica, intendo, per essere preferibile).
Una soluzione semplice è ridurre la metrica quando si visita un nuovo nodo.
Note:
- Una metrica negativa può essere problematica. Per trovare il percorso, non è sicuro usare Dijkstra con negativi. Possiamo normalizzarlo solo con valori positivi usando una funzione sigmoid prima di comparare.
- Abbiamo anche bisogno di codificare la regola secondo cui la distanza è diversa a seconda di quale sia o non abbiamo visitato un nodo. Puoi risolvere questo con mezzi simili a quello che ho descritto per avere parti del grafico non disponibili. Tranne che, invece di passare il nodo corrente per valutare i collegamenti disponibili, si passa al percorso corrente.
Con questa metrica abbiamo:
A B - length: -1
A C D F G I B - length: -6
A C D E G I B - length: -6
A C D E B - length: -4
A C D E J - length: -4
A C D E C D F G I B - length: -5
¯ ¯
A C D E C D E G I B - length: -3
¯ ¯ ¯
A C D E C D E B - length: -1
¯ ¯ ¯
A C D E C D E J - length: -1
¯ ¯ ¯
A C D E C D E C D E F G I B - length: -1
¯ ¯ ¯ ¯ ¯ ¯
Quindi il nostro percorso "più lungo" è uno dei due percorsi più lunghi che non si ripetono ( A C D F G I B
o A C D E G I B
).
Nel caso in cui non sia evidente, un percorso con un loop è sempre considerato peggiore rispetto alla sua variante senza loop poiché il loop attraversa i nodi visitati e quindi aumenta la metrica. E ricorda che stiamo riducendo la metrica.
Se stai usando Dijkstra con un sigmoide di questa metrica - come suggerisco io - i loop verranno scartati perché - come spiegato sopra - porteranno sempre a percorsi peggiori che quelli senza loop.
Addendum : dopo aver postato la risposta, noto che ho ottenuto alcuni risultati interessanti ... ad esempio: A C D E C D F G I B
riesce a visitare più nodi di A C D F G I B
ma punteggi peggiori (superiori), non è quello che mi aspettavo. Suppongo di poterlo modificare per essere più o meno interessati ad andare oltre il suo modo di raggiungere più nodi prima di raggiungere l'obiettivo applicando fattori alla distanza aggiunta o ridotta ... ad esempio, potremmo aumentare solo la metà del valore quando attraversando un nodo visitato Qual è la proporzione ideale per aumentare? Non ne ho idea. Per scopi pratici può essere ottimizzato per adattarsi al design o al dominio del problema.