radiate_core/codecs/subset.rs
1use super::Codec;
2use crate::{BitChromosome, Chromosome, Gene, Genotype};
3use std::sync::Arc;
4
5/// A `Codec` for a subset of items. This is useful for problems where the goal is to find the best subset of items
6/// from a larger set of items. The `encode` function creates a `Genotype` with a single chromosome of `BitGenes`
7/// where each gene represents an item in the `items` vector. The `decode` function creates a `Vec<&T>` from the
8/// `Genotype` where the `Vec` contains the items that are selected by the `BitGenes` - the `true` genes.
9///
10/// A `SubSetCodec` is useful for problems like the Knapsack problem, where the goal is to find the best subset of items
11/// that fit in a knapsack. The `items` vector would contain the items that can be placed in the knapsack and the `Genotype`
12/// would contain `BitGenes` that represent weather or not the item is in the knapsack.
13#[derive(Clone)]
14pub struct SubSetCodec<T> {
15 items: Arc<[Arc<T>]>,
16}
17
18impl<T> SubSetCodec<T> {
19 pub fn new(items: Vec<T>) -> Self {
20 SubSetCodec {
21 items: items.into_iter().map(Arc::new).collect(),
22 }
23 }
24}
25
26impl<T> Codec<BitChromosome, Vec<Arc<T>>> for SubSetCodec<T> {
27 fn encode(&self) -> Genotype<BitChromosome> {
28 Genotype::new(vec![BitChromosome::new(self.items.len())])
29 }
30
31 fn decode(&self, genotype: &Genotype<BitChromosome>) -> Vec<Arc<T>> {
32 let mut result = Vec::new();
33 for (i, gene) in genotype.iter().next().unwrap().iter().enumerate() {
34 if *gene.allele() {
35 result.push(Arc::clone(&self.items[i]));
36 }
37 }
38
39 result
40 }
41}