ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/outil/src/HypergraphLib_Graph.cpp
Revision: 113
Committed: Wed Jun 25 18:44:12 2008 UTC (16 years, 10 months ago) by francois
Original Path: magic/lib/outil/outil/src/HypergraphLib_Graph.cpp
File size: 13827 byte(s)
Error occurred while calculating annotation data.
Log Message:
pb de compatibilite windows apres le passage linux de hypergraph

File Contents

# Content
1 #include "gestionversion.h"
2 #ifdef WINDOWS_VERSION
3 #include <iostream>
4 #include <vector>
5 #include <stdarg.h>
6
7 #pragma hdrstop
8
9 #include "HypergraphLib_platform.h"
10
11 #include "HypergraphLib_Graph.h"
12 #include "HypergraphLib_Arc.h"
13 #include "HypergraphLib_Node.h"
14 #include <algorithm>
15
16
17 namespace HypergraphLib{
18
19 Graph::Graph(int __id)
20 : GraphObject(NULL,__id)
21 {
22
23 }
24
25 Graph::~Graph()
26 {
27 for (MapNodesById::const_iterator it=_nodes.begin();
28 it!=_nodes.end();
29 it ++)
30 {
31 Node * node = it->second;
32 delete node;
33 }
34 for (MapArcsById::const_iterator it=_arcs.begin();
35 it!=_arcs.end();
36 it ++)
37 {
38 Arc * arc = it->second;
39 delete arc;
40 }
41 }
42
43 #undef CHECK_INTEGRITY
44
45
46 Graph::Graph(const Graph &__G, int __clone, int __reverse)
47 :GraphObject(NULL, __G.Id())
48 {
49 for (MapNodesById::const_iterator it=__G._nodes.begin();
50 it!=__G._nodes.end();
51 it ++)
52 {
53 Node * copy = new Node(*it->second, this);
54 _nodes [ it->first ] = copy;
55 }
56
57 for (MapArcsById::const_iterator it=__G._arcs.begin();
58 it!=__G._arcs.end();
59 it ++)
60 {
61 Arc * copy = new Arc(*it->second, this);
62 _arcs [ it->first ] = copy;
63 for (Arc::MultimapNodesById::const_iterator it2=copy->Nodes().begin();
64 it2 != copy->Nodes().end(); it2++)
65 {
66 it2->second->Add(copy);
67 }
68 }
69 }
70
71 Graph::Graph(const Graph &__G, const std::set <Node*> & __nodes)
72 :GraphObject(NULL, __G.Id())
73 {
74 for (std::set <Node*>::const_iterator it=__nodes.begin();
75 it!=__nodes.end();
76 it ++)
77 {
78 Node * src = *it;
79 Node * n = AddNode (src->Id());
80 n->SetUserData(src->GetUserData());
81 }
82
83 for (MapArcsById::const_iterator it=__G._arcs.begin();
84 it!=__G._arcs.end();
85 it ++)
86 {
87 std::vector <int> nodesIds;
88
89 Arc * arc = it->second;
90 for (Arc::MultimapNodesById::const_iterator it2=arc->Nodes().begin();
91 it2 != arc->Nodes().end(); it2++)
92 {
93 if (_nodes.find(it2->first) != _nodes.end())
94 {
95 nodesIds.push_back(it2->first);
96 }
97 }
98
99 if (nodesIds.size() > 0)
100 {
101 int id = arc->Id();
102 Arc * a = AddArc(nodesIds, id);
103 a->SetUserData ( arc->GetUserData() );
104 }
105 }
106 }
107
108 Graph::Graph(const Graph &__G, const std::vector <Node*> & __nodes)
109 :GraphObject(NULL, __G.Id())
110 {
111 for (std::vector <Node*>::const_iterator it=__nodes.begin();
112 it!=__nodes.end();
113 it ++)
114 {
115 Node * src = *it;
116 Node * n = AddNode (src->Id());
117 n->SetUserData(src->GetUserData());
118 }
119
120 for (MapArcsById::const_iterator it=__G._arcs.begin();
121 it!=__G._arcs.end();
122 it ++)
123 {
124 std::vector <int> nodesIds;
125
126 Arc * arc = it->second;
127 for (Arc::MultimapNodesById::const_iterator it2=arc->Nodes().begin();
128 it2 != arc->Nodes().end(); it2++)
129 {
130 if (_nodes.find(it2->first) != _nodes.end())
131 {
132 nodesIds.push_back(it2->first);
133 }
134 }
135
136 if (nodesIds.size() > 1)
137 {
138 int id = arc->Id();
139 Arc * a = AddArc(nodesIds, id);
140 a->SetUserData ( arc->GetUserData() );
141 }
142 }
143 }
144
145 Arc * Graph::DuplicateArc(int __id, int __dupId)
146 {
147 Arc * arc = GetArc(__id);
148 return DuplicateArc(arc, __dupId);
149 }
150
151 Arc * Graph::DuplicateArc(Arc * __arc, int __dupId)
152 {
153 return AddArc(__dupId, __arc->Nodes());
154 }
155
156 Node * Graph::GetNode (int __id) const
157 {
158 MapNodesById::const_iterator it = _nodes.find ( __id );
159 if (it != _nodes.end() )
160 {
161 return it->second;
162 }
163 else
164 {
165 return NULL;
166 }
167 }
168
169 Arc * Graph::GetArc (int __id) const
170 {
171 MapArcsById::const_iterator it = _arcs.find ( __id );
172 if (it != _arcs.end() )
173 {
174 return it->second;
175 }
176 else
177 {
178 return NULL;
179 }
180 }
181
182 int Graph::RemoveNode (Node * __node)
183 {
184 MapNodesById::iterator it = _nodes.find ( __node->Id() );
185 if (it != _nodes.end())
186 {
187 // Remove all references of node n in the arcs of the graph
188 for (Node::MultimapArcsById::iterator itArcs = __node->IncidentArcs().begin();
189 itArcs != __node->IncidentArcs().end();
190 itArcs++)
191 {
192 itArcs->second->Remove(__node);
193 }
194 // Free the memory of n
195 delete __node;
196 _nodes.erase ( it );
197 }
198 else
199 {
200 std::cout << "Error: Graph::RemoveNode ( "<<__node->Id()<<" )"<<std::endl;
201 std::cout << "\t the node was not found !\n"<<__node->Id()<<" )"<<std::endl;
202 return -1;
203 }
204 #ifdef CHECK_INTEGRITY
205 CheckIntegrity();
206 #endif
207 return 0;
208 }
209
210 int Graph::RemoveNode (int __id)
211 {
212 MapNodesById::iterator it = _nodes.find ( __id );
213 if (it != _nodes.end())
214 {
215 Node * n = it->second;
216 return RemoveNode(n);
217 }
218 else
219 {
220 std::cout << "Error: Graph::RemoveNode ( "<<__id<<" )"<<std::endl;
221 std::cout << "\t the node was not found !\n"<<__id<<" )"<<std::endl;
222 return -1;
223 }
224 }
225
226 int Graph::RemoveArc (Arc *__arc)
227 {
228 return RemoveArc (__arc->Id());
229 }
230
231 int Graph::RemoveArc (int __id)
232 {
233 MapArcsById::iterator it = _arcs.find ( __id );
234 if (it != _arcs.end())
235 {
236 Arc * tempArc = it->second;
237
238 for (Arc::MultimapNodesById::const_iterator it2=tempArc->Nodes().begin();
239 it2!=tempArc->Nodes().end();it2++)
240 {
241 it2->second->Remove(__id);
242 }
243
244 delete tempArc;
245 _arcs.erase ( it );
246
247 return 0;
248 }
249 else
250 {
251 std::cout << "Error: Graph::RemoveArc ( "<<__id<<" )"<<std::endl;
252 std::cout << "\t the arc was not found !\n"<<__id<<" )"<<std::endl;
253 return -1;
254 }
255 }
256
257
258 Node *
259 Graph::AddNode (int __id)
260 {
261 if (_nodes.find(__id) != _nodes.end())
262 return NULL;
263
264 Node *n = new Node(this, __id);
265 _nodes [ __id ] = n;
266 return n;
267 }
268
269 /*int Graph::CheckFreeNodeId(int __id) const
270 {
271 int id = __id;
272
273 // Verify that the node Id is free
274 MapNodesById::const_iterator it = _nodes.find(id);
275 bool idExists = (it != _nodes.end())?true:false;
276
277 // if the id is not free, then get the first free one
278 if (idExists)
279 {
280 id = GetFirstFreeKey(_nodes);
281 std::cout << "Warning: The Node ID \""<<__id<<"\" already exists !\n";
282 std::cout << "Taking the Free ID \""<<id<<"\" instead\n";
283 }
284 return id;
285 }
286
287 int Graph::CheckFreeArcId(int __id) const
288 {
289 int id = __id;
290
291 // Verify that the arc Id is free
292 MapArcsById::const_iterator it = _arcs.find(id);
293 bool idExists = (it != _arcs.end())?true:false;
294
295 // if the id is not free, then get the first free one
296 if (idExists)
297 {
298 id = GetFirstFreeKey(_arcs);
299 std::cout << "Warning: The Arc ID \""<<__id<<"\" already exists !\n";
300 std::cout << "Taking the Free ID \""<<id<<"\" instead\n";
301 }
302 return id;
303 }*/
304
305 int Graph::GetMaxArcId()
306 {
307 return std::max_element(_arcs.begin(), _arcs.end())->first;
308 }
309
310 int Graph::GetMaxNodeId()
311 {
312 return std::max_element(_nodes.begin(), _nodes.end())->first;
313 }
314
315 Arc *
316 Graph::AddArc(const int __id, int __rank, ...)
317 {
318 if (_arcs.find(__id) != _arcs.end() )
319 return NULL;
320
321 Arc * a = new Arc (this, __id);
322 _arcs [ __id ] = a;
323
324 va_list argp;
325 va_start(argp, __rank);
326
327 for (int i=0;i<__rank;i++)
328 {
329 int nodeId = va_arg(argp, int);
330 Node * n = GetNode(nodeId);
331 a->Add(n);
332 n->Add(a);
333 }
334
335 return a;
336 }
337
338 Arc *
339 Graph::AddArc(const int __id, const Arc::MultimapNodesById & __nodes)
340 {
341 if (_arcs.find(__id) != _arcs.end() )
342 return NULL;
343
344 Arc * a = new Arc (this, __id);
345 _arcs [ __id ] = a;
346
347 for (Arc::MultimapNodesById::const_iterator itNodes = __nodes.begin();
348 itNodes != __nodes.end();
349 itNodes++)
350 {
351 Node * n = itNodes->second;
352 a->Add(n);
353 n->Add(a);
354 }
355
356 return a;
357 }
358
359 Arc * Graph::AddArc (const std::vector <int> & __nodeIds, int __id)
360 {
361 if (_arcs.find(__id) != _arcs.end() )
362 return NULL;
363
364 Arc * a = new Arc (this, __id);
365 _arcs [ __id ] = a;
366
367 for (unsigned int i=0;i<__nodeIds.size();i++)
368 {
369 int nodeId = __nodeIds[i];
370 Node * n = GetNode(nodeId);
371 a->Add(n);
372 n->Add(a);
373 }
374
375 return a;
376 }
377
378
379 Node*
380 Graph::MergeNodes(int __A, int __B, int __id, bool __keepNodes)
381 {
382 Node * A = GetNode(__A);
383 Node * B = GetNode(__B);
384
385 return MergeNodes(A, B, __id, __keepNodes);
386 }
387
388 /**
389 Merge two nodes.
390
391 This merge is implemented by creating a new node C, and
392 replacing node A by node C in all arcs incident to A, and
393 node B by node C in all arcs incident to B.
394
395 (If there exist two arcs X--A and X--B, it *will* result two
396 parallel arcs X--C. Any arc A--B will result in a loop-arc
397 C--C).
398
399 Then nodes A and B will be removed from the graph.
400 */
401 Node*
402 Graph::MergeNodes(Node *__A, Node *__B, int __id, bool __keepNodes)
403 {
404 Node::MultimapArcsById incidentArcs;
405
406 for (Node::MultimapArcsById::const_iterator it = __A->IncidentArcs().begin();
407 it != __A->IncidentArcs().end();
408 it++)
409 {
410 incidentArcs.insert(std::pair<int,Arc*>(it->first,it->second));
411 }
412
413 for (Node::MultimapArcsById::iterator it = __B->IncidentArcs().begin();
414 it != __B->IncidentArcs().end();
415 it++)
416 {
417 incidentArcs.insert(std::pair<int,Arc*>(it->first,it->second));
418 }
419
420 if (!__keepNodes)
421 {
422 RemoveNode(__A);
423 RemoveNode(__B);
424 }
425
426 Node * C = this->AddNode(__id);
427
428 for (Node::MultimapArcsById::iterator it = incidentArcs.begin();
429 it != incidentArcs.end();
430 it++)
431 {
432 it->second->Add(C);
433 C->Add(it->second);
434 }
435
436 return C;
437 }
438
439 void Graph::CheckIntegrity()const
440 {
441 // * * each incident arc of each node must exist in the graph
442 for (HypergraphLib::Graph::MapNodesById::const_iterator it=GetNodes().begin();
443 it != GetNodes().end(); it++)
444 {
445 for (HypergraphLib::Node::MultimapArcsById::const_iterator it2=it->second->IncidentArcs().begin();
446 it2!=it->second->IncidentArcs().end();it2++)
447 {
448 int id=it2->second->Id();
449 Arc * arcInGraph = GetArc(id);
450 if (arcInGraph != it2->second)
451 std::cerr << "Error: The incident Arc "<<id<<" of node "<<it->second->Id()<<"is not referenced in the graph"<<std::endl;
452 }
453 }
454
455 // * * each node of the arcs must exist in the graph
456 for (HypergraphLib::Graph::MapArcsById::const_iterator it=GetArcs().begin();
457 it != GetArcs().end(); it++)
458 {
459 for (HypergraphLib::Arc::MultimapNodesById::const_iterator it2=it->second->Nodes().begin();
460 it2!=it->second->Nodes().end();it2++)
461 {
462 int id=it2->second->Id();
463 Node * nodeInGraph = GetNode(id);
464 if (nodeInGraph != it2->second)
465 std::cerr << "Error: The Node "<<id<<" of arc "<<it->first<<"is not referenced in the graph"<<std::endl;
466 }
467 }
468
469 // * * each node of each arc must reference this arc
470 for (HypergraphLib::Graph::MapNodesById::const_iterator it=GetNodes().begin();
471 it != GetNodes().end(); it++)
472 {
473 for (HypergraphLib::Node::MultimapArcsById::const_iterator it2=it->second->IncidentArcs().begin();
474 it2!=it->second->IncidentArcs().end();it2++)
475 {
476 int nodeC=it2->second->NodeCount(it->first);
477 int arcC=it->second->ArcCount(it2->first);
478 if (nodeC != arcC)
479 {
480 std::cerr << "Error: the Arc->NodeCount("<<it->first<<")="<<nodeC<<""<<std::endl;
481 std::cerr << "is not equal to the Node->ArcCount("<<it2->first<<")="<<arcC<<""<<std::endl;
482 }
483 }
484 }
485
486 // * * each incident arc of each node must reference this node
487
488 for (HypergraphLib::Graph::MapArcsById::const_iterator it2=GetArcs().begin();
489 it2 != GetArcs().end(); it2++)
490 {
491 for (HypergraphLib::Arc::MultimapNodesById::const_iterator it=it2->second->Nodes().begin();
492 it!=it2->second->Nodes().end();it++)
493 {
494 int nodeC=it2->second->NodeCount(it->first);
495 int arcC=it->second->ArcCount(it2->first);
496 if (nodeC != arcC)
497 {
498 std::cerr << "Error: the Arc->NodeCount("<<it->first<<")="<<nodeC<<""<<std::endl;
499 std::cerr << "is not equal to the Node->ArcCount("<<it2->first<<")="<<arcC<<""<<std::endl;
500 }
501 }
502 }
503 }
504
505 bool Graph::IsCycle() const
506 {
507 if (_nodes.size() != _arcs.size())
508 return false;
509 for (HypergraphLib::Graph::MapArcsById::const_iterator it2=GetArcs().begin();
510 it2 != GetArcs().end(); it2++)
511 if (it2->second->Rank() != 2)
512 return false;
513 return true;
514 }
515
516
517 bool Graph::IsCycle (const std::vector < Node * > & __nodes) const
518 {
519 if (__nodes.size () < 2 ) return false;
520
521 //unsigned nb_nodes_having_2_neighbours = 0;
522
523 const unsigned N = __nodes.size();
524
525 for (unsigned i=0; i<N; i++)
526 {
527 Node * n = __nodes[i];
528 //unsigned nb_neighbours=0;
529 int i_previous = i-1;
530 if (i_previous < 0) i_previous += N;
531 Node *n_previous = __nodes[i_previous];
532 int i_next = (i+1)%N;
533 Node *n_next = __nodes[i_next];
534
535 Arc * arc1 = n->IsAdjacentToNode(n_next);
536 Arc * arc2 = n->IsAdjacentToNode(n_previous);
537
538 if ( arc1 && arc2 && arc1 != arc2 )
539 {
540 if (n_next == n_previous)
541 {
542 if (n->GetNbArcsToNode(n_previous) < 2)
543 return false;
544 else
545 continue;
546 }
547 }
548 else
549 return false;
550 }
551 return true;
552 }
553
554 }
555 #endif
556