-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfhl_tail.cc
67 lines (63 loc) · 1.6 KB
/
fhl_tail.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include "fhl_tail.h"
class FurstHopcroftLuksTail {
typedef std::pair<Permutation,Permutation> team;
Group G;
Group H;
std::vector<std::set<team>> reps;
int n;
bool filter( Permutation, bool add = true );
public:
FurstHopcroftLuks() : G( nullptr ), H( nullptr ) {}
void create( Group groupG, Group groupH, std::deque<team> seed );
};
void FurstHopcroftLuksTail::create( Group groupG, Group groupH, std::deque<team> seed ) {
G = groupG;
H = groupH;
n = G->degree();
reps.resize( n );
for( auto& rep : reps )
reps.emplace( G.one(), H.one() );
bool change = true;
for( auto& p : seed )
filter( p );
std::vector<std::vector<team>> old_pass( n );
std::vector<std::vector<team>> new_pass;
while( change ) {
new_pass.resize( n );
for( int i = 0; i < _n; i++ )
for( int j = 0; j < n; j++ )
for( auto a : old_pass[i] )
for( auto b : reps[j] )
change |= filter(make_pair(a.first*b.first,a.second*b.second));
old_pass = std::move( new_pass );
}
}
bool FurstHopcroftLuksTail::filter( team alpha, bool add ) {
for( int i = 0; i < _n; i++ ) {
bool found = false;
for( const auto& sigma : reps[i] ) {
team tau = make_pair( sigma.first.inverse() * alpha.first, sigma.second.inverse() * alpha.second );
bool doesFix = true;
for( int j = 0; j <= i; j++ ) {
if( (tau.first)(j) != j ) {
doesFix = false;
break;
}
}
if( doesFix ) {
alpha = std::move( tau );
found = true;
break;
}
}
if( !found ) {
if( reps[i].count( alpha ) == 0 ) {
if( add )
reps[i].insert( alpha );
return true;
} else
return false;
}
}
return false;
}