diff --git a/Cargo.toml b/Cargo.toml index da8a093..ad6ae9a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,11 @@ version = "0.1.0" authors = ["Arne Keller "] edition = "2018" +[profile.release] +codegen-units = 1 +opt-level = 3 +panic = "abort" + [dependencies] geo = { git = "https://github.com/FliegendeWurst/geo" } svg = "0.5.12" diff --git a/src/main.rs b/src/main.rs index 06b4348..90237f9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -76,6 +76,12 @@ fn random_world(rng: &mut SmallRng, tris: &mut [Triangle], angles: &mut [f32], f tri.0.x += dx; tri.1.x += dx; tri.2.x += dx; + if tri.0.x < -1000.0 { + tri.0.x += 1000.0; + tri.1.x += 1000.0; + tri.2.x += 1000.0; + break; + } } } world.tris.push((0, tri)); @@ -122,10 +128,10 @@ fn construct_world(tris: &[Triangle], angles: &[f32], flips: &[bool]) -> World { tri.0.x += dx; tri.1.x += dx; tri.2.x += dx; - if tri.0.x < -5000.0 { - tri.0.x += 5000.0; - tri.1.x += 5000.0; - tri.2.x += 5000.0; + if tri.0.x < -1000.0 { + tri.0.x += 1000.0; + tri.1.x += 1000.0; + tri.2.x += 1000.0; break; } } @@ -148,44 +154,38 @@ fn main() { tri.2.y -= tri.0.y; tri.0.y = 0.0; } - let mut angles = vec![0.0; tris.len()]; - let mut flips = vec![false; tris.len()]; - let mut rng = SmallRng::from_entropy(); - let save_prefix = "rand_"; - let mut save_counter = 0; - let mut last_improvement = 0; - let mut best_width = f32::MAX; - let mut best_all = f32::MAX; - let mut random = random_world(&mut rng, &mut tris, &mut angles, &mut flips); + let mut best = f32::MAX; + let mut i = 0u64; + let save_prefix = format!("rand_sel_{}_", random::()); + println!("save prefix: {}", save_prefix); loop { - save_counter += 1; - if save_counter % 1 == 0 { - eprint!("\r[{}]", save_counter); - } - if random.width < best_width { - best_width = random.width; - last_improvement = save_counter; - if best_width < best_all { - best_all = best_width; - println!("[{}] BEST: {}", save_counter, random.width); - display::save_world(&format!("{}{}.svg", save_prefix, save_counter), &random); - optimize(99999, &mut best_all, &mut best_width, &tris, &mut angles, &mut flips, &mut rng, save_prefix, save_counter); - } else { - //eprint!("[{}] best: {} (min: {})", save_counter, random.width, best_all); - eprint!("."); - optimize(24999, &mut best_all, &mut best_width, &tris, &mut angles, &mut flips, &mut rng, save_prefix, save_counter); - } - } - random = random_world(&mut rng, &mut tris, &mut angles, &mut flips); - if save_counter - last_improvement > 200_000 { - // "restart" - best_width += 1000.0; + i += 1; + let new_best = one_main(&mut tris); + if new_best.width < best { + best = new_best.width; + //eprint!("\r"); + println!("[{}] BEST {:.3} ", i, best); + display::save_world(&format!("{}{}.svg", save_prefix, i), &new_best); + } else { + //eprint!("\r"); + println!("[{}] best {:.3} / prev. {:.3} ", i, new_best.width, best); } } } +fn one_main(tris: &mut [Triangle]) -> World { + let mut angles = vec![0.0; tris.len()]; + let mut flips = vec![false; tris.len()]; + let mut rng = SmallRng::from_entropy(); + let mut best_width = f32::MAX; + let mut best_all = f32::MAX; + let _random = random_world(&mut rng, tris, &mut angles, &mut flips); + optimize(69999, &mut best_all, &mut best_width, &tris, &mut angles, &mut flips, &mut rng, "rand_", 0) +} + #[allow(clippy::too_many_arguments)] -fn optimize(iters: usize, best_all: &mut f32, best_width: &mut f32, tris: &[Triangle], best_angles: &mut Vec, best_flips: &mut Vec, rng: &mut SmallRng, save_prefix: &'static str, save_counter: usize) { +fn optimize(iters: usize, best_all: &mut f32, best_width: &mut f32, tris: &[Triangle], best_angles: &mut Vec, best_flips: &mut Vec, rng: &mut SmallRng, save_prefix: &'static str, save_counter: usize) -> World { + let mut best = World { tris: vec![], width: f32::MAX }; let mut found_better = true; let mut iteration = 0; let flip_choice = Bernoulli::from_ratio(1, 11); @@ -210,13 +210,15 @@ fn optimize(iters: usize, best_all: &mut f32, best_width: &mut f32, tris: &[Tria if new.width < *best_width { if new.width < *best_all { *best_all = new.width; - println!("[{}O{}o{}] BEST: {}", save_counter, iteration, i, new.width); - display::save_world(&format!("{}{}_{}_{}.svg", save_prefix, save_counter, iteration, i), &new); + //eprint!("\r[{}O{}o{}] at {:.3}", save_counter, iteration, i, new.width); + //display::save_world(&format!("{}{}_{}_{}.svg", save_prefix, save_counter, iteration, i), &new); + //iters = 99999; + best = new; } else { //eprint!("[{}O{}o{}] best: {} (min: {})", save_counter, iteration, i, new.width, best_all); - eprint!("."); + //eprint!("."); } - *best_width = new.width; + *best_width = best.width; found_better = true; *best_angles = angles; *best_flips = flips; @@ -226,6 +228,7 @@ fn optimize(iters: usize, best_all: &mut f32, best_width: &mut f32, tris: &[Tria } iteration += 1; } + best } #[allow(clippy::cyclomatic_complexity)]