-
Notifications
You must be signed in to change notification settings - Fork 74
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add benches for goal evaluation of CVRPTW
- Loading branch information
1 parent
ef7dbee
commit 442bc59
Showing
5 changed files
with
149 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
Route 1 : 81 78 76 80 | ||
Route 2 : 57 55 54 53 56 58 60 59 | ||
Route 3 : 98 96 95 94 92 93 97 100 99 | ||
Route 4 : 32 33 31 35 37 38 39 36 34 | ||
Route 5 : 13 17 18 19 15 16 14 12 | ||
Route 6 : 90 87 86 83 89 91 | ||
Route 7 : 43 42 41 40 48 51 50 52 49 47 | ||
Route 8 : 67 65 63 62 74 72 61 64 68 66 69 | ||
Route 9 : 5 3 7 8 10 11 9 6 4 2 1 75 | ||
Route 10 : 20 24 30 28 26 23 22 21 | ||
Cost 1000 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
//! This benchmark evaluates the goal pipeline for the Solomon problem variant (CVRPTW). | ||
use criterion::{black_box, criterion_group, criterion_main, Criterion}; | ||
use std::fs::File; | ||
use std::io::BufReader; | ||
use std::sync::Arc; | ||
use vrp_core::construction::heuristics::ActivityContext; | ||
use vrp_core::models::common::{Schedule, Timestamp}; | ||
use vrp_core::models::problem::{JobIdDimension, Single}; | ||
use vrp_core::models::solution::{Activity, Place}; | ||
use vrp_core::prelude::*; | ||
use vrp_scientific::common::read_init_solution; | ||
use vrp_scientific::solomon::SolomonProblem; | ||
|
||
pub fn get_bench_resource(resource_path: &str) -> std::io::Result<File> { | ||
let mut path = std::env::current_dir()?; | ||
path.push("benches"); | ||
path.push(resource_path); | ||
|
||
File::open(path) | ||
} | ||
|
||
/// Returns a partial insertion context: some jobs are excluded from the used initial solution. | ||
fn get_partial_insertion_context() -> InsertionContext { | ||
let environment = Arc::new(Environment::default()); | ||
let problem = Arc::new( | ||
BufReader::new(get_bench_resource("../../examples/data/scientific/solomon/C101.100.txt").unwrap()) | ||
.read_solomon(false) | ||
.unwrap(), | ||
); | ||
assert_eq!(problem.jobs.size(), 100); | ||
|
||
let solution = read_init_solution( | ||
BufReader::new(get_bench_resource("../../examples/data/scientific/solomon/C101.100.partial.txt").unwrap()), | ||
problem.clone(), | ||
environment.random.clone(), | ||
) | ||
.expect("cannot read initial solution"); | ||
|
||
assert!(!solution.routes.is_empty()); | ||
assert!(!solution.unassigned.is_empty()); | ||
|
||
InsertionContext::new_from_solution(problem, (solution, None), environment) | ||
} | ||
|
||
fn get_insertion_entities(solution_ctx: &SolutionContext) -> (&RouteContext, &Arc<Single>) { | ||
// get route for insertion | ||
let route_ctx = solution_ctx | ||
.routes | ||
.iter() | ||
.find(|route_ctx| { | ||
route_ctx | ||
.route() | ||
.tour | ||
.get(1) | ||
.and_then(|a| a.retrieve_job()) | ||
.and_then(|job| job.dimens().get_job_id().cloned()) | ||
.map_or(false, |job_id| job_id == "67") | ||
}) | ||
.expect("cannot find expected route in the solution"); | ||
assert_eq!(route_ctx.route().tour.job_count(), 11, "unexpected job count in the route"); | ||
|
||
// get job for insertion | ||
let job = solution_ctx | ||
.unassigned | ||
.iter() | ||
.find(|(job, _)| job.dimens().get_job_id().map_or(false, |id| id == "45")) | ||
.and_then(|(job, _)| job.as_single()) | ||
.expect("cannot find single job in the unassigned jobs"); | ||
|
||
(route_ctx, job) | ||
} | ||
|
||
fn bench_evaluate_route(c: &mut Criterion) { | ||
c.bench_function("CVRPTW: run Goal::evaluate for route on C101.100", |b| { | ||
let insertion_ctx = get_partial_insertion_context(); | ||
let solution_ctx = &insertion_ctx.solution; | ||
let (route_ctx, job) = get_insertion_entities(solution_ctx); | ||
|
||
b.iter(|| { | ||
insertion_ctx.problem.goal.evaluate(&MoveContext::Route { | ||
solution_ctx, | ||
route_ctx, | ||
job: &Job::Single(job.clone()), | ||
}); | ||
black_box(()) | ||
}) | ||
}); | ||
} | ||
|
||
fn bench_evaluate_activity(c: &mut Criterion) { | ||
c.bench_function("CVRPTW: run Goal::evaluate for activity on C101.100", |b| { | ||
let insertion_ctx = get_partial_insertion_context(); | ||
let solution_ctx = &insertion_ctx.solution; | ||
let (route_ctx, job) = get_insertion_entities(solution_ctx); | ||
|
||
// get activities for insertion context | ||
let prev = route_ctx.route().tour.get(7).unwrap(); | ||
let target = Activity { | ||
place: Place { | ||
idx: 7, | ||
location: job.places[0].location.unwrap(), | ||
duration: job.places[0].duration.clone(), | ||
time: job.places[0].times[0].to_time_window(Timestamp::default()), | ||
}, | ||
schedule: Schedule { arrival: 0.0, departure: 0.0 }, | ||
job: Some(job.clone()), | ||
commute: None, | ||
}; | ||
let next = route_ctx.route().tour.get(8); | ||
|
||
b.iter(|| { | ||
insertion_ctx.problem.goal.evaluate(&MoveContext::Activity { | ||
route_ctx, | ||
activity_ctx: &ActivityContext { index: 0, prev, target: &target, next }, | ||
}); | ||
}) | ||
}); | ||
} | ||
|
||
criterion_group! { | ||
name = benches; | ||
config = Criterion::default().sample_size(64); | ||
targets = bench_evaluate_route, | ||
bench_evaluate_activity, | ||
} | ||
criterion_main!(benches); |