ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/addin/outil/src/hypergraphlib_graph.cpp
Revision: 1156
Committed: Thu Jun 13 22:02:48 2024 UTC (14 months, 2 weeks ago) by francois
File size: 15167 byte(s)
Log Message:
compatibilité Ubuntu 22.04
Suppression des refeences à Windows
Ajout d'une banière

File Contents

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