Randomized improvements, finding best
Takes best close house to a random house
This commit is contained in:
parent
3d17279613
commit
a01fa30954
2 changed files with 61 additions and 27 deletions
|
@ -5,6 +5,8 @@ use main::{get_neighbors, House, City};
|
|||
mod main;
|
||||
|
||||
fn main() {
|
||||
// This is quite frankly useless
|
||||
|
||||
let city = City::read_from_file("01.in");
|
||||
let bar = ProgressBar::new(city.get_house_count() as u64);
|
||||
bar.set_style(ProgressStyle::default_bar()
|
||||
|
|
86
src/main.rs
86
src/main.rs
|
@ -15,7 +15,7 @@ impl City {
|
|||
|
||||
for y in 0..SIZE {
|
||||
for x in 0..SIZE {
|
||||
let price = (values[(y * SIZE + x) * 2] as u16) | ((values[(y * SIZE + x) * 2] as u16) << 8);
|
||||
let price = (values[(y * SIZE + x) * 2] as u16) | ((values[(y * SIZE + x) * 2 + 1] as u16) << 8);
|
||||
prices.push(price);
|
||||
}
|
||||
}
|
||||
|
@ -69,6 +69,7 @@ impl House {
|
|||
fn main() {
|
||||
let city = City::read_from_file("01.in");
|
||||
|
||||
let mut best_price: Option<u32> = None;
|
||||
loop {
|
||||
let seed: u64 = thread_rng().gen();
|
||||
eprintln!("Starting seed {}", seed);
|
||||
|
@ -106,39 +107,70 @@ fn main() {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
let mut price = get_price(&city, &houses);
|
||||
eprintln!("Finished randomized init, price: {}", price);
|
||||
loop {
|
||||
eprintln!("Finished random init, price: {}", price);
|
||||
|
||||
const AROUND_RANGE: i32 = 50;
|
||||
const MAX_CANDIDATES: usize = 20;
|
||||
const MAX_FAILED_ITERATIONS: usize = 50;
|
||||
|
||||
let mut failed_iterations = 0;
|
||||
while failed_iterations < MAX_FAILED_ITERATIONS {
|
||||
let house = &houses.choose(&mut rng).unwrap();
|
||||
let mut new_candidate: Option<House> = None;
|
||||
for _ in 0..5000 {
|
||||
let delta_x = rng.gen_range(-50..=50);
|
||||
let delta_y = rng.gen_range(-50..=50);
|
||||
let new_x = (house.x as i32 + delta_x).max(0).min(SIZE as i32 - 1) as usize;
|
||||
let new_y = (house.y as i32 + delta_y).max(0).min(SIZE as i32 - 1) as usize;
|
||||
if city.is_house_xy(new_x, new_y) && city.get_price_xy(new_x, new_y) < city.get_price(&house) {
|
||||
new_candidate = Some(House::new(new_x, new_y));
|
||||
break;
|
||||
let mut new_candidates = Vec::new();
|
||||
for delta_y in -AROUND_RANGE..=AROUND_RANGE {
|
||||
for delta_x in -AROUND_RANGE..=AROUND_RANGE {
|
||||
let new_x = (house.x as i32 + delta_x).max(0).min(SIZE as i32 - 1) as usize;
|
||||
let new_y = (house.y as i32 + delta_y).max(0).min(SIZE as i32 - 1) as usize;
|
||||
if city.is_house_xy(new_x, new_y) && city.get_price_xy(new_x, new_y) < city.get_price(&house) {
|
||||
new_candidates.push(House::new(new_x, new_y));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(candidate) = new_candidate {
|
||||
eprint!("Found candidate...");
|
||||
let mut new_houses: Vec<_> = houses.to_vec().into_iter().filter(|h| &h != house).collect();
|
||||
new_houses.push(candidate);
|
||||
if let Some(new_price) = is_valid(&city, &new_houses) {
|
||||
let price_diff = new_price as i64 - price as i64;
|
||||
eprintln!(" candidate is valid, price diff: {}.", price_diff);
|
||||
eprintln!("New price: {}", new_price);
|
||||
price = new_price;
|
||||
houses = new_houses;
|
||||
print_houses(&houses);
|
||||
} else {
|
||||
eprintln!(" candidate is invalid.");
|
||||
}
|
||||
} else {
|
||||
new_candidates.sort_by(|a, b| city.get_price(&a).cmp(&city.get_price(&b)));
|
||||
if new_candidates.len() == 0 {
|
||||
eprintln!("Did not find candidate");
|
||||
} else {
|
||||
for (i, &candidate) in new_candidates.iter().enumerate() {
|
||||
if i > MAX_CANDIDATES {
|
||||
break;
|
||||
}
|
||||
|
||||
eprint!("Found candidate {}...", i);
|
||||
let mut new_houses: Vec<_> = houses.to_vec().into_iter().filter(|h| &h != house).collect();
|
||||
new_houses.push(candidate);
|
||||
// TODO: This is_valid check could be way more efficient
|
||||
if let Some(new_price) = is_valid(&city, &new_houses) {
|
||||
let price_diff = new_price as i64 - price as i64;
|
||||
eprintln!(" candidate is valid, price diff: {}.", price_diff);
|
||||
eprintln!("Improved price: {}", new_price);
|
||||
price = new_price;
|
||||
houses = new_houses;
|
||||
failed_iterations = 0;
|
||||
break;
|
||||
} else {
|
||||
eprintln!(" candidate is invalid.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Successful iterations always break
|
||||
failed_iterations += 1;
|
||||
}
|
||||
|
||||
if best_price.is_none() || price < best_price.unwrap() {
|
||||
best_price = Some(price);
|
||||
eprintln!("Finished randomization, price: {}, new best, printing", price);
|
||||
println!("Price {}, seed {}", price, seed);
|
||||
print_houses(&houses);
|
||||
println!();
|
||||
} else {
|
||||
eprintln!("Finished randomization, price: {}, printing", price);
|
||||
println!("Price {}, seed {}", price, seed);
|
||||
print_houses(&houses);
|
||||
println!();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue