Biorithm  1.1
 All Classes Functions Variables Typedefs Friends
dijkstra.h
00001 /**************************************************************************
00002  * Copyright (c) 2004-2011 T. M. Murali                                   *
00003  * Copyright (c) 2005 Shivaram Narayanan                                  *
00004  *                                                                        *
00005  * This file is part of Biorithm.                                         *
00006  *                                                                        *
00007  * Biorithm is free software: you can redistribute it and/or modify       *
00008  * it under the terms of the GNU General Public License as published by   *
00009  * the Free Software Foundation, either version 3 of the License, or      *
00010  * (at your option) any later version.                                    *
00011  *                                                                        *
00012  * Biorithm is distributed in the hope that it will be useful,            *
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of         *
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
00015  * GNU General Public License for more details.                           *
00016  *                                                                        *
00017  * You should have received a copy of the GNU General Public License      *
00018  * along with Biorithm.  If not, see <http://www.gnu.org/licenses/>.      *
00019  *                                                                        *
00020  **************************************************************************/
00021 
00030 #ifndef _DIJKSTRA_H
00031 #define _DIJKSTRA_H
00032 
00033 #include <limits.h> //for INT_MAX
00034 #include <map>
00035 #include <queue>
00036 #include <stack>
00037 
00038 #include "graph.h"
00039 
00040 class NodeElement { 
00041 public: 
00042         friend class PrioritizeNodes; 
00043         NodeElement( string nid, MyNT d) 
00044         { 
00045                 Distance = d; 
00046                 NodeId = nid; 
00047         }
00048         ~NodeElement(){} 
00049         string getNodeId(void)
00050         {
00051                 return NodeId;
00052         }
00053 
00054 private: 
00055         MyNT Distance;
00056         string NodeId; 
00057 };
00058 
00059 class PrioritizeNodes { 
00060 public : 
00061         int operator()( const NodeElement &x, const NodeElement &y )
00062                 { 
00063                         return x.Distance > y.Distance; } 
00064 };
00065 
00066 
00067 //Default Dijkstra visitor.
00068 
00069 
00070 class  MyDefaultDijkstraVisitor
00071 {
00072 public:
00073         
00074         typedef MyNode Node;
00075         typedef MyEdge Edge;
00076         
00077         MyDefaultDijkstraVisitor()
00078     {}
00079         
00080         virtual ~MyDefaultDijkstraVisitor()
00081     {}
00082   
00083         virtual void initVisit(const Node& v) 
00084         {}
00085         // what do i when i visit v first?
00086         virtual void startVisit(const Node& v) 
00087         {}
00088         // finished with v
00089         virtual void finishVisit(const Node& v) 
00090         {}
00091         // discover edge e
00092         virtual void traverseDiscovery(const Edge& e, const Node& from) 
00093         {}
00094         // cross edge e
00095         virtual void traverseCross(const Edge& e, const Node& from) 
00096         {}
00097   
00098 
00099         // done early?  
00100         virtual bool isDone() const { return false; }           
00101 
00102 
00103         //Setting touched/untouched for nodes.
00104         void markTouched(Node& v)
00105         { 
00106                 v.setStatus("touched");
00107         }
00108         void markUntouched(Node& v)
00109         { 
00110                 v.clearStatus("touched");
00111         }
00112         //Setting visited/unvisited for nodes.
00113         void markVisited(Node& v)
00114         { 
00115                 v.setStatus("visited");
00116         }
00117         void markUnvisited(Node& v)
00118         { 
00119                 v.clearStatus("visited");
00120         }
00121 
00122         //Setting visited/unvisited for edges.
00123         void markVisited(Edge& e)
00124         { 
00125                 e.setStatus("visited");
00126         }
00127         void markUnvisited(Edge& e)
00128         { 
00129                 e.clearStatus("visited");
00130         }
00131 
00132 
00133         //Check if node or edge is visited or touched.
00134         bool isTouched(Node& v)
00135         { 
00136                 return v.getStatus("touched");
00137         }
00138         bool isVisited(Node& v)
00139         { 
00140                 return v.getStatus("visited");
00141         }
00142         bool isHidden(Node& v)
00143         {
00144                 return v.isHidden();
00145         }
00146         bool isVisited(Edge& e)
00147         { 
00148                 return e.getStatus("visited");
00149         }
00150 
00151 };
00152 
00153 //
00154 //Dijkstra Visitor for the earlier algorithm (very slow)...
00155 //
00156 
00157 class  MyMainDijkstraVisitor: public MyDefaultDijkstraVisitor
00158 {
00159 private:
00160   
00161 public:
00162         map<string,MyNT>distance;//distance to node.
00163         map<string, unsigned int> count;//no of shortest paths to node.
00164         priority_queue<NodeElement, vector<NodeElement>, PrioritizeNodes> nodesToVisit;
00165 
00166   
00167         MyMainDijkstraVisitor()
00168                 {}
00169   
00170         virtual ~MyMainDijkstraVisitor()
00171                 {}
00172         
00173         virtual void initVisit(const Node& v) 
00174         {
00175                 distance[v.getId()] = 0;
00176                 count[v.getId()] = 1;
00177                 map<string, MyNT>::iterator iter = distance.begin();
00178                 while(iter!=distance.end())
00179                 {
00180                         string nodeid = (*iter).first;
00181                         //cout<<(*iter).first<<endl;
00182                         MyNT distance = (*iter).second;
00183                         Qpush(NodeElement(nodeid,distance));
00184                         iter++;
00185                 }
00186 
00187         }
00188         // what do i when i visit v first?
00189         virtual void startVisit(const Node& v) 
00190         {
00191                 
00192         }
00193         //set distance
00194         void setDistance(string nodeid, MyNT d)
00195         {
00196                 distance[nodeid] = d;
00197         }
00198         //get distance
00199         MyNT getDistance(string nodeid)
00200         {
00201                 return distance[nodeid];
00202         }
00203         //set count
00204         void setCount(string nodeid, unsigned int d)
00205         {
00206           count[nodeid] = d;
00207         }
00208         //get count
00209   unsigned int getCount(string nodeid)
00210         {
00211                 return count[nodeid];
00212         }
00213         // finished with v
00214         virtual void finishVisit(const Node& v) 
00215         {}
00216         // discovery edge e
00217         virtual void traverseDiscovery(const Edge& e, const Node& from) 
00218         {}
00219         // cross edge e
00220         virtual void traverseCross(const Edge& e, const Node& from) 
00221         {}
00222         // done early?  
00223         virtual bool isDone() const { return false; }   
00224 
00225         bool Qempty(){ return nodesToVisit.empty();}
00226         void Qpop(){ return nodesToVisit.pop();}
00227         const NodeElement &Qtop(){ return nodesToVisit.top();}
00228         void Qpush(NodeElement ne){nodesToVisit.push(ne);}
00229 
00230 };
00231 
00232 //
00233 //Implementation of dijkstra for old algo.
00234 //
00235 
00236 template <typename Graph, typename DijkstraVisitor>
00237 class MyDijkstra {
00238 
00239 protected:
00240 
00241         typedef typename Graph::Node    Node;
00242         typedef typename Graph::Edge    Edge;
00243         typedef typename Graph::NodeIterator    NodeIterator;
00244         typedef typename Graph::IncidentEdgeIterator    EdgeIterator;
00245 
00246 protected:                                              // member data
00247 
00248         // the graph to be traversed
00249         Graph& graph;
00250         DijkstraVisitor &visitor;
00251   
00252 public:
00253  
00254         
00255         MyDijkstra(Graph& g, DijkstraVisitor &v) 
00256                   : graph(g), visitor(v)
00257                 {}
00258         
00259         virtual ~MyDijkstra()
00260                 {}
00261 
00262         void initialise() 
00263         {                                       
00264                 NodeIterator nitr = graph.nodes();
00265                 while (nitr.hasNext())
00266                 {
00267                   Node &node = nitr.next();
00268                   visitor.markUnvisited(node);
00269                   visitor.setCount(node.getId(),0);
00270                   visitor.setDistance(node.getId(),INT_MAX);
00271                   EdgeIterator eitr = graph.incidentEdges(node);
00272                   while (eitr.hasNext())
00273                     {
00274                       visitor.markUnvisited(*eitr.next());
00275                     }
00276                 }
00277         }
00278   
00279  
00280 
00281 public:                                         
00282 
00283         //Construct the complete shortest tree DAG rooted at node v.
00284         // perform the traversal
00285   void traverse(const Node& v) 
00286   {
00287     
00288         // gonna implement queue later.
00289         initialise();
00290         visitor.initVisit(v);
00291     while (!visitor.Qempty())
00292       {
00293         NodeElement i = visitor.Qtop();
00294         visitor.Qpop();
00295         // visit node.
00296         Node node = graph._getNode(i.getNodeId());
00297         visitor.startVisit(node);
00298         if(visitor.isVisited(node)) continue;
00299         // mark node as being visited.
00300         visitor.markVisited(node);
00301         if(visitor.isHidden(node)) continue;
00302         //cout<<"Visiting Node "<<node.getId()<<endl;
00303 #ifdef DEBUG
00304 //          cout << "\tNode " << node->getId() << " has degree "
00305 //               << node->degree() << endl;
00306 #endif   
00307         EdgeIterator inEdges = graph.incidentEdges(node);
00308         while (inEdges.hasNext()) 
00309           {
00310             // try all the edges incident on *node.
00311             Edge &e = *inEdges.next();
00312             if (!visitor.isVisited(e)) 
00313               {
00314                 // mark the new edge visited
00315                 visitor.markVisited(e);
00316                 // get next vertex
00317                 Node *w = e.opposite(node);
00318                 MyNT distanceTillnow = visitor.getDistance(node.getId());
00319                 unsigned int countTillnow = visitor.getCount(node.getId());
00320                 MyNT edgeWeight = e.getWeight();//graph.getEdgeWeight(node.getId(),(*w).getId());
00321                 MyNT totalDistance = distanceTillnow + edgeWeight;
00322                 /*      if (!visitor.isVisited(*w))
00323                   {
00324                   visitor.markVisited(*w);
00325                   visitor.setDistance((*w).getId(),totalDistance);
00326                   visitor.Qpush(NodeElement((*w).getId(),totalDistance));
00327                   visitor.setCount((*w).getId(),countTillnow);
00328                   }
00329                   else
00330                   {*/
00331                 if(visitor.getDistance((*w).getId()) > totalDistance)
00332                   {
00333                     visitor.setDistance((*w).getId(),totalDistance);
00334                     visitor.Qpush(NodeElement((*w).getId(),totalDistance));
00335                     visitor.setCount((*w).getId(),countTillnow);
00336                   }
00337                 else if(visitor.getDistance((*w).getId()) == totalDistance)
00338                   {
00339                     unsigned int count = visitor.getCount((*w).getId());
00340                     visitor.setCount((*w).getId(),countTillnow+count);
00341                   }
00342                 //      }   
00343               }
00344                   }
00345         visitor.finishVisit(v);
00346           }
00347     
00348   }
00349 };
00350 
00351 //
00352 //The Dijkstra visitor for the new algorithm (fast).
00353 //
00354 
00355 class MyBCModifiedDijkstraVisitor: public MyMainDijkstraVisitor{
00356         
00357         public:
00358         stack<string> desc;
00359         map< string,vector<string> >pred;
00360 
00361         public:
00362         
00363         MyBCModifiedDijkstraVisitor(){}
00364         virtual ~MyBCModifiedDijkstraVisitor(){}
00365         
00366         void stackPush(string s)
00367         {
00368                 desc.push(s);
00369         }
00370         void addToPred(string pre, string node)
00371         {
00372                 pred[node].push_back(pre);
00373         }
00374         
00375 };
00376 
00377 //
00378 //Implementation of Dijkstra for new algo.
00379 //
00380 
00381 template <typename Graph, typename DijkstraVisitor>
00382 class MyModifiedDijkstra {
00383 
00384 protected:
00385 
00386         typedef typename Graph::Node    Node;
00387         typedef typename Graph::Edge    Edge;
00388         typedef typename Graph::NodeIterator    NodeIterator;
00389         typedef typename Graph::IncidentEdgeIterator    EdgeIterator;
00390 
00391 protected:                                              // member data
00392 
00393         // the graph to be traversed
00394         Graph& graph;
00395         DijkstraVisitor &visitor;
00396   
00397 public:
00398  
00399         
00400         MyModifiedDijkstra(Graph& g, DijkstraVisitor &v) 
00401                   : graph(g), visitor(v)
00402                 {}
00403         
00404         virtual ~MyModifiedDijkstra()
00405                 {}
00406 
00407         void initialise() 
00408         {                                       
00409                 NodeIterator nitr = graph.nodes();
00410                 while (nitr.hasNext())
00411                 {
00412                         Node &node = nitr.next();
00413                         visitor.markUnvisited(node);
00414                         visitor.setCount(node.getId(),0);
00415                         visitor.setDistance(node.getId(),INT_MAX);
00416                         EdgeIterator eitr = graph.incidentEdges(node);
00417                         while (eitr.hasNext())
00418                                 {
00419                                 visitor.markUnvisited(*eitr.next());
00420                                 }
00421                         
00422                 
00423                 }
00424         }
00425   
00426  
00427 
00428 public:                                         
00429 
00430         //Construct the complete shortest tree DAG rooted at node v.
00431         // perform the traversal
00432   void traverse(const Node& v) 
00433   {
00434     
00435         // gonna implement queue later.
00436         initialise();
00437         visitor.initVisit(v);
00438     while (!visitor.Qempty())
00439       {
00440         NodeElement i = visitor.Qtop();
00441         visitor.Qpop();
00442         // visit node.
00443         Node node = graph._getNode(i.getNodeId());
00444         visitor.startVisit(node);
00445         if(visitor.isVisited(node)) continue;
00446         // mark node as being visited.
00447         visitor.markVisited(node);
00448         if(visitor.isHidden(node)) continue;
00449         //cout<<"Visiting Node "<<node.getId()<<endl;
00450 #ifdef DEBUG
00451 //          cout << "\tNode " << node->getId() << " has degree "
00452 //               << node->degree() << endl;
00453 #endif   
00454         EdgeIterator inEdges = graph.incidentEdges(node);
00455         while (inEdges.hasNext()) 
00456           {
00457             // try all the edges incident on *node.
00458             Edge &e = *inEdges.next();
00459             if (!visitor.isVisited(e)) 
00460               {
00461                 // mark the new edge visited
00462                 visitor.markVisited(e);
00463                 // get next vertex
00464                 Node *w = e.opposite(node);
00465                 string visited_nodeid = (*w).getId();
00466                 string nodeid = node.getId(); 
00467                 MyNT distanceTillnow = visitor.getDistance(nodeid);
00468                 unsigned int countTillnow = visitor.getCount(nodeid);
00469                 MyNT edgeWeight = e.getWeight();//graph.getEdgeWeight(nodeid,visited_nodeid);
00470                 MyNT totalDistance = distanceTillnow + edgeWeight;
00471                         /*      if (!visitor.isVisited(*w))
00472                                 {
00473                                         visitor.markVisited(*w);
00474                                         visitor.setDistance((*w).getId(),totalDistance);
00475                                         visitor.Qpush(NodeElement((*w).getId(),totalDistance));
00476                                         visitor.setCount((*w).getId(),countTillnow);
00477                                 }
00478                                 else
00479                                 {*/
00480                 if(visitor.getDistance(visited_nodeid) > totalDistance)
00481                   {
00482                     visitor.setDistance(visited_nodeid,totalDistance);
00483                     visitor.Qpush(NodeElement(visited_nodeid,totalDistance));
00484                     visitor.setCount(visited_nodeid,countTillnow);
00485                     visitor.stackPush(visited_nodeid);
00486                     visitor.addToPred(nodeid,visited_nodeid);
00487                   }
00488                 else if(visitor.getDistance(visited_nodeid) == totalDistance)
00489                   {
00490                     unsigned int count = visitor.getCount(visited_nodeid);
00491                     visitor.setCount(visited_nodeid,countTillnow+count);
00492                     visitor.addToPred(nodeid,visited_nodeid);
00493                   }
00494                         //      }   
00495               }
00496                   }
00497         visitor.finishVisit(v);
00498           }
00499     
00500   }
00501 };
00502 
00503 //
00504 //The Dijkstra visitor for the new algorithm (fast) for finding edge betweeness.
00505 //
00506 
00507 class MyEdgeBetweenessDijkstraVisitor: public MyMainDijkstraVisitor{
00508         
00509         public:
00510         stack<string> desc;
00511         map< string,vector<string> >pred;
00512         map< string,vector<string> >succ;
00513 
00514         public:
00515         
00516         MyEdgeBetweenessDijkstraVisitor(){}
00517         virtual ~MyEdgeBetweenessDijkstraVisitor(){}
00518         
00519         void stackPush(string s)
00520         {
00521                 desc.push(s);
00522         }
00523         void addToPred(string pre, string node)
00524         {
00525                 pred[node].push_back(pre);
00526         }
00527         void addToSucc(string suc, string node)
00528         {
00529                 succ[node].push_back(suc);
00530         }
00531         
00532 };
00533 
00534 //
00535 //Implementation of Dijkstra for new algo to find edge betweeness.
00536 //
00537 
00538 template <typename Graph, typename DijkstraVisitor>
00539 class MyEdgeBetweenessDijkstra {
00540 
00541 protected:
00542 
00543         typedef typename Graph::Node    Node;
00544         typedef typename Graph::Edge    Edge;
00545         typedef typename Graph::NodeIterator    NodeIterator;
00546         typedef typename Graph::IncidentEdgeIterator    EdgeIterator;
00547 
00548 protected:                                              // member data
00549 
00550         // the graph to be traversed
00551         Graph& graph;
00552         DijkstraVisitor &visitor;
00553   
00554 public:
00555  
00556         
00557         MyEdgeBetweenessDijkstra(Graph& g, DijkstraVisitor &v) 
00558                   : graph(g), visitor(v)
00559                 {}
00560         
00561         virtual ~MyEdgeBetweenessDijkstra()
00562                 {}
00563 
00564         void initialise() 
00565         {                                       
00566                 NodeIterator nitr = graph.nodes();
00567                 while (nitr.hasNext())
00568                 {
00569                         Node &node = nitr.next();
00570                         visitor.markUnvisited(node);
00571                         visitor.setCount(node.getId(),0);
00572                         visitor.setDistance(node.getId(),INT_MAX);
00573                         EdgeIterator eitr = graph.incidentEdges(node);
00574                         while (eitr.hasNext())
00575                                 {
00576                                 visitor.markUnvisited(*eitr.next());
00577                                 }
00578                         
00579                 
00580                 }
00581         }
00582   
00583  
00584 
00585 public:                                         
00586 
00587         //Construct the complete shortest tree DAG rooted at node v.
00588         // perform the traversal
00589   void traverse(const Node& v) 
00590   {
00591     
00592         // gonna implement queue later.
00593         initialise();
00594         visitor.initVisit(v);
00595     while (!visitor.Qempty())
00596       {
00597         NodeElement i = visitor.Qtop();
00598         visitor.Qpop();
00599         // visit node.
00600         Node node = graph._getNode(i.getNodeId());
00601         visitor.startVisit(node);
00602         if(visitor.isVisited(node)) continue;
00603         // mark node as being visited.
00604         visitor.markVisited(node);
00605         if(visitor.isHidden(node)) continue;
00606         //cout<<"Visiting Node "<<node.getId()<<endl;
00607 #ifdef DEBUG
00608 //          cout << "\tNode " << node->getId() << " has degree "
00609 //               << node->degree() << endl;
00610 #endif   
00611         EdgeIterator inEdges = graph.incidentEdges(node);
00612         while (inEdges.hasNext()) 
00613           {
00614             // try all the edges incident on *node.
00615             Edge &e = *inEdges.next();
00616             if (!visitor.isVisited(e)) 
00617               {
00618                 // mark the new edge visited
00619                 visitor.markVisited(e);
00620                 // get next vertex
00621                 Node *w = e.opposite(node);
00622                 string visited_nodeid = (*w).getId();
00623                 string nodeid = node.getId(); 
00624                 MyNT distanceTillnow = visitor.getDistance(nodeid);
00625                 unsigned int countTillnow = visitor.getCount(nodeid);
00626                 MyNT edgeWeight = e.getWeight();//graph.getEdgeWeight(nodeid,visited_nodeid);
00627                 MyNT totalDistance = distanceTillnow + edgeWeight;
00628                         /*      if (!visitor.isVisited(*w))
00629                                 {
00630                                         visitor.markVisited(*w);
00631                                         visitor.setDistance((*w).getId(),totalDistance);
00632                                         visitor.Qpush(NodeElement((*w).getId(),totalDistance));
00633                                         visitor.setCount((*w).getId(),countTillnow);
00634                                 }
00635                                 else
00636                                 {*/
00637                 if(visitor.getDistance(visited_nodeid) > totalDistance)
00638                   {
00639                     visitor.setDistance(visited_nodeid,totalDistance);
00640                     visitor.Qpush(NodeElement(visited_nodeid,totalDistance));
00641                     visitor.setCount(visited_nodeid,countTillnow);
00642                     visitor.stackPush(visited_nodeid);
00643                     visitor.addToPred(nodeid,visited_nodeid);
00644                     visitor.addToSucc(visited_nodeid,nodeid);
00645                   }
00646                 else if(visitor.getDistance(visited_nodeid) == totalDistance)
00647                   {
00648                     unsigned int count = visitor.getCount(visited_nodeid);
00649                     visitor.setCount(visited_nodeid,countTillnow+count);
00650                     visitor.addToPred(nodeid,visited_nodeid);
00651                     visitor.addToSucc(visited_nodeid,nodeid);
00652                   }
00653                 //      }   
00654               }
00655           }
00656         visitor.finishVisit(v);
00657           }
00658     
00659   }
00660 };
00661 
00662 
00663 
00664 // class  MyPrimMSTVisitor: public MyDefaultDijkstraVisitor
00665 // {
00666 // private:
00667   
00668 // public:
00669 //   map<string,MyNT>distance;//edge weight.
00670 //   priority_queue<NodeElement, vector<NodeElement>, PrioritizeNodes> nodesToVisit;
00671 
00672   
00673 //   MyPrimMSTVisitor()
00674 //     {}
00675   
00676 //   virtual ~MyPrimMSTVisitor()
00677 //     {}
00678         
00679 //   virtual void initVisit(const Node& v) 
00680 //     {
00681 //       distance[v.getId()] = 0;
00682 //       count[v.getId()] = 1;
00683 //       map<string, MyNT>::iterator iter = distance.begin();
00684 //       while(iter!=distance.end())
00685 //         {
00686 //           string nodeid = (*iter).first;
00687 //           //cout<<(*iter).first<<endl;
00688 //           MyNT distance = (*iter).second;
00689 //           Qpush(NodeElement(nodeid,distance));
00690 //           iter++;
00691 //         }
00692       
00693 //     }
00694 //   // what do i when i visit v first?
00695 //   virtual void startVisit(const Node& v) 
00696 //     {
00697       
00698 //     }
00699 //   //set distance
00700 //   void setDistance(string nodeid, MyNT d)
00701 //     {
00702 //       distance[nodeid] = d;
00703 //     }
00704 //   //get distance
00705 //   MyNT getDistance(string nodeid)
00706 //     {
00707 //       return distance[nodeid];
00708 //     }
00709 //   //set count
00710 //   void setCount(string nodeid, MyNT d)
00711 //     {
00712 //       count[nodeid] = d;
00713 //     }
00714 //   //get count
00715 //   MyNT getCount(string nodeid)
00716 //     {
00717 //       return count[nodeid];
00718 //     }
00719 //   // finished with v
00720 //   virtual void finishVisit(const Node& v) 
00721 //     {}
00722 //   // discovery edge e
00723 //   virtual void traverseDiscovery(const Edge& e, const Node& from) 
00724 //     {}
00725 //   // cross edge e
00726 //   virtual void traverseCross(const Edge& e, const Node& from) 
00727 //     {}
00728 //   // done early?  
00729 //   virtual bool isDone() const { return false; }      
00730   
00731 //   bool Qempty(){ return nodesToVisit.empty();}
00732 //   void Qpop(){ return nodesToVisit.pop();}
00733 //   const NodeElement &Qtop(){ return nodesToVisit.top();}
00734 //   void Qpush(NodeElement ne){nodesToVisit.push(ne);}
00735   
00736 // };
00737 
00738 
00739 #endif // _DIJKSTRA_H 
 All Classes Functions Variables Typedefs Friends