solverforge-solver 0.15.0

Solver engine for SolverForge
Documentation
// Tests for the move module.

use super::*;
use solverforge_core::domain::{
    EntityCollectionExtractor, EntityDescriptor, PlanningSolution, SolutionDescriptor,
};
use solverforge_core::score::SoftScore;
use solverforge_scoring::{Director, ScoreDirector};
use std::any::TypeId;
use std::ptr::NonNull;

struct SnapshotDirector<S, D>
where
    S: PlanningSolution,
    D: Director<S>,
{
    inner: NonNull<D>,
    snapshot: S,
    score_state: solverforge_scoring::DirectorScoreState<S::Score>,
}

unsafe impl<S, D> Send for SnapshotDirector<S, D>
where
    S: PlanningSolution,
    D: Director<S>,
{
}

impl<S, D> SnapshotDirector<S, D>
where
    S: PlanningSolution,
    D: Director<S>,
{
    fn new(inner: &mut D) -> Self {
        Self {
            snapshot: inner.clone_working_solution(),
            score_state: inner.snapshot_score_state(),
            inner: NonNull::from(inner),
        }
    }

    fn undo_changes(&mut self) {
        *self.inner_mut().working_solution_mut() = self.snapshot.clone();
        let current_score_state = self.inner_ref().snapshot_score_state();
        let score_state = std::mem::replace(&mut self.score_state, current_score_state);
        self.inner_mut().restore_score_state(score_state);
    }

    fn inner_ref(&self) -> &D {
        unsafe { self.inner.as_ref() }
    }

    fn inner_mut(&mut self) -> &mut D {
        unsafe { self.inner.as_mut() }
    }
}

impl<S, D> Director<S> for SnapshotDirector<S, D>
where
    S: PlanningSolution,
    D: Director<S>,
{
    fn working_solution(&self) -> &S {
        self.inner_ref().working_solution()
    }

    fn working_solution_mut(&mut self) -> &mut S {
        self.inner_mut().working_solution_mut()
    }

    fn calculate_score(&mut self) -> S::Score {
        self.inner_mut().calculate_score()
    }

    fn solution_descriptor(&self) -> &SolutionDescriptor {
        self.inner_ref().solution_descriptor()
    }

    fn clone_working_solution(&self) -> S {
        self.inner_ref().clone_working_solution()
    }

    fn before_variable_changed(&mut self, descriptor_index: usize, entity_index: usize) {
        self.inner_mut()
            .before_variable_changed(descriptor_index, entity_index);
    }

    fn after_variable_changed(&mut self, descriptor_index: usize, entity_index: usize) {
        self.inner_mut()
            .after_variable_changed(descriptor_index, entity_index);
    }

    fn entity_count(&self, descriptor_index: usize) -> Option<usize> {
        self.inner_ref().entity_count(descriptor_index)
    }

    fn total_entity_count(&self) -> Option<usize> {
        self.inner_ref().total_entity_count()
    }

    fn constraint_metadata(&self) -> Vec<solverforge_scoring::ConstraintMetadata<'_>> {
        self.inner_ref().constraint_metadata()
    }

    fn is_incremental(&self) -> bool {
        self.inner_ref().is_incremental()
    }

    fn snapshot_score_state(&self) -> solverforge_scoring::DirectorScoreState<S::Score> {
        self.inner_ref().snapshot_score_state()
    }

    fn restore_score_state(&mut self, state: solverforge_scoring::DirectorScoreState<S::Score>) {
        self.inner_mut().restore_score_state(state);
    }
}

mod arena;
mod change;
mod compound_scalar;
mod conflict_repair;
mod k_opt;
mod list_change;
mod list_reverse;
mod list_ruin;
mod list_swap;
mod pillar_change;
mod pillar_swap;
mod ruin;
mod sublist_change;
mod sublist_swap;
mod swap;