1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
use crate::format::Location;
use serde::{Deserialize, Serialize};
use std::io::{BufReader, BufWriter, Error, Read, Write};

/// Timing statistic.
#[derive(Clone, Deserialize, Serialize, PartialEq, Debug)]
pub struct Timing {
    /// Driving time.
    pub driving: i64,
    /// Serving time.
    pub serving: i64,
    /// Waiting time.
    pub waiting: i64,
    /// Break time.
    #[serde(rename(serialize = "break", deserialize = "break"))]
    pub break_time: i64,
}

/// Represents statistic.
#[derive(Clone, Deserialize, Serialize, PartialEq, Debug)]
pub struct Statistic {
    /// Total cost.
    pub cost: f64,
    /// Total distance.
    pub distance: i64,
    /// Total duration.
    pub duration: i64,
    /// Timing statistic.
    pub times: Timing,
}

/// Represents a schedule.
#[derive(Clone, Deserialize, Serialize, PartialEq, Debug)]
pub struct Schedule {
    /// Arrival time specified in RFC3339 format.
    pub arrival: String,
    /// Departure time specified in RFC3339 format.
    pub departure: String,
}

/// Represents time interval.
#[derive(Clone, Deserialize, Serialize, PartialEq, Debug)]
pub struct Interval {
    /// Start time specified in RFC3339 format.
    pub start: String,
    /// End time specified in RFC3339 format.
    pub end: String,
}

/// An activity is unit of work performed at some place.
#[derive(Clone, Deserialize, Serialize, PartialEq, Debug)]
#[serde(rename_all = "camelCase")]
pub struct Activity {
    /// Job id.
    pub job_id: String,
    /// Activity type.
    #[serde(rename(serialize = "type", deserialize = "type"))]
    pub activity_type: String,
    /// Location.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub location: Option<Location>,
    /// Active time.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub time: Option<Interval>,
    /// Job tag.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub job_tag: Option<String>,
}

/// A stop is a place where vehicle is supposed to be parked.
#[derive(Clone, Deserialize, Serialize, PartialEq, Debug)]
pub struct Stop {
    /// Stop location.
    pub location: Location,
    /// Stop schedule.
    pub time: Schedule,
    /// Distance traveled since departure from start.
    pub distance: i64,
    /// Vehicle load after departure from this stop.
    pub load: Vec<i32>,
    /// Activities performed at the stop.
    pub activities: Vec<Activity>,
}

/// A tour is list of stops with their activities performed by specific vehicle.
#[derive(Clone, Deserialize, Serialize, PartialEq, Debug)]
#[serde(rename_all = "camelCase")]
pub struct Tour {
    /// Vehicle id.
    pub vehicle_id: String,
    /// Vehicle type id.
    pub type_id: String,
    /// Shift index.
    pub shift_index: usize,
    /// List of stops.
    pub stops: Vec<Stop>,
    /// Tour statistic.
    pub statistic: Statistic,
}

/// Unassigned job reason.
#[derive(Clone, Deserialize, Serialize, PartialEq, Debug)]
pub struct UnassignedJobReason {
    /// A reason code.
    pub code: i32,
    /// Description.
    pub description: String,
}

/// Unassigned job.
#[derive(Clone, Deserialize, Serialize, PartialEq, Debug)]
#[serde(rename_all = "camelCase")]
pub struct UnassignedJob {
    /// Job id.
    pub job_id: String,
    /// Possible reasons.
    pub reasons: Vec<UnassignedJobReason>,
}

/// Specifies a type of violation.
#[derive(Clone, Deserialize, Serialize, PartialEq, Debug)]
#[serde(rename_all = "camelCase")]
#[serde(tag = "type")]
pub enum Violation {
    /// A break assignment violation.
    #[serde(rename(deserialize = "break", serialize = "break"))]
    Break {
        /// An id of a vehicle break belong to.
        vehicle_id: String,
        /// Index of the shift.
        shift_index: usize,
        /// A reason of violation.
        reason: String,
    },
}

/// Encapsulates different measurements regarding algorithm evaluation.
#[derive(Clone, Deserialize, Serialize, PartialEq, Debug)]
pub struct Metrics {
    /// Total algorithm duration.
    pub duration: usize,
    /// Total amount of generations.
    pub generations: usize,
    /// Speed: generations per second.
    pub speed: f64,
    /// Evolution progress.
    pub evolution: Vec<Generation>,
}

/// Represents information about generation.
#[derive(Clone, Deserialize, Serialize, PartialEq, Debug)]
#[serde(rename_all = "camelCase")]
pub struct Generation {
    /// Generation sequence number.
    pub number: usize,
    /// Time since evolution started.
    pub timestamp: f64,
    /// Overall improvement ratio.
    pub i_all_ratio: f64,
    /// Improvement ratio last 1000 generations.
    pub i_1000_ratio: f64,
    /// True if this generation considered as improvement.
    pub is_improvement: bool,
    /// Population state.
    pub population: Vec<Individual>,
}

/// Keeps essential information about particular individual in population.
#[derive(Clone, Deserialize, Serialize, PartialEq, Debug)]
#[serde(rename_all = "camelCase")]
pub struct Individual {
    /// Total amount of tours.
    pub tours: usize,
    /// Total amount of unassigned jobs.
    pub unassigned: usize,
    /// Solution cost.
    pub cost: f64,
    /// Solution cost difference from best individual.
    pub improvement: f64,
    /// Objectives fitness values.
    pub fitness: Vec<f64>,
}

/// Contains extra information.
#[derive(Clone, Deserialize, Serialize, PartialEq, Debug)]
pub struct Extras {
    /// A telemetry metrics.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub metrics: Option<Metrics>,
}

/// A VRP solution.
#[derive(Clone, Deserialize, Serialize, PartialEq, Debug)]
#[serde(rename_all = "camelCase")]
pub struct Solution {
    /// Total statistic.
    pub statistic: Statistic,

    /// List of tours.
    pub tours: Vec<Tour>,

    /// List of unassigned jobs.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub unassigned: Option<Vec<UnassignedJob>>,

    /// List of constraint violations.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub violations: Option<Vec<Violation>>,

    /// An extra information.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub extras: Option<Extras>,
}

/// Serializes solution into json format.
pub fn serialize_solution<W: Write>(writer: BufWriter<W>, solution: &Solution) -> Result<(), Error> {
    serde_json::to_writer_pretty(writer, solution).map_err(Error::from)
}

/// Deserializes solution from json format.
pub fn deserialize_solution<R: Read>(reader: BufReader<R>) -> Result<Solution, Error> {
    serde_json::from_reader(reader).map_err(Error::from)
}