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 = 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) { println!("{}", houses.len()); for house in houses { println!("{} {}", house.y, house.x); } } fn dump_layout(layout: &HouseLayout, best_price: &mut Option, 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!(); } }