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 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