Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Problem mit Dijkstra

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
19.02.2007, 18:13 Uhr
mike
Pinguinhüpfer
(Operator)


Hallo

Ich will den kürzesten Pfad zwischen 2 Punkten finden - das ist ein altbekanntes Problem daher habe ich Dijkstra genommen.

C++:
#include <iostream>
#include <map>
#include <string>
#include <queue>

class Destination {
public:
double distance;
std::string destination;  // need to be public below
Destination (std::string dt, double ds) : distance(ds), destination(dt) {}

bool operator< (const Destination & right) const {
  return distance > right.distance;
}  //reversed so smaller come first in priority_queue
};

typedef std::map<std::string, double> vDistanceMap;
typedef std::map<std::string, vDistanceMap> vGraphMap;

vGraphMap myGraphVec_;

void Dijkstra(vGraphMap& cityMap, std::string start, vDistanceMap & travelCosts)
   // Dijkstra's single source shortest path algorithm
{  // keep a priority queue of distances to cities
  std::priority_queue <Destination> que;
  que.push (Destination(start, 0));

  // while queue not empty
  while (!que.empty()) {
    // remove top entry from queue
    std::string newCity = que.top().destination;
    
    double cost = que.top().distance;
    que.pop();
    // if so far unvisited,
    if(travelCosts.count(newCity) == 0) {
      // visit it now
      travelCosts[newCity] = cost;
      // add reachable cities to list
      vDistanceMap::iterator start = myGraphVec_[newCity].begin();
      vDistanceMap::iterator stop = myGraphVec_[newCity].end();
      for (; start != stop; ++start) {
        std::string destCity = (*start).first;
        double destDistance = (*start).second;
        que.push(Destination(destCity, cost + destDistance));        
      }
    }
  }
}

int main (int argc, char * const argv[]) {
  myGraphVec_["Ort1"]["Ort2"] = 5;
  myGraphVec_["Ort2"]["Ort3"] = 5;
  myGraphVec_["Ort1"]["Ort3"] = 15;
  
  vDistanceMap costs;
  Dijkstra( myGraphVec_, "Ort1" , costs );
  vDistanceMap::iterator it = costs.begin(), stop = costs.end();
  for( ; it != stop ; it++ )
    std::cout << "from " << "Ort1" <<" to " << it->first << " costs " << it->second << std::endl;
    
  return 0;
}



Nun gibt er korrekt aus dass zwischen Ort1 und Ort3 der kürzeste Weg 10 ist. Mein Problem ist nun: Wie kann ich speichern wie der kürzeste Weg verläuft? Also in meinem Beispiel Ort1 - Ort 2 - Ort3
Hab schon die wildestens Konstrukte probiert - aber ich komme nicht dahinter

Danke im Voraus
lg
--

Dieser Post wurde am 19.02.2007 um 18:15 Uhr von mike editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
19.02.2007, 18:45 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


hi, mit dijkstra kannste nur die "Kosten" errechnen, mit A* oder ähnlichem den tatsächlichen weg.
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
19.02.2007, 18:45 Uhr
Blubber2063



Das kann man über Arrays regeln wenn du die Knoten in einem Array hälst: Hier mal Beispiel was wir vor einiger Zeit inner Uni gemacht haben Folien sollten sich nicht geändert haben, ist ein Beispiel in Java drinne.(Wollte den Algorithmus eigentlich beschreiben habs aber sein lassen weil zu umständlich).
http://kbs.cs.tu-berlin.de/teaching/ws2006/info3/folien/info3_10.pdf
Einfach nach Dijkstra suchen.

@Flosoft, doch man kann mit Djikstra auch den Weg den man für die Errechnung der Kosten gebraucht hat ablegen.

Dieser Post wurde am 19.02.2007 um 18:47 Uhr von Blubber2063 editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
19.02.2007, 20:45 Uhr
mike
Pinguinhüpfer
(Operator)


@Blubber2063: hab auf folie info3_11.pdf was gefunden - aber das speichert den Weg auch nicht. Kannst du mir das evntl. noch detaillierter erklären wie du das machen würdest?

@Flo: müsste schon gehen - A* soll in gewisser Hinsicht "effektiver" sein

Danke i.V.
lg
--
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
19.02.2007, 21:22 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


ja natürlich - nur speicheraufwand/rechenzeit für dijkstra ist zur wegfindung ungeeignet - da gibts bessere methoden.

schade das unser robolab-prof das zeug der wegfindungsgruppe noch nicht hochgeladen hat - sonst hätt ich dir das geben können, da kam das alles vor ;-)
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
19.02.2007, 21:29 Uhr
Blubber2063



Naja steht auf Seite 30 unten in p ist der kürzeste Weg Baum gespeichert. Du sammelst ja immer den bis dahin kürzesten Weg zu dem Knoten und dabei kannst du eben auch in einem Array ablegen, von welchem Knoten du gekommen bist. Der kW-Baum lässt sich aus dem Array p lesen. Du musst also nur vom Zielknoten den Weg durch die Knoten rückwärts gehen und schon gelangst du am Start an. Falls dir das nicht reicht ich hab auch noch irgendwo auf der Platte eine Implementation des ganzen in Java.

@Flosoft das mit der Rechenzeit kann sein, wobei viel schneller als Dijkstra wirst du kaum werden. Du musst ja schließlich jeden Knoten anschauen.

Dieser Post wurde am 19.02.2007 um 21:33 Uhr von Blubber2063 editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: