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 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(); 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(); 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); 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;
use crate::city::{City, House, SIZE, HOUSE_RANGE}; use crate::city::{City, House, SIZE, HOUSE_RANGE};
use itertools::Itertools; use itertools::Itertools;
use itertools::iproduct;
use std::collections::VecDeque; use std::collections::VecDeque;
use std::collections::vec_deque::Iter; 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() 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())
.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()) .map(|l| l.iter().sorted_by(|h1, h2| h2.x.cmp(&h1.x)).map(|x| *x).collect())
.collect(); .collect();
@ -34,7 +35,7 @@ pub fn try_combine(city: &City, left_layouts: &Vec<&Vec<House>>, right_layouts:
for x in 0..SIZE { for x in 0..SIZE {
eprintln!("Starting x {}", x); eprintln!("Starting x {}", x);
// Update the lines // 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() { while let Some(house) = left_houses.last() {
if house.x == x { if house.x == x {
left_line.add_house(*house, &city); 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); right_line.remove_houses(x, &city);
} }
@ -56,31 +57,32 @@ pub fn try_combine(city: &City, left_layouts: &Vec<&Vec<House>>, right_layouts:
continue; 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 compatibles = 0;
let mut incompatibles = 0; let mut incompatibles = 0;
for (left_i, left) in lefts.iter().enumerate() { for (left, right, price, left_i, right_i) in pairs {
for (right_i, right) in rights.iter().enumerate() { if is_compatible(city, &left, &right) {
if left_i == right_i { if best_price.is_none() || price < best_price.unwrap() {
// Do not compare the same layout best_price = Some(price);
continue; 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();
if is_compatible(city, &left, &right) { println!("{}", new_houses.len());
let price = left.price + right.price; for house in new_houses {
if best_price.is_none() || price < best_price.unwrap() { println!("{} {}", house.y, house.x);
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