ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/outil/src/hypergraphlib_dijkstra.cpp
Revision: 64
Committed: Fri Feb 1 18:27:30 2008 UTC (17 years, 3 months ago) by foucault
Original Path: magic/lib/outil/outil/src/HypergraphLib_Dijkstra.cpp
File size: 4026 byte(s)
Log Message:
mise a jour final these Gilles Foucault

File Contents

# User Rev Content
1 foucault 27 #include "HypergraphLib_Dijkstra.h"
2    
3     #include "HypergraphLib_Graph.h"
4     #include "HypergraphLib_Node.h"
5     #include "HypergraphLib_Arc.h"
6    
7     #include <stdio.h>
8    
9     using namespace HypergraphLib;
10    
11     //---------------------------------------------------------------------------
12     struct DJNode {
13     int nbVisit;
14     double d;
15     Node * n;
16     Node * previous;
17     Arc * prevArc;
18     };
19    
20     //---------------------------------------------------------------------------
21 foucault 64 //Calcule le chemin le plus court entre les noeuds a et b, selon la
22     //fonction de coût distanceFunc
23 foucault 27 double
24     HypergraphLib::Dijkstra(Graph * __G, Node * source, Node * destination, double (* distanceFunc) (HypergraphLib::Node*, HypergraphLib::Node*, HypergraphLib::Arc*) , std::vector<Node *> & path, std::vector<Arc*> & pathArcs)
25     {
26     int i,j,k;
27    
28     #define djnode(xtmp) ((DJNode*)xtmp->GetUserData(50))
29    
30    
31     Graph::MapNodesById graphNodes = __G->GetNodes();
32     for (Graph::MapNodesById::iterator itNode = graphNodes.begin();
33     itNode != graphNodes.end();
34     itNode ++ )
35     {
36     Node * n = itNode->second;
37     struct DJNode * dj = new struct DJNode;
38     dj->previous = NULL;
39     dj->n = n;
40     dj->nbVisit = 0;
41     dj->d = 1E300;
42     dj->prevArc = 0;
43    
44     n->SetUserData(50,dj);
45     }
46    
47     if (__G->GetNode(source->Id()) != source || __G->GetNode(destination->Id()) != destination )
48     return 1E300;
49    
50     djnode(source)->d = 0;
51    
52     typedef std::pair < double, DJNode * > DJElement;
53     std::set < DJElement > Q;
54 foucault 64 std::set < DJElement >::iterator itQ;
55 foucault 27 DJNode* djSource=djnode(source);
56     DJNode* djDestination=djnode(destination);
57     Q.insert(DJElement(djSource->d,djSource));
58    
59     while ( ! Q.empty() )
60     {
61     struct DJNode * current = NULL;
62    
63     DJElement top = *Q.begin();
64     Q.erase(Q.begin());
65     current = top.second;
66    
67     if ( current == NULL )
68     break;
69    
70     current->nbVisit++;
71    
72     for ( Node::MultimapArcsById::iterator itArc1 = current->n->IncidentArcs().begin();
73     itArc1 != current->n->IncidentArcs().end();
74     itArc1 ++ )
75     {
76     Arc * arc = itArc1->second;
77     for ( Arc::MultimapNodesById::iterator itNode = arc->Nodes().begin();
78     itNode != arc->Nodes().end();
79     itNode ++ )
80     {
81     Node * child = itNode->second;
82     if (child == current->n)
83     continue;
84    
85 foucault 64 struct DJNode * sDJNodeChild = djnode(child);
86 foucault 27 double dist_child = distanceFunc(child, current->n, arc);
87    
88     if ( sDJNodeChild->d > current->d + dist_child)
89     {
90     if(sDJNodeChild->d < 1E100) {
91 foucault 64 itQ = Q.find(DJElement(sDJNodeChild->d,sDJNodeChild));
92     if (itQ != Q.end())
93     Q.erase(itQ);
94 foucault 27 }
95    
96     sDJNodeChild->d = current->d + dist_child;
97     sDJNodeChild->previous = current->n;
98     sDJNodeChild->prevArc = arc;
99    
100     Q.insert(DJElement(sDJNodeChild->d,sDJNodeChild));
101     }
102     }
103     }
104     }
105    
106     struct DJNode * n = djDestination;
107     double length = n->d;
108    
109     int nb_node = __G->GetNodes().size();
110    
111     for (i=0; i<nb_node ; i++)
112     {
113     path.insert(path.begin(), n->n);
114     if (n->prevArc)
115     pathArcs.insert(pathArcs.begin(), n->prevArc);
116     if ( n->n == source )
117     break;
118     else
119     {
120     if (n->previous)
121     n = djnode(n->previous);
122     else
123     break;
124     }
125     }
126     if (i == nb_node)
127     length = 1E300;
128    
129     for (Graph::MapNodesById::iterator itNode = graphNodes.begin();
130     itNode != graphNodes.end();
131     itNode ++ )
132     {
133     Node * node = itNode->second;
134     struct DJNode * djtmp = djnode(node);
135     delete djtmp;
136     node->SetUserData(50,0);
137     }
138     #undef djnode
139    
140     return length;
141     }