Skip to main content

quantrs2_tytan/applications/logistics/
functions.rs

1//! Auto-generated module
2//!
3//! 🤖 Generated with [SplitRS](https://github.com/cool-japan/splitrs)
4
5use scirs2_core::ndarray::{Array1, Array2};
6use scirs2_core::random::prelude::*;
7use scirs2_core::random::prelude::*;
8
9use super::types::{
10    BinaryVehicleRoutingProblem, Customer, DistributionCenter, Supplier, SupplyChainNetwork,
11    SupplyChainOptimizer, TSPOptimizer, TimeWindow, VehicleRoutingOptimizer, Warehouse,
12};
13
14/// Simplified optimization problem trait for binary VRP
15pub trait OptimizationProblem {
16    type Solution;
17    /// Evaluate the objective function
18    fn evaluate(&self, solution: &Self::Solution) -> f64;
19}
20/// Create benchmark problems for testing
21pub fn create_benchmark_problems() -> Vec<BinaryVehicleRoutingProblem> {
22    let mut problems = Vec::new();
23    let small_distances = Array2::from_shape_vec(
24        (4, 4),
25        vec![
26            0.0, 10.0, 15.0, 20.0, 10.0, 0.0, 25.0, 30.0, 15.0, 25.0, 0.0, 35.0, 20.0, 30.0, 35.0,
27            0.0,
28        ],
29    )
30    .expect("Small benchmark distance matrix has valid shape");
31    let small_demands = Array1::from_vec(vec![0.0, 10.0, 15.0, 20.0]);
32    let small_optimizer =
33        VehicleRoutingOptimizer::new(small_distances.clone(), 50.0, small_demands.clone(), 2)
34            .expect("Small benchmark VRP has valid configuration");
35    problems.push(BinaryVehicleRoutingProblem::new(small_optimizer));
36    let medium_distances = Array2::from_shape_vec(
37        (6, 6),
38        vec![
39            0.0, 10.0, 15.0, 20.0, 25.0, 30.0, 10.0, 0.0, 25.0, 30.0, 35.0, 40.0, 15.0, 25.0, 0.0,
40            35.0, 40.0, 45.0, 20.0, 30.0, 35.0, 0.0, 45.0, 50.0, 25.0, 35.0, 40.0, 45.0, 0.0, 55.0,
41            30.0, 40.0, 45.0, 50.0, 55.0, 0.0,
42        ],
43    )
44    .expect("Medium benchmark distance matrix has valid shape");
45    let medium_demands = Array1::from_vec(vec![0.0, 12.0, 18.0, 22.0, 16.0, 14.0]);
46    let medium_optimizer = VehicleRoutingOptimizer::new(medium_distances, 60.0, medium_demands, 3)
47        .expect("Medium benchmark VRP has valid configuration");
48    problems.push(BinaryVehicleRoutingProblem::new(medium_optimizer));
49    let cvrptw_optimizer = VehicleRoutingOptimizer::new(small_distances, 40.0, small_demands, 2)
50        .expect("CVRPTW benchmark VRP has valid configuration")
51        .with_time_windows(vec![
52            TimeWindow {
53                start: 0.0,
54                end: 100.0,
55                service_time: 5.0,
56            },
57            TimeWindow {
58                start: 10.0,
59                end: 50.0,
60                service_time: 10.0,
61            },
62            TimeWindow {
63                start: 20.0,
64                end: 60.0,
65                service_time: 8.0,
66            },
67            TimeWindow {
68                start: 30.0,
69                end: 80.0,
70                service_time: 12.0,
71            },
72        ]);
73    problems.push(BinaryVehicleRoutingProblem::new(cvrptw_optimizer));
74    problems
75}
76#[cfg(test)]
77mod tests {
78    use super::*;
79    #[test]
80    fn test_vrp_optimizer() {
81        let distances = Array2::from_shape_vec(
82            (4, 4),
83            vec![
84                0.0, 10.0, 15.0, 20.0, 10.0, 0.0, 25.0, 30.0, 15.0, 25.0, 0.0, 35.0, 20.0, 30.0,
85                35.0, 0.0,
86            ],
87        )
88        .expect("Test distance matrix has valid shape");
89        let demands = Array1::from_vec(vec![0.0, 10.0, 15.0, 20.0]);
90        let optimizer = VehicleRoutingOptimizer::new(distances, 50.0, demands, 2)
91            .expect("Test VRP optimizer should be created with valid inputs");
92        let (_qubo, var_map) = optimizer
93            .build_qubo()
94            .expect("VRP QUBO should build successfully");
95        assert!(!var_map.is_empty());
96    }
97    #[test]
98    fn test_tsp_optimizer() {
99        let distances = Array2::from_shape_vec(
100            (4, 4),
101            vec![
102                0.0, 10.0, 15.0, 20.0, 10.0, 0.0, 25.0, 30.0, 15.0, 25.0, 0.0, 35.0, 20.0, 30.0,
103                35.0, 0.0,
104            ],
105        )
106        .expect("Test distance matrix has valid shape");
107        let optimizer =
108            TSPOptimizer::new(distances).expect("TSP optimizer should be created with valid input");
109        let (_qubo, var_map) = optimizer
110            .build_qubo()
111            .expect("TSP QUBO should build successfully");
112        assert_eq!(var_map.len(), 16);
113    }
114    #[test]
115    fn test_supply_chain() {
116        let network = SupplyChainNetwork {
117            suppliers: vec![Supplier {
118                id: 0,
119                capacity: 100.0,
120                cost_per_unit: 10.0,
121                lead_time: 2,
122                reliability: 0.95,
123            }],
124            warehouses: vec![Warehouse {
125                id: 0,
126                capacity: 200.0,
127                holding_cost: 1.0,
128                fixed_cost: 1000.0,
129                location: (0.0, 0.0),
130            }],
131            distribution_centers: vec![DistributionCenter {
132                id: 0,
133                capacity: 150.0,
134                processing_cost: 2.0,
135                location: (10.0, 10.0),
136            }],
137            customers: vec![Customer {
138                id: 0,
139                demand: Array1::from_vec(vec![20.0, 25.0, 30.0]),
140                priority: 1.0,
141                location: (20.0, 20.0),
142            }],
143            links: vec![],
144        };
145        let optimizer = SupplyChainOptimizer::new(network, 3);
146        let (_qubo, var_map) = optimizer
147            .build_qubo()
148            .expect("Supply chain QUBO should build successfully");
149        assert!(!var_map.is_empty());
150    }
151    #[test]
152    fn test_binary_vrp_wrapper() {
153        let distances = Array2::from_shape_vec(
154            (4, 4),
155            vec![
156                0.0, 10.0, 15.0, 20.0, 10.0, 0.0, 25.0, 30.0, 15.0, 25.0, 0.0, 35.0, 20.0, 30.0,
157                35.0, 0.0,
158            ],
159        )
160        .expect("Test distance matrix has valid shape");
161        let demands = Array1::from_vec(vec![0.0, 10.0, 15.0, 20.0]);
162        let optimizer = VehicleRoutingOptimizer::new(distances, 50.0, demands, 2)
163            .expect("Test VRP optimizer should be created with valid inputs");
164        let binary_vrp = BinaryVehicleRoutingProblem::new(optimizer);
165        assert_eq!(binary_vrp.num_variables(), 32);
166        let solution = binary_vrp.random_solution();
167        assert_eq!(solution.len(), 32);
168        let energy = binary_vrp.evaluate_binary(&solution);
169        assert!(energy.is_finite());
170        let routes = binary_vrp.decode_binary_solution(&solution);
171        assert!(routes.len() <= 2);
172    }
173    #[test]
174    fn test_create_benchmark_problems() {
175        let problems = create_benchmark_problems();
176        assert_eq!(problems.len(), 3);
177        for (i, problem) in problems.iter().enumerate() {
178            let solution = problem.random_solution();
179            let energy = problem.evaluate_binary(&solution);
180            assert!(energy.is_finite(), "Problem {i} should have finite energy");
181            let routes = problem.decode_binary_solution(&solution);
182            assert!(
183                routes.len() <= 3,
184                "Problem {i} should have at most 3 routes"
185            );
186        }
187    }
188}