pub struct Solution {
pub id: i32,
pub solution: Vec<Vec<Game>>,
}Expand description
Represents a solution for the scheduling problem.
Each Solution contains an id identifying the solution,
and a solution matrix where solution[slot][team]
stores a Game indicating the opponent and if the game is home or away.
§Fields
id- A unique identifier for the solution.solution- A 2D vector ofGameinstances representing the schedule matrix.
§Example
let solution = Solution {
id: 1,
solution: vec![vec![Game { home_game: true, opponent: 2 }]],
};
println!("Solution ID: {}", solution.id);Fields§
§id: i32§solution: Vec<Vec<Game>>Implementations§
Source§impl Solution
impl Solution
Sourcepub fn new(data: &Rawdata) -> Solution
pub fn new(data: &Rawdata) -> Solution
Creates a new, empty Solution instance initialized with default game values.
This function constructs a solution matrix where each slot and team position
is filled with a Game:
home_gameis set tofalseopponentis set to-1(indicating: no opponent assigned yet)
§Arguments
data- A reference to theRawdatastructure containing teams and slots information. The size of the solution matrix is derived from:data.teams.len()data.slots.len()
§Returns
A Solution struct with:
idinitialized to-1solutioninitialized as aslots x teamsmatrix filled with default games.
§Example
let data = Rawdata::generate_example();
let solution = Solution::new(&data);
assert_eq!(solution.solution.len(), data.slots.len());
assert_eq!(solution.solution[0].len(), data.teams.len());Sourcepub fn generate_traveling_distance_matrix(data: &Rawdata) -> Vec<Vec<i32>>
pub fn generate_traveling_distance_matrix(data: &Rawdata) -> Vec<Vec<i32>>
Generates a traveling distance matrix based on the distance in Rawdata.
This function constructs a 2D matrix where each cell (i, j) represents the
distance traveled from team i to team j. The matrix is initialized with
zeros and populated using the distances list contained inside Rawdata.
§Arguments
data- A reference to theRawdatastructure containing team distance relationships.data.distancesis expected to list distances between pairs of teams.
§Returns
A 2D vector (Vec<Vec<i32>>) where:
- The row index corresponds to the origin team
- The column index corresponds to the destination team
- Each cell contains the travel distance between them
§Example
let data = Rawdata::generate_example();
let distance_matrix = generate_traveling_distance_matrix(&data);
println!("Distance: {}", distance_matrix[0][2]);Sourcepub fn has_duplicate_solutions(solutions: &Vec<Solution>) -> bool
pub fn has_duplicate_solutions(solutions: &Vec<Solution>) -> bool
Checks if a list of Solution objects contains duplicates.
This function iterates over all solutions and attempts to insert each one into a
HashSet. If insertion fails for any solution, it means a duplicate exists,
and the function returns true.
§Arguments
solutions- A reference to a vector ofSolutioninstances to be checked.
§Returns
trueif one or more duplicates are found.falseif all solutions are unique.
§Requirements
The Solution type must implement:
HashEq
§Example
let solutions = load_solutions("output/solutions/");
if has_duplicate_solutions(&solutions) {
println!("Duplicate.");
} else {
println!("No duplicates.");
}Sourcepub fn load_solutions(path: &str) -> Vec<Solution>
pub fn load_solutions(path: &str) -> Vec<Solution>
Loads all solution files from a directory and returns them as a vector of Solution.
This function scans the directory for files whose names follow the pattern
solutions_*.json. Each file is opened, deserialized into a Solution,
and collected into a vector. After loading, the solutions are sorted in ascending
order based on their id field.
§Arguments
path- A string slice representing the directory to search for solution files.
§Returns
A vector of Solution objects loaded from the directory.
§Panics
This function will panic if:
- The directory cannot be read.
- A file cannot be opened.
- A JSON file cannot be deserialized into a
Solution.
§Example
let solutions = load_solutions("output/solutions/");
println!("Loaded {} solutions", solutions.len());
if let Some(first) = solutions.first() {
println!("First solution ID: {}", first.id);
}Sourcepub fn generate_distances(
solutions: Vec<Solution>,
data: &Rawdata,
traveling_distance_matrix: &Vec<Vec<i32>>,
) -> Vec<i128>
pub fn generate_distances( solutions: Vec<Solution>, data: &Rawdata, traveling_distance_matrix: &Vec<Vec<i32>>, ) -> Vec<i128>
Calculates the total traveling distances for a list of solutions.
This function iterates over each solution, evaluates it using the provided traveling distance matrix, and collects the total distances into a vector.
§Arguments
solutions- A vector ofSolutioninstances to evaluate.data- A reference to theRawdatacontaining teams and constraints.traveling_distance_matrix- A reference to a 2D vector wherematrix[i][j]represents the distance from teamito teamj.
§Returns
A vector of i128 where each element represents the total traveling distance
of the corresponding solution.
§Example
let data = Rawdata::generate_example();
let distance_matrix = vec![vec![0,5,7], vec![5,0,3], vec![7,3,0]];
let solutions = vec![Solution::generate_example(), Solution::generate_example()];
let distances = generate_distances(solutions, &data, &distance_matrix);
println!("All distances: {:?}", distances);Sourcefn log_solution(
solution: &Solution,
data: &Rawdata,
traveling_distance_matrix: &Vec<Vec<i32>>,
) -> i32
fn log_solution( solution: &Solution, data: &Rawdata, traveling_distance_matrix: &Vec<Vec<i32>>, ) -> i32
Logs a solution’s schedule and its evaluation metrics.
This function prints a representation of the solution, including the total traveling distance, capacity, round-robin and separation constraint violations, It also returns the total distance.
§Arguments
solution- A reference to theSolutionto log.data- A reference to theRawdatacontaining teams and constraints.traveling_distance_matrix- A reference to a 2D vector wherematrix[i][j]represents the distance from teamito teamj.
§Returns
The total traveling distance (i32) of the solution.
§Example
let data = Rawdata::generate_example();
let solution = Solution::generate_example();
let distance = Solution::log_solution(&solution, &data, &vec![vec![0,5,7], vec![5,0,3], vec![7,3,0]]);
println!("Total distance: {}", distance);Sourcefn generate_solution(
data: &Rawdata,
perm: &Vec<Team>,
fixed_team: usize,
upward: bool,
id: i32,
) -> Solution
fn generate_solution( data: &Rawdata, perm: &Vec<Team>, fixed_team: usize, upward: bool, id: i32, ) -> Solution
Generates a complete solution for a given team permutation using Florian’s method.
This function clones the input Rawdata, applies the given team permutation, and
generates a round-robin schedule using generate_florian_solution. The resulting
solution is assigned the provided ID.
§Arguments
data- A reference to theRawdatacontaining the original teams, traveling_distance_matrix and constraints.perm- A reference to a vector ofTeamrepresenting the ordered permutation of teams.fixed_team- The index of the team to remain fixed during the method rotations.upward- Iftrue, the home/away pattern follows an upward direction, otherwise downward.id- The unique ID to assign to the generated solution.
§Returns
A Solution struct representing the generated schedule with the specified ID.
§Example
let data = Rawdata::generate_example();
let perm = data.teams.clone();
let solution = generate_solution(&data, &perm, 0, true, 1);
println!("{}", solution_to_string(&solution, &data));Sourcepub fn generate_random_permutations(
data: &Rawdata,
number_permutations: i32,
seed: u64,
path: &str,
save: bool,
) -> Vec<Vec<i32>>
pub fn generate_random_permutations( data: &Rawdata, number_permutations: i32, seed: u64, path: &str, save: bool, ) -> Vec<Vec<i32>>
Generates a set of unique random permutations of the team IDs.
This function takes the list of teams from Rawdata and generates the requested number of
unique permutations. Each permutation is randomized and stored in a Vec<i32>.
§Arguments
data- A reference to theRawdatastruct containing the list of teams.number_permutation- A reference to ani32specifying how many unique permutations should be generated.
§Returns
A vector of vectors (Vec<Vec<i32>>), where each inner vector is a unique permutation
of the team IDs.
§Example
let data = Rawdata::generate_example();
let permutations = generate_random_permutations(&data, &5);Sourcepub fn generate_all_solutions(
data: &Rawdata,
traveling_distance_matrix: &Vec<Vec<i32>>,
permutation: Vec<Vec<i32>>,
path: &str,
save: bool,
) -> (Vec<Solution>, Vec<i128>)
pub fn generate_all_solutions( data: &Rawdata, traveling_distance_matrix: &Vec<Vec<i32>>, permutation: Vec<Vec<i32>>, path: &str, save: bool, ) -> (Vec<Solution>, Vec<i128>)
Generates all possible solutions for a given team permutation using Florian’s method, evaluates their distances, and optionally saves them to disk.
This function iterates over all possible combinations of fixed teams and home/away patterns (upward/downward) for a given permutation of teams. Each generated solution is evaluated using the traveling distance matrix, logged, and optionally saved as JSON.
§Arguments
data- A reference to theRawdatacontaining teams, slots, and constraints.traveling_distance_matrix- A reference to a 2D vector wherematrix[i][j]represents the distance from teamito teamj.permutation- A vector of vect of team IDs representing the order in which teams are considered.path- A string slice representing the directory path where solutions will be saved ifSAVE_ENABLEDis true.
§Returns
A tuple (solutions, all_distances):
solutions(Vec): all generated solution matrices. all_distances(Vec): total traveling distance for each solution.
§Panics
This function may panic if saving a solution to file fails.
§Example
let data = Rawdata::generate_example();
let distance_matrix = vec![vec![0,5,7], vec![5,0,3], vec![7,3,0]];
let permutation = vec![0,1,2];
let (solutions, distances) = generate_all_solutions(&data, &distance_matrix, permutation, "output");
println!("Solutions length {}", solutions.len());
println!("Distances: {:?}", distances);Sourcepub fn generate_florian_solution(
data: &Rawdata,
fixed_team: usize,
upward: bool,
) -> Solution
pub fn generate_florian_solution( data: &Rawdata, fixed_team: usize, upward: bool, ) -> Solution
Generates a schedule using Florian’s method construction.
This function constructs a round-robin schedule fixing a team. The upward
flag determines the pattern of home/away assignments for the first match
of each pairing.
§Arguments
data- A reference toRawdatacontaining team information.fixed_team- The index of the team to remain fixed during rotations.upward- Iftrue, the home team assignment follows an upward pattern; otherwise downward.
§Returns
A Solution struct with the scheduled matches for all slots and teams.
§Example
let data = Rawdata::generate_example();
let solution = generate_florian_solution(&data, 0, true);
println!("{}", solution_to_string(&solution, &data));Sourcepub fn solution_to_string(solution_matrix: &Solution, data: &Rawdata) -> String
pub fn solution_to_string(solution_matrix: &Solution, data: &Rawdata) -> String
Converts a Solution matrix into a formatted string representation.
This function generates a human-readable string showing the schedule of all teams
for each slot. Each cell shows the opponent ID followed by H for a home game or
A for an away game. The output also includes team names and IDs as headers.
§Arguments
solution_matrix- A reference to theSolutioncontaining the schedule.data- A reference to theRawdatastruct containing team information.
§Returns
A String representing the formatted solution.
§Example
let data = Rawdata::generate_example();
let solution = Solution::generate_example();
let output_str = solution_to_string(&solution, &data);
println!("{}", output_str);Example output:
Id: 1
ATL:0 NYM:1 PHI:2
Slot:0 1H 2A 0H
Slot:1 2H 0A 1HSourcefn check_constraints(
data: &Rawdata,
solution_matrix: &Solution,
) -> (i32, i32, bool)
fn check_constraints( data: &Rawdata, solution_matrix: &Solution, ) -> (i32, i32, bool)
Checks all constraints for a solution, including capacity, separation, and round-robin.
-
Capacity constraints: Verifies for each team, within the specified interval (
c_intp) of consecutive slots, the number of home or away games falls within the minimum (c_min) and maximum (c_max) allowed. -
Separation constraints: Ensures that matches between two teams respect the minimum and maximum separation distances defined by each constraint.
-
Round-robin constraints: Checks that no pair of teams plays against each other more than 4 times (2 pairs of game).
§Arguments
data- A reference to theRawdatacontaining teams and constraints.solution_matrix- A reference to theSolutionwith the scheduled games.
§Returns
A tuple (capacity_violations, separation_violations, round_robin_respected)
capacity_violations(i32): total number of capacity constraint violations.separation_violations(i32): total number of separation constraint violations.round_robin_respected(bool): true if all pairs of teams respect the round-robin.
§Example
let data = Rawdata::generate_example();
let solution = Solution::generate_example();
let (cap_viol, sep_viol, rr_ok) = check_constraints(&data, &solution);
println!("Capacity violations: {}, Separation violations: {}, Round-robin ok: {}", cap_viol, sep_viol, rr_ok);Sourcefn evaluate_objective(
traveling_distance_matrix: &Vec<Vec<i32>>,
solution_matrix: &Solution,
) -> i32
fn evaluate_objective( traveling_distance_matrix: &Vec<Vec<i32>>, solution_matrix: &Solution, ) -> i32
Calculates the total traveling distance for all teams in a given solution.
This function iterates over all teams and all slots in the solution. For each team, it tracks the current location and adds the distance to the next game location. Home games do not require traveling, while away games add the distance to the opponent’s location.
§Arguments
traveling_distance_matrix- A reference to a 2D vector wherematrix[i][j]represents the distance from teamito teamj.solution_matrix- A reference to theSolutioncontaining the schedule of games for all slots and teams.
§Returns
The total traveling distance for all teams (i32).
§Example
let distance_matrix = vec![vec![0, 5, 7], vec![5, 0, 3], vec![7, 3, 0]];
let total = evaluate_objective(&distance_matrix, &solution);
println!("Total traveling distance: {}", total);Sourcepub fn evaluate_solution(
data: &Rawdata,
traveling_distance_matrix: &Vec<Vec<i32>>,
solution_matrix: &Solution,
) -> (i32, i32, i32, bool)
pub fn evaluate_solution( data: &Rawdata, traveling_distance_matrix: &Vec<Vec<i32>>, solution_matrix: &Solution, ) -> (i32, i32, i32, bool)
Evaluates a given solution by calculating the total traveling distance and checking constraints.
This function combines the distance evaluation and constraint checks for a solution. It returns the total traveling distance, the total violations of capacity constraints, the total violations of separation constraints, and a boolean indicating if the round-robin structure is respected.
§Arguments
data- A reference to theRawdatastruct containing teams, slots, and constraints.traveling_distance_matrix- A reference to a 2D vector wherematrix[i][j]represents the distance from teamito teamj.solution_matrix- A reference to theSolutioncontaining the schedule of games for all slots and teams.
§Returns
A tuple (total_distance, capacity_violations, separation_violations, round_robin_respected)
total_distance(i32): total traveling distance for all teams.capacity_violations(i32): total penalty for capacity constraints violations.separation_violations(i32): total penalty for separation constraints violations.round_robin_respected(bool): true if the round-robin structure is respected.
§Example
let data = Rawdata::generate_example();
let distance_matrix = vec![vec![0,5,7], vec![5,0,3], vec![7,3,0]];
let solution = Solution::generate_example();
let (total_distance, cap_viol, sep_viol, rr_ok) = evaluate_solution(&data, &distance_matrix, &solution);