Řešení KSP úlohy 33-3-4 Obsazování území https://ksp.mff.cuni.cz/h/ulohy/33/zadani3.html#task-33-3-4
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

95 lines
3.5 KiB

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::SqliteLayoutDB;
use crate::population::{build_house_probabilities, populate_from_saved_layout};
use itertools::Itertools;
mod optimization;
mod population;
mod city;
mod db;
enum RunType {
GenNew, TryImproveBest
}
fn main() {
let mut db = SqliteLayoutDB::from_file("layouts.sqlite", false).expect("Failed to load the DB");
eprintln!("Loaded the DB, {} stored layouts", db.layouts().len());
let city = City::read_from_file("01.in", city::INPUT_CITY_WIDTH, city::INPUT_CITY_HEIGHT);
eprintln!("Loaded the city file, {} houses", city.get_house_count());
const MIN_WEIGHT_SCORE: f64 = 530000.;
const MAX_WEIGHT_SCORE: f64 = 540000.;
const DB_CHOICE_PROBABILITY: f64 = 0.99;
const START_WITH_MERGE: bool = false;
//let best_layouts: Vec<_> = db.layouts().iter()
// .sorted_by(|x, y| city::get_price(&city, x.houses()).cmp(&city::get_price(&city, y.houses())))
// .take_while(|x| city::get_price(&city, x.houses()) < 535000)
// .map(|x| x.clone())
// .collect();
//if let Some(best_layout) = db.layouts().iter()
// .sorted_by(|x, y| city::get_price(&city, x.houses()).cmp(&city::get_price(&city, y.houses())))
// .next() {
// eprintln!("Printing best layout, ID {}, price {}", best_layout.id(), city::get_price(&city, best_layout.houses()));
// print_houses(best_layout.houses());
//}
let mut best_price: Option<u32> = None;
//for best_layout in best_layouts {
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 weighted 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());
//populate_from_saved_layout(&mut layout, &best_layout);
//eprintln!("Finished loading DB layout ID {}, price: {}, houses: {}", best_layout.id(), layout.price(), layout.houses().len());
let improved = optimization::iterate_improvements(&mut layout, &mut rng, true, START_WITH_MERGE);
dump_layout(&layout, &mut best_price, seed);
//if improved {
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!();
}
}