Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

One to Many Dijkstra gecoded: funktioniert natürlich noch nicht ganz.

  • Loading branch information...
commit faf48642056d70ad3ad2ea1204f23797b4331abc 1 parent 0e370fb
chaot4 chaot4 authored
2  src/Makefile
... ... @@ -1,5 +1,5 @@
1 1 CC = g++
2   -CXXFLAGS = -Wall -g -std=c++0x -lglut -lGL -pthread -O3
  2 +CXXFLAGS = -Wall -g -std=c++0x -lglut -lGL -pthread# -O3
3 3 LDFLAGS = -Il /usr/lib/libGLEW.so /usr/lib/libSOIL.a
4 4 BIN =pferd
5 5
114 src/graphalgs.cpp
@@ -561,8 +561,7 @@ list<unsigned int> independent_set(Graph* g){
561 561 return solution;
562 562 }
563 563
564   -unsigned int CHDijkstra(SCGraph* g, unsigned int node_id0, unsigned int node_id1,
565   - list<unsigned int>* path){
  564 +unsigned int CHDijkstra(SCGraph* g, unsigned int node_id0, unsigned int node_id1){
566 565 // Wegen Codeschönheit: Array für Source und Target anlegen.
567 566 vector<unsigned int> node_id(2);
568 567 node_id[0] = node_id0;
@@ -572,7 +571,7 @@ unsigned int CHDijkstra(SCGraph* g, unsigned int node_id0, unsigned int node_id1
572 571 unsigned int nr_of_nodes = g->getNodeCount();
573 572 unsigned int min_path_length = numeric_limits<unsigned int>::max();
574 573 unsigned int min_path_center;
575   - vector<unsigned int> dist(nr_of_nodes,numeric_limits<unsigned int>::max());
  574 + vector<unsigned int> dist(nr_of_nodes);
576 575 // Gibt an mit welcher Kante Dijkstra 0/1 einen bestimmten Knoten schon gefunden hat.
577 576 // Wenn nicht ist der Wert -1.
578 577 vector< vector<int> > found_by(2,vector<int> (nr_of_nodes,-1));
@@ -657,19 +656,104 @@ unsigned int CHDijkstra(SCGraph* g, unsigned int node_id0, unsigned int node_id1
657 656 return min_path_length;
658 657 }
659 658
660   -bool CHDijkstraTest(Graph* g, SCGraph* scg, unsigned int maxid){
661   - unsigned int dist0;
662   - unsigned int dist1;
663   - for(unsigned int i=0; i<=maxid; i++){
664   - list<unsigned int> path;
665   -// cout << "starte Dijkstra " << endl;
666   - dist0 = Dijkstra(g, 0, i);
667   -// cout << "starte CHDijkstra " << endl;
668   - dist1 = CHDijkstra(scg, 0, i, &path);
669   - cout << "Dijkstra dist für Knoten " << i << ": " << dist0 << ", CHDijkstra dist: " << dist1 << endl;
670   - if(dist0 != dist1){
671   - return false;
  659 +void CHDijkstra(SCGraph* g, unsigned int node_id0, vector<unsigned int>* targets){
  660 + // Von den targets alle aufsteigenden Kanten besuchen und markieren.
  661 + vector<unsigned int> marked(g->getEdgeCount(), false);
  662 + markAscEdges(g, targets, &marked);
  663 +
  664 + // Von node_id0 aus einen "normalen" Dijkstra machen und dabei aufsteigende
  665 + // und markierte Kanten benutzen. Sobald wir alle targets gefunden haben
  666 + // brechen wir ab.
  667 + std::priority_queue<U_element, std::vector<U_element>, Compare_U_element> U;
  668 + unsigned int nr_of_nodes = g->getNodeCount();
  669 + unsigned int tmpnode;
  670 + // Ist -1 wenn der Knoten noch nicht gefunden wurde, sonst steht die
  671 + // id des Knotens drin, von dem er gefunden wurde.
  672 + vector<int> found_by(nr_of_nodes,-1);
  673 + // TODO zum Testen ist hier noch ein dist-vector drin.
  674 + vector<unsigned int> dist(nr_of_nodes);
  675 +
  676 + // Den ersten Knoten abarbeiten
  677 + U.push(U_element(0,node_id0,0));
  678 +
  679 + // Die restlichen Knoten abarbeiten
  680 + for(unsigned int i=0; i<targets->size(); i++){
  681 + unsigned int target = (*targets)[i];
  682 + if(found_by[target] == -1){
  683 + while(!U.empty() && U.top().id != target){
  684 + // Die Distanz Eintragen, wenn der kürzeste gefunden wurde (und weiter suchen)
  685 + tmpnode = U.top().id;
  686 + if(found_by[tmpnode] == -1){
  687 + dist[tmpnode] = U.top().distance;
  688 + found_by[tmpnode] = (int)U.top().eid;
  689 + // Die ausgehenden Kanten durchgehen und wenn sie aufwärts gehen oder
  690 + // markiert sind auf ihnen weitersuchen.
  691 + EdgesIterator it = g->getOutEdgesIt(tmpnode);
  692 + while(it.hasNext()){
  693 + Edge* tmpedge = it.getNext();
  694 + // Wenn der Knoten noch nicht gefunden wurde UND (sein Level größer ist
  695 + // ODER die Kante markiert ist).
  696 + if(found_by[tmpedge->other_node] == -1
  697 + && (tmpedge->other_lvl > g->getNodeLVL(tmpnode) || marked[tmpedge->id])){
  698 + // ...tu sie in U
  699 + U.push(U_element(
  700 + tmpedge->value+U.top().distance,tmpedge->other_node,tmpedge->id));
  701 + }
  702 + }
  703 + }
  704 + U.pop();
  705 + }
  706 + }
  707 + // Die Distanz des Knotens setzen, je nachdem ob er...
  708 + if(found_by[target] != -1){
  709 + //...schon gefunden wurde...
  710 + (*targets)[i] = dist[target];
672 711 }
  712 + else{
  713 + if(U.top().id == target){
  714 + //...erst gerade gefunden wurde...
  715 + dist[target] = U.top().distance;
  716 + (*targets)[i] = U.top().distance;
  717 + }
  718 + else{
  719 + //...oder garnicht gefunden wurde.
  720 + (*targets)[i] = numeric_limits<unsigned int>::max();
  721 + }
  722 + }
  723 + // TODO Backtracing des aktuellen Knotens.
  724 + }
  725 +}
  726 +
  727 +void markAscEdges(SCGraph* g, vector<unsigned int>* nodes, vector<unsigned int>* marked){
  728 + vector<unsigned int> todo;
  729 + // Erstmal alle Startknoten einfürgen. TODO man könnte auch
  730 + // vllt direkt den nodes Vektor benutzen, je nach Implementierung
  731 + // des Rests.
  732 + // TODO Der marked Vektor muss im Moment noch komplett mit false initialisiert
  733 + // übergeben werden.
  734 + todo.assign(nodes->begin(), nodes->end());
  735 + while(!todo.empty()){
  736 + unsigned int tmpnode = todo.back();todo.pop_back();
  737 + EdgesIterator it = g->getInEdgesIt(tmpnode);
  738 + while(it.hasNext()){
  739 + Edge* tmpedge = it.getNext();
  740 + // Wenn wir nicht schon hier waren und es nach oben geht.
  741 + if(!(*marked)[tmpedge->id] && tmpedge->other_lvl > g->getNodeLVL(tmpnode)){
  742 + (*marked)[tmpedge->id] = true;
  743 + todo.push_back(tmpedge->other_node);
  744 + }
  745 + }
  746 + }
  747 +}
  748 +
  749 +bool CHDijkstraTest(Graph* g, SCGraph* scg, unsigned int maxid){
  750 + vector<unsigned int> targets;
  751 + for(unsigned int i=0; i<100; i++){
  752 + targets.push_back(i);
  753 + }
  754 + CHDijkstra(scg, 0, &targets);
  755 + for(unsigned int i=0; i<100; i++){
  756 + cout << "Für Knoten " << i << ": " << targets[i] << " und " << CHDijkstra(scg, 0, i) << endl;
673 757 }
674 758 return true;
675 759 }
14 src/graphalgs.h
@@ -67,8 +67,18 @@ list<unsigned int> independent_set(Graph* g);
67 67 /*
68 68 * One to one Dijkstra auf der CH.
69 69 */
70   -unsigned int CHDijkstra(SCGraph* g, unsigned int node_id0, unsigned int node_id1,
71   - list<unsigned int>* path);
  70 +unsigned int CHDijkstra(SCGraph* g, unsigned int node_id0, unsigned int node_id1);
  71 +
  72 +/*
  73 + * One to many Dijkstra auf der CH. Die Distanzen werden in den targets-vector geschrieben
  74 + * and die entsprechende Stelle.
  75 + */
  76 +void CHDijkstra(SCGraph* g, unsigned int node_id0, vector<unsigned int>* targets);
  77 +
  78 +/*
  79 + * Markiert alle aufsteigenden Kanten von nodes aus.
  80 + */
  81 +void markAscEdges(SCGraph* g, vector<unsigned int>* nodes, vector<unsigned int>* marked);
72 82
73 83 /*
74 84 * Test für den CHDijkstra.
2  src/pferd.cpp
@@ -94,7 +94,7 @@ int main(int argc, char *argv[]){
94 94 // vis anzeige(&scg); anzeige.start();
95 95
96 96
97   - CHDijkstraTest(&g, &scg, 15045);
  97 + CHDijkstraTest(&g, &scg, 149909);
98 98
99 99 return 0;
100 100 }

0 comments on commit faf4864

Please sign in to comment.
Something went wrong with that request. Please try again.