@@ -105,124 +105,109 @@ bool Transform::matchStar(const Star& src, const Star& dst,
105
105
if (srcEdges.size () > dstEdges.size ()) {
106
106
std::cout << " Not injective" << std::endl;
107
107
return false ;
108
- }
108
+ }
109
+
110
+ // Calcul le matching de deux graphes biparti en temps
111
+ // polynomial. Utilise le concepte de couplage et de
112
+ // chemins alternés augmentant
109
113
110
- // Liste les liens possibles des atomes voisins
111
- // de src avec les atomes voisins de dst
112
- // links[i] correspond au i-ème atome dans srcEdge[i]
113
- // Les indices des atomes voisins de dst dans links[i] j
114
- // correspondent aux atomes j-ième atome dans dstEdge[j]
115
- std::vector< std::vector<size_t > > links;
114
+ // Construit le graphe biparti
115
+ // srcLinks[i] correspond à srcEdges[i]
116
+ // contient la liste des indices des atomes
117
+ // correspondant à dstEdges[j]
118
+ // dstLinks[i] correspond à dstEdges[i]
119
+ // contient la liste des indices des atomes
120
+ // correspondant à srcEdges[j]
121
+ std::vector< std::vector<size_t > > srcLinks (srcEdges.size ());
122
+ std::vector< std::vector<size_t > > dstLinks (dstEdges.size ());
116
123
117
- // Parcours les voisins de src et dst pour
118
- // remplir links
119
124
for (size_t i=0 ;i<srcEdges.size ();i++) {
120
- links.push_back (std::vector<size_t >());
121
125
for (size_t j=0 ;j<dstEdges.size ();j++) {
122
126
if (
123
127
_graph.getVertex (srcEdges[i])
124
128
->isRepresent (
125
129
_graph.getVertex (dstEdges[j]))
126
130
) {
127
- links[links.size ()-1 ].push_back (j);
131
+ srcLinks[i].push_back (j);
132
+ dstLinks[j].push_back (i);
128
133
}
129
134
}
130
135
// Test si tous les atomes voisins de src
131
136
// ont au moins un atome voisin de dst
132
137
// qui lui correspond
133
- if (links[links. size ()- 1 ].size () == 0 ) {
138
+ if (srcLinks[i ].size () == 0 ) {
134
139
std::cout << " No represent" << std::endl;
135
140
return false ;
136
141
}
137
142
}
138
- assert (links.size () == srcEdges.size ());
139
-
140
- // Contient pour chaque atomes voisins de src l'indice
141
- // du voisin de dst auquel il est lié
142
- // association[i]=j correspond à srdEdges[i] et j
143
- // correspond ) dstEdges[links[i][j]]
144
- std::vector<size_t > associations;
145
-
146
- // Contient pour chaque atomes voisins de dst non
147
- // exclut un booleen indiquant si l'atomes est utilisé (lié)
148
- // dans le tableau d'association
149
- // used[i] correspond à dstEdges[i]
150
- std::vector<bool > used;
143
+
144
+ // Contient pour les atomes src et dst l'atome de l'autre
145
+ // coté au quel il est lié. -1 si pas de liaison
146
+ std::vector<size_t > srcMatching (srcEdges.size (), -1 );
147
+ std::vector<size_t > dstMatching (dstEdges.size (), -1 );
151
148
152
- // Initialise associations avec les premières
153
- // valeurs possibles dans links pour tous les atomes
154
- for (size_t i=0 ;i<links.size ();i++) {
155
- associations.push_back (0 );
149
+ // Initialise le couplage pour chaque atomes src si possible
150
+ for (size_t i=0 ;i<srcEdges.size ();i++) {
151
+ for (size_t j=0 ;j<srcLinks[i].size ();j++) {
152
+ if (dstMatching[srcLinks[i][j]] != -1 ) {
153
+ assert (srcMatching[i] == -1 );
154
+ srcMatching[i] = srcLinks[i][j];
155
+ dstMatching[srcLinks[i][j]] = i;
156
+ break ;
157
+ }
158
+ }
156
159
}
157
- assert (associations.size () == srcEdges.size ());
158
160
159
- // Initialise les états de used à non
160
- // utilisé
161
- for (size_t i=0 ;i<dstEdges.size ();i++) {
162
- used.push_back (false );
163
- }
164
- assert (used.size () == dstEdges.size ());
161
+ // Défini une liste pour le parcours en largeur
162
+ std::list<size_t > bfs;
165
163
166
- while (true ) {
167
- std::cout << " >>> loop " << std::endl;
168
- // Reset les valeurs de used
169
- for (size_t i=0 ;i<used.size ();i++) {
170
- used[i] = false ;
171
- }
172
- // Test si la configuration est valide
173
- bool matched = true ;
174
- for (size_t i=0 ;i<associations.size ();i++) {
175
- // On regarde si un voisins de dst est utilisé
176
- // deux fois
177
- if (used[links[i][associations[i]]] == true ) {
178
- // La configuration est invalide, on sort de la
179
- // boucle
180
- matched = false ;
181
- break ;
182
- } else {
183
- // La configuration est valide pour le moment
184
- used[links[i][associations[i]]] = true ;
164
+ // Applique l'algorithme tant qu'un chemin améliorant
165
+ // est trouvé
166
+ bool changed = true ;
167
+ while (changed) {
168
+ changed = false ;
169
+ // On recherche un sommets de src non saturé
170
+ for (size_t i=0 ;i<srcEdges.size ();i++) {
171
+ if (srcMatching[i] == -1 ) {
172
+ // On cherche par un parcours en largeur
173
+ // du graphe un chemin alterné améliorant
174
+ bfs.clear ();
175
+ bfs.push_back (i);
176
+ size_t from = -1 ;
177
+ bool even = true ;
178
+ while () {
179
+ size_t current = bfs.front ();
180
+ bfs.pop_front ();
181
+ if (!event && dstMatching[current] == -1 ) {
182
+ //
183
+ }
184
+ size_t size = even ? srcLinks[current].size () : dstLinks[current].size ();
185
+ for (size_t j=0 ;j<size;j++) {
186
+ size_t index = even ? srcLinks[current][j] : dstLinks[current][j];
187
+ if (index != from) {
188
+ bfs.push_back (index);
189
+ }
190
+ }
191
+ from = current;
192
+ }
193
+ if () {
194
+ changed = true ;
195
+ break ;
196
+ }
185
197
}
186
198
}
187
- // Si la configuration est valide, on sort de la boucle
188
- // d'exploration
189
- // Sinon on incrémente
190
- if (matched) {
191
- std::cout << " Valid !" << std::endl;
192
- break ;
193
- }
194
- // Incrémente de "un" le vecteur
195
- // des associations (itération sur
196
- // toutes les valeurs possibles)
197
- size_t digit = 0 ;
198
- while (true ) {
199
- std::cout << " loop digit " << digit << " (" << links[digit].size () << " ) " << associations[digit] << " " << associations.size () << std::endl;
200
- // On incrémente le digit
201
- associations[digit]++;
202
- // Si on dépasse les valeurs possible
203
- // on retourne à 0 et on continue avec le
204
- // prochain digit
205
- if (associations[digit] == links[digit].size ()) {
206
- associations[digit] = 0 ;
207
- std::cout << " carry true" << std::endl;
208
- }
209
- // Sinon, on sort de la boucle, le vecteur est
210
- // incrémenté
211
- else {
212
- std::cout << " carry false" << std::endl;
213
- break ;
214
- }
215
- digit++;
216
- // Si on a parcourus tous le vecteur
217
- // association, celà veut dire que l'ont a testé
218
- // toutes les valeurs sans résultat
219
- if (digit == associations.size ()) {
220
- std::cout << " Overflow, break" << std::endl;
221
- return false ;
222
- }
199
+ }
200
+
201
+ //
202
+ for (size_t i=0 ;i<srcEdges.size ();i++) {
203
+ if (srcMatching[i] == -1 ) {
204
+ std::cout << " No matching" << std::endl;
205
+ return ;
223
206
}
224
207
}
225
208
209
+ // ...
210
+
226
211
// Les voisins de dst correspondants sont insérés dans
227
212
// matches
228
213
for (size_t i=0 ;i<used.size ();i++) {
0 commit comments