ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/outil/src/HypergraphLib_FindCycles.cpp
Revision: 253
Committed: Tue Jul 13 19:40:46 2010 UTC (14 years, 10 months ago) by francois
File size: 4990 byte(s)
Error occurred while calculating annotation data.
Log Message:
changement de hiearchie et utilisation de ccmake + mise a jour

File Contents

# Content
1 #include "gestionversion.h"
2 #include "HypergraphLib_platform.h"
3
4 #include "HypergraphLib_FindCycles.h"
5 #include "HypergraphLib_Node.h"
6 #include "HypergraphLib_Arc.h"
7 #include "HypergraphLib_Graph.h"
8 #include <algorithm>
9 #include <iostream>
10
11 #undef DEBUG
12
13 namespace HypergraphLib {
14
15 int find_n( std::vector < Node * > & __depthFirstSearchNodes, Node *__n)
16 {
17 for (unsigned i=0; i<__depthFirstSearchNodes.size(); i++)
18 if (__depthFirstSearchNodes[i] == __n)
19 return i;
20 return -1;
21 }
22
23 int find_n( std::vector < Arc * > & __depthFirstSearchArcs, Arc *__a)
24 {
25 for (unsigned i=0; i<__depthFirstSearchArcs.size(); i++)
26 if (__depthFirstSearchArcs[i] == __a)
27 return i;
28 return -1;
29 }
30
31 /**
32 * returns :
33 * -2 if the cycle does not exist
34 * -1 if the cycle exist
35 * j if the cycle at index j is longer than the new one
36 */
37
38 int does_cycle_already_exist( const std::vector < std::vector < Node * > > & cycles, const std::vector < Node * > & cycle)
39 {
40 for (unsigned i = 0; i < cycles.size(); i++)
41 {
42 for (unsigned j=0; j<cycles[i].size(); j++)
43 {
44 std::vector < Node * >::const_iterator it = std::find(cycle.begin(), cycle.end(), cycles[i][j]);
45 if (it == cycle.end())
46 goto not_equal_cycles;
47 }
48 if (cycles[i].size() == cycle.size())
49 {
50 #ifdef DEBUG
51 std::cout << "Cycle \"";
52 for (int j=0; j<cycle.size(); j++)
53 std::cout << cycle[j]->Id() << ", ";
54 std::cout << "\" matches cycle ";
55 for (int j=0; j<cycles[i].size(); j++)
56 std::cout << cycles[i][j]->Id() << ", ";
57 std::cout << std::endl;
58 #endif
59 }
60 else if (cycles[i].size() > cycle.size())
61 {
62 #ifdef DEBUG
63 std::cout << "the candidate cycle \"";
64 for (int j=0; j<cycle.size(); j++)
65 std::cout << cycle[j]->Id() << ", ";
66 std::cout << "\" is shorter than the cycle \"";
67 for (int j=0; j<cycles[i].size(); j++)
68 std::cout << cycles[i][j]->Id() << ", ";
69 std::cout << "\"";
70 std::cout << std::endl;
71 #endif
72 return i;
73 }
74 else
75 {
76 #ifdef DEBUG
77 std::cout << "the candidate cycle \"";
78 for (int j=0; j<cycle.size(); j++)
79 std::cout << cycle[j]->Id() << ", ";
80 std::cout << "\" is longer than the cycle \"";
81 for (int j=0; j<cycles[i].size(); j++)
82 std::cout << cycles[i][j]->Id() << ", ";
83 std::cout << "\"";
84 std::cout << std::endl;
85 #endif
86 }
87 return -1;
88 not_equal_cycles:
89 continue;
90 }
91 #ifdef DEBUG
92 std::cout << "Cycle \"";
93 for (int j=0; j<cycle.size(); j++)
94 std::cout << cycle[j]->Id() << ", ";
95 std::cout << "\" is a new cycle "<< std::endl;
96 #endif
97
98 return -2;
99 }
100
101 void
102 dfsCycle(Node *__n, std::vector < Node * > & __depthFirstSearchNodes, std::vector< Arc * > & __depthFirstSearchArcs, std::vector < std::vector < Node * > > & cycles )
103 {
104 std::set < Node * > adj;
105 __n->AdjacentNodes( adj );
106 std::vector<Node*>::iterator it3;
107
108 //int pos_n;
109 if (__depthFirstSearchNodes.size() == 0)
110 __depthFirstSearchNodes.push_back(__n);
111
112 for ( Node::MultimapArcsById::iterator itIncidentArcs = __n->IncidentArcs().begin();
113 itIncidentArcs != __n->IncidentArcs().end();
114 itIncidentArcs++ )
115 {
116 Arc * incidentArc = itIncidentArcs->second;
117 for ( Arc::MultimapNodesById::iterator itAdjNodes = incidentArc->Nodes().begin();
118 itAdjNodes != incidentArc->Nodes().end();
119 itAdjNodes++)
120 {
121 Node * adjNode = itAdjNodes->second;
122 std::vector < Node * > tempPath = __depthFirstSearchNodes;
123 std::vector < Arc * > tempPathArcs = __depthFirstSearchArcs;
124
125 if (__n->Owner()->IsCycle(tempPath))
126 {
127 //std::vector < Node * > cycle;
128 //for (int i=0; i<tempPath.size(); i++)
129 // cycle.push_back(tempPath[i]);
130 int is_cycle_exists = does_cycle_already_exist(cycles, tempPath);
131 // if the cycle does not exists
132 if (is_cycle_exists == -2)
133 cycles.push_back(tempPath);
134 // if a shorter cycle exists : replace the long cycle with the short cycle
135 if (is_cycle_exists > 0)
136 {
137 cycles [is_cycle_exists] = tempPath;
138 }
139 //tempPath = __depthFirstSearchNodes;
140 }
141 else if ( find_n(__depthFirstSearchNodes, adjNode) == -1 && find_n(__depthFirstSearchArcs, incidentArc) == -1)
142 {
143 tempPath.push_back(adjNode);
144 tempPathArcs.push_back(incidentArc);
145 dfsCycle (adjNode, tempPath, tempPathArcs, cycles);
146 }
147 }
148 }
149 }
150
151
152 void
153 FindCycles(Graph * __G, std::vector < std::vector < Node * > > & cycles)
154 {
155 std::vector < Node * > depthFirstSearchNodes;
156 std::vector < Arc * > depthFirstSearchArcs;
157
158 GRAPH_FOR_EACH_NODE_CONST(__G, startNode)
159 {
160 depthFirstSearchNodes.clear();
161 dfsCycle (startNode->second, depthFirstSearchNodes, depthFirstSearchArcs, cycles);
162 }
163 }
164 }
165