MAGiC  V5.0
Mailleurs Automatiques de Géometries intégrés à la Cao
hypergraphlib_findcycles.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_findcycles.cpp
15 //####//
16 //####//------------------------------------------------------------
17 //####//------------------------------------------------------------
18 //####// COPYRIGHT 2000-2024
19 //####// jeu 13 jun 2024 11:53:59 EDT
20 //####//------------------------------------------------------------
21 //####//------------------------------------------------------------
22 #include "hypergraphlib_platform.h"
23 
25 #include "hypergraphlib_node.h"
26 #include "hypergraphlib_arc.h"
27 #include "hypergraphlib_graph.h"
28 #include <algorithm>
29 #include <iostream>
30 
31 #undef DEBUG
32 
33 namespace HypergraphLib {
34 
35 int find_n( std::vector < Node * > & __depthFirstSearchNodes, Node *__n)
36 {
37  for (unsigned i=0; i<__depthFirstSearchNodes.size(); i++)
38  if (__depthFirstSearchNodes[i] == __n)
39  return i;
40  return -1;
41 }
42 
43 int find_n( std::vector < Arc * > & __depthFirstSearchArcs, Arc *__a)
44 {
45  for (unsigned i=0; i<__depthFirstSearchArcs.size(); i++)
46  if (__depthFirstSearchArcs[i] == __a)
47  return i;
48  return -1;
49 }
50 
58 int does_cycle_already_exist( const std::vector < std::vector < Node * > > & cycles, const std::vector < Node * > & cycle)
59 {
60  for (unsigned i = 0; i < cycles.size(); i++)
61  {
62  for (unsigned j=0; j<cycles[i].size(); j++)
63  {
64  std::vector < Node * >::const_iterator it = std::find(cycle.begin(), cycle.end(), cycles[i][j]);
65  if (it == cycle.end())
66  goto not_equal_cycles;
67  }
68  if (cycles[i].size() == cycle.size())
69  {
70 #ifdef DEBUG
71  std::cout << "Cycle \"";
72  for (int j=0; j<cycle.size(); j++)
73  std::cout << cycle[j]->Id() << ", ";
74  std::cout << "\" matches cycle ";
75  for (int j=0; j<cycles[i].size(); j++)
76  std::cout << cycles[i][j]->Id() << ", ";
77  std::cout << std::endl;
78 #endif
79  }
80  else if (cycles[i].size() > cycle.size())
81  {
82 #ifdef DEBUG
83  std::cout << "the candidate cycle \"";
84  for (int j=0; j<cycle.size(); j++)
85  std::cout << cycle[j]->Id() << ", ";
86  std::cout << "\" is shorter than the cycle \"";
87  for (int j=0; j<cycles[i].size(); j++)
88  std::cout << cycles[i][j]->Id() << ", ";
89  std::cout << "\"";
90  std::cout << std::endl;
91 #endif
92  return i;
93  }
94  else
95  {
96 #ifdef DEBUG
97  std::cout << "the candidate cycle \"";
98  for (int j=0; j<cycle.size(); j++)
99  std::cout << cycle[j]->Id() << ", ";
100  std::cout << "\" is longer than the cycle \"";
101  for (int j=0; j<cycles[i].size(); j++)
102  std::cout << cycles[i][j]->Id() << ", ";
103  std::cout << "\"";
104  std::cout << std::endl;
105 #endif
106  }
107  return -1;
108 not_equal_cycles:
109  continue;
110  }
111 #ifdef DEBUG
112  std::cout << "Cycle \"";
113  for (int j=0; j<cycle.size(); j++)
114  std::cout << cycle[j]->Id() << ", ";
115  std::cout << "\" is a new cycle "<< std::endl;
116 #endif
117 
118  return -2;
119 }
120 
121 void
122 dfsCycle(Node *__n, std::vector < Node * > & __depthFirstSearchNodes, std::vector< Arc * > & __depthFirstSearchArcs, std::vector < std::vector < Node * > > & cycles )
123 {
124  std::set < Node * > adj;
125  __n->AdjacentNodes( adj );
126  std::vector<Node*>::iterator it3;
127 
128  //int pos_n;
129  if (__depthFirstSearchNodes.size() == 0)
130  __depthFirstSearchNodes.push_back(__n);
131 
132  for ( Node::MultimapArcsById::iterator itIncidentArcs = __n->IncidentArcs().begin();
133  itIncidentArcs != __n->IncidentArcs().end();
134  itIncidentArcs++ )
135  {
136  Arc * incidentArc = itIncidentArcs->second;
137  for ( Arc::MultimapNodesById::iterator itAdjNodes = incidentArc->Nodes().begin();
138  itAdjNodes != incidentArc->Nodes().end();
139  itAdjNodes++)
140  {
141  Node * adjNode = itAdjNodes->second;
142  std::vector < Node * > tempPath = __depthFirstSearchNodes;
143  std::vector < Arc * > tempPathArcs = __depthFirstSearchArcs;
144 
145  if (__n->Owner()->IsCycle(tempPath))
146  {
147  //std::vector < Node * > cycle;
148  //for (int i=0; i<tempPath.size(); i++)
149  // cycle.push_back(tempPath[i]);
150  int is_cycle_exists = does_cycle_already_exist(cycles, tempPath);
151  // if the cycle does not exists
152  if (is_cycle_exists == -2)
153  cycles.push_back(tempPath);
154  // if a shorter cycle exists : replace the long cycle with the short cycle
155  if (is_cycle_exists > 0)
156  {
157  cycles [is_cycle_exists] = tempPath;
158  }
159  //tempPath = __depthFirstSearchNodes;
160  }
161  else if ( find_n(__depthFirstSearchNodes, adjNode) == -1 && find_n(__depthFirstSearchArcs, incidentArc) == -1)
162  {
163  tempPath.push_back(adjNode);
164  tempPathArcs.push_back(incidentArc);
165  dfsCycle (adjNode, tempPath, tempPathArcs, cycles);
166  }
167  }
168  }
169 }
170 
171 
172 void
173 FindCycles(Graph * __G, std::vector < std::vector < Node * > > & cycles)
174 {
175  std::vector < Node * > depthFirstSearchNodes;
176  std::vector < Arc * > depthFirstSearchArcs;
177 
178  GRAPH_FOR_EACH_NODE_CONST(__G, startNode)
179  {
180  depthFirstSearchNodes.clear();
181  dfsCycle (startNode->second, depthFirstSearchNodes, depthFirstSearchArcs, cycles);
182  }
183 }
184 }
185 
hypergraphlib_findcycles.h
hypergraphlib_arc.h
HypergraphLib::Arc
Definition: hypergraphlib_arc.h:37
HypergraphLib::FindCycles
void FindCycles(Graph *__G, std::vector< std::vector< Node * > > &cycles)
Definition: hypergraphlib_findcycles.cpp:173
GRAPH_FOR_EACH_NODE_CONST
#define GRAPH_FOR_EACH_NODE_CONST(G, N)
Definition: hypergraphlib_graph.h:41
HypergraphLib
Definition: hypergraphlib_arc.cpp:32
hypergraphlib_graph.h
HypergraphLib::Node::IncidentArcs
MultimapArcsById & IncidentArcs()
Definition: hypergraphlib_node.h:53
hypergraphlib_platform.h
HypergraphLib::Node::AdjacentNodes
void AdjacentNodes(std::set< int > &__adjacentNodes)
Definition: hypergraphlib_node.cpp:73
HypergraphLib::Node
Definition: hypergraphlib_node.h:35
HypergraphLib::dfsCycle
void dfsCycle(Node *__n, std::vector< Node * > &__depthFirstSearchNodes, std::vector< Arc * > &__depthFirstSearchArcs, std::vector< std::vector< Node * > > &cycles)
Definition: hypergraphlib_findcycles.cpp:122
HypergraphLib::find_n
int find_n(std::vector< Node * > &__depthFirstSearchNodes, Node *__n)
Definition: hypergraphlib_findcycles.cpp:35
hypergraphlib_node.h
HypergraphLib::GraphObject::Owner
const Graph * Owner() const
Definition: hypergraphlib_graphobject.cpp:52
HypergraphLib::does_cycle_already_exist
int does_cycle_already_exist(const std::vector< std::vector< Node * > > &cycles, const std::vector< Node * > &cycle)
Definition: hypergraphlib_findcycles.cpp:58
HypergraphLib::Arc::Nodes
MultimapNodesById & Nodes()
Definition: hypergraphlib_arc.cpp:97
HypergraphLib::Graph::IsCycle
bool IsCycle() const
Definition: hypergraphlib_graph.cpp:524