MAGiC  V5.0
Mailleurs Automatiques de Géometries intégrés à la Cao
hypergraphlib_graph.cpp
Aller à la documentation de ce fichier.
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 
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 
325 {
326  return std::max_element(_arcs.begin(), _arcs.end())->first;
327 }
328 
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 
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 
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 
HypergraphLib::GraphObject::GetUserData
void * GetUserData() const
Definition: hypergraphlib_graphobject.cpp:57
HypergraphLib::Graph::RemoveArc
int RemoveArc(int __id)
Definition: hypergraphlib_graph.cpp:250
HypergraphLib::Graph::GetMaxArcId
int GetMaxArcId()
Definition: hypergraphlib_graph.cpp:324
HypergraphLib::Arc::Add
void Add(Node *)
Definition: hypergraphlib_arc.cpp:59
HypergraphLib::Graph::_arcs
MapArcsById _arcs
Definition: hypergraphlib_graph.h:211
HypergraphLib::Graph::MergeNodes
Node * MergeNodes(Node *__A, Node *__B, int __id, bool __keepNodes=false)
Definition: hypergraphlib_graph.cpp:421
hypergraphlib_arc.h
HypergraphLib::Graph::GetNodes
const MapNodesById & GetNodes() const
Definition: hypergraphlib_graph.h:178
HypergraphLib::Arc::MultimapNodesById
std::multimap< int, Node * > MultimapNodesById
Definition: hypergraphlib_arc.h:39
HypergraphLib::Graph::GetMaxNodeId
int GetMaxNodeId()
Definition: hypergraphlib_graph.cpp:329
a
#define a(i, j)
HypergraphLib::Node::IsAdjacentToNode
Arc * IsAdjacentToNode(int __nodeId)
Definition: hypergraphlib_node.cpp:119
HypergraphLib::Graph::GetArc
Arc * GetArc(int) const
Definition: hypergraphlib_graph.cpp:188
HypergraphLib::Arc
Definition: hypergraphlib_arc.h:37
HypergraphLib
Definition: hypergraphlib_arc.cpp:32
hypergraphlib_graph.h
HypergraphLib::Node::GetNbArcsToNode
int GetNbArcsToNode(Node *__other)
Definition: hypergraphlib_node.cpp:134
HypergraphLib::Graph::_nodes
MapNodesById _nodes
Definition: hypergraphlib_graph.h:212
HypergraphLib::Arc::Remove
int Remove(int __id)
Definition: hypergraphlib_arc.cpp:69
HypergraphLib::Graph::DuplicateArc
Arc * DuplicateArc(int __id, int __dupId)
Definition: hypergraphlib_graph.cpp:164
HypergraphLib::Graph::AddArc
Arc * AddArc(const std::vector< int > &, int __id)
Definition: hypergraphlib_graph.cpp:378
HypergraphLib::Node::MultimapArcsById
std::multimap< int, Arc * > MultimapArcsById
Definition: hypergraphlib_node.h:37
HypergraphLib::GraphObject
Definition: hypergraphlib_graphobject.h:31
HypergraphLib::Node::Add
void Add(Arc *)
Definition: hypergraphlib_node.cpp:45
HypergraphLib::Graph::RemoveNode
int RemoveNode(int __id)
Definition: hypergraphlib_graph.cpp:229
HypergraphLib::Graph::GetArcs
const MapArcsById & GetArcs() const
Definition: hypergraphlib_graph.h:171
node
#define node(i, j)
HypergraphLib::GraphObject::Graph
friend class Graph
Definition: hypergraphlib_graphobject.h:45
HypergraphLib::GraphObject::Id
int Id() const
Definition: hypergraphlib_graphobject.cpp:47
HypergraphLib::Graph::AddNode
Node * AddNode(int __id=0)
Definition: hypergraphlib_graph.cpp:278
HypergraphLib::Node::IncidentArcs
MultimapArcsById & IncidentArcs()
Definition: hypergraphlib_node.h:53
hypergraphlib_platform.h
HypergraphLib::Graph::CheckIntegrity
void CheckIntegrity() const
Definition: hypergraphlib_graph.cpp:458
HypergraphLib::Node
Definition: hypergraphlib_node.h:35
HypergraphLib::Graph::~Graph
~Graph()
Definition: hypergraphlib_graph.cpp:44
HypergraphLib::Graph::GetNode
Node * GetNode(int) const
Definition: hypergraphlib_graph.cpp:175
hypergraphlib_node.h
HypergraphLib::GraphObject::SetUserData
void SetUserData(void *)
Definition: hypergraphlib_graphobject.cpp:66
HypergraphLib::Arc::Nodes
MultimapNodesById & Nodes()
Definition: hypergraphlib_arc.cpp:97
HypergraphLib::Graph::IsCycle
bool IsCycle() const
Definition: hypergraphlib_graph.cpp:524