Trying to organize it all :$
This commit is contained in:
@@ -5,28 +5,61 @@ extern crate planner;
|
|||||||
|
|
||||||
use self::cookbook::*;
|
use self::cookbook::*;
|
||||||
use self::cookbook::models::Recipe;
|
use self::cookbook::models::Recipe;
|
||||||
use self::planner::solver::{Domain, Problem, Constraint, Variables};
|
use self::planner::solver::{Variables, Domain, Problem, Constraint};
|
||||||
|
|
||||||
/// We want a mapping of the week meals (matin, midi, soir)
|
/// We want a mapping of the week meals (matin, midi, soir)
|
||||||
|
/// Breakfast => RecipeCategory::Breakfast
|
||||||
|
/// Lunch => RecipeCategory::MainCourse
|
||||||
|
/// Dinner => RecipeCategory::MainCourse
|
||||||
|
type Day = String;
|
||||||
|
|
||||||
|
enum Meals {
|
||||||
|
Breakfast(Day),
|
||||||
|
Lunch(Day),
|
||||||
|
Dinner(Day)
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Into<String> for Meals {
|
||||||
|
fn into(self) -> String {
|
||||||
|
match self {
|
||||||
|
Meals::Breakfast(d) => format!("{}_Breakfast", d),
|
||||||
|
Meals::Lunch(d) => format!("{}_Lunch", d),
|
||||||
|
Meals::Dinner(d) => format!("{}_Dinner", d),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
/// associated with filters for Domain, depending on recipes RecipeCategory
|
/// associated with filters for Domain, depending on recipes RecipeCategory
|
||||||
|
enum RecipeCategory {
|
||||||
|
Breakfast,
|
||||||
|
MainCourse
|
||||||
|
}
|
||||||
/// It may also contains an initial value for each variable
|
/// It may also contains an initial value for each variable
|
||||||
|
fn generate_variables<V>(domain: &Domain<V>) -> Vec<(String, &Domain<V>, Option<&V>)> {
|
||||||
|
let mut vars = Vec::new();
|
||||||
|
for day in &["Lundi", "Mardi", "Mercredi"] {
|
||||||
|
vars.push((Meals::Lunch(String::from(day)).into(), domain, None));
|
||||||
|
vars.push((Meals::Dinner(String::from(day)).into(), domain, None));
|
||||||
|
}
|
||||||
|
vars
|
||||||
|
}
|
||||||
|
|
||||||
fn ingredients_contains<'a>(assign: &Variables<'a,Recipe>) -> bool {
|
fn ingredients_contains<'a>(assign: &Variables<'a,Recipe>) -> bool {
|
||||||
assign.get("Lundi_midi").unwrap().unwrap().ingredients.contains("Patates")
|
assign.get("Lundi_Lunch").unwrap().unwrap().ingredients.contains("Patates")
|
||||||
&& assign.get("Mardi_midi").unwrap().unwrap().ingredients.contains("Patates")
|
&& !assign.get("Mardi_Lunch").unwrap().unwrap().ingredients.contains("Patates")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_planning_all_results() -> String {
|
fn get_planning_all_results() -> String {
|
||||||
let conn = establish_connection();
|
let conn = establish_connection();
|
||||||
let possible_values = recipes::load_all(&conn);
|
let possible_values = recipes::load_all(&conn);
|
||||||
let domain = Domain::new(possible_values);
|
let domain = Domain::new(possible_values);
|
||||||
let mut problem = Problem::build()
|
let mut problem = Problem::build();
|
||||||
.add_variable("Lundi_midi".to_string(), &domain, None)
|
for (var, dom, ini) in generate_variables(&domain) {
|
||||||
.add_variable("Mardi_midi".to_string(), &domain, None)
|
problem = problem.add_variable(var, dom, ini);
|
||||||
.add_constraint(ingredients_contains)
|
}
|
||||||
.finish();
|
let mut problem = problem.add_constraint(ingredients_contains)
|
||||||
|
.finish();
|
||||||
let results = problem.solve_all();
|
let results = problem.solve_all();
|
||||||
format!("{:#?}\nTotal = {}", &results, results.len())
|
format!("{:#?}\nTotal = {}", &results.first(), results.len())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ enum Assignment<'a, V> {
|
|||||||
Clear(String)
|
Clear(String)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Domains<'a, V> = HashMap<String, &'a Domain<V>>;
|
||||||
/// The domain of values that can be assigned to variables
|
/// The domain of values that can be assigned to variables
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Domain<V> {
|
pub struct Domain<V> {
|
||||||
@@ -51,13 +51,14 @@ impl<V: fmt::Debug> fmt::Debug for Domain<V> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub type Constraint<'a,V> = fn(&Variables<'a,V>) -> bool;
|
pub type Constraint<'a,V> = fn(&Variables<'a,V>) -> bool;
|
||||||
|
|
||||||
pub struct Problem<'a, V> {
|
pub struct Problem<'a, V> {
|
||||||
/// The initial assignements map
|
/// The initial assignements map
|
||||||
variables: Variables<'a, V>,
|
variables: Variables<'a, V>,
|
||||||
/// Each variable has its associated domain
|
/// Each variable has its associated domain
|
||||||
domains: HashMap<String, &'a Domain<V>>,
|
domains: Domains<'a,V>,
|
||||||
/// Set of constraints to validate
|
/// Set of constraints to validate
|
||||||
constraints: Vec<Constraint<'a,V>>,
|
constraints: Vec<Constraint<'a,V>>,
|
||||||
}
|
}
|
||||||
@@ -141,11 +142,10 @@ impl<'a, V> ProblemBuilder<'a, V> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_variable(mut self,
|
pub fn add_variable<S>(mut self, name: S, domain: &'a Domain<V>, value: Option<&'a V>) -> Self
|
||||||
name: String,
|
where S: Into<String>
|
||||||
domain: &'a Domain<V>,
|
{
|
||||||
value: Option<&'a V>,
|
let name = name.into();
|
||||||
) -> Self {
|
|
||||||
self.0.variables.insert(name.clone(), value);
|
self.0.variables.insert(name.clone(), value);
|
||||||
self.0.domains.insert(name, domain);
|
self.0.domains.insert(name, domain);
|
||||||
self
|
self
|
||||||
|
|||||||
Reference in New Issue
Block a user