Small changes to subcity runner; used ranges
This commit is contained in:
parent
2e3a31612b
commit
d60dee1772
1 changed files with 72 additions and 26 deletions
|
@ -25,10 +25,32 @@ fn main() {
|
||||||
.next().expect("No best layout found");
|
.next().expect("No best layout found");
|
||||||
eprintln!("Found best layout, ID {}, price {}", best_layout.id(), get_price(&city, best_layout.houses()));
|
eprintln!("Found best layout, ID {}, price {}", best_layout.id(), get_price(&city, best_layout.houses()));
|
||||||
|
|
||||||
let x_range = 5533..=12000;
|
//let x_range = 5533..=12000;
|
||||||
let y_range = 4750..=12500;
|
//let y_range = 4750..=12500;
|
||||||
//let x_range = 5533..=8000;
|
//let x_range = 9500..=14100;
|
||||||
//let y_range = 4750..=8000;
|
//let y_range = 10300..=14400;
|
||||||
|
//let x_range = 14900..=16200;
|
||||||
|
//let y_range = 7720..=10400;
|
||||||
|
//let x_range = 9982..=16383;
|
||||||
|
//let y_range = 0..=2720;
|
||||||
|
//let x_range = 7720..=12000;
|
||||||
|
//let y_range = 5608..=11000;
|
||||||
|
//let x_range = 3542..=8423;
|
||||||
|
//let y_range = 4832..=8423;
|
||||||
|
//let x_range = 1200..=9200;
|
||||||
|
//let y_range = 9000..=16383;
|
||||||
|
//let x_range = 9200..=16383;
|
||||||
|
//let y_range = 9200..=16383;
|
||||||
|
//let x_range = 9201..=16383;
|
||||||
|
//let y_range = 0..=7500;
|
||||||
|
//let x_range = 11100..=13333;
|
||||||
|
//let y_range = 14700..=16383;
|
||||||
|
//let x_range = 0..=7500;
|
||||||
|
//let y_range = 0..=7500;
|
||||||
|
let x_range = 0..=7500;
|
||||||
|
let y_range = 9500..=16383;
|
||||||
|
//let x_range = 9500..=16383;
|
||||||
|
//let y_range = 0..=7500;
|
||||||
eprintln!("X {}-{}, Y {}-{}", x_range.start(), x_range.end(), y_range.start(), y_range.end());
|
eprintln!("X {}-{}, Y {}-{}", x_range.start(), x_range.end(), y_range.start(), y_range.end());
|
||||||
|
|
||||||
let static_houses: Vec<House> = best_layout.houses().iter()
|
let static_houses: Vec<House> = best_layout.houses().iter()
|
||||||
|
@ -56,11 +78,21 @@ fn main() {
|
||||||
|
|
||||||
//let mut subcity_db = MemoryLayoutDB::new();
|
//let mut subcity_db = MemoryLayoutDB::new();
|
||||||
let filename = format!("X{}_{}Y{}_{}ID{}.sqlite", x_range.start(), x_range.end(), y_range.start(), y_range.end(), best_layout.id());
|
let filename = format!("X{}_{}Y{}_{}ID{}.sqlite", x_range.start(), x_range.end(), y_range.start(), y_range.end(), best_layout.id());
|
||||||
let mut subcity_db = SqliteLayoutDB::from_file(&filename).unwrap();
|
let mut subcity_db = SqliteLayoutDB::from_file(&filename, true).unwrap();
|
||||||
|
|
||||||
|
// The following part merges best subcity layouts back into the global layout and
|
||||||
|
// inserting them into the database
|
||||||
|
|
||||||
|
// Setting this value allows attempts at improving suboptimal subcities after merging them back.
|
||||||
|
// A subcity may result in a better score than original even if the subcity is worse than the
|
||||||
|
// original if global improvements improve the cost.
|
||||||
|
//const SUBOPTIMAL_SUBCITY_COST_MARGIN: u32 = 5000;
|
||||||
|
//const CHECKED_CITY_LIMIT: usize = 50;
|
||||||
|
|
||||||
//for layout in subcity_db.layouts().iter()
|
//for layout in subcity_db.layouts().iter()
|
||||||
// .filter(|x| get_price(subcity.city(), x.houses()) < removed_price)
|
// .filter(|x| get_price(subcity.city(), x.houses()) < removed_price + SUBOPTIMAL_SUBCITY_COST_MARGIN)
|
||||||
// .sorted_by(|x, y| get_price(subcity.city(), x.houses()).cmp(&get_price(subcity.city(), y.houses()))) {
|
// .sorted_by(|x, y| get_price(subcity.city(), x.houses()).cmp(&get_price(subcity.city(), y.houses())))
|
||||||
|
// .take(CHECKED_CITY_LIMIT) {
|
||||||
// let price = get_price(subcity.city(), layout.houses());
|
// let price = get_price(subcity.city(), layout.houses());
|
||||||
// let mut full_houses = subcity.to_full_houses(layout.houses());
|
// let mut full_houses = subcity.to_full_houses(layout.houses());
|
||||||
// assert!(city::is_valid(&city, &full_houses).is_some());
|
// assert!(city::is_valid(&city, &full_houses).is_some());
|
||||||
|
@ -71,7 +103,7 @@ fn main() {
|
||||||
// }
|
// }
|
||||||
// let seed: u64 = thread_rng().gen();
|
// let seed: u64 = thread_rng().gen();
|
||||||
// let mut rng = StdRng::seed_from_u64(seed);
|
// let mut rng = StdRng::seed_from_u64(seed);
|
||||||
// optimization::iterate_improvements(&mut house_layout, &mut rng, true);
|
// optimization::iterate_improvements(&mut house_layout, &mut rng, true, false);
|
||||||
// eprintln!("Improvements finished");
|
// eprintln!("Improvements finished");
|
||||||
// assert!(house_layout.is_valid());
|
// assert!(house_layout.is_valid());
|
||||||
// let improved_price = city::get_price(&city, house_layout.houses());
|
// let improved_price = city::get_price(&city, house_layout.houses());
|
||||||
|
@ -82,9 +114,17 @@ fn main() {
|
||||||
|
|
||||||
// assert!(city::is_valid(&city, &full_houses).is_some());
|
// assert!(city::is_valid(&city, &full_houses).is_some());
|
||||||
// println!("Layout {}, price {}, full price {}", layout.id(), price, city::get_price(&city, &full_houses));
|
// println!("Layout {}, price {}, full price {}", layout.id(), price, city::get_price(&city, &full_houses));
|
||||||
// // Be careful with duplicates here
|
// if improved_price < city::get_price(&city, best_layout.houses()) {
|
||||||
// //sqlite_db.add_layout(&full_houses, true);
|
// eprintln!("Found a new best layout for the full city");
|
||||||
// //println!("Inserted into the global DB");
|
// println!("Found a new best layout for the full city");
|
||||||
|
// println!("Layout {}, price {}, full price {}", layout.id(), price, city::get_price(&city, &full_houses));
|
||||||
|
// }
|
||||||
|
// //eprintln!("NOT inserting into the DB");
|
||||||
|
// // Be careful with duplicates here
|
||||||
|
// sqlite_db.add_layout(&full_houses, true);
|
||||||
|
// eprintln!("Inserted into the global DB");
|
||||||
|
// println!("Inserted into the global DB");
|
||||||
|
// //}
|
||||||
//}
|
//}
|
||||||
//return;
|
//return;
|
||||||
|
|
||||||
|
@ -96,12 +136,16 @@ fn main() {
|
||||||
// Generate `WEIGHTED_RANDOM_LAYOUTS` layouts weighted by scores from existing layouts
|
// Generate `WEIGHTED_RANDOM_LAYOUTS` layouts weighted by scores from existing layouts
|
||||||
// }
|
// }
|
||||||
|
|
||||||
const FULL_RANDOM_LAYOUTS: usize = 100;
|
const FULL_RANDOM_LAYOUTS: usize = 200;
|
||||||
const DB_CHOICE_PROBABILITY: f64 = 0.90;
|
const DB_CHOICE_PROBABILITY: f64 = 0.95;
|
||||||
const WEIGHTED_RANDOM_LAYOUTS: usize = 200;
|
const WEIGHTED_RANDOM_LAYOUTS: usize = 100;
|
||||||
const CUT_COMBINE_TOP_LAYOUTS: usize = 500;
|
const CUT_COMBINE_TOP_LAYOUTS: usize = 500;
|
||||||
const IGNORED_WEIGHT_RATIO: f64 = 0.5;
|
const IGNORED_WEIGHT_RATIO: f64 = 0.5;
|
||||||
|
|
||||||
|
const THREAD_COUNT: usize = 12;
|
||||||
|
|
||||||
|
rayon::ThreadPoolBuilder::new().num_threads(THREAD_COUNT).build_global();
|
||||||
|
|
||||||
if subcity_db.layouts().len() == 0 {
|
if subcity_db.layouts().len() == 0 {
|
||||||
let mut full_random_layouts = Vec::new();
|
let mut full_random_layouts = Vec::new();
|
||||||
|
|
||||||
|
@ -119,7 +163,7 @@ fn main() {
|
||||||
}));
|
}));
|
||||||
|
|
||||||
for houses in &full_random_layouts {
|
for houses in &full_random_layouts {
|
||||||
subcity_db.add_layout(houses, true);
|
subcity_db.add_layout(houses, true).expect("Failed to add new layout");
|
||||||
}
|
}
|
||||||
|
|
||||||
eprintln!("Finished initial full random population");
|
eprintln!("Finished initial full random population");
|
||||||
|
@ -127,9 +171,13 @@ fn main() {
|
||||||
eprintln!("Skipping initial full random population because DB is non-empty [{} layouts]", subcity_db.layouts().len());
|
eprintln!("Skipping initial full random population because DB is non-empty [{} layouts]", subcity_db.layouts().len());
|
||||||
}
|
}
|
||||||
|
|
||||||
let best_price: u32 = subcity_db.layouts().iter().map(|layout| layout.houses().iter().map(|h| subcity.city().get_price(*h) as u32).sum()).min().unwrap();
|
fn print_status<TDB: LayoutDB>(db: &TDB, subcity: &City) {
|
||||||
let worst_price: u32 = subcity_db.layouts().iter().map(|layout| layout.houses().iter().map(|h| subcity.city().get_price(*h) as u32).sum()).max().unwrap();
|
let best_price: u32 = db.layouts().iter().map(|layout| layout.houses().iter().map(|h| subcity.get_price(*h) as u32).sum()).min().unwrap();
|
||||||
eprintln!("Best {}, worst {} [{} layouts]", best_price, worst_price, subcity_db.layouts().len());
|
let worst_price: u32 = db.layouts().iter().map(|layout| layout.houses().iter().map(|h| subcity.get_price(*h) as u32).sum()).max().unwrap();
|
||||||
|
eprintln!("Best {}, worst {} [{} layouts]", best_price, worst_price, db.layouts().len());
|
||||||
|
}
|
||||||
|
|
||||||
|
print_status(&subcity_db, subcity.city());
|
||||||
|
|
||||||
let mut cache = combine::CompatibilityCache::new();
|
let mut cache = combine::CompatibilityCache::new();
|
||||||
|
|
||||||
|
@ -138,10 +186,8 @@ fn main() {
|
||||||
// This is a bottleneck when it comes to multithreading, it only runs on a single thread
|
// This is a bottleneck when it comes to multithreading, it only runs on a single thread
|
||||||
combine::iterate_combines(&mut subcity_db, CUT_COMBINE_TOP_LAYOUTS, subcity.city(), &mut cache, false);
|
combine::iterate_combines(&mut subcity_db, CUT_COMBINE_TOP_LAYOUTS, subcity.city(), &mut cache, false);
|
||||||
|
|
||||||
let best_price: u32 = subcity_db.layouts().iter().map(|layout| layout.houses().iter().map(|h| subcity.city().get_price(*h) as u32).sum()).min().unwrap();
|
|
||||||
let worst_price: u32 = subcity_db.layouts().iter().map(|layout| layout.houses().iter().map(|h| subcity.city().get_price(*h) as u32).sum()).max().unwrap();
|
|
||||||
eprintln!("Finished cut combines");
|
eprintln!("Finished cut combines");
|
||||||
eprintln!("Best {}, worst {} [{} layouts]", best_price, worst_price, subcity_db.layouts().len());
|
print_status(&subcity_db, subcity.city());
|
||||||
|
|
||||||
let mut weighted_random_layouts = Vec::new();
|
let mut weighted_random_layouts = Vec::new();
|
||||||
// Only using the underlying memory-based DB is required here as the SqliteLayoutDB
|
// Only using the underlying memory-based DB is required here as the SqliteLayoutDB
|
||||||
|
@ -152,25 +198,25 @@ fn main() {
|
||||||
let mut rng = StdRng::seed_from_u64(seed);
|
let mut rng = StdRng::seed_from_u64(seed);
|
||||||
let mut layout = HouseLayout::new(subcity.city());
|
let mut layout = HouseLayout::new(subcity.city());
|
||||||
|
|
||||||
|
let best_price: u32 = memory_db.layouts().iter().map(|layout| layout.houses().iter().map(|h| subcity.city().get_price(*h) as u32).sum()).min().unwrap();
|
||||||
|
let worst_price: u32 = memory_db.layouts().iter().map(|layout| layout.houses().iter().map(|h| subcity.city().get_price(*h) as u32).sum()).max().unwrap();
|
||||||
let price_range = worst_price - best_price;
|
let price_range = worst_price - best_price;
|
||||||
let max_price = best_price as f64 + (price_range as f64 * (1. - IGNORED_WEIGHT_RATIO));
|
let max_price = best_price as f64 + (price_range as f64 * (1. - IGNORED_WEIGHT_RATIO));
|
||||||
//eprintln!("Starting random weighted population {}, using DB, score range {}-{}, DB use probability {}...", i, best_price, worst_price, DB_CHOICE_PROBABILITY);
|
//eprintln!("Starting random weighted population {}, using DB, score range {}-{}, DB use probability {}...", i, best_price, worst_price, DB_CHOICE_PROBABILITY);
|
||||||
population::populate_using_db(&mut layout, &mut rng, memory_db, best_price as f64, max_price as f64, DB_CHOICE_PROBABILITY);
|
population::populate_using_db(&mut layout, &mut rng, memory_db, best_price as f64, max_price as f64, DB_CHOICE_PROBABILITY);
|
||||||
//eprintln!("Finished random init {}, price: {}, houses: {}", i, layout.price(), layout.houses().len());
|
//eprintln!("Finished random init {}, price: {}, houses: {}", i, layout.price(), layout.houses().len());
|
||||||
optimization::iterate_improvements(&mut layout, &mut rng, false);
|
optimization::iterate_improvements(&mut layout, &mut rng, false, false);
|
||||||
//eprintln!("Finished iterated improvements {}, price: {}, houses: {}", i, layout.price(), layout.houses().len());
|
//eprintln!("Finished iterated improvements {}, price: {}, houses: {}", i, layout.price(), layout.houses().len());
|
||||||
layout.houses().clone()
|
layout.houses().clone()
|
||||||
}));
|
}));
|
||||||
|
|
||||||
for houses in &weighted_random_layouts {
|
for houses in &weighted_random_layouts {
|
||||||
subcity_db.add_layout(houses, true);
|
subcity_db.add_layout(houses, true).expect("Failed to add new layout");
|
||||||
}
|
}
|
||||||
|
|
||||||
let w_best: u32 = weighted_random_layouts.iter().map(|houses| houses.iter().map(|h| subcity.city().get_price(*h) as u32).sum()).min().unwrap();
|
let w_best: u32 = weighted_random_layouts.iter().map(|houses| houses.iter().map(|h| subcity.city().get_price(*h) as u32).sum()).min().unwrap();
|
||||||
let w_worst: u32 = weighted_random_layouts.iter().map(|houses| houses.iter().map(|h| subcity.city().get_price(*h) as u32).sum()).max().unwrap();
|
let w_worst: u32 = weighted_random_layouts.iter().map(|houses| houses.iter().map(|h| subcity.city().get_price(*h) as u32).sum()).max().unwrap();
|
||||||
let best_price: u32 = subcity_db.layouts().iter().map(|layout| layout.houses().iter().map(|h| subcity.city().get_price(*h) as u32).sum()).min().unwrap();
|
|
||||||
let worst_price: u32 = subcity_db.layouts().iter().map(|layout| layout.houses().iter().map(|h| subcity.city().get_price(*h) as u32).sum()).max().unwrap();
|
|
||||||
eprintln!("Finished weighted random population, price range {}-{}", w_best, w_worst);
|
eprintln!("Finished weighted random population, price range {}-{}", w_best, w_worst);
|
||||||
eprintln!("Best {}, worst {} [{} layouts]", best_price, worst_price, subcity_db.layouts().len());
|
print_status(&subcity_db, subcity.city());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue