I am implementing a function that takes a list of indices representing a solution to the traveling salesman problem, and calculate the total travel distance using a distance matrix.
I need to iterate over the list in windows of 2 and aggregate the distances, including a last iteration of traveling back from the last index in the list to the first one.
I'm trying to solve it in a functional-style way, my current solution is:
fn calculate_solution_distance(solution: Vec<usize>, distance_matrix: Vec<Vec<i32>>) -> i32 {
[solution.as_slice(), &[solution[0]]]
.concat()
.windows(2)
.map(|indices| get_distance(indices[0], indices[1], &distance_matrix))
.sum()
}
fn get_distance(from: usize, to: usize, distance_matrix: &Vec<Vec<i32>>) -> i32 {
distance_matrix[from][to]
}
This code works. however it seems rather inefficient, speficially creating a slice from the first index just so I can concat it with a slice of my list. Is there a more efficient way to iterate over the list in windows of 2 such that the last item in the list is also iterated over twice?