MeshKit
1.0
|
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