KrisLibrary  1.0.0
permutation.h
Go to the documentation of this file.
1 #ifndef UTILS_PERMUTATION_H
2 #define UTILS_PERMUTATION_H
3 
4 #include <vector>
5 #include <KrisLibrary/errors.h>
6 
17 
18 inline void IdentityPermutation(int v[],int n)
19 {
20  for(int i=0;i<n;i++) v[i]=i;
21 }
22 
23 template <class T>
24 inline void RandomlyPermute(T v[],int n)
25 {
26  for(int i=0;i<n;i++) {
27  int k=i+rand()%(n-i);
28  std::swap(v[i],v[k]);
29  }
30 }
31 
32 inline void RandomPermutation(int v[],int n)
33 {
34  IdentityPermutation(v,n);
35  RandomlyPermute(v,n);
36 }
37 
38 inline void IdentityPermutation(std::vector<int>& v)
39 {
40  int n=(int)v.size();
41  for(int i=0;i<n;i++) v[i]=i;
42 }
43 
44 template <class T>
45 inline void RandomlyPermute(std::vector<T>& v)
46 {
47  int n=(int)v.size();
48  for(int i=0;i<n;i++) {
49  int k=i+rand()%(n-i);
50  std::swap(v[i],v[k]);
51  }
52 }
53 
54 inline void RandomPermutation(std::vector<int>& v)
55 {
56  IdentityPermutation(v);
57  RandomlyPermute(v);
58 }
59 
60 
61 inline void FirstPermutation(int v[],int k,int n)
62 {
63  for(int i=0;i<k;i++) v[i]=0;
64 }
65 
66 inline void FirstPermutation(std::vector<int>& v,int n)
67 {
68  std::fill(v.begin(),v.end(),0);
69 }
70 
71 inline void LastPermutation(int v[],int k,int n)
72 {
73  for(int i=0;i<k;i++) v[i]=n-1;
74 }
75 
76 inline void LastPermutation(std::vector<int>& v,int n)
77 {
78  std::fill(v.begin(),v.end(),n-1);
79 }
80 
81 
84 inline int NextPermutation(int v[],int k,int n)
85 {
86  for(int i=k-1;i>=0;i--) {
87  v[i]++;
88  if(v[i] >= n) v[i]=0;
89  else return 0;
90  }
91  return 1;
92 }
93 
96 inline int NextPermutation(std::vector<int>& v,int n)
97 {
98  int k=(int)v.size();
99  for(int i=k-1;i>=0;i--) {
100  v[i]++;
101  if(v[i] >= n) v[i]=0;
102  else return 0;
103  }
104  return 1;
105 }
106 
109 inline int PrevPermutation(int v[],int k,int n)
110 {
111  for(int i=k-1;i>=0;i--) {
112  v[i]--;
113  if(v[i] < 0) v[i]=n-1;
114  else return 0;
115  }
116  return 1;
117 }
118 
121 inline int PrevPermutation(std::vector<int>& v,int n)
122 {
123  int k=(int)v.size();
124  for(int i=k-1;i>=0;i--) {
125  v[i]--;
126  if(v[i] < 0) v[i]=n-1;
127  else return 0;
128  }
129  return 1;
130 }
131 
132 
136 {
137  public:
138  inline Permutation(int _n) :value(_n,0),n(_n),numCycles(0) {}
139  inline Permutation(int _k,int _n) :value(_k,0),n(_n),numCycles(0) {}
140  inline const Permutation& operator ++() {
141  numCycles += NextPermutation(value,n);
142  return *this;
143  }
144  inline const Permutation& operator ++(int) { return operator ++(); }
145  inline const Permutation& operator --() {
146  numCycles -= PrevPermutation(value,n);
147  return *this;
148  }
149  inline const Permutation& operator --(int) { return operator --(); }
150  inline int cycleCount() const { return numCycles; }
151  inline bool isDone() const { return numCycles>0; }
152  inline const std::vector<int>& operator*() const { return value; }
153  inline const std::vector<int>* operator ->() const { return &value; }
154  inline const Permutation& operator = (const Permutation& c) {
155  value = c.value;
156  n = c.n;
157  numCycles = c.numCycles;
158  return *this;
159  }
160  inline bool operator == (const Permutation& c) const { return n == c.n && numCycles == c.numCycles && value == c.value; }
161  inline bool operator < (const Permutation& c) const {
162  Assert(n == c.n);
163  if(numCycles < c.numCycles) return true;
164  else if(numCycles > c.numCycles) return false;
165  return std::lexicographical_compare(value.begin(),value.end(),c.value.begin(),c.value.end());
166  }
167 
168  private:
169  std::vector<int> value;
170  int n;
171  int numCycles;
172 };
173 
176 #endif
A class that enumerates permutations.
Definition: permutation.h:135
int NextPermutation(int v[], int k, int n)
Definition: permutation.h:84
int PrevPermutation(int v[], int k, int n)
Definition: permutation.h:109