solverforge-solver 0.8.6

Solver engine for SolverForge
Documentation
use super::*;
use solverforge_core::domain::{EntityCollectionExtractor, EntityDescriptor, SolutionDescriptor};
use solverforge_core::score::SoftScore;
use solverforge_scoring::ScoreDirector;
use std::any::TypeId;

#[derive(Clone, Debug)]
struct Task {
    id: usize,
    priority: Option<i32>,
}

#[derive(Clone, Debug)]
struct TaskSolution {
    tasks: Vec<Task>,
    score: Option<SoftScore>,
}

impl PlanningSolution for TaskSolution {
    type Score = SoftScore;

    fn score(&self) -> Option<Self::Score> {
        self.score
    }

    fn set_score(&mut self, score: Option<Self::Score>) {
        self.score = score;
    }
}

fn create_director(tasks: Vec<Task>) -> ScoreDirector<TaskSolution, ()> {
    let solution = TaskSolution { tasks, score: None };
    let extractor = Box::new(EntityCollectionExtractor::new(
        "Task",
        "tasks",
        |s: &TaskSolution| &s.tasks,
        |s: &mut TaskSolution| &mut s.tasks,
    ));
    let entity_desc =
        EntityDescriptor::new("Task", TypeId::of::<Task>(), "tasks").with_extractor(extractor);
    let descriptor = SolutionDescriptor::new("TaskSolution", TypeId::of::<TaskSolution>())
        .with_entity(entity_desc);
    ScoreDirector::simple(solution, descriptor, |s, _| s.tasks.len())
}

#[test]
fn test_static_value_selector_selector() {
    let director = create_director(vec![Task {
        id: 0,
        priority: None,
    }]);
    let selector = StaticValueSelector::<TaskSolution, i32>::new(vec![1, 2, 3, 4, 5]);

    let values: Vec<_> = selector.iter_typed(&director, 0, 0).collect();
    assert_eq!(values, vec![1, 2, 3, 4, 5]);
    assert_eq!(selector.size(&director, 0, 0), 5);
}

#[test]
fn test_from_solution_value_selector_selector() {
    let director = create_director(vec![
        Task {
            id: 0,
            priority: Some(10),
        },
        Task {
            id: 1,
            priority: Some(20),
        },
    ]);

    let solution = director.working_solution();
    assert_eq!(solution.tasks[0].id, 0);
    assert_eq!(solution.tasks[1].id, 1);

    fn extract_priorities(s: &TaskSolution) -> Vec<i32> {
        s.tasks.iter().filter_map(|t| t.priority).collect()
    }

    let selector = FromSolutionValueSelector::new(extract_priorities);

    let values: Vec<_> = selector.iter_typed(&director, 0, 0).collect();
    assert_eq!(values, vec![10, 20]);
}