parent
d6ba6a9199
commit
956c550998
@ -0,0 +1,42 @@ |
||||
use bit_field::BitField; |
||||
|
||||
// permutation type is a bit field,
|
||||
// 1 at i-th position means that in the permutation,
|
||||
// value i must occur earlier than the value i+1
|
||||
|
||||
// For a given ordered vector (similar to what vec.dedup needs - that is,
|
||||
// matching values only appear next to each other),
|
||||
// it should return a permutation type with 1 in position of all values
|
||||
// which are equal to the next values,
|
||||
// so that all permutations of this type applied to the vector
|
||||
// will produce all unique permutations of its values
|
||||
pub fn get_required_permutation_type<T: Eq>(ordered_vector_to_permute: &[T]) -> u16 { |
||||
let mut result: u16 = 0; |
||||
for i in 0..(ordered_vector_to_permute.len() - 1) { |
||||
if ordered_vector_to_permute[i] == ordered_vector_to_permute[i+1] { |
||||
result.set_bit(i, true); |
||||
} |
||||
} |
||||
|
||||
result |
||||
} |
||||
|
||||
pub fn get_supported_permutation_types(inverse_permutation: &[usize]) -> Vec<u16> { |
||||
assert!(inverse_permutation.len() <= 16); |
||||
|
||||
let mut max_supported_type: u16 = 0; |
||||
for i in 0..(inverse_permutation.len()-1) { |
||||
if inverse_permutation[i] < inverse_permutation[i+1] { |
||||
max_supported_type.set_bit(i, true); |
||||
} |
||||
} |
||||
|
||||
let mut supported_types: Vec<u16> = Vec::new(); |
||||
for i in 0..=u16::MAX { |
||||
if (i & max_supported_type) == i { |
||||
supported_types.push(i); |
||||
} |
||||
} |
||||
|
||||
supported_types |
||||
} |
@ -1 +1,58 @@ |
||||
use permutohedron::Heap; |
||||
use crate::permutation_type::get_required_permutation_type; |
||||
use crate::permutation_type::get_supported_permutation_types; |
||||
|
||||
pub struct PermutationsCache { |
||||
permutations_by_type: Vec<Vec<Vec<usize>>>, |
||||
set_length: usize, |
||||
} |
||||
|
||||
fn invert_permutation(permutation: &Vec<usize>) -> Vec<usize> { |
||||
let mut result = permutation.clone(); |
||||
for i in 0..permutation.len() { |
||||
result[permutation[i]] = i; |
||||
} |
||||
|
||||
result |
||||
} |
||||
|
||||
impl PermutationsCache { |
||||
pub fn new(set_length: usize) -> PermutationsCache { |
||||
assert!(set_length <= 16); |
||||
|
||||
let mut permutations_by_type: Vec<Vec<Vec<usize>>> = Vec::with_capacity(1 << 16); |
||||
|
||||
for _i in 0..=u16::MAX { |
||||
permutations_by_type.push(Vec::new()); |
||||
} |
||||
|
||||
let mut placeholder: Vec<usize> = (0..set_length).collect(); |
||||
let heap = Heap::new(&mut placeholder); |
||||
for permutation in heap { |
||||
for permutation_type in get_supported_permutation_types(&invert_permutation(&permutation)) { |
||||
permutations_by_type[permutation_type as usize].push(permutation.clone()); |
||||
} |
||||
} |
||||
|
||||
PermutationsCache { |
||||
permutations_by_type, |
||||
set_length, |
||||
} |
||||
} |
||||
|
||||
pub fn get_permuted_vectors<T: Eq + Copy>(&self, ordered_vector_to_permute: &Vec<T>) -> Vec<Vec<T>> { |
||||
//println!("set_length: {}, vector: {:?}", self.set_length, ordered_vector_to_permute);
|
||||
assert_eq!(ordered_vector_to_permute.len(), self.set_length); |
||||
|
||||
let permutation_type = get_required_permutation_type(ordered_vector_to_permute); |
||||
let permutations = &self.permutations_by_type[permutation_type as usize]; |
||||
|
||||
return permutations.iter() |
||||
.map(|permutation| { |
||||
permutation.iter() |
||||
.map(|&index| ordered_vector_to_permute[index]) |
||||
.collect() |
||||
}) |
||||
.collect() |
||||
} |
||||
} |
Loading…
Reference in new issue