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; | mod main; | ||||||
| 
 | 
 | ||||||
| fn main() { | fn main() { | ||||||
|  |     // This is quite frankly useless
 | ||||||
|  | 
 | ||||||
|     let city = City::read_from_file("01.in"); |     let city = City::read_from_file("01.in"); | ||||||
|     let bar = ProgressBar::new(city.get_house_count() as u64); |     let bar = ProgressBar::new(city.get_house_count() as u64); | ||||||
|     bar.set_style(ProgressStyle::default_bar() |     bar.set_style(ProgressStyle::default_bar() | ||||||
|  |  | ||||||
							
								
								
									
										62
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										62
									
								
								src/main.rs
									
									
									
									
									
								
							|  | @ -15,7 +15,7 @@ impl City { | ||||||
| 
 | 
 | ||||||
|         for y in 0..SIZE { |         for y in 0..SIZE { | ||||||
|             for x 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); |                 prices.push(price); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  | @ -69,6 +69,7 @@ impl House { | ||||||
| fn main() { | fn main() { | ||||||
|     let city = City::read_from_file("01.in"); |     let city = City::read_from_file("01.in"); | ||||||
| 
 | 
 | ||||||
|  |     let mut best_price: Option<u32> = None; | ||||||
|     loop { |     loop { | ||||||
|         let seed: u64 = thread_rng().gen(); |         let seed: u64 = thread_rng().gen(); | ||||||
|         eprintln!("Starting seed {}", seed); |         eprintln!("Starting seed {}", seed); | ||||||
|  | @ -106,40 +107,71 @@ fn main() { | ||||||
|                 break; |                 break; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|         let mut price = get_price(&city, &houses); |         let mut price = get_price(&city, &houses); | ||||||
|         eprintln!("Finished randomized init, price: {}", price); |         eprintln!("Finished random init, price: {}", price); | ||||||
|         loop { | 
 | ||||||
|  |         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 house = &houses.choose(&mut rng).unwrap(); | ||||||
|             let mut new_candidate: Option<House> = None; |             let mut new_candidates = Vec::new(); | ||||||
|             for _ in 0..5000 { |             for delta_y in -AROUND_RANGE..=AROUND_RANGE { | ||||||
|                 let delta_x = rng.gen_range(-50..=50); |                 for delta_x in -AROUND_RANGE..=AROUND_RANGE { | ||||||
|                 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_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; |                     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) { |                     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)); |                         new_candidates.push(House::new(new_x, new_y)); | ||||||
|                     break; |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             if let Some(candidate) = new_candidate { |             new_candidates.sort_by(|a, b| city.get_price(&a).cmp(&city.get_price(&b))); | ||||||
|                 eprint!("Found candidate..."); |             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(); |                     let mut new_houses: Vec<_> = houses.to_vec().into_iter().filter(|h| &h != house).collect(); | ||||||
|                     new_houses.push(candidate); |                     new_houses.push(candidate); | ||||||
|  |                     // TODO: This is_valid check could be way more efficient
 | ||||||
|                     if let Some(new_price) = is_valid(&city, &new_houses) { |                     if let Some(new_price) = is_valid(&city, &new_houses) { | ||||||
|                         let price_diff = new_price as i64 - price as i64; |                         let price_diff = new_price as i64 - price as i64; | ||||||
|                         eprintln!(" candidate is valid, price diff: {}.", price_diff); |                         eprintln!(" candidate is valid, price diff: {}.", price_diff); | ||||||
|                     eprintln!("New price: {}", new_price); |                         eprintln!("Improved price: {}", new_price); | ||||||
|                         price = new_price; |                         price = new_price; | ||||||
|                         houses = new_houses; |                         houses = new_houses; | ||||||
|                     print_houses(&houses); |                         failed_iterations = 0; | ||||||
|  |                         break; | ||||||
|                     } else { |                     } else { | ||||||
|                         eprintln!(" candidate is invalid."); |                         eprintln!(" candidate is invalid."); | ||||||
|                     } |                     } | ||||||
|             } else { |  | ||||||
|                 eprintln!("Did not find candidate"); |  | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  | 
 | ||||||
|  |             // 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