Browse Source

Stop combining if finished, update layouts between x and y

master
Jirka Sejkora 4 years ago
parent
commit
148f59010e
  1. 31
      src/combine-layouts.rs
  2. 20
      src/combine.rs

31
src/combine-layouts.rs

@ -7,6 +7,11 @@ mod city;
mod db; mod db;
mod combine; mod combine;
#[derive(Eq, PartialEq)]
enum LastStep {
None, Vertical, Horizontal
}
fn main() { fn main() {
let mut db = LayoutDB::from_file("layouts.sqlite").expect("Failed to load the DB"); let mut db = LayoutDB::from_file("layouts.sqlite").expect("Failed to load the DB");
eprintln!("Loaded the DB, {} stored layouts", db.layouts().len()); eprintln!("Loaded the DB, {} stored layouts", db.layouts().len());
@ -18,22 +23,36 @@ fn main() {
let transposed_city = transpose_city(&city); let transposed_city = transpose_city(&city);
eprintln!("Finished building a transposed city"); eprintln!("Finished building a transposed city");
const TOP_LAYOUT_COUNT: usize = 100;
let mut last_improve_step = LastStep::None;
loop { loop {
if last_improve_step == LastStep::Vertical { break; }
eprintln!("Starting to combine {} top houses DB; vertical cuts", TOP_LAYOUT_COUNT);
let sorted: Vec<_> = db.layouts().iter() let sorted: Vec<_> = db.layouts().iter()
.sorted_by(|x, y| city::get_price(&city, x.houses()).cmp(&city::get_price(&city, y.houses()))) .sorted_by(|x, y| city::get_price(&city, x.houses()).cmp(&city::get_price(&city, y.houses())))
.map(|layout| layout.clone()) .map(|layout| layout.clone())
.collect(); .collect();
const TOP_LAYOUT_COUNT: usize = 1000;
let chosen_layouts: Vec<_> = sorted.iter().take(TOP_LAYOUT_COUNT).map(|l| l.houses().clone()).collect(); let chosen_layouts: Vec<_> = sorted.iter().take(TOP_LAYOUT_COUNT).map(|l| l.houses().clone()).collect();
if combine::try_combine(&city, &chosen_layouts, &chosen_layouts, &mut db, false) {
last_improve_step = LastStep::Vertical;
}
eprintln!("Finished vertical cuts, improvement: {}", last_improve_step == LastStep::Vertical);
eprintln!("Starting to combine {} top houses DB; vertical cuts", TOP_LAYOUT_COUNT); if last_improve_step == LastStep::Horizontal { break; }
combine::try_combine(&city, &chosen_layouts, &chosen_layouts, &mut db, false);
let sorted: Vec<_> = db.layouts().iter()
.sorted_by(|x, y| city::get_price(&city, x.houses()).cmp(&city::get_price(&city, y.houses())))
.map(|layout| layout.clone())
.collect();
let chosen_layouts: Vec<_> = sorted.iter().take(TOP_LAYOUT_COUNT).map(|l| l.houses().clone()).collect();
let transposed_chosen_layouts: Vec<_> = chosen_layouts.iter().map(|x| transpose_layout(x)).collect(); let transposed_chosen_layouts: Vec<_> = chosen_layouts.iter().map(|x| transpose_layout(x)).collect();
eprintln!("Starting to combine {} top houses DB; horizontal cuts", TOP_LAYOUT_COUNT); eprintln!("Starting to combine {} top houses DB; horizontal cuts", TOP_LAYOUT_COUNT);
combine::try_combine(&transposed_city, &transposed_chosen_layouts, &transposed_chosen_layouts, &mut db, true); if combine::try_combine(&transposed_city, &transposed_chosen_layouts, &transposed_chosen_layouts, &mut db, true) {
last_improve_step = LastStep::Horizontal;
}
eprintln!("Finished horizontal cuts, improvement: {}", last_improve_step == LastStep::Horizontal);
} }
} }

20
src/combine.rs

@ -6,7 +6,9 @@ use itertools::iproduct;
use std::collections::VecDeque; use std::collections::VecDeque;
use std::collections::vec_deque::Iter; use std::collections::vec_deque::Iter;
pub fn try_combine(city: &City, left_layouts: &Vec<Vec<House>>, right_layouts: &Vec<Vec<House>>, db: &mut LayoutDB, transposed: bool) { pub fn try_combine(city: &City, left_layouts: &Vec<Vec<House>>, right_layouts: &Vec<Vec<House>>, db: &mut LayoutDB, transposed: bool) -> bool {
let mut improved = false;
// Sorted in reverse so we can remove from the end // Sorted in reverse so we can remove from the end
let mut left_houses_sorted: Vec<Vec<House>> = left_layouts.iter() let mut left_houses_sorted: Vec<Vec<House>> = left_layouts.iter()
.map(|l| l.iter().sorted_by(|h1, h2| h2.x.cmp(&h1.x)).map(|x| *x).collect()) .map(|l| l.iter().sorted_by(|h1, h2| h2.x.cmp(&h1.x)).map(|x| *x).collect())
@ -35,13 +37,11 @@ pub fn try_combine(city: &City, left_layouts: &Vec<Vec<House>>, right_layouts: &
.map(|layout| city::get_price(&city, layout)) .map(|layout| city::get_price(&city, layout))
.min(); .min();
let axis = if transposed { "y" } else { "x" };
// x is the last left coordinate, x+1 is right // x is the last left coordinate, x+1 is right
for x in 0..SIZE { for x in 0..SIZE {
if transposed { eprintln!("Starting {} {}", axis, x);
eprintln!("Starting y {}", x);
} else {
eprintln!("Starting x {}", x);
}
// Update the lines // Update the lines
for (left_line, left_houses) in lefts.iter_mut().zip(left_houses_sorted.iter_mut()) { for (left_line, left_houses) in lefts.iter_mut().zip(left_houses_sorted.iter_mut()) {
@ -78,9 +78,8 @@ pub fn try_combine(city: &City, left_layouts: &Vec<Vec<House>>, right_layouts: &
if is_compatible(city, &left, &right) { if is_compatible(city, &left, &right) {
if best_price.is_none() || price < best_price.unwrap() { if best_price.is_none() || price < best_price.unwrap() {
best_price = Some(price); best_price = Some(price);
let axis = if transposed { "y" } else { "x" }; eprintln!("{} - new best score, cut on {} {}, left {} - right {}, printing", price, axis, x, left_i, right_i);
eprintln!("{} - new best score, cut on {} {}, left {} - right {}, printing", axis, price, x, left_i, right_i); println!("{} - new best score, cut on {} {}, left {} - right {}", price, axis, x, left_i, right_i);
println!("{} - new best score, cut on {} {}, left {} - right {}", axis, price, x, left_i, right_i);
let mut new_houses: Vec<_> = left.houses().copied().chain(right.houses().copied()).collect(); let mut new_houses: Vec<_> = left.houses().copied().chain(right.houses().copied()).collect();
if transposed { if transposed {
new_houses = transpose_layout(&new_houses); new_houses = transpose_layout(&new_houses);
@ -92,6 +91,7 @@ pub fn try_combine(city: &City, left_layouts: &Vec<Vec<House>>, right_layouts: &
// We only add best results to avoid overfilling the database with similar layouts // We only add best results to avoid overfilling the database with similar layouts
db.add_layout(&new_houses, true); db.add_layout(&new_houses, true);
improved = true;
} }
compatibles += 1; compatibles += 1;
@ -104,6 +104,8 @@ pub fn try_combine(city: &City, left_layouts: &Vec<Vec<House>>, right_layouts: &
eprintln!("{} incompatibles checked before {} compatible", incompatibles, compatibles); eprintln!("{} incompatibles checked before {} compatible", incompatibles, compatibles);
} }
improved
} }
fn is_compatible(city: &City, left: &LeftLine, right: &RightLine) -> bool { fn is_compatible(city: &City, left: &LeftLine, right: &RightLine) -> bool {

Loading…
Cancel
Save