1 |
#include "gestionversion.h" |
2 |
#include "HypergraphLib_platform.h"
|
3 |
|
4 |
#include "HypergraphLib_Graph.h"
|
5 |
#include "HypergraphLib_Node.h"
|
6 |
#include "HypergraphLib_Arc.h"
|
7 |
|
8 |
#include <set>
|
9 |
#include <vector>
|
10 |
#include <map>
|
11 |
|
12 |
|
13 |
/**
|
14 |
* Algorithme de décomposition d'un graphe en filaments
|
15 |
*/
|
16 |
|
17 |
namespace HypergraphLib {
|
18 |
|
19 |
HYPERGRAPHLIB_ITEM void
|
20 |
Filaments ( Graph * G, std::vector < std::vector < int > > & __filaments )
|
21 |
{
|
22 |
std::set <int> visited;
|
23 |
std::set <int> next;
|
24 |
std::vector <int> filament;
|
25 |
std::set <int> unvisited;
|
26 |
std::set <int> adjacentNodes;
|
27 |
|
28 |
// Initialize the set of unvisited nodes
|
29 |
for (Graph::MapNodesById::const_iterator itNodes = G->GetNodes().begin();
|
30 |
itNodes != G->GetNodes().end();
|
31 |
itNodes++ )
|
32 |
{
|
33 |
unvisited.insert (itNodes->first);
|
34 |
}
|
35 |
|
36 |
while (unvisited.size() > 0)
|
37 |
{
|
38 |
Node * N = G->GetNode(*(unvisited.begin()));
|
39 |
for (std::set<int>::const_iterator itAN = unvisited.begin();
|
40 |
itAN != unvisited.end();
|
41 |
itAN++ )
|
42 |
{
|
43 |
Node * N2 = G->GetNode(*itAN);
|
44 |
if (N2->IncidentArcs().size() == 1)
|
45 |
{
|
46 |
N = N2;
|
47 |
break;
|
48 |
}
|
49 |
}
|
50 |
|
51 |
visited.insert(N->Id());
|
52 |
unvisited.erase(unvisited.find(N->Id()));
|
53 |
next.clear();
|
54 |
adjacentNodes.clear();
|
55 |
N->AdjacentNodes(adjacentNodes);
|
56 |
for (std::set<int>::const_iterator itAN = adjacentNodes.begin();
|
57 |
itAN != adjacentNodes.end();
|
58 |
itAN++ )
|
59 |
{
|
60 |
if ( visited.find (*itAN) == visited.end() )
|
61 |
{
|
62 |
next.insert (*itAN);
|
63 |
break;
|
64 |
}
|
65 |
}
|
66 |
filament.clear();
|
67 |
filament.push_back (N->Id());
|
68 |
|
69 |
while (next.size() > 0)
|
70 |
{
|
71 |
N = G->GetNode(*(next.begin()));
|
72 |
visited.insert(N->Id());
|
73 |
unvisited.erase(unvisited.find(N->Id()));
|
74 |
adjacentNodes.clear();
|
75 |
next.clear();
|
76 |
filament.push_back (N->Id());
|
77 |
|
78 |
N->AdjacentNodes(adjacentNodes);
|
79 |
for (std::set<int>::const_iterator itAN = adjacentNodes.begin();
|
80 |
itAN != adjacentNodes.end();
|
81 |
itAN++ )
|
82 |
{
|
83 |
// printf("Candidate node %d\n",*itAN);
|
84 |
if ( visited.find (*itAN) == visited.end() )
|
85 |
{
|
86 |
int count_filament_adjacency = 0;
|
87 |
std::vector<int>::const_iterator it_fil = filament.begin();
|
88 |
bool is_adjacent_to_start=false;
|
89 |
bool is_adjacent_to_end=false;
|
90 |
Node * fN=NULL;
|
91 |
|
92 |
it_fil = filament.begin();
|
93 |
fN = G->GetNode (*it_fil);
|
94 |
is_adjacent_to_start = fN->IsAdjacentToNode(*itAN);
|
95 |
|
96 |
|
97 |
it_fil = filament.end();it_fil--;
|
98 |
fN = G->GetNode (*it_fil);
|
99 |
is_adjacent_to_end = fN->IsAdjacentToNode(*itAN);
|
100 |
|
101 |
for ( it_fil = filament.begin();
|
102 |
it_fil != filament.end(); it_fil++)
|
103 |
{
|
104 |
fN = G->GetNode (*it_fil);
|
105 |
if (fN->IsAdjacentToNode(*itAN))
|
106 |
count_filament_adjacency++;
|
107 |
}
|
108 |
it_fil = filament.end();it_fil--;
|
109 |
// printf("count_filament_adjacency = %d, is_adjacent_to_(%d)=%d\n", count_filament_adjacency,*it_fil,is_adjacent_to_end);
|
110 |
it_fil = filament.begin();
|
111 |
// printf("is_adjacent_to_(%d)=%d\n",*it_fil,is_adjacent_to_start);
|
112 |
|
113 |
bool is_not_T = true;
|
114 |
if ( is_adjacent_to_end && is_adjacent_to_start)
|
115 |
{
|
116 |
|
117 |
for ( it_fil = filament.begin();
|
118 |
it_fil != filament.end(); it_fil++)
|
119 |
{
|
120 |
fN = G->GetNode (*it_fil);
|
121 |
for ( Node::MultimapArcsById::const_iterator itArcs = fN->IncidentArcs().begin();
|
122 |
itArcs != fN->IncidentArcs().end();
|
123 |
itArcs++ )
|
124 |
{
|
125 |
Arc * arc = itArcs->second;
|
126 |
|
127 |
if ( arc->Nodes().find(*itAN) != arc->Nodes().end()
|
128 |
&& arc->Nodes().find(filament[0]) != arc->Nodes().end()
|
129 |
&& arc->Nodes().find(filament[filament.size()-1]) != arc->Nodes().end() )
|
130 |
{
|
131 |
is_not_T = false;
|
132 |
}
|
133 |
}
|
134 |
}
|
135 |
|
136 |
}
|
137 |
|
138 |
if (count_filament_adjacency == 1 || ( is_adjacent_to_end && is_adjacent_to_start && is_not_T) )
|
139 |
{
|
140 |
next.insert (*itAN);
|
141 |
// printf("Candidate Node %d choosen!\n", *itAN);
|
142 |
break;
|
143 |
}
|
144 |
}
|
145 |
}
|
146 |
}
|
147 |
__filaments.push_back(filament);
|
148 |
}
|
149 |
|
150 |
}
|
151 |
} |
152 |
|