Skip to content

Commit

Permalink
improved documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
JeroenGar committed Feb 10, 2024
1 parent c9965c6 commit 892aeda
Show file tree
Hide file tree
Showing 12 changed files with 50 additions and 42 deletions.
2 changes: 2 additions & 0 deletions jaguars/src/entities/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ use crate::util::assertions;
/// Static representation of a problem instance.
#[derive(Debug)]
pub struct Instance {
/// Items to be packed in the instance, along with their requested quantities
items: Vec<(Item, usize)>,
/// Total area of all items in the instance
item_area: f64,
packing_type: PackingType,
}
Expand Down
8 changes: 4 additions & 4 deletions jaguars/src/entities/problems/bin_packing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ use crate::entities::placing_option::PlacingOption;
use crate::entities::instance::{Instance, PackingType};
use crate::entities::layout::Layout;
use crate::entities::placed_item::PlacedItemUID;
use crate::entities::problems::problem::{LayoutIndex, Problem};
use crate::entities::problems::problem::private::ProblemPrivate;
use crate::entities::problems::problem::{LayoutIndex, ProblemVariant};
use crate::entities::problems::problem::private::ProblemVariantPrivate;
use crate::entities::solution::Solution;
use crate::util::assertions;

Expand Down Expand Up @@ -114,7 +114,7 @@ impl BPProblem {
}
}

impl Problem for BPProblem {
impl ProblemVariant for BPProblem {
fn place_item(&mut self, i_opt: &PlacingOption) {
let item_id = i_opt.item_id;
let layout = match &i_opt.layout_index {
Expand Down Expand Up @@ -280,7 +280,7 @@ impl Problem for BPProblem {
}


impl ProblemPrivate for BPProblem {
impl ProblemVariantPrivate for BPProblem {
fn next_solution_id(&mut self) -> usize {
self.solution_id_counter += 1;
self.solution_id_counter
Expand Down
32 changes: 19 additions & 13 deletions jaguars/src/entities/problems/problem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,29 @@ use crate::entities::instance::Instance;
use crate::entities::layout::Layout;
use crate::entities::placed_item::PlacedItemUID;
use crate::entities::problems::bin_packing::BPProblem;
use crate::entities::problems::problem::private::ProblemPrivate;
use crate::entities::problems::problem::private::ProblemVariantPrivate;
use crate::entities::problems::strip_packing::SPProblem;
use crate::entities::solution::Solution;

/// Enum which contains all the different types implementing the Problem trait.
/// Enum which contains all the different types implementing the `ProblemVariant` trait.
/// A `Problem` represents a problem instance in a modifiable state.
/// It can insert or remove items, create a snapshot from the current state called a `Solution`,
/// and restore its state to a previous `Solution`.
/// <br>
/// Uses the enum_dispatch crate to have performant polymorphism for different problem types, see
/// <https://docs.rs/enum_dispatch/latest/enum_dispatch/> for more information on enum_dispatch
#[derive(Clone)]
#[enum_dispatch]
pub enum ProblemType {
pub enum Problem {
/// Bin Packing Problem
BP(BPProblem),
/// Strip Packing Problem
SP(SPProblem),
}

/// Trait for public shared functionality of all problem types.
/// A `Problem` represents a problem instance in a modifiable state.
/// It can insert or remove items, create a snapshot from the current state called a `Solution`,
/// and restore its state to a previous `Solution`.
#[enum_dispatch(ProblemType)]
pub trait Problem: ProblemPrivate {
/// Trait for public shared functionality of all problem variants.
#[enum_dispatch(Problem)]
pub trait ProblemVariant: ProblemVariantPrivate {

/// Places an item into the problem instance according to the given `PlacingOption`.
fn place_item(&mut self, i_opt: &PlacingOption);
Expand All @@ -51,8 +52,13 @@ pub trait Problem: ProblemPrivate {

fn layouts_mut(&mut self) -> &mut [Layout];


/// Returns layouts of the problem instance, which are currently empty (no items placed in them).
/// These layouts can be used to place items into.
fn empty_layouts(&self) -> &[Layout];

/// The quantity of each item that is requested but currently missing in the problem instance.
/// Indexed by item id.
fn missing_item_qtys(&self) -> &[isize];

fn usage(&mut self) -> f64 {
Expand Down Expand Up @@ -106,11 +112,11 @@ pub trait Problem: ProblemPrivate {

pub(super) mod private {
use enum_dispatch::enum_dispatch;
use crate::entities::problems::problem::ProblemType;
use crate::entities::problems::problem::Problem;

/// Trait for shared functionality of all problem types, but not exposed to the public.
#[enum_dispatch(ProblemType)]
pub trait ProblemPrivate : Clone {
/// Trait for shared functionality of all problem variants, but not exposed to the public.
#[enum_dispatch(Problem)]
pub trait ProblemVariantPrivate: Clone {
fn next_solution_id(&mut self) -> usize;

fn missing_item_qtys_mut(&mut self) -> &mut [isize];
Expand Down
8 changes: 4 additions & 4 deletions jaguars/src/entities/problems/strip_packing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ use crate::entities::placing_option::PlacingOption;
use crate::entities::instance::{Instance, PackingType};
use crate::entities::layout::Layout;
use crate::entities::placed_item::PlacedItemUID;
use crate::entities::problems::problem::{LayoutIndex, Problem};
use crate::entities::problems::problem::private::ProblemPrivate;
use crate::entities::problems::problem::{LayoutIndex, ProblemVariant};
use crate::entities::problems::problem::private::ProblemVariantPrivate;
use crate::entities::solution::Solution;
use crate::geometry::geo_traits::{Shape, Transformable};
use crate::util::assertions;
Expand Down Expand Up @@ -103,7 +103,7 @@ impl SPProblem {
}
}

impl Problem for SPProblem {
impl ProblemVariant for SPProblem {
fn place_item(&mut self, i_opt: &PlacingOption) {
assert_eq!(i_opt.layout_index, LayoutIndex::Existing(0), "strip packing problems only have a single layout");
let item_id = i_opt.item_id;
Expand Down Expand Up @@ -173,7 +173,7 @@ impl Problem for SPProblem {
}


impl ProblemPrivate for SPProblem {
impl ProblemVariantPrivate for SPProblem {
fn next_solution_id(&mut self) -> usize {
self.solution_id_counter += 1;
self.solution_id_counter
Expand Down
8 changes: 4 additions & 4 deletions jaguars/src/io/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::entities::instance::{Instance, PackingType};
use crate::entities::item::Item;
use crate::entities::placing_option::PlacingOption;
use crate::entities::problems::bin_packing::BPProblem;
use crate::entities::problems::problem::{LayoutIndex, ProblemType, Problem};
use crate::entities::problems::problem::{LayoutIndex, Problem, ProblemVariant};
use crate::entities::problems::strip_packing::SPProblem;
use crate::entities::quality_zone::QualityZone;
use crate::entities::solution::Solution;
Expand Down Expand Up @@ -174,14 +174,14 @@ impl Parser {
}

fn build_solution_from_json(json_layouts: &[JsonLayout], instance: Arc<Instance>, cde_config: CDEConfig) -> Solution {
let mut problem: ProblemType = match instance.packing_type() {
PackingType::BinPacking(_) => ProblemType::BP(BPProblem::new(instance.clone())),
let mut problem: Problem = match instance.packing_type() {
PackingType::BinPacking(_) => Problem::BP(BPProblem::new(instance.clone())),
PackingType::StripPacking { .. } => {
assert_eq!(json_layouts.len(), 1);
match json_layouts[0].object_type {
JsonObjectType::Object { .. } => panic!("Strip packing solution should not contain layouts with references to an Object"),
JsonObjectType::Strip { width, height: _ } => {
ProblemType::SP(SPProblem::new(instance.clone(), width, cde_config))
Problem::SP(SPProblem::new(instance.clone(), width, cde_config))
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions jaguars/src/util/assertions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use crate::entities::bin::Bin;
use crate::entities::instance::PackingType;
use crate::entities::item::Item;
use crate::entities::layout::Layout;
use crate::entities::problems::problem::Problem;
use crate::entities::problems::problem::ProblemVariant;
use crate::entities::solution::Solution;
use crate::entities::layout::LayoutSnapshot;
use crate::geometry::geo_traits::{Shape, Transformable};
Expand Down Expand Up @@ -48,7 +48,7 @@ pub fn instance_item_bin_ids_correct(items: &Vec<(Item, usize)>, packing_type: &
};
}

pub fn problem_matches_solution<P: Problem>(problem: &P, solution: &Solution) -> bool {
pub fn problem_matches_solution<P: ProblemVariant>(problem: &P, solution: &Solution) -> bool {
for l in problem.layouts() {
let sl = solution.layout_snapshots.iter().find(|sl| sl.id() == l.id()).unwrap();
match layouts_match(l, sl) {
Expand Down
2 changes: 1 addition & 1 deletion lbf/benches/edge_sensitivity_bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use rand::prelude::{IteratorRandom, SmallRng};
use rand::SeedableRng;
use jaguars::entities::instance::Instance;
use jaguars::entities::item::Item;
use jaguars::entities::problems::problem::{LayoutIndex, Problem};
use jaguars::entities::problems::problem::{LayoutIndex, ProblemVariant};
use jaguars::geometry::geo_traits::{Shape, TransformableFrom};
use jaguars::geometry::primitives::point::Point;
use jaguars::geometry::primitives::simple_polygon::SimplePolygon;
Expand Down
2 changes: 1 addition & 1 deletion lbf/benches/fast_fail_bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use tribool::Tribool;
use jaguars::entities::instance::{Instance, PackingType};
use jaguars::entities::placed_item::PlacedItemUID;
use jaguars::entities::placing_option::PlacingOption;
use jaguars::entities::problems::problem::{LayoutIndex, Problem, ProblemType};
use jaguars::entities::problems::problem::{LayoutIndex, ProblemVariant, Problem};
use jaguars::entities::problems::strip_packing::SPProblem;
use jaguars::geometry::fail_fast::sp_surrogate::SPSurrogate;
use jaguars::geometry::geo_traits::TransformableFrom;
Expand Down
2 changes: 1 addition & 1 deletion lbf/benches/hpg_bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use rand::SeedableRng;
use jaguars::entities::layout::Layout;

use jaguars::entities::placing_option::PlacingOption;
use jaguars::entities::problems::problem::{LayoutIndex, Problem};
use jaguars::entities::problems::problem::{LayoutIndex, ProblemVariant};
use jaguars::entities::problems::strip_packing::SPProblem;
use jaguars::geometry::geo_traits::{Shape, TransformableFrom};
use jaguars::io::json_instance::JsonInstance;
Expand Down
2 changes: 1 addition & 1 deletion lbf/benches/quadtree_bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use rand::seq::IteratorRandom;
use jaguars::entities::instance::{Instance, PackingType};
use jaguars::entities::placed_item::PlacedItemUID;
use jaguars::entities::placing_option::PlacingOption;
use jaguars::entities::problems::problem::{LayoutIndex, Problem, ProblemType};
use jaguars::entities::problems::problem::{LayoutIndex, ProblemVariant, Problem};
use jaguars::entities::problems::strip_packing::SPProblem;
use jaguars::geometry::geo_traits::TransformableFrom;
use jaguars::io::json_instance::JsonInstance;
Expand Down
4 changes: 2 additions & 2 deletions lbf/benches/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use rand::prelude::{IteratorRandom, SmallRng};
use rand::SeedableRng;
use jaguars::entities::instance::{Instance, PackingType};
use jaguars::entities::placed_item::PlacedItemUID;
use jaguars::entities::problems::problem::{LayoutIndex, Problem, ProblemType};
use jaguars::entities::problems::problem::{LayoutIndex, ProblemVariant, Problem};
use jaguars::entities::problems::strip_packing::SPProblem;
use jaguars::io::json_instance::JsonInstance;
use jaguars::io::parser::Parser;
Expand Down Expand Up @@ -39,7 +39,7 @@ pub fn create_blf_problem(instance: Arc<Instance>, config: Config, n_items_remov
lbf_optimizer.solve();

let mut problem = match lbf_optimizer.problem().clone() {
ProblemType::SP(sp_problem) => sp_problem,
Problem::SP(sp_problem) => sp_problem,
_ => panic!("Expected SPProblem")
};

Expand Down
18 changes: 9 additions & 9 deletions lbf/src/lbf_optimizer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use jaguars::entities::item::Item;
use jaguars::entities::layout::Layout;
use jaguars::entities::placing_option::PlacingOption;
use jaguars::entities::problems::bin_packing::BPProblem;
use jaguars::entities::problems::problem::{LayoutIndex, Problem, ProblemType};
use jaguars::entities::problems::problem::{LayoutIndex, ProblemVariant, Problem};
use jaguars::entities::problems::strip_packing::SPProblem;
use jaguars::entities::solution::Solution;
use jaguars::geometry::convex_hull::convex_hull_from_points;
Expand All @@ -36,7 +36,7 @@ pub const ITEM_LIMIT: usize = 1000;

pub struct LBFOptimizer {
instance: Arc<Instance>,
problem: ProblemType,
problem: Problem,
config: Config,
/// SmallRng is a fast, non-cryptographic PRNG <https://rust-random.github.io/book/guide-rngs.html>
rng: SmallRng,
Expand Down Expand Up @@ -91,8 +91,8 @@ impl LBFOptimizer {
}
None => {
match &mut self.problem {
ProblemType::BP(_) => break,
ProblemType::SP(sp_problem) => {
Problem::BP(_) => break,
Problem::SP(sp_problem) => {
let new_width = sp_problem.strip_width() * 1.1;
info!("Extending the strip by 10%: {:.3}", new_width);
sp_problem.modify_strip_width(new_width);
Expand All @@ -104,8 +104,8 @@ impl LBFOptimizer {
}

match &mut self.problem {
ProblemType::BP(_) => {}
ProblemType::SP(sp_problem) => {
Problem::BP(_) => {}
Problem::SP(sp_problem) => {
sp_problem.fit_strip_width();
info!("Final strip width: {:.3}", sp_problem.strip_width());
}
Expand All @@ -121,15 +121,15 @@ impl LBFOptimizer {
pub fn instance(&self) -> &Arc<Instance> {
&self.instance
}
pub fn problem(&self) -> &ProblemType {
pub fn problem(&self) -> &Problem {
&self.problem
}
pub fn config(&self) -> &Config {
&self.config
}
}

fn find_placement(problem: &ProblemType, item: &Item, config: &Config, rng: &mut impl Rng) -> Option<PlacingOption> {
fn find_placement(problem: &Problem, item: &Item, config: &Config, rng: &mut impl Rng) -> Option<PlacingOption> {
let layouts_to_sample =
(0..problem.layouts().len()).map(|i| (LayoutIndex::Existing(i)))
.chain((0..problem.empty_layouts().len())
Expand All @@ -144,7 +144,7 @@ fn find_placement(problem: &ProblemType, item: &Item, config: &Config, rng: &mut
best_i_opt
}

pub fn sample_layout(problem: &ProblemType, layout_index: LayoutIndex, item: &Item, config: &Config, rng: &mut impl Rng) -> Option<PlacingOption> {
pub fn sample_layout(problem: &Problem, layout_index: LayoutIndex, item: &Item, config: &Config, rng: &mut impl Rng) -> Option<PlacingOption> {
let item_id = item.id();
let layout: &Layout = problem.get_layout(&layout_index);
let entities_to_ignore = item.hazard_filter()
Expand Down

0 comments on commit 892aeda

Please sign in to comment.