PhoenixGraph  01.0.0
Set of tools to simplify graph manipulation
Loading...
Searching...
No Matches
Graph_impl.h
Go to the documentation of this file.
1/***************************************
2 Auteur : Pierre Aubert
3 Mail : pierre.aubert@lapp.in2p3.fr
4 Licence : CeCILL-C
5****************************************/
6
7#ifndef __GRAPH_H_IMPL__
8#define __GRAPH_H_IMPL__
9
10#include <stdlib.h>
11#include <iostream>
12
13#include "Graph.h"
14
16template<typename T, typename UIdx>
20
22
24template<typename T, typename UIdx>
26 copyGraph(other);
27}
28
30template<typename T, typename UIdx>
34
36
39template<typename T, typename UIdx>
41 copyGraph(other);
42 return *this;
43}
44
46
49template<typename T, typename UIdx>
50bool Graph<T, UIdx>::savePng(const std::string & fileNamePng) const{
51 if(fileNamePng == "") return false;
52 std::string fileTxt("output.dot");
53 if(!saveDot(fileTxt)){
54 std::cerr << "Graph<T, UIdx>::savePng : can't create file '" << fileTxt << "'" << std::endl;
55 return false;
56 }
57 std::string commande("dot -Tpng -o " + fileNamePng + " " + fileTxt + " && rm " + fileTxt);
58 if(system(commande.c_str()) != 0){
59 std::cerr << "Graph<T, UIdx>::savePng : can't create png file '" << fileNamePng << "'" << std::endl;
60 return false;
61 }
62 return true;
63}
64
66
68template<typename T, typename UIdx>
69bool Graph<T, UIdx>::saveDot(const std::string & fileName) const{
70 if(fileName == ""){return false;}
71 std::ofstream fs;
72 fs.open(fileName.c_str());
73 if(!fs.is_open()){
74 std::cerr << "Graph<T, UIdx>::saveDot : can't open file '" << fileName << "'" << std::endl;
75 return false;
76 }
77 bool b(saveDot(fs));
78 fs.close();
79 return b;
80}
81
83
85template<typename T, typename UIdx>
86bool Graph<T, UIdx>::saveDot(std::ofstream & fs) const{
87 fs << toDot();
88 return true;
89}
90
92
94template<typename T, typename UIdx>
95std::string Graph<T, UIdx>::toDot() const{
96 std::string body("");
97 body += "digraph G{\n";
98 //save the node definition
99 for(typename std::map<UIdx, Node<T, UIdx> >::const_iterator it(p_mapNode.begin()); it != p_mapNode.end(); ++it){
100 body += it->second.getDotDefinition();
101 }
102 //save the connections between nodes
103 for(typename std::map<UIdx, Node<T, UIdx> >::const_iterator itNode(p_mapNode.begin()); itNode != p_mapNode.end(); ++itNode){
104 const std::string & parentNodeName(itNode->second.getDotName());
105 const std::list<UIdx> & listChild = itNode->second.getListChild();
106 for(typename std::list<UIdx>::const_iterator it(listChild.begin()); it != listChild.end(); ++it){
107 const Node<T, UIdx> * childNode = getNode(*it);
108 if(childNode == NULL){continue;}
109 const std::string & childNodeName(childNode->getDotName());
110 body += "\t" + parentNodeName + " -> " + childNodeName + "[color=\"red\"];\n";
111 }
112 }
113 body += "}\n\n";
114 return body;
115}
116
118
122template<typename T, typename UIdx>
123UIdx Graph<T, UIdx>::createNode(const T & data, const std::string & name){
124 UIdx nodeIndex(p_mapNode.size());
125 while(getNode(nodeIndex) != NULL){
126 ++nodeIndex;
127 }
128 Node<T, UIdx> node(data, name);
129 node.setIndex(nodeIndex);
130 p_mapNode[nodeIndex] = node;
131 return nodeIndex;
132}
133
135
139template<typename T, typename UIdx>
140Node<T, UIdx> * Graph<T, UIdx>::createNodePtr(const T & data, const std::string & name){
141 UIdx node = createNode(data, name);
142 return getNode(node);
143}
144
146
151template<typename T, typename UIdx>
152bool Graph<T, UIdx>::createNode(const T & data, const UIdx & index, const std::string & name){
153 if(getNode(index) != NULL){ //Check if the Node already exists
154 return false;
155 }
156 Node<T, UIdx> node(data, name);
157 node.setIndex(index);
158 p_mapNode[index] = node;
159 return true;
160}
161
163
168template<typename T, typename UIdx>
169Node<T, UIdx> * Graph<T, UIdx>::createNodePtr(const T & data, const UIdx & index, const std::string & name){
170 if(createNode(data, index, name)){
171 return getNode(index);
172 }else{
173 return NULL;
174 }
175}
176
178template<typename T, typename UIdx>
180 for(typename std::map<UIdx, Node<T, UIdx> >::iterator it(p_mapNode.begin()); it != p_mapNode.end(); ++it){
181 it->second.setIsUpdated(false);
182 }
183}
184
186template<typename T, typename UIdx>
188
190template<typename T, typename UIdx>
192
194template<typename T, typename UIdx>
196
197//Clear all Node
198template<typename T, typename UIdx>
204
206
209template<typename T, typename UIdx>
210void Graph<T, UIdx>::removeNode(UIdx index, bool reconnectParentToChildren){
211 Node<T, UIdx> * indexNode = getNode(index);
212 if(indexNode == NULL){return;} //If the Node does not exist, we stop
213 //Get the parents of the current Node
214 std::list<UIdx> & listParent = indexNode->getListParent();
215 if(listParent.size() != 0lu){
216 //Tell them they do not have child anymore
217 for(typename std::list<UIdx>::iterator it(listParent.begin()); it != listParent.end(); ++it){
218 Node<T, UIdx> * parentNode = getNode(*it);
219 if(parentNode == NULL){continue;}
220 parentNode->removeChild(index);
221 }
222 }else{
223 //Let's remove the current Node from first Node
225 }
226 //Get the children of the current Node
227 std::list<UIdx> & listChild = indexNode->getListChild();
228 if(listChild.size() != 0lu){
229 //Tell them they do not have parent anymore
230 for(typename std::list<UIdx>::iterator it(listChild.begin()); it != listChild.end(); ++it){
231 Node<T, UIdx> * childNode = getNode(*it);
232 if(childNode == NULL){continue;}
233 childNode->removeParent(index);
234 }
235 }else{
236 //Let's remove the current Node from last Node
238 }
239 if(reconnectParentToChildren && listParent.size() != 0lu && listChild.size() != 0lu){
240 for(typename std::list<UIdx>::iterator it(listParent.begin()); it != listParent.end(); ++it){
241 connectNode(*it, listChild);
242 }
243 }
244 //Now, let's remove the current Node
245 p_mapNode.erase(index);
246}
247
249template<typename T, typename UIdx>
253 for(typename std::map<UIdx, Node<T, UIdx> >::iterator itNode(p_mapNode.begin()); itNode != p_mapNode.end(); ++itNode){
254 if(itNode->second.isStart()){ //If the Node does not have any parent, it is a first Node
255 p_listFirstNode.push_back(itNode->first);
256 }
257 if(itNode->second.isEnd()){ //If the Node does not have any child, it is a last Node
258 p_listLastNode.push_back(itNode->first);
259 }
260 }
261}
262
264
267template<typename T, typename UIdx>
268void Graph<T, UIdx>::connectNode(UIdx parent, UIdx child){
269 Node<T, UIdx> * parentNode = getNode(parent);
270 if(parentNode == NULL){return;}
271 Node<T, UIdx> * childNode = getNode(child);
272 if(childNode == NULL){return;}
273 parentNode->addChild(child);
274 childNode->addParent(parent);
275}
276
278
281template<typename T, typename UIdx>
282void Graph<T, UIdx>::connectNode(UIdx parent, const std::list<UIdx> & listChildren){
283 Node<T, UIdx> * parentNode = getNode(parent);
284 if(parentNode == NULL){return;}
285 for(typename std::list<UIdx>::const_iterator it(listChildren.begin()); it != listChildren.end(); ++it){
286 UIdx child = *it;
287 Node<T, UIdx> * childNode = getNode(child);
288 if(childNode == NULL){continue;}
289 parentNode->addChild(child);
290 childNode->addParent(parent);
291 }
292}
293
295
298template<typename T, typename UIdx>
299void Graph<T, UIdx>::connectNode(UIdx parent, const std::vector<UIdx> & vecChildren){
300 Node<T, UIdx> * parentNode = getNode(parent);
301 if(parentNode == NULL){return;}
302 for(typename std::vector<UIdx>::const_iterator it(vecChildren.begin()); it != vecChildren.end(); ++it){
303 UIdx child = *it;
304 Node<T, UIdx> * childNode = getNode(child);
305 if(childNode == NULL){continue;}
306 parentNode->addChild(child);
307 childNode->addParent(parent);
308 }
309}
310
312
315template<typename T, typename UIdx>
316const Node<T, UIdx> * Graph<T, UIdx>::getNode(UIdx index) const{
317 typename std::map<UIdx, Node<T, UIdx> >::const_iterator it(p_mapNode.find(index));
318 if(it != p_mapNode.end()){
319 return &(it->second);
320 }else{
321 return NULL;
322 }
323}
324
326
329template<typename T, typename UIdx>
331 typename std::map<UIdx, Node<T, UIdx> >::iterator it(p_mapNode.find(index));
332 if(it != p_mapNode.end()){
333 return &(it->second);
334 }else{
335 return NULL;
336 }
337}
338
340
342template<typename T, typename UIdx>
344 for(typename std::map<UIdx, Node<T, UIdx> >::const_iterator itNode(p_mapNode.begin()); itNode != p_mapNode.end(); ++itNode){
345 if(!itNode->second.getIsUpdated()){
346 return &(itNode->second);
347 }
348 }
349 return NULL;
350}
351
353
355template<typename T, typename UIdx>
357 for(typename std::map<UIdx, Node<T, UIdx> >::iterator itNode(p_mapNode.begin()); itNode != p_mapNode.end(); ++itNode){
358 if(!itNode->second.getIsUpdated()){
359 return &(itNode->second);
360 }
361 }
362 return NULL;
363}
364
366
369template<typename T, typename UIdx>
370bool Graph<T, UIdx>::isNodeExist(UIdx index) const{
371 typename std::map<UIdx, Node<T, UIdx> >::iterator it(p_mapNode.find(index));
372 return it != p_mapNode.end();
373}
374
376
378template<typename T, typename UIdx>
379size_t Graph<T, UIdx>::size() const{
380 return p_mapNode.size();
381}
382
384
386template<typename T, typename UIdx>
387const std::list<UIdx> & Graph<T, UIdx>::getListFirstNode() const{
388 return p_listFirstNode;
389}
390
392
394template<typename T, typename UIdx>
395const std::list<UIdx> & Graph<T, UIdx>::getListLastNode() const{
396 return p_listLastNode;
397}
398
400
403template<typename T, typename UIdx>
404bool Graph<T, UIdx>::iterateChildren(std::list<UIdx> & listNode) const{
405 if(listNode.size() == 0lu){
406 listNode = getListFirstNode();
407 }else{
408 std::map<UIdx, bool> mapListChildren;
409 for(typename std::list<UIdx>::iterator itNode(listNode.begin()); itNode != listNode.end(); ++itNode){
410 const Node<T, UIdx> * node = getNode(*itNode);
411 if(node != NULL){
412 const std::list<UIdx> & listChildren = node->getListChild();
413 for(typename std::list<UIdx>::const_iterator it(listChildren.begin()); it != listChildren.end(); ++it){
414 mapListChildren[*it] = true;
415 }
416 }
417 }
418 std::list<UIdx> listNodeOut;
419 for(typename std::map<UIdx, bool>::iterator it(mapListChildren.begin()); it != mapListChildren.end(); ++it){
420 listNodeOut.push_back(it->first);
421 }
422 listNode = listNodeOut;
423 }
424 return listNode.size() != 0lu;
425}
426
428
431template<typename T, typename UIdx>
432bool Graph<T, UIdx>::iterateParent(std::list<UIdx> & listNode) const{
433 if(listNode.size() == 0lu){
434 listNode = getListLastNode();
435 }else{
436 std::map<UIdx, bool> mapListParent;
437 for(typename std::list<UIdx>::iterator itNode(listNode.begin()); itNode != listNode.end(); ++itNode){
438 const Node<T, UIdx> * node = getNode(*itNode);
439 if(node != NULL){
440 const std::list<UIdx> & listParent = node->getListParent();
441 for(typename std::list<UIdx>::const_iterator it(listParent.begin()); it != listParent.end(); ++it){
442 mapListParent[*it] = true;
443 }
444 }
445 }
446 std::list<UIdx> listNodeOut;
447 for(typename std::map<UIdx, bool>::iterator it(mapListParent.begin()); it != mapListParent.end(); ++it){
448 listNodeOut.push_back(it->first);
449 }
450 listNode = listNodeOut;
451 }
452 return listNode.size() != 0lu;
453}
454
456
459template<typename T, typename UIdx>
460bool Graph<T, UIdx>::isListNodeUdpated(const std::list<UIdx> & listNode) const{
461 bool b(true);
462 for(typename std::list<UIdx>::const_iterator itNode(listNode.begin()); itNode != listNode.end() && b; ++itNode){
463 const Node<T, UIdx> * node = getNode(*itNode);
464 if(node != NULL){
465 b &= node->getIsUpdated();
466 }
467 }
468 return b;
469}
470
472
475template<typename T, typename UIdx>
476bool Graph<T, UIdx>::iterateChildrenCheckUpdate(std::list<UIdx> & listNode){
477 if(listNode.size() == 0lu){
479 listNode = getListFirstNode();
480 }else{
481 std::map<UIdx, bool> mapListChildren;
482 for(typename std::list<UIdx>::iterator itNode(listNode.begin()); itNode != listNode.end(); ++itNode){
483 Node<T, UIdx> * node = getNode(*itNode);
484 if(node != NULL){
485 node->setIsUpdated(true); //This node has been iterated, so we do not want to pick it as a child
486 std::list<UIdx> & listChildren = node->getListChild();
487 for(typename std::list<UIdx>::iterator it(listChildren.begin()); it != listChildren.end(); ++it){
488 Node<T, UIdx> * nodeChild = getNode(*it);
489 if(nodeChild != NULL){
490 if(!nodeChild->getIsUpdated()){
491 //The child node is added only if its parents are updated
492 if(isListNodeUdpated(nodeChild->getListParent())){
493 mapListChildren[*it] = true;
494 nodeChild->setIsUpdated(true);
495 }
496 }
497 }
498 }
499 }
500 }
501 std::list<UIdx> listNodeOut;
502 for(typename std::map<UIdx, bool>::iterator it(mapListChildren.begin()); it != mapListChildren.end(); ++it){
503 listNodeOut.push_back(it->first);
504 }
505 listNode = listNodeOut;
506 }
507 return listNode.size() != 0lu;
508}
509
511
514template<typename T, typename UIdx>
515bool Graph<T, UIdx>::iterateParentCheckUpdate(std::list<UIdx> & listNode){
516 if(listNode.size() == 0lu){
518 listNode = getListLastNode();
519 }else{
520 std::map<UIdx, bool> mapListParent;
521 for(typename std::list<UIdx>::iterator itNode(listNode.begin()); itNode != listNode.end(); ++itNode){
522 Node<T, UIdx> * node = getNode(*itNode);
523 if(node != NULL){
524 node->setIsUpdated(true); //This node has been iterated, so we do not want to pick it as a parent
525 std::list<UIdx> & listParent = node->getListParent();
526 for(typename std::list<UIdx>::iterator it(listParent.begin()); it != listParent.end(); ++it){
527 Node<T, UIdx> * nodeParent = getNode(*it);
528 if(nodeParent != NULL){
529 if(!nodeParent->getIsUpdated()){
530 //The parent node is added only if its children are updated
531 if(isListNodeUdpated(nodeParent->getListChild())){
532 mapListParent[*it] = true;
533 nodeParent->setIsUpdated(true);
534 }
535 }
536 }
537 }
538 }
539 }
540 std::list<UIdx> listNodeOut;
541 for(typename std::map<UIdx, bool>::iterator it(mapListParent.begin()); it != mapListParent.end(); ++it){
542 listNodeOut.push_back(it->first);
543 }
544 listNode = listNodeOut;
545 }
546 return listNode.size() != 0lu;
547}
548
550
552template<typename T, typename UIdx>
558
560template<typename T, typename UIdx>
564
565
566
567
568
569#endif
570
571
572
UIdx createNode(const T &data, const std::string &name)
Create a node and get its index.
Definition Graph_impl.h:123
void initialisationGraph()
Initialisation function of the class Graph.
Definition Graph_impl.h:561
bool savePng(const std::string &fileNamePng) const
Save a png file of the graph.
Definition Graph_impl.h:50
void updateFirstLastNode()
Update the first and last Node of the Graph.
Definition Graph_impl.h:250
bool isListNodeUdpated(const std::list< UIdx > &listNode) const
Check if the list of given nodes are all updated or not.
Definition Graph_impl.h:460
bool iterateParent(std::list< UIdx > &listNode) const
Iterate from children to parents.
Definition Graph_impl.h:432
bool saveDot(const std::string &fileName) const
Save the Graph in a dot file.
Definition Graph_impl.h:69
void removeNode(UIdx index, bool reconnectParentToChildren=false)
Remove a Node from the Graph.
Definition Graph_impl.h:210
size_t size() const
Get the number of nodes inside the graph.
Definition Graph_impl.h:379
bool iterateChildrenCheckUpdate(std::list< UIdx > &listNode)
Iterate from parents to chidren (all node are iterated only once)
Definition Graph_impl.h:476
Graph()
Default constructeur of Graph.
Definition Graph_impl.h:17
void clearAll()
Definition Graph_impl.h:199
const Node< T, UIdx > * getNode(UIdx index) const
Get a Node by pointer.
Definition Graph_impl.h:316
Node< T, UIdx > * createNodePtr(const T &data, const std::string &name)
Create a node and get its pointer.
Definition Graph_impl.h:140
const std::list< UIdx > & getListFirstNode() const
Get the list of the first nodes (without parent)
Definition Graph_impl.h:387
Graph & operator=(const Graph< T, UIdx > &other)
Definition of equal operator of Graph.
Definition Graph_impl.h:40
bool iterateChildren(std::list< UIdx > &listNode) const
Iterate from parents to chidren.
Definition Graph_impl.h:404
std::map< UIdx, Node< T, UIdx > > p_mapNode
Map of the Node.
Definition Graph.h:78
bool isNodeExist(UIdx index) const
Say if the node at index does exit.
Definition Graph_impl.h:370
const std::list< UIdx > & getListLastNode() const
Get the list of the last nodes (without child)
Definition Graph_impl.h:395
std::list< UIdx > p_listFirstNode
List of the first Node (without parent)
Definition Graph.h:80
std::list< UIdx > p_listLastNode
List of the last Node (without child)
Definition Graph.h:82
std::string toDot() const
Convert the graph to dot language.
Definition Graph_impl.h:95
void copyGraph(const Graph< T, UIdx > &other)
Copy function of Graph.
Definition Graph_impl.h:553
void clearMapNode()
Clear the map of Node.
Definition Graph_impl.h:187
const Node< T, UIdx > * getFirstNotUpdatedNode() const
Get the first node which is not udpated (getIsUpdated() == false)
Definition Graph_impl.h:343
void clearIsUpdated()
Clear the isUpdated attriburte of the Node.
Definition Graph_impl.h:179
void connectNode(UIdx parent, UIdx child)
Connect a parent to its child.
Definition Graph_impl.h:268
void clearFirstNode()
Clear the list of first Node.
Definition Graph_impl.h:191
bool iterateParentCheckUpdate(std::list< UIdx > &listNode)
Iterate from children to parents (all node are iterated only once)
Definition Graph_impl.h:515
void clearLastNode()
Clear the list of last Node.
Definition Graph_impl.h:195
virtual ~Graph()
Destructeur of Graph.
Definition Graph_impl.h:31
Node of a Graph.
Definition Node.h:17
const std::list< UIdx > & getListParent() const
Get the list of parents of the Node.
Definition Node_impl.h:164
void setIsUpdated(bool isUpdated)
Say if the node is updated.
Definition Node_impl.h:140
std::string getDotName() const
Get the dot name of the current Node.
Definition Node_impl.h:230
void removeParent(UIdx parent)
Remove connection with parent.
Definition Node_impl.h:108
void addChild(UIdx child)
Add a child to the current Node.
Definition Node_impl.h:84
const std::list< UIdx > & getListChild() const
Get the list of children of the Node.
Definition Node_impl.h:152
void setIndex(UIdx index)
Set the index of the Node.
Definition Node_impl.h:128
void addParent(UIdx parent)
Add a parent to the current Node.
Definition Node_impl.h:92
bool getIsUpdated() const
Say if the node is updated.
Definition Node_impl.h:194
void removeChild(UIdx child)
Remove connection with child.
Definition Node_impl.h:100
void listindex_remove(std::list< UIdx > &listIndex, UIdx index)
Remove index from listIndex.