MeshKit  1.0
MKGraph.cpp
Go to the documentation of this file.
00001 #include "meshkit/MKGraph.hpp"
00002 #include "meshkit/MeshOp.hpp"
00003 #include "lemon/core.h"
00004 #include "lemon/adaptors.h"
00005 #include "lemon/connectivity.h"
00006 #include "lemon/math.h"
00007 #include "lemon/graph_to_eps.h"
00008 
00009 namespace MeshKit 
00010 {
00011     
00012 MKGraph::MKGraph() 
00013         : mkGraph(), rootNode(NULL), leafNode(NULL), nodeMap(mkGraph, NULL)
00014 {
00015 }
00016     
00017 MKGraph::~MKGraph() 
00018 {
00019 }
00020 
00021 void MKGraph::clear_graph() 
00022 {
00023     // get all the non-root, non-leaf nodes
00024   std::vector<lemon::ListDigraph::Node> nodes;
00025   for (lemon::ListDigraph::NodeIt nit(mkGraph); nit != lemon::INVALID; ++nit) 
00026     if (nit != rootNode->get_node() && nit != leafNode->get_node())
00027       nodes.push_back(nit);
00028   
00029     // now delete all those nodes
00030   // lemon will automatically delete all the edges connected to these nodes
00031   for (std::vector<lemon::ListDigraph::Node>::iterator vit = nodes.begin(); vit != nodes.end(); vit++) {
00032     if (nodeMap[*vit]) delete nodeMap[*vit];
00033     else mkGraph.erase(*vit);
00034   }
00035   
00036     // restore an edge between the root and leaf !! comment this out
00037   // we are not creating it anymore in the constructor of MKCore
00038   /*if (!mkGraph.valid(lemon::ArcLookUp<lemon::ListDigraph>(mkGraph)(rootNode->get_node(), leafNode->get_node())))
00039     mkGraph.addArc(rootNode->get_node(), leafNode->get_node());*/
00040 }
00041 
00042 void MKGraph::print_graph(const char * filename)
00043 {
00044   for (lemon::ListDigraph::NodeIt nit(mkGraph); nit != lemon::INVALID; ++nit) {
00045     std::cout << "Node: " << mkGraph.id(nit) << " ";
00046     if (nit == rootNode->get_node()) std::cout << "root node" << std::endl;
00047     else if (nit == leafNode->get_node()) std::cout << "leaf node" << std::endl;
00048     else if (nodeMap[nit]) std::cout << nodeMap[nit]->get_name() << std::endl;
00049     else std::cout << "(no MeshOp)" << std::endl;
00050   }
00051   for (lemon::ListDigraph::ArcIt ait(mkGraph); ait != lemon::INVALID; ++ait) {
00052     //lemon::ListDigraph::A
00053     lemon::ListDigraph::Node s=mkGraph.source(ait);
00054     lemon::ListDigraph::Node t=mkGraph.target(ait);
00055 
00056     std::cout << "Arc: "<< mkGraph.id(ait)<< " : "<< nodeMap[s]->get_name() << "(" <<  mkGraph.id(s)<< ") - " <<
00057      nodeMap[t]->get_name() << "(" <<  mkGraph.id(t)<< ")\n";
00058   }
00059 
00060   typedef lemon::dim2::Point<int> Point;
00061   lemon::ListDigraph::NodeMap< Point > coords(mkGraph);
00062 
00063   lemon::Bfs<lemon::ListDigraph> bfs(mkGraph);
00064   bfs.init();
00065   bfs.addSource(rootNode->get_node());
00066 
00067   lemon::ListDigraph::NodeMap<std::string> label(mkGraph);
00068 
00069   while (!bfs.emptyQueue()) {
00070     lemon::ListDigraph::Node nd = bfs.processNextNode();
00071     //assert(nd != lemon::INVALID && (nodeMap[nd] || (nd == leafNode->get_node() || nd == rootNode->get_node())));
00072     std::cout << "BFS_Node, distance: " << bfs.dist(nd) << "\n ";
00073     coords[nd]=Point(10*bfs.dist(nd), 10*mkGraph.id(nd));
00074     if (nd == rootNode->get_node())
00075       label[nd]="Root";
00076     else
00077     {
00078       if (nd == leafNode->get_node())
00079         label[nd] = "Leaf";
00080       else
00081         label[nd] = nodeMap[nd]->get_name();
00082     }
00083   }
00084 
00085   std::string filen;
00086   if (filename)
00087     filen=std::string(filename);
00088   else
00089     filen = "graph.eps";
00090 
00091   graphToEps(mkGraph, filen).coords(coords).nodeTexts(label).
00092       nodeTextSize(3).drawArrows().run();
00093 
00094 }
00095 
00096 void MKGraph::print_bfs_graph() 
00097 {
00098   lemon::Bfs<lemon::ListDigraph> bfs(mkGraph);
00099   bfs.init();
00100   bfs.addSource(rootNode->get_node());
00101 
00102   while (!bfs.emptyQueue()) {
00103     lemon::ListDigraph::Node nd = bfs.processNextNode();
00104     assert(nd != lemon::INVALID && (nodeMap[nd] || (nd == leafNode->get_node() || nd == rootNode->get_node())));
00105     std::cout << "BFS_Node, distance: " << bfs.dist(nd) << ", ";
00106     if (nd == rootNode->get_node()) std::cout << "root node" << std::endl;
00107     else if (nd == leafNode->get_node()) std::cout << "leaf node" << std::endl;
00108     else if (nodeMap[nd]) std::cout << nodeMap[nd]->get_name() << std::endl;
00109     else std::cout << "(no MeshOp)" << std::endl;
00110   }
00111 }
00112 
00114 MeshOp *MKGraph::get_meshop(lemon::ListDigraph::Node node) const
00115 {
00116   return dynamic_cast<MeshOp*>(nodeMap[node]);
00117 }
00118   
00119 GraphNode *MKGraph::other_node(lemon::ListDigraph::Arc arc, GraphNode *node) const 
00120 {
00121   lemon::ListDigraph::Node src = mkGraph.source(arc);
00122   if (src != node->get_node()) return get_node(src);
00123   else return get_node(mkGraph.target(arc));
00124 }
00125 
00126 MeshOp *MKGraph::find_meshop(std::string op_name) const
00127 {
00128   GraphNode *node = find_node(op_name);
00129   return node ? dynamic_cast<MeshOp*>(node) : 0;
00130 }
00131     
00132 GraphNode *MKGraph::find_node(std::string op_name) const
00133 {
00134     // run BFS on forward graph
00135   lemon::Bfs<lemon::ListDigraph> bfs(mkGraph);
00136   bfs.init();
00137   bfs.addSource(rootNode->get_node());
00138   while (!bfs.emptyQueue()) {
00139     lemon::ListDigraph::Node nd = bfs.processNextNode();
00140     assert(nd != lemon::INVALID && (nodeMap[nd] || (nd == leafNode->get_node() || nd == rootNode->get_node())));
00141     if (nodeMap[nd] && nodeMap[nd]->get_name() == op_name) return nodeMap[nd];
00142   }
00143   return NULL;
00144 }
00145 
00146 void MKGraph::insert_node(GraphNode *inserted, GraphNode *before, GraphNode *after) 
00147 {
00148     // if inserted is a leaf node (i.e. is connected to leafNode), disconnect from that
00149   if (mkGraph.target(inserted->out_arcs()) == leafNode->get_node())
00150     mkGraph.erase(inserted->out_arcs());
00151 
00152     // if inserted is a root node (i.e. is connected to rootNode), also disconnect that
00153   if (mkGraph.source(inserted->in_arcs()) == rootNode->get_node())
00154     mkGraph.erase(inserted->in_arcs());
00155 
00156   lemon::ListDigraph::InArcIt iter, jter;
00157   if (after != NULL) { // if after is specified
00158     lemon::ListDigraph::Node after_node = after->get_node();
00159 
00160     // check if it is already connected
00161     bool b_connected = false;
00162     for (iter = inserted->in_arcs(); iter != lemon::INVALID; ++iter) {
00163       if (mkGraph.source(iter) == after_node) {
00164         b_connected = true;
00165         break;
00166       }
00167     }
00168     
00169     if (!b_connected) mkGraph.addArc(after_node, inserted->get_node()); // add a new arc
00170 
00171     // remove the arc from after node
00172     for (iter = before->in_arcs(); iter != lemon::INVALID; ++iter) {
00173       if (mkGraph.source(iter) == after_node) {
00174         mkGraph.erase(iter);
00175         break;
00176       }
00177     }
00178   }
00179   else { // check all predecessors
00180     for (iter = before->in_arcs(); iter != lemon::INVALID;) {
00181       lemon::ListDigraph::Node after_node = mkGraph.source(iter);
00182 
00183       // check if it is already connected
00184       bool b_connected = false;
00185       for (jter = inserted->in_arcs(); jter != lemon::INVALID; ++jter) {
00186         if (mkGraph.source(jter) == after_node) {
00187           b_connected = true;
00188           break;
00189         }
00190       }
00191 
00192       if (!b_connected) mkGraph.addArc(after_node, inserted->get_node());  // add a new arc
00193 
00194       jter = iter;
00195       ++iter;
00196       mkGraph.erase(jter); // remove the arc from after node
00197     }
00198   }
00199     
00200     // now link inserted to before
00201   mkGraph.addArc(inserted->get_node(), before->get_node());
00202 
00203   // if before is a root node (i.e. is connected to rootNode), also disconnect that
00204   if (mkGraph.source(before->in_arcs()) == rootNode->get_node())
00205     mkGraph.erase(before->in_arcs());
00206 }
00207 
00208 void MKGraph::add_arc(GraphNode *source, GraphNode *target) 
00209 {
00210     // add an arc from one node to another, e.g. to add a dependency between them
00211     // get the corresponding Lemon nodes
00212   lemon::ListDigraph::Node lsource = source->get_node(), 
00213       ltarget = target->get_node();
00214   
00215     // if inserted is a leaf node (i.e. is connected to leafNode), disconnect from that
00216   if (mkGraph.target(source->out_arcs()) == leafNode->get_node())
00217     mkGraph.erase(source->out_arcs());
00218 
00219     // if before is a root node (i.e. is connected to rootNode), also disconnect that
00220   if (mkGraph.source(target->in_arcs()) == rootNode->get_node())
00221     mkGraph.erase(target->in_arcs());
00222     
00223     // now link them
00224   mkGraph.addArc(lsource, ltarget);
00225 }
00226 
00228 void MKGraph::setup(bool reset)
00229 {
00230     // run BFS on reversed graph
00231   lemon::ReverseDigraph<lemon::ListDigraph> rg(mkGraph);
00232   if (reset)
00233   {
00234     lemon::Bfs<lemon::ReverseDigraph<lemon::ListDigraph> > rbfs1(rg);
00235     rbfs1.init();
00236     rbfs1.addSource(leafNode->get_node());
00237     while (!rbfs1.emptyQueue()) {
00238       lemon::ListDigraph::Node nd = rbfs1.processNextNode();
00239       assert(nd != lemon::INVALID && (nodeMap[nd] || (nd == leafNode->get_node() || nd == rootNode->get_node())));
00240       if (nodeMap[nd]) nodeMap[nd]->setup_called(false);
00241     }
00242   }
00243   bool called_one;
00244   do {
00245     called_one = false;
00246     lemon::Bfs<lemon::ReverseDigraph<lemon::ListDigraph> > rbfs2(rg);
00247     rbfs2.init();
00248     rbfs2.addSource(leafNode->get_node());
00249     while (!rbfs2.emptyQueue()) {
00250       lemon::ListDigraph::Node nd = rbfs2.processNextNode();
00251       assert(nd != lemon::INVALID && (nodeMap[nd] || (nd == leafNode->get_node() || nd == rootNode->get_node())));
00252       if (nodeMap[nd] && !nodeMap[nd]->setup_called()) {
00253         nodeMap[nd]->setup_this();
00254         nodeMap[nd]->setup_called(true);
00255         called_one = true;
00256       }
00257     }
00258   }
00259   while (called_one);
00260 }
00261 
00263 void MKGraph::execute() 
00264 {
00265 
00266   typedef lemon::IterableIntMap<lemon::ListDigraph, lemon::ListDigraph::Node> topomap;
00267 
00268   // Run execute_this on all nodes in topological order
00269   topomap topo_levels( mkGraph ); 
00270   lemon::topologicalSort( mkGraph, topo_levels );
00271 
00272   for( int i = 0; i<topo_levels.size(); ++i){
00273     for( topomap::ItemIt j(topo_levels, i); j != lemon::INVALID; ++j ){
00274       GraphNode* gn = nodeMap[ j ];
00275       assert( gn );
00276       gn->execute_called(false);
00277     }
00278   }
00279   
00280   for( int i = 0; i<topo_levels.size(); ++i){
00281 
00282     for( topomap::ItemIt j(topo_levels, i); j != lemon::INVALID; ++j ){
00283 
00284       GraphNode* gn = nodeMap[ j ];
00285       assert( gn );
00286       if (!gn->execute_called()) {
00287         gn->execute_this();
00288         gn->execute_called(true);
00289       }
00290     }
00291   }
00292 
00293 }
00294 // run execute on all nodes before this node (it may be a second run)
00295 void MKGraph::execute_before(GraphNode * upto)
00296 {
00297 
00298   typedef lemon::IterableIntMap<lemon::ListDigraph, lemon::ListDigraph::Node> topomap;
00299 
00300   // Run execute_this on all nodes in topological order
00301   topomap topo_levels( mkGraph );
00302   int upToId = mkGraph.id(upto->get_node());
00303   lemon::topologicalSort( mkGraph, topo_levels );
00304   for( int i = 0; i<topo_levels.size(); ++i){
00305 
00306     for( topomap::ItemIt j(topo_levels, i); j != lemon::INVALID; ++j ){
00307 
00308       GraphNode* gn = nodeMap[ j ];
00309       assert( gn );
00310       if (mkGraph.id(gn->get_node())==upToId)
00311         return; // stop when we reached our node, do not execute again
00312       if (!gn->execute_called()) {
00313         gn->execute_this();
00314         gn->execute_called(true);
00315       }
00316     }
00317   }
00318 
00319   return;
00320 }
00321 } // namespace MeshKit
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines