94 lines
3.4 KiB
Rust
94 lines
3.4 KiB
Rust
use rand::prelude::{StdRng, SliceRandom};
|
|
use rand::{SeedableRng, Rng, thread_rng};
|
|
use std::fmt;
|
|
use std::fmt::Formatter;
|
|
use std::collections::{HashMap, HashSet};
|
|
use city::{HouseLayout, City, House};
|
|
use crate::db::LayoutDB;
|
|
use crate::population::build_house_probabilities;
|
|
|
|
mod optimization;
|
|
mod population;
|
|
mod city;
|
|
mod db;
|
|
|
|
fn main() {
|
|
let mut db = LayoutDB::from_file("layouts.sqlite").expect("Failed to load the DB");
|
|
eprintln!("Loaded the DB, {} stored layouts", db.layouts().len());
|
|
|
|
let city = City::read_from_file("01.in");
|
|
eprintln!("Loaded the city file, {} houses", city.get_house_count());
|
|
|
|
const MIN_WEIGHT_SCORE: f64 = 600000.;
|
|
const MAX_WEIGHT_SCORE: f64 = 700000.;
|
|
const DB_CHOICE_PROBABILITY: f64 = 0.99;
|
|
|
|
let mut best_price: Option<u32> = None;
|
|
|
|
loop {
|
|
let seed: u64 = thread_rng().gen();
|
|
eprintln!("Starting seed {}", seed);
|
|
let mut rng = StdRng::seed_from_u64(seed);
|
|
let mut layout = HouseLayout::new(&city);
|
|
//eprintln!("Starting random population...");
|
|
//population::populate_random(&mut layout, &mut rng);
|
|
eprintln!("Starting random population, using DB ({}-{} {})...",
|
|
MIN_WEIGHT_SCORE, MAX_WEIGHT_SCORE, DB_CHOICE_PROBABILITY);
|
|
population::populate_using_db(&mut layout, &mut rng, &db, MIN_WEIGHT_SCORE, MAX_WEIGHT_SCORE, DB_CHOICE_PROBABILITY);
|
|
eprintln!("Finished random init, price: {}, houses: {}", layout.price(), layout.houses().len());
|
|
let mut last_improved_step = -1;
|
|
loop {
|
|
if last_improved_step == 1 {
|
|
break;
|
|
}
|
|
eprintln!("Starting moving individual houses...");
|
|
if optimization::improve_move_individual_houses(&mut layout, &mut rng) {
|
|
dump_layout(&layout, &mut best_price, seed);
|
|
last_improved_step = 1;
|
|
}
|
|
eprintln!("Finished moving individual houses...");
|
|
|
|
if last_improved_step == 2 {
|
|
break;
|
|
}
|
|
eprintln!("Starting pairwise house merge...");
|
|
if optimization::improve_merge_pairwise(&mut layout) {
|
|
dump_layout(&layout, &mut best_price, seed);
|
|
last_improved_step = 2;
|
|
}
|
|
eprintln!("Finished pairwise house merge");
|
|
//eprintln!("Starting pairwise house move...");
|
|
//if optimization::improve_move_houses_pairwise(&mut layout) {
|
|
// dump_layout(&layout, &mut best_price, seed);
|
|
// improved = true;
|
|
//}
|
|
//eprintln!("Finished pairwise house move");
|
|
}
|
|
db.add_layout(&layout.houses(), true).expect("Failed to insert into DB");
|
|
}
|
|
}
|
|
|
|
fn print_houses(houses: &Vec<House>) {
|
|
println!("{}", houses.len());
|
|
for house in houses {
|
|
println!("{} {}", house.y, house.x);
|
|
}
|
|
}
|
|
|
|
fn dump_layout(layout: &HouseLayout, best_price: &mut Option<u32>, seed: u64) {
|
|
let price = layout.price();
|
|
if best_price.is_none() || price < best_price.unwrap() {
|
|
*best_price = Some(price);
|
|
eprintln!("Printing {} - new best", price);
|
|
println!("New best!");
|
|
println!("Price {}, seed {}", price, seed);
|
|
print_houses(&layout.houses());
|
|
println!();
|
|
} else {
|
|
eprintln!("Printing {}", price);
|
|
println!("Price {}, seed {}", price, seed);
|
|
print_houses(&layout.houses());
|
|
println!();
|
|
}
|
|
}
|
|
|