@@ -69,9 +69,181 @@ Time taken: 770.787 seconds
6969
7070
7171```
72+ kushal@flex2024:~/src/rust/tsp_rust$ cargo fmt --all -- --check
73+ Diff in /home/kushal/src/rust/tsp_rust/src/main.rs:122:
74+ if n <= 1 {
75+ return;
76+ }
77+ -
78+ +
79+ if n <= 4 {
80+ // For very small problems, just use single-threaded
81+ self.solve_all_permutations();
82+ Diff in /home/kushal/src/rust/tsp_rust/src/main.rs:132:
83+ // We'll fix city 0 at position 0, then distribute the work
84+ // by having each thread handle different starting cities at position 1
85+ let cities_to_permute: Vec<usize> = (1..n).collect();
86+ -
87+ +
88+ // Shared state for best solution
89+ let best_distance = Arc::new(Mutex::new(f64::INFINITY));
90+ let best_path = Arc::new(Mutex::new(Vec::new()));
91+ Diff in /home/kushal/src/rust/tsp_rust/src/main.rs:141:
92+ // Create threads
93+ let mut handles = Vec::new();
94+ let chunk_size = cities_to_permute.len().div_ceil(num_threads);
95+ -
96+ +
97+ for chunk in cities_to_permute.chunks(chunk_size) {
98+ let chunk = chunk.to_vec();
99+ let all_cities = cities_to_permute.clone();
100+ Diff in /home/kushal/src/rust/tsp_rust/src/main.rs:157:
101+ for &start_city in &chunk {
102+ // Create a path starting with 0 and this city
103+ let mut path = vec![0, start_city];
104+ -
105+ +
106+ // Add remaining cities
107+ let mut remaining: Vec<usize> = all_cities
108+ .iter()
109+ Diff in /home/kushal/src/rust/tsp_rust/src/main.rs:164:
110+ .filter(|&&c| c != start_city)
111+ .cloned()
112+ .collect();
113+ -
114+ +
115+ // Generate all permutations with this fixed start
116+ permute_and_check(
117+ &cities,
118+ Diff in /home/kushal/src/rust/tsp_rust/src/main.rs:211:
119+ // Complete path
120+ let mut full_path = prefix.clone();
121+ full_path.extend_from_slice(remaining);
122+ -
123+ +
124+ let distance = calculate_distance(cities, &full_path);
125+ if distance < *best_distance {
126+ *best_distance = distance;
127+ Diff in /home/kushal/src/rust/tsp_rust/src/main.rs:222:
128+
129+ for i in start_idx..remaining.len() {
130+ remaining.swap(start_idx, i);
131+ - permute_and_check(cities, prefix, remaining, start_idx + 1, best_distance, best_path);
132+ + permute_and_check(
133+ + cities,
134+ + prefix,
135+ + remaining,
136+ + start_idx + 1,
137+ + best_distance,
138+ + best_path,
139+ + );
140+ remaining.swap(start_idx, i);
141+ }
142+ }
143+ Diff in /home/kushal/src/rust/tsp_rust/src/main.rs:240:
144+ fn generate_random_cities(n: usize, seed: u64) -> Vec<City> {
145+ let mut cities = Vec::new();
146+ let mut rng = SimpleRng::new(seed);
147+ -
148+ +
149+ for i in 0..n {
150+ cities.push(City {
151+ id: i,
152+ Diff in /home/kushal/src/rust/tsp_rust/src/main.rs:248:
153+ y: rng.next_f64() * 100.0,
154+ });
155+ }
156+ -
157+ +
158+ cities
159+ }
160+
161+ Diff in /home/kushal/src/rust/tsp_rust/src/main.rs:259:
162+
163+ impl SimpleRng {
164+ fn new(seed: u64) -> Self {
165+ - SimpleRng {
166+ - state: if seed == 0 { 12345 } else { seed }
167+ + SimpleRng {
168+ + state: if seed == 0 { 12345 } else { seed },
169+ }
170+ }
171+ -
172+ +
173+ fn next(&mut self) -> u64 {
174+ self.state = self.state.wrapping_mul(1664525).wrapping_add(1013904223);
175+ self.state
176+ Diff in /home/kushal/src/rust/tsp_rust/src/main.rs:270:
177+ }
178+ -
179+ +
180+ fn next_f64(&mut self) -> f64 {
181+ (self.next() as f64) / (u64::MAX as f64)
182+ }
183+ Diff in /home/kushal/src/rust/tsp_rust/src/main.rs:284:
184+
185+ fn main() {
186+ let args: Vec<String> = env::args().collect();
187+ -
188+ +
189+ if args.len() < 2 {
190+ print_usage();
191+ process::exit(1);
192+ Diff in /home/kushal/src/rust/tsp_rust/src/main.rs:291:
193+ }
194+ -
195+ +
196+ let num_cities = match args[1].parse::<usize>() {
197+ Ok(n) => n,
198+ Err(_) => {
199+ Diff in /home/kushal/src/rust/tsp_rust/src/main.rs:298:
200+ process::exit(1);
201+ }
202+ };
203+ -
204+ +
205+ if num_cities > 10 {
206+ - eprintln!("Warning: {} cities will take a very long time with brute force!", num_cities);
207+ - eprintln!("Factorial complexity: {}! permutations to check", num_cities);
208+ + eprintln!(
209+ + "Warning: {} cities will take a very long time with brute force!",
210+ + num_cities
211+ + );
212+ + eprintln!(
213+ + "Factorial complexity: {}! permutations to check",
214+ + num_cities
215+ + );
216+ }
217+ -
218+ +
219+ let seed = if args.len() >= 3 {
220+ args[2].parse::<u64>().unwrap_or(42)
221+ } else {
222+ Diff in /home/kushal/src/rust/tsp_rust/src/main.rs:321:
223+ .map(|n| n.get())
224+ .unwrap_or(4)
225+ };
226+ -
227+ +
228+ println!("=== Traveling Salesman Problem Solver ===");
229+ println!("Cities: {}", num_cities);
230+ println!("Seed: {}", seed);
231+ Diff in /home/kushal/src/rust/tsp_rust/src/main.rs:328:
232+ println!("Available CPU threads: {}", num_threads);
233+ println!();
234+ -
235+ +
236+ // Generate cities
237+ let cities = generate_random_cities(num_cities, seed);
238+ -
239+ +
240+ // Print city positions
241+ println!("City Positions:");
242+ for city in &cities {
243+ kushal@flex2024:~/src/rust/tsp_rust$ cargo fmt --all
72244kushal@flex2024:~/src/rust/tsp_rust$ time cargo run --release 10 42
73245 Compiling tsp_rust v0.1.0 (/home/kushal/src/rust/tsp_rust)
74- Finished `release` profile [optimized] target(s) in 0.63s
246+ Finished `release` profile [optimized] target(s) in 1.01s
75247 Running `target/release/tsp_rust 10 42`
76248=== Traveling Salesman Problem Solver ===
77249Cities: 10
@@ -94,20 +266,62 @@ City Positions:
94266Best path: [0, 4, 8, 9, 7, 1, 3, 5, 2, 6]
95267Route: 0 -> 4 -> 8 -> 9 -> 7 -> 1 -> 3 -> 5 -> 2 -> 6 -> 0
96268Total distance: 394.17
97- Time taken: 0.040 seconds
269+ Time taken: 0.045 seconds
98270
99271=== Multi-threaded Solution (8 threads) ===
100- Best path: [0, 4, 8, 9, 7 , 1, 3, 5, 2, 6 ]
101- Route: 0 -> 4 -> 8 -> 9 -> 7 -> 1 -> 3 -> 5 -> 2 -> 6 -> 0
272+ Best path: [0, 6, 2, 5, 3 , 1, 7, 9, 8, 4 ]
273+ Route: 0 -> 6 -> 2 -> 5 -> 3 -> 1 -> 7 -> 9 -> 8 -> 4 -> 0
102274Total distance: 394.17
103- Time taken: 0.648 seconds
275+ Time taken: 0.020 seconds
104276
105277✓ Both methods found the same optimal solution!
106- Speedup: 0.06x
278+ Speedup: 2.20x
107279
108- real 0m1.390s
109- user 0m2.341s
110- sys 0m2.258s
280+ real 0m1.158s
281+ user 0m1.179s
282+ sys 0m0.507s
283+ kushal@flex2024:~/src/rust/tsp_rust$ time cargo run --release 12 42
284+ Finished `release` profile [optimized] target(s) in 0.01s
285+ Running `target/release/tsp_rust 12 42`
286+ Warning: 12 cities will take a very long time with brute force!
287+ Factorial complexity: 12! permutations to check
288+ === Traveling Salesman Problem Solver ===
289+ Cities: 12
290+ Seed: 42
291+ Available CPU threads: 8
292+
293+ City Positions:
294+ City 0: (0.00, 0.01)
295+ City 1: (78.56, 60.47)
296+ City 2: (81.05, 1.19)
297+ City 3: (70.41, 37.51)
298+ City 4: (28.28, 37.96)
299+ City 5: (63.30, 31.49)
300+ City 6: (41.54, 8.58)
301+ City 7: (99.72, 80.97)
302+ City 8: (29.60, 45.77)
303+ City 9: (0.91, 96.23)
304+ City 10: (24.66, 76.52)
305+ City 11: (24.11, 45.28)
306+
307+ === Single-threaded Solution ===
308+ Best path: [0, 6, 2, 5, 3, 1, 7, 10, 9, 11, 8, 4]
309+ Route: 0 -> 6 -> 2 -> 5 -> 3 -> 1 -> 7 -> 10 -> 9 -> 11 -> 8 -> 4 -> 0
310+ Total distance: 403.69
311+ Time taken: 4.589 seconds
312+
313+ === Multi-threaded Solution (8 threads) ===
314+ Best path: [0, 6, 2, 5, 3, 1, 7, 10, 9, 11, 8, 4]
315+ Route: 0 -> 6 -> 2 -> 5 -> 3 -> 1 -> 7 -> 10 -> 9 -> 11 -> 8 -> 4 -> 0
316+ Total distance: 403.69
317+ Time taken: 1.353 seconds
318+
319+ ✓ Both methods found the same optimal solution!
320+ Speedup: 3.39x
321+
322+ real 0m6.024s
323+ user 0m11.485s
324+ sys 0m0.037s
111325kushal@flex2024:~/src/rust/tsp_rust$ time cargo run --release 13 42
112326 Finished `release` profile [optimized] target(s) in 0.01s
113327 Running `target/release/tsp_rust 13 42`
@@ -137,19 +351,19 @@ City Positions:
137351Best path: [0, 4, 8, 11, 12, 10, 9, 7, 1, 3, 5, 2, 6]
138352Route: 0 -> 4 -> 8 -> 11 -> 12 -> 10 -> 9 -> 7 -> 1 -> 3 -> 5 -> 2 -> 6 -> 0
139353Total distance: 403.93
140- Time taken: 48.396 seconds
354+ Time taken: 55.959 seconds
141355
142356=== Multi-threaded Solution (8 threads) ===
143- Best path: [0, 4, 8, 11, 12, 10, 9, 7, 1, 3, 5, 2, 6 ]
144- Route: 0 -> 4 -> 8 -> 11 -> 12 -> 10 -> 9 -> 7 -> 1 -> 3 -> 5 -> 2 -> 6 -> 0
357+ Best path: [0, 6, 2, 5, 3, 1, 7, 9, 10, 12, 11, 8, 4 ]
358+ Route: 0 -> 6 -> 2 -> 5 -> 3 -> 1 -> 7 -> 9 -> 10 -> 12 -> 11 -> 8 -> 4 -> 0
145359Total distance: 403.93
146- Time taken: 1352.130 seconds
360+ Time taken: 15.452 seconds
147361
148362✓ Both methods found the same optimal solution!
149- Speedup: 0.04x
363+ Speedup: 3.62x
150364
151- real 23m20.593s
152- user 41m44.955s
153- sys 74m49.482s
365+ real 1m11.505s
366+ user 2m25.218s
367+ sys 0m0.086s
154368kushal@flex2024:~/src/rust/tsp_rust$
155369```
0 commit comments