Browse Source

Start combining from best pairs, stop at cheapest valid

master
Jirka Sejkora 3 years ago
parent
commit
dfedf7b3ae
  1. 2
      src/combine-layouts.rs
  2. 50
      src/combine.rs

2
src/combine-layouts.rs

@ -16,7 +16,7 @@ fn main() {
let layouts = db.layouts();
let sorted: Vec<_> = layouts.iter().sorted_by(|x, y| city::get_price(&city, x.houses()).cmp(&city::get_price(&city, y.houses()))).collect();
const TOP_LAYOUT_COUNT: usize = 10;
const TOP_LAYOUT_COUNT: usize = 100;
let chosen_layouts = sorted.iter().take(TOP_LAYOUT_COUNT).map(|l| l.houses()).collect();
eprintln!("Starting to combine {} top houses DB; vertical cuts", TOP_LAYOUT_COUNT);

50
src/combine.rs

@ -1,6 +1,7 @@
use crate::city;
use crate::city::{City, House, SIZE, HOUSE_RANGE};
use itertools::Itertools;
use itertools::iproduct;
use std::collections::VecDeque;
use std::collections::vec_deque::Iter;
@ -9,7 +10,7 @@ pub fn try_combine(city: &City, left_layouts: &Vec<&Vec<House>>, right_layouts:
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())
.collect();
let mut right_houses_sorted: Vec<Vec<House>> = right_layouts.iter()
let right_houses_sorted: Vec<Vec<House>> = right_layouts.iter()
.map(|l| l.iter().sorted_by(|h1, h2| h2.x.cmp(&h1.x)).map(|x| *x).collect())
.collect();
@ -34,7 +35,7 @@ pub fn try_combine(city: &City, left_layouts: &Vec<&Vec<House>>, right_layouts:
for x in 0..SIZE {
eprintln!("Starting x {}", x);
// Update the lines
for (mut left_line, mut 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()) {
while let Some(house) = left_houses.last() {
if house.x == x {
left_line.add_house(*house, &city);
@ -45,7 +46,7 @@ pub fn try_combine(city: &City, left_layouts: &Vec<&Vec<House>>, right_layouts:
}
}
for mut right_line in rights.iter_mut() {
for right_line in rights.iter_mut() {
right_line.remove_houses(x, &city);
}
@ -56,31 +57,32 @@ pub fn try_combine(city: &City, left_layouts: &Vec<&Vec<House>>, right_layouts:
continue;
}
let pairs: Vec<_> = iproduct!(lefts.iter().enumerate(), rights.iter().enumerate())
.filter(|((left_i, left), (right_i, right))| left_i != right_i)
.map(|((left_i, left), (right_i, right))| (left, right, left.price + right.price, left_i, right_i))
.sorted_by(|(_, _, price1, _, _), (_, _, price2, _, _)| price1.cmp(&price2))
.collect();
let mut compatibles = 0;
let mut incompatibles = 0;
for (left_i, left) in lefts.iter().enumerate() {
for (right_i, right) in rights.iter().enumerate() {
if left_i == right_i {
// Do not compare the same layout
continue;
}
if is_compatible(city, &left, &right) {
let price = left.price + right.price;
if best_price.is_none() || price < best_price.unwrap() {
best_price = Some(price);
eprintln!("{} - new best score, cut on x {}, left {} - right {}, printing", price, x, left_i, right_i);
println!("{} - new best score, cut on x {}, left {} - right {}", price, x, left_i, right_i);
let new_houses: Vec<_> = left.houses().chain(right.houses()).collect();
println!("{}", new_houses.len());
for house in new_houses {
println!("{} {}", house.y, house.x);
}
for (left, right, price, left_i, right_i) in pairs {
if is_compatible(city, &left, &right) {
if best_price.is_none() || price < best_price.unwrap() {
best_price = Some(price);
eprintln!("{} - new best score, cut on x {}, left {} - right {}, printing", price, x, left_i, right_i);
println!("{} - new best score, cut on x {}, left {} - right {}", price, x, left_i, right_i);
let new_houses: Vec<_> = left.houses().chain(right.houses()).collect();
println!("{}", new_houses.len());
for house in new_houses {
println!("{} {}", house.y, house.x);
}
compatibles += 1;
} else {
incompatibles += 1;
}
compatibles += 1;
// All other pairs would be more expensive
break;
} else {
incompatibles += 1;
}
}

Loading…
Cancel
Save