1
1
#include "symmetry.h"
14
typedef map<int,class TrieNode> Map;
21
TrieNode(IntegerVector const &v, int i)
24
m[v[i]]=TrieNode(v,i+1);
26
int stabilizerSize(IntegerVector const &v, int i)const
29
if(i==v.size())return 1;
30
for(Map::const_iterator j=m.begin();j!=m.end();j++)
33
ret+=j->second.stabilizerSize(v,i+1);
37
void search(IntegerVector const &v, IntegerVector &building, IntegerVector &tempPerm, IntegerVector &ret, IntegerVector &optimal, int i, bool &isImproving)const
39
if(i==v.size()){ret=tempPerm;optimal=building;isImproving=false;return;}
41
building[i]=-0x7fffffff;
43
building[i]=optimal[i];
44
for(Map::const_iterator j=m.begin();j!=m.end();j++)
45
if(v[j->first]>building[i])
48
building[i]=v[j->first];
50
for(Map::const_iterator j=m.begin();j!=m.end();j++)
51
if(v[j->first]==building[i])
54
j->second.search(v,building,tempPerm,ret,optimal,i+1,isImproving);
57
void searchStabalizer(IntegerVector const &v, IntegerVector &building, IntegerVector &tempPerm, IntegerVector &ret, IntegerVector &optimal, int i, bool &isImproving, IntegerVector const &toBeFixed)const
60
if(!(SymmetryGroup::compose(tempPerm,v)<optimal))
63
optimal=SymmetryGroup::compose(tempPerm,v);
66
for(Map::const_iterator j=m.begin();j!=m.end();j++)
67
if(toBeFixed[i]==toBeFixed[j->first])
70
j->second.searchStabalizer(v,building,tempPerm,ret,optimal,i+1,isImproving,toBeFixed);
73
/* this code contains mistakes void searchStabalizer(IntegerVector const &v, IntegerVector &building, IntegerVector &tempPerm, IntegerVector &ret, IntegerVector &optimal, int i, bool &isImproving, IntegerVector const &toBeFixed)const
75
if(i==v.size()){ret=tempPerm;optimal=building;isImproving=false;debug<<"DEEP";return;}
77
building[i]=-0x7fffffff;
79
building[i]=optimal[i];
80
for(Map::const_iterator j=m.begin();j!=m.end();j++)
81
if(toBeFixed[i]==toBeFixed[j->first])
82
if(v[j->first]>building[i])
85
building[i]=v[j->first];
87
for(Map::const_iterator j=m.begin();j!=m.end();j++)
88
if(toBeFixed[i]==toBeFixed[j->first])
89
if(v[j->first]==building[i])
91
debug.printInteger(i);debug<<":";
92
debug.printInteger(j->first);debug<<" ";
94
j->second.searchStabalizer(v,building,tempPerm,ret,optimal,i+1,isImproving,toBeFixed);
97
// void doubleSearch();
98
void insert(IntegerVector const &v, int i)
100
if(i==v.size())return;
102
m[v[i]].insert(v,i+1);
104
m[v[i]]= TrieNode(v,i+1);
106
void print(int i, int n)const
109
for(Map::const_iterator j=m.begin();j!=m.end();j++)
111
{for(int j=0;j<2*i;j++)debug<<" ";}
112
debug.printInteger(j->first);
114
j->second.print(i+1,n);
117
int size(int i,int n)const
121
for(Map::const_iterator j=m.begin();j!=m.end();j++)
122
ret+=j->second.size(i+1,n);
131
theTree(SymmetryGroup::identity(n_),0)
136
return theTree.size(0,n);
138
void insert(IntegerVector const &v)
142
// theTree.print(0,v.size());
144
// debug<<"---------------------------------------------\n";
147
* returns the sigma from the set with sigma(v) maximal in the lexicographic ordering.
149
IntegerVector search(IntegerVector const &v)
151
IntegerVector tempPerm(v.size());
152
IntegerVector ret(v.size());
153
IntegerVector building(v.size());
154
IntegerVector optimal=v;//the identity is always in the trie
155
bool isImproving=true;
156
theTree.search(v,building,tempPerm,ret,optimal,0,isImproving);
159
IntegerVector searchStabalizer(IntegerVector const &v, IntegerVector const &toBeFixed)
161
IntegerVector tempPerm=SymmetryGroup::identity(v.size());
162
IntegerVector ret(v.size());
163
IntegerVector building(v.size());
164
IntegerVector optimal=v;//the identity is always in the trie
165
bool isImproving=true;
166
theTree.searchStabalizer(v,building,tempPerm,ret,optimal,0,isImproving,toBeFixed);
169
int stabilizerSize(IntegerVector const &v)const
171
return theTree.stabilizerSize(v,0);
5
181
IntegerVector SymmetryGroup::identity(int n)
377
IntegerVector SymmetryGroup::orbitRepresentative(IntegerVector const &v, IntegerVector *usedPermutation)const
382
*usedPermutation=trie->search(v);
383
return compose(*usedPermutation,v);
385
return compose(trie->search(v),v);
388
ElementContainer::const_iterator usedPerm;
389
for(ElementContainer::const_iterator i=elements.begin();i!=elements.end();i++)
391
IntegerVector q=compose(*i,v);
392
if(! (q<ret))//negation to make sure that usedPerm is set
399
if(usedPermutation)*usedPermutation=*usedPerm;
403
// debug<<"Input"<<v<<"\n";
404
// debug<<"Bruteforce"<<ret<<"\n";
405
IntegerVector triePerm=trie->search(v);
406
// debug<<"Trie"<<compose(triePerm,v)<<"\n";
407
assert((compose(triePerm,v)-ret).isZero());
413
IntegerVector SymmetryGroup::orbitRepresentativeFixing(IntegerVector const &v, IntegerVector const &fixed)const
416
return compose(trie->searchStabalizer(v,fixed),v);
420
for(ElementContainer::const_iterator i=elements.begin();i!=elements.end();i++)
421
if(compose(*i,fixed)==fixed)
423
IntegerVector q=compose(*i,v);
427
IntegerVector temp=compose(trie->searchStabalizer(v,fixed),v);
428
// debug<<"Input"<<v;
429
// debug<<"Brute"<<ret;
430
// debug<<"Quick"<<temp;
431
assert((temp-ret).isZero());
432
// return compose(trie->searchStabalizer(v,fixed),v);
437
bool SymmetryGroup::isPermutation(IntegerVector const &a)
440
IntegerVector temp(n);
441
for(int i=0;i<n;i++)temp[i]=-1;
444
if(a[i]<0 || a[i]>=n)return false;
447
for(int i=0;i<n;i++)if(temp[i]<0)return false;
452
IntegerVector SymmetryGroup::combinePermutationAndSignChanges(IntegerVector const &permutation, IntegerVector const &signChanges)
454
assert(isPermutation(permutation));
455
int n=permutation.size();
456
assert(n==signChanges.size());
457
IntegerVector ret(2*n);
459
if(signChanges[i]==1)
461
ret[i]=permutation[i];
462
ret[i+n]=n+permutation[i];
466
ret[i]=n+permutation[i];
467
ret[i+n]=permutation[i];
472
void SymmetryGroup::extractPermuationAndSignChanges(IntegerVector const &v, IntegerVector &permutation, IntegerVector &signChanges)
475
permutation=IntegerVector(n);
476
signChanges=IntegerVector(n);
480
permutation[i]=v[i]%n;
489
int SymmetryGroup::orbitSize(IntegerVector const &stable)const
491
int groupSize=elements.size();
498
numFixed=trie->stabilizerSize(stable);
502
for(SymmetryGroup::ElementContainer::const_iterator j=elements.begin();j!=elements.end();j++)
507
if(stable[i]!=stable[(*j)[i]])
512
if(doesFix)numFixed++;
515
return groupSize/numFixed;
519
IntegerVector SymmetryGroup::fundamentalDomainInequality(IntegerVector const &perm)
521
for(int i=0;i<perm.size();i++)
523
return IntegerVector::standardVector(perm.size(),i)-IntegerVector::standardVector(perm.size(),perm[i]);
524
// return -IntegerVector::standardVector(perm.size(),i)-IntegerVector::standardVector(perm.size(),perm[i]);//USE this for 4x4 of 5x5
525
return IntegerVector(perm.size());
529
IntegerVectorList SymmetryGroup::fundamentalDomainInequalities()const
531
set<IntegerVector> ret2;
532
for(ElementContainer::const_iterator i=elements.begin();i!=elements.end();i++)
533
ret2.insert(fundamentalDomainInequality(*i));
535
IntegerVectorList ret;
536
for(set<IntegerVector>::const_iterator i=ret2.begin();i!=ret2.end();i++)
537
if(!i->isZero())ret.push_back(*i);
543
void SymmetryGroup::createByteTable()
546
int n=sizeOfBaseSet();
547
byteTableHeight=elements.size();
548
byteTable=(unsigned char*)malloc(n*byteTableHeight*sizeof(unsigned char));
551
for(ElementContainer::const_iterator i=elements.begin();i!=elements.end();i++,j++)
554
byteTable[j*n+k]=(*i)[k];
558
void SymmetryGroup::createTrie()
560
log1 debug<<"Creating symmetry trie.\n";
561
trie=new Trie(sizeOfBaseSet());
562
for(ElementContainer::const_iterator i=elements.begin();i!=elements.end();i++)
564
log2 debug<<"Number of elements";log2 debug.printInteger(trie->size());log2 debug<<"\n";
565
log1 debug<<"Done creating symmetry trie.\n";
569
unsigned char * SymmetryGroup::getByteTable()const
575
int SymmetryGroup::getByteTableHeight()const
577
return byteTableHeight;
581
bool SymmetryGroup::isTrivial()const
583
ElementContainer::const_iterator i=elements.begin();
584
assert(i!=elements.end());
586
return i==elements.end();
589
static int mergeSortRek(IntegerVector &v, int begin, int end, IntegerVector &temp)
591
if(end-begin<2)return 0;
592
int med=(begin+end)>>1;
593
int nswaps=mergeSortRek(v,begin,med,temp);
594
nswaps+=mergeSortRek(v,med,end,temp);
598
int Alength=med-begin;
604
// debug<<"Astart:"<<Astart<<"Alength:"<<Alength<<"Bstart:"<<Bstart<<"Blength:"<<Blength<<"nextFree:"<<nextFree<<"\n";
605
if(Blength==0 || (Alength!=0 && v[Astart]<v[Bstart]))
607
temp[nextFree++]=v[Astart++];
612
temp[nextFree++]=v[Bstart++];
617
for(int i=begin;i!=end;i++)v[i]=temp[i];
623
int mergeSort(IntegerVector &v)
625
IntegerVector temp(v.size());
626
return mergeSortRek(v,0,v.size(),temp);