ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/outil/src/HypergraphLib_FindCycles.cpp
Revision: 27
Committed: Thu Jul 5 15:26:40 2007 UTC (17 years, 10 months ago) by foucault
Original Path: magic/lib/outil/outil/src/HypergraphLib_FindCycles.cpp
File size: 4960 byte(s)
Log Message:

File Contents

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