Stop combining if finished, update layouts between x and y
This commit is contained in:
parent
2b08da0809
commit
148f59010e
2 changed files with 36 additions and 15 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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…
Reference in a new issue