1use crate::vehicle::Vehicle;
2use crate::location::Location;
3use crate::route::Route;
4use crate::errors::InfeasableProblem;
5use itertools::Itertools;
6
7pub struct UnsolvedProblem {
8 vehicles: Vec<Vehicle>,
9 destinations: Vec<Location>,
10}
11
12impl UnsolvedProblem {
13 pub fn new(vehicles: Vec<Vehicle>, destinations: Vec<Location>) -> Self {
14 UnsolvedProblem {
15 vehicles,
16 destinations
17 }
18 }
19
20 pub fn initial_solution(self) -> Result<SolvedProblem, InfeasableProblem> {
21 if !self.solvable() {
22 return Err(InfeasableProblem)
23 }
24
25 let mut routes: Vec<Route> = Vec::new();
26 let mut destinations = self.destinations;
27 let mut vehicles = self.vehicles;
28
29 destinations.sort_by(|a, b| b.cmp(a));
30 vehicles.sort_by(|a, b| b.cmp(a));
31
32 for vehicle in vehicles {
33 let mut route = Route::new(vehicle);
34
35 let mut remainder = Vec::new();
36 for destination in destinations.into_iter() {
37
38 if destination.demand <= route.vehicle.capacity {
39 dbg!(&route.vehicle);
40 route.vehicle.capacity -= destination.demand;
41 route.destinations.push(destination)
42 } else {
43 remainder.push(destination)
44 }
45 }
46 destinations = remainder;
47
48 routes.push(route)
49 }
50
51 dbg!(&routes);
52
53 Ok(SolvedProblem::new(routes))
54 }
55
56 pub fn solvable(&self) -> bool {
63 let mut demands: Vec<i64> = self.destinations.iter().map(|location| &location.demand).copied().collect();
64 let mut capacities: Vec<i64> = self.vehicles.iter().map(|vehicle| &vehicle.capacity).copied().collect();
65
66 demands.sort_by(|a, b| b.cmp(a));
67 capacities.sort_by(|a, b| b.cmp(a));
68
69 let mut put_in_bin: bool;
70 for demand in demands {
71 put_in_bin = false;
72 for capacity in capacities.iter_mut() {
73 dbg!(&demand, &capacity);
74 if demand <= *capacity {
75 *capacity -= demand;
76 put_in_bin = true;
77 break;
78 }
79 }
80 if !put_in_bin {
81 return false
82 }
83 }
84 true
85 }
86}
87
88pub struct SolvedProblem {
89 routes: Vec<Route>,
90}
91
92impl SolvedProblem {
93 pub fn new(routes: Vec<Route>) -> SolvedProblem {
94 SolvedProblem {
95 routes: routes
96 }
97 }
98
99 pub fn intra_two_opt(mut self) -> SolvedProblem {
100 fn two_opt(route: &mut Route) {
101 let n_nodes = 2;
102 let mut best_cost = route.cost();
103 for i in 0..route.destinations.len()-(n_nodes-1) {
104 let mut candidate_route_destinations = route.destinations.clone();
105 candidate_route_destinations.swap(i, i+n_nodes);
106
107 std::mem::swap(&mut route.destinations, &mut candidate_route_destinations);
108 let cost = route.cost();
109 if cost < best_cost {
110 best_cost = cost;
111 } else {
112 std::mem::swap(&mut route.destinations, &mut candidate_route_destinations);
113 }
114 }
115 }
116
117 for route in self.routes.iter_mut() {
118 two_opt(route)
119 }
120
121 self
122 }
123
124 pub fn intra_three_opt(mut self) -> SolvedProblem {
125 fn three_opt(route: &mut Route) {
126 let n_nodes: usize = 3;
127 let mut best_cost = route.cost();
128
129 let route_len = route.destinations.len();
130 for i in 0..route_len-(n_nodes-1) {
131 for j in i..route_len-(n_nodes-2) {
132 for k in j..route_len {
133 let index = [i,j,k];
134 let options = index.iter().permutations(3);
135 'options: for option in options {
136 let i2 = *option[0]; let j2 = *option[1]; let k2 = *option[2]; let mut candidate_route_destinations = route.destinations.clone();
141 candidate_route_destinations.swap(i, i2);
142 candidate_route_destinations.swap(j, j2);
143 candidate_route_destinations.swap(k, k2);
144
145 std::mem::swap(&mut route.destinations, &mut candidate_route_destinations);
146 let cost = route.cost();
147 if cost < best_cost {
148 best_cost = cost;
149 break 'options;
150 } else {
151 std::mem::swap(&mut route.destinations, &mut candidate_route_destinations);
152 }
153 }
154 }
155 }
156 }
157 }
158 for route in self.routes.iter_mut() {
159 three_opt(route)
160 }
161
162 self
163 }
164
165
166}