Skip to content

Commit

Permalink
renamed empty layouts to template layouts
Browse files Browse the repository at this point in the history
  • Loading branch information
JeroenGar committed Feb 23, 2024
1 parent 9892f2d commit e16610e
Show file tree
Hide file tree
Showing 12 changed files with 82 additions and 82 deletions.
39 changes: 19 additions & 20 deletions jagua-rs/src/entities/problems/bin_packing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ use crate::util::assertions;
pub struct BPProblem {
pub instance: BPInstance,
layouts: Vec<Layout>,
// TODO: document empty layouts
empty_layouts: Vec<Layout>,
template_layouts: Vec<Layout>,
missing_item_qtys: Vec<isize>,
bin_qtys: Vec<usize>,
layout_id_counter: usize,
Expand All @@ -33,18 +32,18 @@ impl BPProblem {
let missing_item_qtys = instance.items.iter().map(|(_, qty)| *qty as isize).collect_vec();
let bin_qtys = instance.bins.iter().map(|(_, qty)| *qty).collect_vec();
let layouts = vec![];
let empty_layouts = instance.bins.iter().enumerate().map(|(i, (bin, _))| {
Layout::new(i, bin.clone())
}).collect_vec();
let layout_id_counter = empty_layouts.len();
let template_layouts = instance.bins.iter().enumerate()
.map(|(i, (bin, _))| Layout::new(i, bin.clone()))
.collect_vec();
let layout_id_counter = template_layouts.len();
let unchanged_layouts = vec![];
let unchanged_layouts_solution_id = None;
let uncommitted_removed_layouts = vec![];

Self {
instance,
layouts,
empty_layouts,
template_layouts,
missing_item_qtys,
bin_qtys,
layout_id_counter,
Expand All @@ -67,20 +66,20 @@ impl BPProblem {
}
);
self.layouts.push(layout);
LayoutIndex::Existing(self.layouts.len() - 1)
LayoutIndex::Real(self.layouts.len() - 1)
}

pub fn unregister_layout(&mut self, layout_index: LayoutIndex) {
match layout_index {
LayoutIndex::Existing(i) => {
LayoutIndex::Real(i) => {
let layout = self.layouts.remove(i);
self.layout_has_changed(layout.id());
self.unregister_bin(layout.bin().id);
layout.placed_items().iter().for_each(
|v| { self.unregister_included_item(v.item_id()) });
self.uncommitted_removed_layouts.push(layout);
}
LayoutIndex::Empty(_) => unreachable!("cannot remove empty layout")
LayoutIndex::Template(_) => unreachable!("cannot remove template layout")
}
}

Expand Down Expand Up @@ -114,18 +113,18 @@ impl BPProblem {
impl ProblemGeneric for BPProblem {
fn place_item(&mut self, i_opt: &PlacingOption) -> LayoutIndex {
let layout_index = match &i_opt.layout_index {
LayoutIndex::Existing(i) => LayoutIndex::Existing(*i),
LayoutIndex::Empty(i) => {
LayoutIndex::Real(i) => LayoutIndex::Real(*i),
LayoutIndex::Template(i) => {
//Layout is empty, clone it and add it to `layouts`
let next_layout_id = self.next_layout_id();
let empty_layout = &self.empty_layouts[*i];
let copy = empty_layout.clone_with_id(next_layout_id);
let template = &self.template_layouts[*i];
let copy = template.clone_with_id(next_layout_id);
self.register_layout(copy)
}
};
let layout = match layout_index {
LayoutIndex::Existing(i) => &mut self.layouts[i],
LayoutIndex::Empty(_) => unreachable!("cannot place item in empty layout")
LayoutIndex::Real(i) => &mut self.layouts[i],
LayoutIndex::Template(_) => unreachable!("cannot place item in template layout")
};
let item = self.instance.item(i_opt.item_id);
layout.place_item(item, &i_opt.d_transf);
Expand All @@ -139,7 +138,7 @@ impl ProblemGeneric for BPProblem {

fn remove_item(&mut self, layout_index: LayoutIndex, pi_uid: &PlacedItemUID, commit_instantly: bool) {
match layout_index {
LayoutIndex::Existing(i) => {
LayoutIndex::Real(i) => {
self.layout_has_changed(self.layouts[i].id());
let layout = &mut self.layouts[i];
layout.remove_item(pi_uid, commit_instantly);
Expand All @@ -149,7 +148,7 @@ impl ProblemGeneric for BPProblem {
}
self.unregister_included_item(pi_uid.item_id);
}
LayoutIndex::Empty(_) => unreachable!("cannot remove item from empty layout")
LayoutIndex::Template(_) => unreachable!("cannot remove item from template layout")
}
}

Expand Down Expand Up @@ -262,8 +261,8 @@ impl ProblemGeneric for BPProblem {
&mut self.layouts
}

fn empty_layouts(&self) -> &[Layout] {
&self.empty_layouts
fn template_layouts(&self) -> &[Layout] {
&self.template_layouts
}

fn missing_item_qtys(&self) -> &[isize] {
Expand Down
10 changes: 5 additions & 5 deletions jagua-rs/src/entities/problems/problem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ use crate::entities::layout::Layout;
use crate::entities::placed_item::PlacedItemUID;
use crate::entities::placing_option::PlacingOption;
use crate::entities::problems::bin_packing::BPProblem;
use crate::entities::problems::problem_generic::private::ProblemGenericPrivate;
use crate::entities::problems::problem_generic::{LayoutIndex, ProblemGeneric};
use crate::entities::problems::problem_generic::private::ProblemGenericPrivate;
use crate::entities::problems::strip_packing::SPProblem;
use crate::entities::solution::Solution;

Expand All @@ -23,7 +23,7 @@ pub enum Problem {
}

impl ProblemGeneric for Problem {
fn place_item(&mut self, i_opt: &PlacingOption) -> LayoutIndex{
fn place_item(&mut self, i_opt: &PlacingOption) -> LayoutIndex {
match self {
Problem::BP(bp) => bp.place_item(i_opt),
Problem::SP(sp) => sp.place_item(i_opt),
Expand Down Expand Up @@ -65,10 +65,10 @@ impl ProblemGeneric for Problem {
}
}

fn empty_layouts(&self) -> &[Layout] {
fn template_layouts(&self) -> &[Layout] {
match self {
Problem::BP(bp) => bp.empty_layouts(),
Problem::SP(sp) => sp.empty_layouts(),
Problem::BP(bp) => bp.template_layouts(),
Problem::SP(sp) => sp.template_layouts(),
}
}

Expand Down
35 changes: 20 additions & 15 deletions jagua-rs/src/entities/problems/problem_generic.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::borrow::Borrow;

use crate::entities::layout::Layout;
use crate::entities::placed_item::PlacedItemUID;
use crate::entities::placing_option::PlacingOption;
Expand All @@ -7,7 +8,6 @@ use crate::entities::solution::Solution;

/// Trait for public shared functionality of all problem variants.
pub trait ProblemGeneric: ProblemGenericPrivate {

/// Places an item into the problem instance according to the given `PlacingOption`.
/// Returns the index of the layout where the item was placed.
fn place_item(&mut self, i_opt: &PlacingOption) -> LayoutIndex;
Expand All @@ -27,9 +27,9 @@ pub trait ProblemGeneric: ProblemGenericPrivate {
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];
/// Returns the template layouts of the problem instance, with no items placed in them.
/// When an item is placed in a template layout, a new real layout is created
fn template_layouts(&self) -> &[Layout];

/// The quantity of each item that is requested but currently missing in the problem instance.
/// Indexed by item id.
Expand All @@ -50,15 +50,23 @@ pub trait ProblemGeneric: ProblemGenericPrivate {

fn included_item_qtys(&self) -> Vec<usize>;

fn empty_layout_has_stock(&self, index: usize) -> bool {
let bin_id = self.empty_layouts()[index].bin().id;
self.bin_qtys()[bin_id] > 0
fn layout_indices(&self) -> impl Iterator<Item=LayoutIndex> {
(0..self.layouts().len()).into_iter().map(|i| LayoutIndex::Real(i))
}

fn template_layout_indices_with_stock(&self) -> impl Iterator<Item=LayoutIndex> {
self.template_layouts().iter().enumerate().filter_map(|(i, l)| {
match self.bin_qtys()[l.bin().id] {
0 => None,
_ => Some(LayoutIndex::Template(i))
}
})
}

fn get_layout(&self, index: impl Borrow<LayoutIndex>) -> &Layout {
match index.borrow() {
LayoutIndex::Existing(i) => &self.layouts()[*i],
LayoutIndex::Empty(i) => &self.empty_layouts()[*i]
LayoutIndex::Real(i) => &self.layouts()[*i],
LayoutIndex::Template(i) => &self.template_layouts()[*i]
}
}

Expand All @@ -81,7 +89,6 @@ pub trait ProblemGeneric: ProblemGenericPrivate {
}

pub(super) mod private {

/// Trait for shared functionality of all problem variants, but not exposed to the public.
pub trait ProblemGenericPrivate: Clone {
fn next_solution_id(&mut self) -> usize;
Expand All @@ -99,10 +106,8 @@ pub(super) mod private {
}

#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
/// Unique identifier for a layout in a problem instance.
/// Unique index for a `Layout` in a problem instance.
pub enum LayoutIndex {
/// Existing layout (at least one item) and its index in the `Problem`'s `layouts` vector.
Existing(usize),
/// Empty layout (no items) and its index in the `Problem`'s `empty_layouts` vector.
Empty(usize),
Real(usize),
Template(usize),
}
16 changes: 8 additions & 8 deletions jagua-rs/src/entities/problems/strip_packing.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::slice;
use std::{iter, slice};

use itertools::Itertools;
use ordered_float::NotNan;
Expand Down Expand Up @@ -63,7 +63,7 @@ impl SPProblem {
let transformed_shape = shape.transform_clone(&transf);
if !self.layout.cde().shape_collides(&transformed_shape, entities_to_ignore.as_ref()) {
let insert_opt = PlacingOption {
layout_index: LayoutIndex::Existing(0),
layout_index: LayoutIndex::Real(0),
item_id: p_uid.item_id,
transf,
d_transf: p_uid.d_transf.clone(),
Expand Down Expand Up @@ -99,17 +99,17 @@ impl SPProblem {

impl ProblemGeneric for SPProblem {
fn place_item(&mut self, i_opt: &PlacingOption) -> LayoutIndex {
assert_eq!(i_opt.layout_index, LayoutIndex::Existing(0), "strip packing problems only have a single layout");
assert_eq!(i_opt.layout_index, LayoutIndex::Real(0), "Strip packing problems only have a single layout");
let item_id = i_opt.item_id;
let item = self.instance.item(item_id);
self.layout.place_item(item, &i_opt.d_transf);

self.register_included_item(item_id);
LayoutIndex::Existing(0)
LayoutIndex::Real(0)
}

fn remove_item(&mut self, layout_index: LayoutIndex, pi_uid: &PlacedItemUID, commit_instantly: bool) {
assert_eq!(layout_index, LayoutIndex::Existing(0), "strip packing problems only have a single layout");
assert_eq!(layout_index, LayoutIndex::Real(0), "strip packing problems only have a single layout");
self.layout.remove_item(pi_uid, commit_instantly);
self.unregister_included_item(pi_uid.item_id);
}
Expand Down Expand Up @@ -146,7 +146,7 @@ impl ProblemGeneric for SPProblem {
slice::from_mut(&mut self.layout)
}

fn empty_layouts(&self) -> &[Layout] {
fn template_layouts(&self) -> &[Layout] {
&[]
}

Expand All @@ -160,8 +160,8 @@ impl ProblemGeneric for SPProblem {
.collect_vec()
}

fn empty_layout_has_stock(&self, _index: usize) -> bool {
false
fn template_layout_indices_with_stock(&self) -> impl Iterator<Item=LayoutIndex> {
iter::empty::<LayoutIndex>()
}

fn bin_qtys(&self) -> &[usize] {
Expand Down
8 changes: 4 additions & 4 deletions jagua-rs/src/io/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,8 +198,8 @@ fn build_solution_from_json(json_layouts: &[JsonLayout], instance: Arc<Instance>
};
//Create the layout by inserting the first item

//Find the empty layout matching the bin id in the JSON solution, 0 if strip packing instance.
let (empty_layout_index, _) = problem.empty_layouts().iter().enumerate()
//Find the template layout matching the bin id in the JSON solution, 0 if strip packing instance.
let (template_layout_index, _) = problem.template_layouts().iter().enumerate()
.find(|(_, layout)| layout.bin().id == bin.map_or(0, |b| b.id)).unwrap();

let bin_centering = bin.map_or(DTransformation::empty(), |b| DTransformation::from(&b.centering_transform)).translation();
Expand All @@ -220,7 +220,7 @@ fn build_solution_from_json(json_layouts: &[JsonLayout], instance: Arc<Instance>
let d_transf = transf.decompose();

let initial_insert_opt = PlacingOption {
layout_index: LayoutIndex::Empty(empty_layout_index),
layout_index: LayoutIndex::Template(template_layout_index),
item_id: first_item.id,
transf,
d_transf,
Expand All @@ -244,7 +244,7 @@ fn build_solution_from_json(json_layouts: &[JsonLayout], instance: Arc<Instance>
let d_transf = transf.decompose();

let insert_opt = PlacingOption {
layout_index: LayoutIndex::Existing(layout_index),
layout_index: LayoutIndex::Real(layout_index),
item_id: item.id,
transf,
d_transf,
Expand Down
4 changes: 2 additions & 2 deletions lbf/benches/edge_sensitivity_bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,13 @@ fn edge_sensitivity_bench(config: Config, mut g: BenchmarkGroup<WallTime>) {
surrogate: true,
..SvgDrawOptions::default()
};
let svg = io::layout_to_svg::layout_to_svg(problem.get_layout(LayoutIndex::Existing(0)), &instance, draw_options);
let svg = io::layout_to_svg::layout_to_svg(problem.get_layout(LayoutIndex::Real(0)), &instance, draw_options);
io::write_svg(&svg, Path::new(&format!("edge_sensitivity_{edge_multiplier}.svg")));
}

let mut rng = SmallRng::seed_from_u64(0);

let layout = problem.get_layout(LayoutIndex::Existing(0));
let layout = problem.get_layout(LayoutIndex::Real(0));
/*let samples = {
let sampler = UniformAARectSampler::new(layout.bin().bbox(), instance.item(0));
(0..N_SAMPLES).map(
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 @@ -53,7 +53,7 @@ fn fast_fail_query_bench(c: &mut Criterion) {
println!("avg number of edges per item: {}", ITEMS_ID_TO_TEST.iter().map(|&item_id| instance.item(item_id).shape.number_of_points()).sum::<usize>() as f64 / ITEMS_ID_TO_TEST.len() as f64);

let mut rng = SmallRng::seed_from_u64(0);
let layout = problem.get_layout(LayoutIndex::Existing(0));
let layout = problem.get_layout(LayoutIndex::Real(0));
let samples = ITEMS_ID_TO_TEST.iter()
.map(|&item_id| {
let sampler = HPGSampler::new(instance.item(item_id), layout).unwrap();
Expand Down
Loading

0 comments on commit e16610e

Please sign in to comment.