DirectedGraph.h

Go to the documentation of this file.
00001 //
00002 // Copyright 2002,2003 Sony Corporation 
00003 //
00004 // Permission to use, copy, modify, and redistribute this software for
00005 // non-commercial use is hereby granted.
00006 //
00007 // This software is provided "as is" without warranty of any kind,
00008 // either expressed or implied, including but not limited to the
00009 // implied warranties of fitness for a particular purpose.
00010 //
00011 
00012 #ifndef DirectedGraph_h_DEFINED
00013 #define DirectedGraph_h_DEFINED
00014 
00015 #include <stdio.h>
00016 
00017 #include <list>
00018 #include <map>
00019 #include <set>
00020 using std::list;
00021 using std::map;
00022 using std::set;
00023 using std::multiset;
00024 using std::less;
00025 
00026 template <class Node, class Arc>
00027 class DirectedGraph {
00028 private:
00029     map<Node, list<Arc>, less<Node> > graph_;
00030 
00031 private:
00032     class Path {
00033     public:
00034         Path(const Arc& arc) {
00035             distance_ = arc.Distance();
00036             path_.push_back(arc);
00037         }
00038         ~Path() {}
00039 
00040         void PushBack(const Arc& arc) {
00041             distance_ += arc.Distance();
00042             path_.push_back(arc);
00043         }
00044         void PopBack() {
00045             distance_ -= path_.back().Distance();
00046             path_.pop_back();
00047         }
00048 
00049         const list<Arc>& ArcList() const { return path_;   }
00050         int         Distance()   const { return distance_; }
00051         const Node& LatestNode() const { return (path_.back()).Destination(); }
00052 
00053         friend bool operator< (const Path& a, const Path& b) {
00054             return (a.distance_ < b.distance_) ? true : false;
00055         }
00056     
00057     private:
00058         int        distance_;
00059         list<Arc>  path_;
00060     };
00061 
00062 public:
00063     DirectedGraph() {}
00064     ~DirectedGraph() {}
00065 
00066     inline void Add(const Arc& arc);
00067     inline void Remove(const Arc& arc);
00068     inline int  Search(const Node& src, const Node& dest, list<Arc>& path);
00069     inline void Print();
00070 };
00071 
00072 template <class Node, class Arc>
00073 void
00074 DirectedGraph<Node, Arc>::Add(const Arc& arc)
00075 {
00076     ( graph_[arc.Source()] ).push_back(arc);
00077 }
00078 
00079 template <class Node, class Arc>
00080 void
00081 DirectedGraph<Node, Arc>::Remove(const Arc& arc)
00082 {
00083     ( graph_[arc.Source()] ).remove(arc);
00084 }
00085 
00086 template <class Node, class Arc>
00087 int
00088 DirectedGraph<Node, Arc>::Search(const Node& src,
00089                                  const Node& dest, list<Arc>& path)
00090 {
00091     set<Node, less<Node> > T;
00092     multiset<Path, less<Path> > F;
00093 
00094     T.insert(src);
00095     typename list<Arc>::iterator iter = (graph_[src]).begin();
00096     typename list<Arc>::iterator last = (graph_[src]).end();
00097     while (iter != last) {
00098         F.insert(Path(*iter)); iter++;
00099     }
00100     
00101     while (1) {
00102 
00103         typename multiset<Path, less<Path> >::iterator path_iter = F.begin();
00104         if (path_iter == F.end()) {
00105 
00106             // Path is not found.
00107             return -1;
00108 
00109         } else if ( (*path_iter).LatestNode() == dest) {
00110 
00111             // Path is found.
00112             path = (*path_iter).ArcList();
00113             return (*path_iter).Distance();
00114         }
00115 
00116         Path nearestPath = *path_iter;  F.erase(path_iter);
00117         Node latestNode  = nearestPath.LatestNode();
00118 
00119         if (T.find(latestNode) == T.end()) {
00120 
00121             T.insert(latestNode);
00122 
00123             typename list<Arc>::iterator iter2 = graph_[latestNode].begin();
00124             typename list<Arc>::iterator last2 = graph_[latestNode].end();
00125             while (iter2 != last2) {
00126                 if ( T.find((*iter2).Destination()) == T.end() ) {
00127                     nearestPath.PushBack(*iter2);
00128                     F.insert(nearestPath);
00129                     nearestPath.PopBack();
00130                 }
00131                 ++iter2;
00132             }
00133         }
00134     }
00135 }
00136 
00137 template <class Node, class Arc>
00138 void
00139 DirectedGraph<Node, Arc>::Print()
00140 {
00141     typename map<Node, list<Arc>, less<Node> >::iterator iter = graph_.begin();
00142     typename map<Node, list<Arc>, less<Node> >::iterator last = graph_.end();
00143     while (iter != last) {
00144         printf("Node ");
00145         (*iter).first.Print();
00146         printf(" : ");
00147         typename list<Arc>::iterator iter2 = (*iter).second.begin();
00148         typename list<Arc>::iterator last2 = (*iter).second.end();
00149         while (iter2 != last2) {
00150             (*iter2).Print();
00151             ++iter2;
00152         }
00153         printf("\n");
00154         ++iter;
00155     }
00156 }
00157 
00158 #endif // DirectedGraph_h_DEFINED

Generated on Sun Dec 2 23:04:28 2007 for openSDK by  doxygen 1.3.9.1