Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
permutation.h
Go to the documentation of this file.
1#ifndef ROUTING_KIT_PERMUTATION_H
2#define ROUTING_KIT_PERMUTATION_H
3
5
6#include <vector>
7#include <assert.h>
8#include <algorithm>
9
10namespace RoutingKit{
11
12//
13// Applying a permutation p to a vector v consists of computing the vector {v[p[0]], v[p[1]], v[p[2]], ... , v[p[n]]}
14//
15// Applying a permutation p to the elements of a vector v consists of computing the vector {p[v[0]], p[v[1]], p[v[2]], ... , p[v[n]]}
16//
17
18inline
19bool is_permutation(const std::vector<unsigned>&p){
20 std::vector<bool>found(p.size(), false);
21 for(unsigned x:p){
22 if(x >= p.size())
23 return false;
24 if(found[x])
25 return false;
26 found[x] = true;
27 }
28 return true;
29}
30
31inline
32std::vector<unsigned>chain_permutation_first_left_then_right(const std::vector<unsigned>&p, const std::vector<unsigned>&q){
33 assert(is_permutation(p) && "p must be a permutation");
34 assert(is_permutation(q) && "q must be a permutation");
35 assert(p.size() == q.size() && "p and q must permute the same number of objects");
36 std::vector<unsigned>r(p.size());
37 for(unsigned i=0; i<r.size(); ++i)
38 r[i] = p[q[i]];
39 return r;
40}
41
42inline
43std::vector<unsigned>chain_permutation_first_right_then_left(const std::vector<unsigned>&p, const std::vector<unsigned>&q){
45}
46
47template<class T>
48std::vector<T> apply_permutation(const std::vector<unsigned>&p, const std::vector<T>&v){
49 assert(is_permutation(p) && "p must be a permutation");
50 assert(p.size() == v.size() && "permutation and vector must have the same size");
51
52 std::vector<T>r(v.size());
53 for(unsigned i = 0; i<v.size(); ++i)
54 r[i] = v[p[i]];
55
56 return r; // NVRO
57}
58
59template<class T>
60std::vector<T> apply_permutation(const std::vector<unsigned>&p, std::vector<T>&&v){
61 assert(is_permutation(p) && "p must be a permutation");
62 assert(p.size() == v.size() && "permutation and vector must have the same size");
63
64 std::vector<T>r(v.size());
65 for(unsigned i = 0; i<v.size(); ++i)
66 r[i] = std::move(v[p[i]]);
67
68 return r; // NVRO
69}
70
71template<class T>
72std::vector<T> apply_inverse_permutation(const std::vector<unsigned>&p, const std::vector<T>&v){
73 assert(is_permutation(p) && "p must be a permutation");
74 assert(p.size() == v.size() && "permutation and vector must have the same size");
75
76 std::vector<T>r(v.size());
77 for(unsigned i = 0; i<v.size(); ++i)
78 r[p[i]] = v[i];
79
80 return r; // NVRO
81}
82
83template<class T>
84std::vector<T> apply_inverse_permutation(const std::vector<unsigned>&p, std::vector<T>&&v){
85 assert(is_permutation(p) && "p must be a permutation");
86 assert(p.size() == v.size() && "permutation and vector must have the same size");
87
88 std::vector<T>r(v.size());
89 for(unsigned i = 0; i<v.size(); ++i)
90 r[p[i]] = std::move(v[i]);
91
92 return r; // NVRO
93}
94
95inline
96void inplace_apply_permutation_to_elements_of(const std::vector<unsigned>&p, std::vector<unsigned>&v){
97 assert(is_permutation(p) && "p must be a permutation");
98 assert(std::all_of(v.begin(), v.end(), [&](unsigned x){return x < p.size();}) && "v has an out of bounds element");
99
100 for(unsigned i=0; i<v.size(); ++i)
101 v[i] = p[v[i]];
102}
103
104inline
105std::vector<unsigned> apply_permutation_to_elements_of(const std::vector<unsigned>&p, const std::vector<unsigned>&v){
106 assert(is_permutation(p) && "p must be a permutation");
107 assert(std::all_of(v.begin(), v.end(), [&](unsigned x){return x < p.size();}) && "v has an out of bounds element");
108
109 std::vector<unsigned> r = v;
111 return r; // NVRO
112}
113
114
115inline
116void inplace_apply_permutation_to_possibly_invalid_elements_of(const std::vector<unsigned>&p, std::vector<unsigned>&v){
117 assert(is_permutation(p) && "p must be a permutation");
118 assert(std::all_of(v.begin(), v.end(), [&](unsigned x){return x < p.size() || x == invalid_id;}) && "v has an out of bounds element");
119
120 for(unsigned i=0; i<v.size(); ++i)
121 if(v[i] != invalid_id)
122 v[i] = p[v[i]];
123}
124
125inline
126std::vector<unsigned> apply_permutation_to_possibly_invalid_elements_of(const std::vector<unsigned>&p, const std::vector<unsigned>&v){
127 assert(is_permutation(p) && "p must be a permutation");
128 assert(std::all_of(v.begin(), v.end(), [&](unsigned x){return x < p.size() || x == invalid_id;}) && "v has an out of bounds element");
129
130 std::vector<unsigned> r = v;
132 return r; // NVRO
133}
134
135
136inline
137std::vector<unsigned> invert_permutation(const std::vector<unsigned>&p){
138 assert(is_permutation(p) && "p must be a permutation");
139
140 std::vector<unsigned> inv_p(p.size());
141 for(unsigned i=0; i<p.size(); ++i)
142 inv_p[p[i]] = i;
143
144 return inv_p; // NVRO
145}
146
147inline
148std::vector<unsigned> identity_permutation(unsigned n){
149 std::vector<unsigned> p(n);
150 for(unsigned i=0; i<n; ++i)
151 p[i] = i;
152 return p; // NVRO
153}
154
155template<class RandomGenerator>
156std::vector<unsigned> random_permutation(unsigned n, RandomGenerator&&gen){
157 auto r = identity_permutation(n);
158 std::shuffle(r.begin(), r.end(), std::forward<RandomGenerator>(gen));
159 return r;
160}
161
162} // RoutingKit
163
164#endif
165
std::vector< unsigned > chain_permutation_first_left_then_right(const std::vector< unsigned > &p, const std::vector< unsigned > &q)
Definition permutation.h:32
std::vector< unsigned > chain_permutation_first_right_then_left(const std::vector< unsigned > &p, const std::vector< unsigned > &q)
Definition permutation.h:43
void inplace_apply_permutation_to_elements_of(const std::vector< unsigned > &p, std::vector< unsigned > &v)
Definition permutation.h:96
std::vector< T > apply_permutation(const std::vector< unsigned > &p, const std::vector< T > &v)
Definition permutation.h:48
std::vector< T > apply_inverse_permutation(const std::vector< unsigned > &p, const std::vector< T > &v)
Definition permutation.h:72
std::vector< unsigned > random_permutation(unsigned n, RandomGenerator &&gen)
std::vector< unsigned > apply_permutation_to_possibly_invalid_elements_of(const std::vector< unsigned > &p, const std::vector< unsigned > &v)
std::vector< unsigned > invert_permutation(const std::vector< unsigned > &p)
bool is_permutation(const std::vector< unsigned > &p)
Definition permutation.h:19
std::vector< unsigned > apply_permutation_to_elements_of(const std::vector< unsigned > &p, const std::vector< unsigned > &v)
std::vector< unsigned > identity_permutation(unsigned n)
void inplace_apply_permutation_to_possibly_invalid_elements_of(const std::vector< unsigned > &p, std::vector< unsigned > &v)