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}