-
Notifications
You must be signed in to change notification settings - Fork 35
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
"Player 0x0bf860653e4a21553d9507dde3f9e59c88e8514a submitted 'clarke_…
…wright' for challenge vehicle_routing"
- Loading branch information
0x0bf860653e4a21553d9507dde3f9e59c88e8514a
committed
May 16, 2024
1 parent
39e40f4
commit c8c728a
Showing
7 changed files
with
513 additions
and
1 deletion.
There are no files selected for viewing
102 changes: 102 additions & 0 deletions
102
tig-algorithms/src/vehicle_routing/clarke_wright/benchmarker_outbound.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
/*! | ||
Copyright 2024 Uncharted Trading Limited | ||
Licensed under the TIG Benchmarker Outbound Game License v1.0 (the "License"); you | ||
may not use this file except in compliance with the License. You may obtain a copy | ||
of the License at | ||
https://github.com/tig-foundation/tig-monorepo/tree/main/docs/licenses | ||
Unless required by applicable law or agreed to in writing, software distributed | ||
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR | ||
CONDITIONS OF ANY KIND, either express or implied. See the License for the specific | ||
language governing permissions and limitations under the License. | ||
*/ | ||
|
||
use tig_challenges::vehicle_routing::*; | ||
|
||
pub fn solve_challenge(challenge: &Challenge) -> anyhow::Result<Option<Solution>> { | ||
let d = &challenge.distance_matrix; | ||
let c = challenge.max_capacity; | ||
let n = challenge.difficulty.num_nodes; | ||
|
||
// Clarke-Wright heuristic for node pairs based on their distances to depot | ||
// vs distance between each other | ||
let mut scores: Vec<(i32, usize, usize)> = Vec::new(); | ||
for i in 1..n { | ||
for j in (i + 1)..n { | ||
scores.push((d[i][0] + d[0][j] - d[i][j], i, j)); | ||
} | ||
} | ||
scores.sort_by(|a, b| b.0.cmp(&a.0)); // Sort in descending order by score | ||
|
||
// Create a route for every node | ||
let mut routes: Vec<Option<Vec<usize>>> = (0..n).map(|i| Some(vec![i])).collect(); | ||
routes[0] = None; | ||
let mut route_demands: Vec<i32> = challenge.demands.clone(); | ||
|
||
// Iterate through node pairs, starting from greatest score | ||
for (s, i, j) in scores { | ||
// Stop if score is negative | ||
if s < 0 { | ||
break; | ||
} | ||
|
||
// Skip if joining the nodes is not possible | ||
if routes[i].is_none() || routes[j].is_none() { | ||
continue; | ||
} | ||
|
||
let left_route = routes[i].as_ref().unwrap(); | ||
let right_route = routes[j].as_ref().unwrap(); | ||
let mut left_startnode = left_route[0]; | ||
let right_startnode = right_route[0]; | ||
let left_endnode = left_route[left_route.len() - 1]; | ||
let mut right_endnode = right_route[right_route.len() - 1]; | ||
let merged_demand = route_demands[left_startnode] + route_demands[right_startnode]; | ||
|
||
if left_startnode == right_startnode || merged_demand > c { | ||
continue; | ||
} | ||
|
||
let mut left_route = routes[i].take().unwrap(); | ||
let mut right_route = routes[j].take().unwrap(); | ||
routes[left_startnode] = None; | ||
routes[right_startnode] = None; | ||
routes[left_endnode] = None; | ||
routes[right_endnode] = None; | ||
|
||
// reverse it | ||
if left_startnode == i { | ||
left_route.reverse(); | ||
left_startnode = left_endnode; | ||
} | ||
if right_endnode == j { | ||
right_route.reverse(); | ||
right_endnode = right_startnode; | ||
} | ||
|
||
let mut new_route = left_route; | ||
new_route.extend(right_route); | ||
|
||
// Only the start and end nodes of routes are kept | ||
routes[left_startnode] = Some(new_route.clone()); | ||
routes[right_endnode] = Some(new_route); | ||
route_demands[left_startnode] = merged_demand; | ||
route_demands[right_endnode] = merged_demand; | ||
} | ||
|
||
Ok(Some(Solution { | ||
routes: routes | ||
.into_iter() | ||
.enumerate() | ||
.filter(|(i, x)| x.as_ref().is_some_and(|x| x[0] == *i)) | ||
.map(|(_, mut x)| { | ||
let mut route = vec![0]; | ||
route.append(x.as_mut().unwrap()); | ||
route.push(0); | ||
route | ||
}) | ||
.collect(), | ||
})) | ||
} |
102 changes: 102 additions & 0 deletions
102
tig-algorithms/src/vehicle_routing/clarke_wright/commercial.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
/*! | ||
Copyright 2024 Uncharted Trading Limited | ||
Licensed under the TIG Commercial License v1.0 (the "License"); you | ||
may not use this file except in compliance with the License. You may obtain a copy | ||
of the License at | ||
https://github.com/tig-foundation/tig-monorepo/tree/main/docs/licenses | ||
Unless required by applicable law or agreed to in writing, software distributed | ||
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR | ||
CONDITIONS OF ANY KIND, either express or implied. See the License for the specific | ||
language governing permissions and limitations under the License. | ||
*/ | ||
|
||
use tig_challenges::vehicle_routing::*; | ||
|
||
pub fn solve_challenge(challenge: &Challenge) -> anyhow::Result<Option<Solution>> { | ||
let d = &challenge.distance_matrix; | ||
let c = challenge.max_capacity; | ||
let n = challenge.difficulty.num_nodes; | ||
|
||
// Clarke-Wright heuristic for node pairs based on their distances to depot | ||
// vs distance between each other | ||
let mut scores: Vec<(i32, usize, usize)> = Vec::new(); | ||
for i in 1..n { | ||
for j in (i + 1)..n { | ||
scores.push((d[i][0] + d[0][j] - d[i][j], i, j)); | ||
} | ||
} | ||
scores.sort_by(|a, b| b.0.cmp(&a.0)); // Sort in descending order by score | ||
|
||
// Create a route for every node | ||
let mut routes: Vec<Option<Vec<usize>>> = (0..n).map(|i| Some(vec![i])).collect(); | ||
routes[0] = None; | ||
let mut route_demands: Vec<i32> = challenge.demands.clone(); | ||
|
||
// Iterate through node pairs, starting from greatest score | ||
for (s, i, j) in scores { | ||
// Stop if score is negative | ||
if s < 0 { | ||
break; | ||
} | ||
|
||
// Skip if joining the nodes is not possible | ||
if routes[i].is_none() || routes[j].is_none() { | ||
continue; | ||
} | ||
|
||
let left_route = routes[i].as_ref().unwrap(); | ||
let right_route = routes[j].as_ref().unwrap(); | ||
let mut left_startnode = left_route[0]; | ||
let right_startnode = right_route[0]; | ||
let left_endnode = left_route[left_route.len() - 1]; | ||
let mut right_endnode = right_route[right_route.len() - 1]; | ||
let merged_demand = route_demands[left_startnode] + route_demands[right_startnode]; | ||
|
||
if left_startnode == right_startnode || merged_demand > c { | ||
continue; | ||
} | ||
|
||
let mut left_route = routes[i].take().unwrap(); | ||
let mut right_route = routes[j].take().unwrap(); | ||
routes[left_startnode] = None; | ||
routes[right_startnode] = None; | ||
routes[left_endnode] = None; | ||
routes[right_endnode] = None; | ||
|
||
// reverse it | ||
if left_startnode == i { | ||
left_route.reverse(); | ||
left_startnode = left_endnode; | ||
} | ||
if right_endnode == j { | ||
right_route.reverse(); | ||
right_endnode = right_startnode; | ||
} | ||
|
||
let mut new_route = left_route; | ||
new_route.extend(right_route); | ||
|
||
// Only the start and end nodes of routes are kept | ||
routes[left_startnode] = Some(new_route.clone()); | ||
routes[right_endnode] = Some(new_route); | ||
route_demands[left_startnode] = merged_demand; | ||
route_demands[right_endnode] = merged_demand; | ||
} | ||
|
||
Ok(Some(Solution { | ||
routes: routes | ||
.into_iter() | ||
.enumerate() | ||
.filter(|(i, x)| x.as_ref().is_some_and(|x| x[0] == *i)) | ||
.map(|(_, mut x)| { | ||
let mut route = vec![0]; | ||
route.append(x.as_mut().unwrap()); | ||
route.push(0); | ||
route | ||
}) | ||
.collect(), | ||
})) | ||
} |
102 changes: 102 additions & 0 deletions
102
tig-algorithms/src/vehicle_routing/clarke_wright/inbound.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
/*! | ||
Copyright 2024 Uncharted Trading Limited | ||
Licensed under the TIG Inbound Game License v1.0 or (at your option) any later | ||
version (the "License"); you may not use this file except in compliance with the | ||
License. You may obtain a copy of the License at | ||
https://github.com/tig-foundation/tig-monorepo/tree/main/docs/licenses | ||
Unless required by applicable law or agreed to in writing, software distributed | ||
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR | ||
CONDITIONS OF ANY KIND, either express or implied. See the License for the specific | ||
language governing permissions and limitations under the License. | ||
*/ | ||
|
||
use tig_challenges::vehicle_routing::*; | ||
|
||
pub fn solve_challenge(challenge: &Challenge) -> anyhow::Result<Option<Solution>> { | ||
let d = &challenge.distance_matrix; | ||
let c = challenge.max_capacity; | ||
let n = challenge.difficulty.num_nodes; | ||
|
||
// Clarke-Wright heuristic for node pairs based on their distances to depot | ||
// vs distance between each other | ||
let mut scores: Vec<(i32, usize, usize)> = Vec::new(); | ||
for i in 1..n { | ||
for j in (i + 1)..n { | ||
scores.push((d[i][0] + d[0][j] - d[i][j], i, j)); | ||
} | ||
} | ||
scores.sort_by(|a, b| b.0.cmp(&a.0)); // Sort in descending order by score | ||
|
||
// Create a route for every node | ||
let mut routes: Vec<Option<Vec<usize>>> = (0..n).map(|i| Some(vec![i])).collect(); | ||
routes[0] = None; | ||
let mut route_demands: Vec<i32> = challenge.demands.clone(); | ||
|
||
// Iterate through node pairs, starting from greatest score | ||
for (s, i, j) in scores { | ||
// Stop if score is negative | ||
if s < 0 { | ||
break; | ||
} | ||
|
||
// Skip if joining the nodes is not possible | ||
if routes[i].is_none() || routes[j].is_none() { | ||
continue; | ||
} | ||
|
||
let left_route = routes[i].as_ref().unwrap(); | ||
let right_route = routes[j].as_ref().unwrap(); | ||
let mut left_startnode = left_route[0]; | ||
let right_startnode = right_route[0]; | ||
let left_endnode = left_route[left_route.len() - 1]; | ||
let mut right_endnode = right_route[right_route.len() - 1]; | ||
let merged_demand = route_demands[left_startnode] + route_demands[right_startnode]; | ||
|
||
if left_startnode == right_startnode || merged_demand > c { | ||
continue; | ||
} | ||
|
||
let mut left_route = routes[i].take().unwrap(); | ||
let mut right_route = routes[j].take().unwrap(); | ||
routes[left_startnode] = None; | ||
routes[right_startnode] = None; | ||
routes[left_endnode] = None; | ||
routes[right_endnode] = None; | ||
|
||
// reverse it | ||
if left_startnode == i { | ||
left_route.reverse(); | ||
left_startnode = left_endnode; | ||
} | ||
if right_endnode == j { | ||
right_route.reverse(); | ||
right_endnode = right_startnode; | ||
} | ||
|
||
let mut new_route = left_route; | ||
new_route.extend(right_route); | ||
|
||
// Only the start and end nodes of routes are kept | ||
routes[left_startnode] = Some(new_route.clone()); | ||
routes[right_endnode] = Some(new_route); | ||
route_demands[left_startnode] = merged_demand; | ||
route_demands[right_endnode] = merged_demand; | ||
} | ||
|
||
Ok(Some(Solution { | ||
routes: routes | ||
.into_iter() | ||
.enumerate() | ||
.filter(|(i, x)| x.as_ref().is_some_and(|x| x[0] == *i)) | ||
.map(|(_, mut x)| { | ||
let mut route = vec![0]; | ||
route.append(x.as_mut().unwrap()); | ||
route.push(0); | ||
route | ||
}) | ||
.collect(), | ||
})) | ||
} |
Oops, something went wrong.