Skip to content

Commit

Permalink
docs improved
Browse files Browse the repository at this point in the history
  • Loading branch information
JeroenGar committed Feb 11, 2024
1 parent 133a236 commit ed5b680
Show file tree
Hide file tree
Showing 23 changed files with 125 additions and 123 deletions.
3 changes: 1 addition & 2 deletions jaguars/src/collision_detection/haz_prox_grid/hpg_cell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ use crate::geometry::geo_traits::{DistanceFrom, Shape};
use crate::geometry::primitives::aa_rectangle::AARectangle;
use crate::geometry::primitives::circle::Circle;
use crate::geometry::primitives::point::Point;
use crate::N_QUALITIES;

use crate::entities::quality_zone::N_QUALITIES;

/// Represents a cell in the Hazard Proximity Grid
#[derive(Clone, Debug)]
Expand Down
14 changes: 8 additions & 6 deletions jaguars/src/entities/bin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ use crate::geometry::geo_traits::Shape;
use crate::geometry::primitives::aa_rectangle::AARectangle;
use crate::geometry::primitives::simple_polygon::SimplePolygon;
use crate::geometry::transformation::Transformation;
use crate::N_QUALITIES;
use crate::entities::quality_zone::N_QUALITIES;
use crate::util::config::CDEConfig;

/// A `Bin` is a container in which items can be placed.
/// Its interior is defined by an outer polygon and zero or more holes.
#[derive(Clone, Debug)]
pub struct Bin {
id: usize,
Expand All @@ -29,12 +31,12 @@ impl Bin {
pub fn new(id: usize, outer: SimplePolygon, value: u64, centering_transform: Transformation, holes: Vec<SimplePolygon>, quality_zones: Vec<QualityZone>, cde_config: CDEConfig) -> Self {
let outer = Arc::new(outer);
let holes = holes.into_iter().map(|z| Arc::new(z)).collect_vec();
assert_eq!(quality_zones.len(), quality_zones.iter().map(|qz| qz.quality()).unique().count(), "Quality zones must have unique qualities");
assert!(quality_zones.iter().map(|qz| qz.quality()).all(|q| q < N_QUALITIES), "All quality zones must be below N_QUALITIES");
assert_eq!(quality_zones.len(), quality_zones.iter().map(|qz| qz.quality).unique().count(), "Quality zones must have unique qualities");
assert!(quality_zones.iter().map(|qz| qz.quality).all(|q| q < N_QUALITIES), "All quality zones must be below N_QUALITIES");
let quality_zones = {
let mut qz = <[_; N_QUALITIES]>::default();
for q in quality_zones {
let quality = q.quality();
let quality = q.quality;
qz[quality] = Some(q);
}
qz
Expand Down Expand Up @@ -81,9 +83,9 @@ impl Bin {
hazards.extend(
quality_zones.iter().flatten().map(
|q_zone| {
q_zone.shapes().iter().enumerate().map(|(id, shape)| {
q_zone.zones.iter().enumerate().map(|(id, shape)| {
let haz_entity = HazardEntity::QualityZoneInferior {
quality: q_zone.quality(),
quality: q_zone.quality,
id,
};
Hazard::new(haz_entity, shape.clone())
Expand Down
16 changes: 12 additions & 4 deletions jaguars/src/entities/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,20 @@ use crate::entities::item::Item;
use crate::geometry::geo_traits::Shape;
use crate::util::assertions;

/// Static representation of a problem instance.
/// An `Instance` is the static (unmodifiable) representation of a problem instance.
/// This enum contains all variants of an instance.
/// See [`crate::entities::problems::problem::Problem`] for more information about the choice to represent variants as enums.
#[derive(Debug, Clone)]
#[enum_dispatch]
pub enum Instance {
SP(SPInstance),
BP(BPInstance),
}


/// Trait for shared functionality of all instance variants.
#[enum_dispatch(Instance)]
pub trait InstanceVariant {
pub trait InstanceGeneric {
fn items(&self) -> &[(Item, usize)];
fn item_qty(&self, id: usize) -> usize{
self.items()[id].1
Expand All @@ -29,6 +33,8 @@ pub trait InstanceVariant {
}


/// Bin-packing problem instance: a set of items to be packed into a set of bins.
/// The items are to be packed in such a way that the total cost of the bins used is minimized.
#[derive(Debug, Clone)]
pub struct BPInstance {
/// Items to be packed in the instance, along with their requested quantities
Expand All @@ -39,6 +45,8 @@ pub struct BPInstance {
pub bins: Vec<(Bin, usize)>,
}

/// Strip-packing problem instance: a set of items to be packed into a single strip.
/// The items are to be packed in such a way that the total width of the strip used is minimized.
#[derive(Debug, Clone)]
pub struct SPInstance {
pub items: Vec<(Item, usize)>,
Expand All @@ -64,7 +72,7 @@ impl SPInstance {
}
}

impl InstanceVariant for BPInstance {
impl InstanceGeneric for BPInstance {
fn items(&self) -> &[(Item, usize)] {
&self.items
}
Expand All @@ -74,7 +82,7 @@ impl InstanceVariant for BPInstance {
}
}

impl InstanceVariant for SPInstance {
impl InstanceGeneric for SPInstance {
fn items(&self) -> &[(Item, usize)] {
&self.items
}
Expand Down
1 change: 1 addition & 0 deletions jaguars/src/entities/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::geometry::primitives::simple_polygon::SimplePolygon;
use crate::geometry::transformation::Transformation;
use crate::util::config::SPSurrogateConfig;

/// An `Item` can be placed in a `Bin`.
#[derive(Clone, Debug)]
pub struct Item {
id: usize,
Expand Down
36 changes: 11 additions & 25 deletions jaguars/src/entities/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ use crate::geometry::d_transformation::DTransformation;
use crate::geometry::geo_traits::Shape;
use crate::util::assertions;

///A `Layout` represents a configuration of one or more `Item`s placed in a `Bin`.
///It is a mutable representation, and can be modified by placing or removing items.
#[derive(Clone)]
pub struct Layout {
id: usize,
Expand Down Expand Up @@ -102,8 +104,7 @@ impl Layout {
pub fn id(&self) -> usize {
self.id
}



pub fn cde(&self) -> &CDEngine {
&self.cde
}
Expand All @@ -113,29 +114,14 @@ impl Layout {
}
}


/// A `LayoutSnapshot` is an immutable representation of a `Layout` at a certain point in time.
/// `Layout`s can create `LayoutSnapshot`s, and restore themselves to a previous state using them.
#[derive(Clone, Debug)]
pub struct LayoutSnapshot {
id: usize,
bin: Bin,
placed_items: Vec<PlacedItem>,
cde_snapshot: CDESnapshot,
usage: f64,
}

impl LayoutSnapshot {
pub fn id(&self) -> usize {
self.id
}

pub fn bin(&self) -> &Bin {
&self.bin
}

pub fn placed_items(&self) -> &Vec<PlacedItem> {
&self.placed_items
}

pub fn usage(&self) -> f64 {
self.usage
}
pub id: usize,
pub bin: Bin,
pub placed_items: Vec<PlacedItem>,
pub cde_snapshot: CDESnapshot,
pub usage: f64,
}
2 changes: 1 addition & 1 deletion jaguars/src/entities/placing_option.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::geometry::d_transformation::DTransformation;
use crate::geometry::transformation::Transformation;

#[derive(Clone, Debug)]
/// Contains information about how an `Item` with a `Transformation` applied can be placed in a `Layout`
/// Contains all required information to place an `Item` in a `Problem`
pub struct PlacingOption {
pub layout_index: LayoutIndex,
pub item_id: usize,
Expand Down
22 changes: 11 additions & 11 deletions jaguars/src/entities/problems/bin_packing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ use std::sync::Arc;
use itertools::Itertools;

use crate::entities::instance::{BPInstance, Instance};
use crate::entities::instance::InstanceVariant;
use crate::entities::instance::InstanceGeneric;
use crate::entities::layout::Layout;
use crate::entities::placed_item::PlacedItemUID;
use crate::entities::placing_option::PlacingOption;
use crate::entities::problems::problem::{LayoutIndex, ProblemVariant};
use crate::entities::problems::problem::private::ProblemVariantPrivate;
use crate::entities::problems::problem::{LayoutIndex, ProblemGeneric};
use crate::entities::problems::problem::private::ProblemGenericPrivate;
use crate::entities::solution::Solution;
use crate::util::assertions;

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

impl ProblemVariant for BPProblem {
impl ProblemGeneric 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 @@ -162,7 +162,7 @@ impl ProblemVariant for BPProblem {
assert_eq!(old_solution.id, self.unchanged_layouts_solution_id.unwrap());
self.layouts.iter_mut().map(|l| {
match self.unchanged_layouts.contains(&l.id()) {
true => old_solution.layout_snapshots.iter().find(|sl| sl.id() == l.id()).unwrap().clone(),
true => old_solution.layout_snapshots.iter().find(|sl| sl.id == l.id()).unwrap().clone(),
false => l.create_layout_snapshot()
}
}).collect()
Expand Down Expand Up @@ -191,7 +191,7 @@ impl ProblemVariant for BPProblem {
let mut layout_ids_not_in_solution = vec![];
for layout in self.layouts.iter_mut() {
//For all layouts in the problem, check which ones occur in the solution
match solution.layout_snapshots.iter().position(|sl| sl.id() == layout.id()) {
match solution.layout_snapshots.iter().position(|sl| sl.id == layout.id()) {
Some(i) => {
//layout is present in the solution
match self.unchanged_layouts.contains(&layout.id()) {
Expand All @@ -215,9 +215,9 @@ impl ProblemVariant for BPProblem {

//Some layouts are present in the solution, but not in the problem
for sl in solution.layout_snapshots.iter() {
if !layout_ids_in_problem.contains(&sl.id()) {
if !layout_ids_in_problem.contains(&sl.id) {
//It is possible they are in the uncommitted_removed_layouts
match self.uncommitted_removed_layouts.iter().position(|l| l.id() == sl.id()) {
match self.uncommitted_removed_layouts.iter().position(|l| l.id() == sl.id) {
Some(i) => {
//original layout is still present, restore it and add it to the problem
let mut layout = self.uncommitted_removed_layouts.swap_remove(i);
Expand All @@ -226,7 +226,7 @@ impl ProblemVariant for BPProblem {
}
None => {
//If not, the layout will have to be rebuilt from scratch
let layout = Layout::new_from_stored(sl.id(), sl);
let layout = Layout::new_from_stored(sl.id, sl);
self.layouts.push(layout);
}
}
Expand All @@ -237,7 +237,7 @@ impl ProblemVariant for BPProblem {
//The id of the solution does not match unchanged_layouts_solution_id, a partial restore is not possible
self.layouts.clear();
for sl in solution.layout_snapshots.iter() {
let layout = Layout::new_from_stored(sl.id(), sl);
let layout = Layout::new_from_stored(sl.id, sl);
self.layouts.push(layout);
}
}
Expand Down Expand Up @@ -282,7 +282,7 @@ impl ProblemVariant for BPProblem {
}


impl ProblemVariantPrivate for BPProblem {
impl ProblemGenericPrivate for BPProblem {
fn next_solution_id(&mut self) -> usize {
self.solution_id_counter += 1;
self.solution_id_counter
Expand Down
18 changes: 10 additions & 8 deletions jaguars/src/entities/problems/problem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,23 @@ use itertools::Itertools;

use crate::entities::placing_option::PlacingOption;
use crate::entities::instance::Instance;
use crate::entities::instance::InstanceVariant;
use crate::entities::instance::InstanceGeneric;
use crate::entities::layout::Layout;
use crate::entities::placed_item::PlacedItemUID;
use crate::entities::problems::bin_packing::BPProblem;
use crate::entities::problems::problem::private::ProblemVariantPrivate;
use crate::entities::problems::problem::private::ProblemGenericPrivate;
use crate::entities::problems::strip_packing::SPProblem;
use crate::entities::solution::Solution;

/// Enum which contains all the different types implementing the `ProblemVariant` trait.
/// Enum which contains all the different 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`,
/// 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
/// Uses the `enum_dispatch` crate to have polymorphism with static dispatch, see
/// <https://docs.rs/enum_dispatch/latest/enum_dispatch/> for more information on enum_dispatch.
/// Also enables use match statements on the `Problem` enum when variant-specific behavior is required,
/// When a new variant is added, compile errors will be generated everywhere specific behaviour is required.
#[derive(Clone)]
#[enum_dispatch]
pub enum Problem {
Expand All @@ -32,7 +34,7 @@ pub enum Problem {

/// Trait for public shared functionality of all problem variants.
#[enum_dispatch(Problem)]
pub trait ProblemVariant: ProblemVariantPrivate {
pub trait ProblemGeneric: ProblemGenericPrivate {

/// Places an item into the problem instance according to the given `PlacingOption`.
fn place_item(&mut self, i_opt: &PlacingOption);
Expand Down Expand Up @@ -111,7 +113,7 @@ pub(super) mod private {

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

fn missing_item_qtys_mut(&mut self) -> &mut [isize];
Expand Down
10 changes: 5 additions & 5 deletions jaguars/src/entities/problems/strip_packing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ use crate::collision_detection::hazard_filters::hazard_filter;
use crate::entities::bin::Bin;
use crate::entities::placing_option::PlacingOption;
use crate::entities::instance::{BPInstance, Instance, SPInstance};
use crate::entities::instance::InstanceVariant;
use crate::entities::instance::InstanceGeneric;
use crate::entities::layout::Layout;
use crate::entities::placed_item::PlacedItemUID;
use crate::entities::problems::problem::{LayoutIndex, ProblemVariant};
use crate::entities::problems::problem::private::ProblemVariantPrivate;
use crate::entities::problems::problem::{LayoutIndex, ProblemGeneric};
use crate::entities::problems::problem::private::ProblemGenericPrivate;
use crate::entities::solution::Solution;
use crate::geometry::geo_traits::{Shape, Transformable};
use crate::util::assertions;
Expand Down Expand Up @@ -101,7 +101,7 @@ impl SPProblem {
}
}

impl ProblemVariant for SPProblem {
impl ProblemGeneric 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 ProblemVariant for SPProblem {
}


impl ProblemVariantPrivate for SPProblem {
impl ProblemGenericPrivate for SPProblem {
fn next_solution_id(&mut self) -> usize {
self.solution_id_counter += 1;
self.solution_id_counter
Expand Down
21 changes: 9 additions & 12 deletions jaguars/src/entities/quality_zone.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,23 @@
use std::sync::Arc;

use crate::geometry::primitives::simple_polygon::SimplePolygon;
use crate::N_QUALITIES;

/// Maximum number of qualities that can be used
pub const N_QUALITIES: usize = 10;

/// Represents a zone of certain quality in the `Bin`
#[derive(Clone, Debug)]
pub struct QualityZone {
/// Higher quality is better
quality: usize,
shapes: Vec<Arc<SimplePolygon>>,
pub quality: usize,
/// The outer shapes of all zones of this quality
pub zones: Vec<Arc<SimplePolygon>>,
}

impl QualityZone {
pub fn new(quality: usize, shapes: Vec<SimplePolygon>) -> Self {
assert!(quality < N_QUALITIES, "Quality must be less than N_QUALITIES");
let shapes = shapes.into_iter().map(|z| Arc::new(z)).collect();
Self { quality, shapes }
}
pub fn quality(&self) -> usize {
self.quality
}

pub fn shapes(&self) -> &Vec<Arc<SimplePolygon>> {
&self.shapes
let zones = shapes.into_iter().map(|z| Arc::new(z)).collect();
Self { quality, zones }
}
}
Loading

0 comments on commit ed5b680

Please sign in to comment.