package algorithmen; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.nio.file.*; import java.util.Arrays; import graph.*; /** * Dieser Algorithmus findet die kürzesten Pfade in einem gewichteten Graphen. * Algorithmus: Dijkstra * * @version 7.1 from 12.02.2025 * @author Thomas Schaller */ public class GraphAlgo_DijkstraMitVorgaenger extends GraphAlgo { // Anfang Attribute public String getBezeichnung() { return "Kürzester Pfad (Dijkstra mit Vorgänger)"; } public void init() { List alle = g.getAlleKnoten(); for(Knoten k : alle) { k.set("Vorgänger","-"); k.set("Entfernung",Double.POSITIVE_INFINITY); k.setSortierkriterium("Entfernung"); } gp.getGraphOptions().knotenKurztext = new String[]{"Entfernung","Vorgänger"}; gp.getGraphOptions().knotenLangtext = new String[]{"Infotext","Entfernung","Vorgänger","Markiert","Besucht"}; } public void fuehreAlgorithmusAus() throws InterruptedException { if (g.getAnzahlKnoten()==0) { return; } info("Erzeuge leere toDo-Liste und füge Startknoten hinzu"); List toDo = new ArrayList(); getStartKnoten().setBesucht(true); getStartKnoten().set("Entfernung", 0); toDo.add(getStartKnoten()); while(toDo.size()>0) { info("Sortiere toDo-Liste nach der Entfernung"); Collections.sort(toDo); info("Nimm ersten Knoten aus der toDo-Liste (momentan "+toDo.size()+" Elemente) heraus"); Knoten k = toDo.remove(0); infoIndentMore(); k.setMarkiert(true); info("Markiere den Knoten"); info("Er hat Entfernung "+k.getString("Entfernung")); info("Für jeden Nachbarknoten"); infoIndentMore(); for(Knoten n : g.getNachbarknoten(k)) { if(!n.isMarkiert()){ if(!n.getInfotext().isEmpty()) { info("- "+n.getInfotext()+" ist noch nicht markiert"); } else { info("- Knoten Nr. "+g.getNummer(n)+" ist noch nicht markiert"); } Kante ka = g.getKante(k, n); if(!n.isBesucht() || n.getDouble("Entfernung") > k.getDouble("Entfernung") + ka.getGewicht()){ if(n.isBesucht()) { List eingehend = g.getEingehendeKanten(n, ka2 -> !ka2.isGeloescht() && ka2.isMarkiert()); Kante alterWeg = eingehend.get(0); // Kante alterWeg = g.beschraenkeKantenAuf(g.getEingehendeKanten(n), Graph.MARKIERT, Graph.NICHTGELOESCHT).get(0); // alterWeg.setGeloescht(true); // alterWeg.setMarkiert(false); alterWeg.setGeloescht(true); alterWeg.setMarkiert(false); info(" loesche bisherigen Weg dorthin"); } n.set("Entfernung", k.getInt("Entfernung")+ka.getGewicht()); if(k.getInfotext().equals("")) { n.set("Vorgänger",g.getNummer(k)); } else { n.set("Vorgänger",k.getInfotext()); } if(!toDo.contains(n)) toDo.add(n); ka.setMarkiert(true); n.setBesucht(true); info(" setze Entfernung "+n.getString("Entfernung")+" und füge ggf. ToDo-Liste hinzu."); info(" toDo-Liste hat jetzt "+toDo.size()+" Elemente"); } else { info(" keine neue beste Entfernung"); ka.setGeloescht(true); } } } infoIndentLess(); infoIndentLess(); step(); } info("ToDo-Liste fertig abgearbeitet"); } // end // Ende Methoden }