permutation generation outputting explicitly PermutationAlgebra class
This commit is contained in:
parent
0fa4f9fc2e
commit
41e9c359d5
@ -262,7 +262,7 @@ PERM_RANK_TYPE sumperm=0;
|
|||||||
|
|
||||||
p2:
|
p2:
|
||||||
sumperm++;
|
sumperm++;
|
||||||
if(!select || (select&1) == (sumperm&1)) (*callback)(*this);
|
if(callback) {if(!select || (select&1) == (sumperm&1)) {(*callback)(*this); this->copyonwrite();}}
|
||||||
j=n; s=0;
|
j=n; s=0;
|
||||||
p4:
|
p4:
|
||||||
q=c[j]+d[j];
|
q=c[j]+d[j];
|
||||||
@ -284,6 +284,36 @@ end:
|
|||||||
return select? sumperm/2:sumperm;
|
return select? sumperm/2:sumperm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static PermutationAlgebra<T,T> *list_all_return;
|
||||||
|
|
||||||
|
static PERM_RANK_TYPE list_all_index;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static void list_all_callback(const NRPerm<T> &p)
|
||||||
|
{
|
||||||
|
(*list_all_return<T>)[list_all_index].weight= (list_all_index&1)?-1:1;
|
||||||
|
(*list_all_return<T>)[list_all_index].perm=p;
|
||||||
|
(*list_all_return<T>)[list_all_index].perm.copyonwrite();
|
||||||
|
++list_all_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
PermutationAlgebra<T,T> NRPerm<T>::list_all(int parity_sel)
|
||||||
|
{
|
||||||
|
PERM_RANK_TYPE number = factorial(this->size());
|
||||||
|
if(parity_sel) number/=2;
|
||||||
|
PermutationAlgebra<T,T> ret(number);
|
||||||
|
list_all_return<T> = &ret;
|
||||||
|
list_all_index=0;
|
||||||
|
this->generate_all(list_all_callback,parity_sel);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//Algorithm L2 from Knuth's volume 4 for multiset permutations
|
//Algorithm L2 from Knuth's volume 4 for multiset permutations
|
||||||
//input must be initialized with (repeated) numbers in any order
|
//input must be initialized with (repeated) numbers in any order
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -298,7 +328,7 @@ while(1)
|
|||||||
T t;
|
T t;
|
||||||
|
|
||||||
sumperm++;
|
sumperm++;
|
||||||
(*callback)(*this);
|
if(callback) (*callback)(*this);
|
||||||
j=this->size()-1;
|
j=this->size()-1;
|
||||||
while(j>0 && (*this)[j]>=(*this)[j+1]) j--;
|
while(j>0 && (*this)[j]>=(*this)[j+1]) j--;
|
||||||
if(j==0) break; /*finished*/
|
if(j==0) break; /*finished*/
|
||||||
@ -347,7 +377,7 @@ if(n<= _n<T>)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
_sumperm++;
|
_sumperm++;
|
||||||
(*_callback<T>)(*_perm<T>);
|
if(_callback<T>) (*_callback<T>)(*_perm<T>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -373,7 +403,7 @@ PERM_RANK_TYPE np=0;
|
|||||||
this->identity();
|
this->identity();
|
||||||
do{
|
do{
|
||||||
++np;
|
++np;
|
||||||
(*callback)(*this);
|
if(callback) (*callback)(*this);
|
||||||
}while(this->next());
|
}while(this->next());
|
||||||
return np;
|
return np;
|
||||||
}
|
}
|
||||||
@ -429,12 +459,13 @@ if(n<=_n2<T>)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
_sumperm2++;
|
_sumperm2++;
|
||||||
(*_callback2<T>)(*_perm2<T>);
|
if(_callback2<T>) {(*_callback2<T>)(*_perm2<T>); _perm2<T> -> copyonwrite();}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
PERM_RANK_TYPE NRPerm<T>::generate_restricted(void (*callback)(const NRPerm<T>&), const NRVec_from1<T> &classes, int restriction_type)
|
PERM_RANK_TYPE NRPerm<T>::generate_restricted(void (*callback)(const NRPerm<T>&), const NRVec_from1<T> &classes, int restriction_type)
|
||||||
{
|
{
|
||||||
@ -451,6 +482,30 @@ permg2<T>(1);
|
|||||||
return _sumperm2;
|
return _sumperm2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static PermutationAlgebra<T,T> *list_restricted_return;
|
||||||
|
|
||||||
|
static PERM_RANK_TYPE list_restricted_index;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static void list_restricted_callback(const NRPerm<T> &p)
|
||||||
|
{
|
||||||
|
(*list_restricted_return<T>)[list_restricted_index].weight=p.parity();
|
||||||
|
(*list_restricted_return<T>)[list_restricted_index].perm=p;
|
||||||
|
(*list_restricted_return<T>)[list_restricted_index].copyonwrite();
|
||||||
|
++list_restricted_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
PermutationAlgebra<T,T> NRPerm<T>::list_restricted(const NRVec_from1<T> &classes, int restriction_type)
|
||||||
|
{
|
||||||
|
PERM_RANK_TYPE number = this->generate_restricted(NULL,classes,restriction_type);
|
||||||
|
PermutationAlgebra<T,T> ret(number);
|
||||||
|
list_restricted_return<T> = &ret;
|
||||||
|
list_restricted_index=0;
|
||||||
|
generate_restricted(list_restricted_callback,classes,restriction_type);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -1140,7 +1195,7 @@ template <typename T>
|
|||||||
void partgen(int remain, int pos)
|
void partgen(int remain, int pos)
|
||||||
{
|
{
|
||||||
int hi,lo;
|
int hi,lo;
|
||||||
if(remain==0) {++partitioncount; (*_pcallback<T>)(*partition<T>); return;}
|
if(remain==0) {++partitioncount; if(_pcallback<T>) (*_pcallback<T>)(*partition<T>); return;}
|
||||||
if(partitiontyp) lo=(remain+partitiontypabs-pos)/(partitiontypabs-pos+1); else lo=1;
|
if(partitiontyp) lo=(remain+partitiontypabs-pos)/(partitiontypabs-pos+1); else lo=1;
|
||||||
hi=remain;
|
hi=remain;
|
||||||
if(partitiontyp>0) hi -= partitiontypabs-pos;
|
if(partitiontyp>0) hi -= partitiontypabs-pos;
|
||||||
@ -1539,7 +1594,7 @@ if(ncyc> _ncycles<T>)
|
|||||||
{
|
{
|
||||||
if(_callyoung)
|
if(_callyoung)
|
||||||
{
|
{
|
||||||
_young_callback<T>(*_tchi<T>);
|
if(_young_callback<T>) _young_callback<T>(*_tchi<T>);
|
||||||
_character<T> ++;
|
_character<T> ++;
|
||||||
}
|
}
|
||||||
else _character<T> += _tchi<T>->character_contribution(_ncycles<T>);
|
else _character<T> += _tchi<T>->character_contribution(_ncycles<T>);
|
||||||
|
@ -69,10 +69,12 @@ public:
|
|||||||
void randomize(void); //uniformly random by Fisher-Yates shuffle
|
void randomize(void); //uniformly random by Fisher-Yates shuffle
|
||||||
bool next(); //generate next permutation in lex order
|
bool next(); //generate next permutation in lex order
|
||||||
PERM_RANK_TYPE generate_all(void (*callback)(const NRPerm<T>&), int parity_select=0); //Algorithm L from Knuth's vol.4, efficient but not in lex order!
|
PERM_RANK_TYPE generate_all(void (*callback)(const NRPerm<T>&), int parity_select=0); //Algorithm L from Knuth's vol.4, efficient but not in lex order!
|
||||||
PERM_RANK_TYPE generate_all_multi(void (*callback)(const NRPerm<T>&)); //Algorithm L2 from Knuth's vol.4, for multiset (repeated numbers, not really permutations)
|
PermutationAlgebra<T,T> list_all(int parity_select=0);
|
||||||
|
PERM_RANK_TYPE generate_all_multi(void (*callback)(const NRPerm<T>&)); //Algorithm L2 from Knuth's vol.4, for a multiset (repeated numbers, not really permutations)
|
||||||
PERM_RANK_TYPE generate_all2(void (*callback)(const NRPerm<T>&)); //recursive method, also not lexicographic
|
PERM_RANK_TYPE generate_all2(void (*callback)(const NRPerm<T>&)); //recursive method, also not lexicographic
|
||||||
PERM_RANK_TYPE generate_all_lex(void (*callback)(const NRPerm<T>&)); //generate in lex order using next()
|
PERM_RANK_TYPE generate_all_lex(void (*callback)(const NRPerm<T>&)); //generate in lex order using next()
|
||||||
PERM_RANK_TYPE generate_restricted(void (*callback)(const NRPerm<T>&), const NRVec_from1<T> &classes, int restriction_type=0);
|
PERM_RANK_TYPE generate_restricted(void (*callback)(const NRPerm<T>&), const NRVec_from1<T> &classes, int restriction_type=0);
|
||||||
|
PermutationAlgebra<T,T> list_restricted(const NRVec_from1<T> &classes, int restriction_type=0); //weight is set to parity (antisymmetrizer) by default
|
||||||
PERM_RANK_TYPE rank() const; //counted from 0 to n!-1
|
PERM_RANK_TYPE rank() const; //counted from 0 to n!-1
|
||||||
NRVec_from1<T> inversions(const int type, PERM_RANK_TYPE *prank=NULL) const; //inversion tables
|
NRVec_from1<T> inversions(const int type, PERM_RANK_TYPE *prank=NULL) const; //inversion tables
|
||||||
explicit NRPerm(const int type, const NRVec_from1<T> &inversions); //compute permutation from inversions
|
explicit NRPerm(const int type, const NRVec_from1<T> &inversions); //compute permutation from inversions
|
||||||
|
9
t.cc
9
t.cc
@ -2211,18 +2211,19 @@ int tot=p.generate_all_multi(printme0);
|
|||||||
cout <<"generated "<<tot<<endl;
|
cout <<"generated "<<tot<<endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(0)
|
if(1)
|
||||||
{
|
{
|
||||||
int n; cin >>n;
|
int n; cin >>n;
|
||||||
NRPerm<int> p(n);
|
NRPerm<int> p(n);
|
||||||
NRVec_from1<int> classes; cin>>classes;
|
NRVec_from1<int> classes; cin>>classes;
|
||||||
if(classes.size()!=p.size()) laerror("sizes do not match");
|
if(classes.size()!=p.size()) laerror("sizes do not match");
|
||||||
int tot=p.generate_restricted(printme1,classes,-2);
|
PermutationAlgebra<int,int> tot = p.list_restricted(classes,-2);
|
||||||
cout <<"generated "<<tot<<endl;
|
cout <<"generated\n"<<tot<<endl;
|
||||||
|
cout <<"ALL\n"<<p.list_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if(1)
|
if(0)
|
||||||
{
|
{
|
||||||
int n;;
|
int n;;
|
||||||
cin >>n >>unitary_n;
|
cin >>n >>unitary_n;
|
||||||
|
Loading…
Reference in New Issue
Block a user