use std::fmt::Debug;
use std::marker::PhantomData;
use solverforge_config::ConstructionObligation;
use solverforge_core::domain::PlanningSolution;
use solverforge_scoring::Director;
use crate::heuristic::r#move::Move;
use crate::scope::{ProgressCallback, StepScope};
use super::Placement;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ConstructionChoice {
KeepCurrent,
Select(usize),
}
pub trait ConstructionForager<S, M>: Send + Debug
where
S: PlanningSolution,
M: Move<S>,
{
fn pick_move_index<D: Director<S>>(
&self,
placement: &Placement<S, M>,
score_director: &mut D,
) -> ConstructionChoice;
fn select_move_index<D, BestCb>(
&self,
placement: &Placement<S, M>,
_construction_obligation: ConstructionObligation,
step_scope: &mut StepScope<'_, '_, '_, S, D, BestCb>,
) -> Option<ConstructionChoice>
where
D: Director<S>,
BestCb: ProgressCallback<S>,
{
Some(self.pick_move_index(placement, step_scope.score_director_mut()))
}
}
pub struct FirstFitForager<S, M> {
_phantom: PhantomData<fn() -> (S, M)>,
}
impl<S, M> Clone for FirstFitForager<S, M> {
fn clone(&self) -> Self {
*self
}
}
impl<S, M> Copy for FirstFitForager<S, M> {}
impl<S, M> Default for FirstFitForager<S, M> {
fn default() -> Self {
Self::new()
}
}
impl<S, M> Debug for FirstFitForager<S, M> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("FirstFitForager").finish()
}
}
impl<S, M> FirstFitForager<S, M> {
pub fn new() -> Self {
Self {
_phantom: PhantomData,
}
}
}
pub struct BestFitForager<S, M> {
_phantom: PhantomData<fn() -> (S, M)>,
}
impl<S, M> Clone for BestFitForager<S, M> {
fn clone(&self) -> Self {
*self
}
}
impl<S, M> Copy for BestFitForager<S, M> {}
impl<S, M> Default for BestFitForager<S, M> {
fn default() -> Self {
Self::new()
}
}
impl<S, M> Debug for BestFitForager<S, M> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("BestFitForager").finish()
}
}
impl<S, M> BestFitForager<S, M> {
pub fn new() -> Self {
Self {
_phantom: PhantomData,
}
}
}
pub struct FirstFeasibleForager<S, M> {
_phantom: PhantomData<fn() -> (S, M)>,
}
impl<S, M> Clone for FirstFeasibleForager<S, M> {
fn clone(&self) -> Self {
*self
}
}
impl<S, M> Copy for FirstFeasibleForager<S, M> {}
impl<S, M> Default for FirstFeasibleForager<S, M> {
fn default() -> Self {
Self::new()
}
}
impl<S, M> Debug for FirstFeasibleForager<S, M> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("FirstFeasibleForager").finish()
}
}
impl<S, M> FirstFeasibleForager<S, M> {
pub fn new() -> Self {
Self {
_phantom: PhantomData,
}
}
}
pub struct WeakestFitForager<S, M> {
strength_fn: fn(&M, &S) -> i64,
_phantom: PhantomData<fn() -> S>,
}
impl<S, M> Clone for WeakestFitForager<S, M> {
fn clone(&self) -> Self {
*self
}
}
impl<S, M> Copy for WeakestFitForager<S, M> {}
impl<S, M> Debug for WeakestFitForager<S, M> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("WeakestFitForager").finish()
}
}
impl<S, M> WeakestFitForager<S, M> {
pub fn new(strength_fn: fn(&M, &S) -> i64) -> Self {
Self {
strength_fn,
_phantom: PhantomData,
}
}
pub(crate) fn strength(&self, mov: &M, solution: &S) -> i64 {
(self.strength_fn)(mov, solution)
}
}
pub struct StrongestFitForager<S, M> {
strength_fn: fn(&M, &S) -> i64,
_phantom: PhantomData<fn() -> S>,
}
impl<S, M> Clone for StrongestFitForager<S, M> {
fn clone(&self) -> Self {
*self
}
}
impl<S, M> Copy for StrongestFitForager<S, M> {}
impl<S, M> Debug for StrongestFitForager<S, M> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("StrongestFitForager").finish()
}
}
impl<S, M> StrongestFitForager<S, M> {
pub fn new(strength_fn: fn(&M, &S) -> i64) -> Self {
Self {
strength_fn,
_phantom: PhantomData,
}
}
pub(crate) fn strength(&self, mov: &M, solution: &S) -> i64 {
(self.strength_fn)(mov, solution)
}
}
#[cfg(test)]
mod tests;