Skip to content

Commit

Permalink
Add further improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
reinterpretcat committed Jun 26, 2024
1 parent f9a4358 commit 7556d72
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 52 deletions.
15 changes: 8 additions & 7 deletions examples/json-pragmatic/benches/general_benchmark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@ use std::fs::File;
use std::io::BufReader;
use std::sync::Arc;
use vrp_pragmatic::core::construction::heuristics::InsertionContext;
use vrp_pragmatic::core::models::Solution;
use vrp_pragmatic::core::prelude::{create_default_config_builder, Problem, Solver};
use vrp_pragmatic::core::prelude::*;
use vrp_pragmatic::core::rosomaxa::evolution::TelemetryMode;
use vrp_pragmatic::core::solver::search::{Recreate, RecreateWithCheapest};
use vrp_pragmatic::core::solver::{create_elitism_population, RefinementContext};
use vrp_pragmatic::core::utils::Environment;
use vrp_pragmatic::format::problem::PragmaticProblem;

fn get_problem(problem_path: &str) -> Arc<Problem> {
Expand All @@ -20,17 +18,20 @@ fn get_problem(problem_path: &str) -> Arc<Problem> {
)
}

/// Runs solver with specific amount of generations. It involves some non-determenism.
/// Runs solver with specific number of generations. It involves some non-determenism.
fn solve_problem_with_max_generations(problem_path: &str, generations: usize) -> Solution {
let problem = get_problem(problem_path);

create_default_config_builder(problem.clone(), Arc::new(Environment::default()), TelemetryMode::None)
VrpConfigBuilder::new(problem.clone())
.set_telemetry_mode(TelemetryMode::None)
.prebuild()
.expect("cannot prebuild configuration")
.with_max_generations(Some(generations))
.build()
.map(|config| Solver::new(problem, config))
.unwrap_or_else(|err| panic!("cannot build solver: {}", err))
.expect("cannot build solver")
.solve()
.unwrap_or_else(|err| panic!("cannot solver problem: {}", err))
.expect("cannot solver problem: {}")
}

/// Solve problem using cheapest insertion heuristic and returns one solution.
Expand Down
5 changes: 5 additions & 0 deletions vrp-core/examples/cvrp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,5 +105,10 @@ fn main() -> GenericResult<()> {
assert_eq!(solution.routes.len(), 2, "two tours are expected");
assert_eq!(solution.cost, 2135., "unexpected cost (total distance traveled)");

println!(
"\nIn solution, locations are visited in the following order:\n{:?}\n",
solution.get_locations().map(Iterator::collect::<Vec<_>>).collect::<Vec<_>>()
);

Ok(())
}
21 changes: 11 additions & 10 deletions vrp-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,24 +70,25 @@
//!
//! # Examples
//!
//! The most simple way to run solver is to use `Builder`. You can tweak metaheuristic parameters by
//! calling corresponding methods of the builder instance:
//! Detailed examples for some of the VRP variants can be found in `examples` folder.
//!
//! Here, the example shows how to construct default configuration for the solver, override some
//! of the default metaheuristic parameters using fluent interface methods, and run the solver:
//!
//! ```
//! # use vrp_core::models::examples::create_example_problem;
//! # use vrp_core::solver::get_default_telemetry_mode;
//! # use std::sync::Arc;
//! use vrp_core::prelude::*;
//!
//! // create your VRP problem
//! let problem = create_example_problem();
//! let environment = Arc::new(Environment::new_with_time_quota(Some(10)));
//! let telemetry_mode = get_default_telemetry_mode(environment.logger.clone());
//! // build solver config to run 10 secs or 1000 generation
//! let config = create_default_config_builder(problem.clone(), environment, telemetry_mode)
//! .with_max_time(Some(10))
//! .with_max_generations(Some(10))
//! let problem: Arc<Problem> = create_example_problem();
//! // build solver config using pre-build builder with defaults and then override some parameters
//! let config = VrpConfigBuilder::new(problem.clone())
//! .prebuild()?
//! .with_max_time(Some(60))
//! .with_max_generations(Some(100))
//! .build()?;
//!
//! // run solver and get the best known solution.
//! let solution = Solver::new(problem, config).solve()?;
//!
Expand Down
9 changes: 8 additions & 1 deletion vrp-core/src/models/domain.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::construction::heuristics::UnassignmentInfo;
use crate::models::common::Cost;
use crate::models::common::{Cost, Location};
use crate::models::problem::*;
use crate::models::solution::{Registry, Route};
use crate::models::*;
Expand Down Expand Up @@ -239,3 +239,10 @@ impl ProblemBuilder {
Ok(Problem { fleet, jobs, locks: vec![], goal, activity, transport, extras })
}
}

impl Solution {
/// Iterates through all tours and returns locations of each activity in the order they are visited.
pub fn get_locations(&self) -> impl Iterator<Item = impl Iterator<Item = Location> + '_> + '_ {
self.routes.iter().map(|route| route.tour.all_activities().map(|activity| activity.place.location))
}
}
34 changes: 0 additions & 34 deletions vrp-core/src/solver/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,40 +216,6 @@ impl InitialOperator for RecreateInitialOperator {

/// Solves a Vehicle Routing Problem and returns a _(solution, its cost)_ pair in case of success
/// or error description, if solution cannot be found.
///
/// A newly created builder instance is pre-configured with some reasonable defaults for mid-size
/// problems (~200), so there is no need to call any of its methods.
///
///
/// # Examples
///
/// This example shows how to construct default configuration for the solver, override some of default
/// metaheuristic parameters using fluent interface methods, and run the solver:
///
/// ```
/// # use vrp_core::models::examples::create_example_problem;
/// # use vrp_core::solver::get_default_telemetry_mode;
/// # use std::sync::Arc;
/// use vrp_core::prelude::*;
///
/// // create your VRP problem
/// let problem: Arc<Problem> = create_example_problem();
/// let environment = Arc::new(Environment::new_with_time_quota(Some(60)));
/// let telemetry_mode = get_default_telemetry_mode(environment.logger.clone());
/// // build solver config using pre-build builder with defaults and then override some parameters
/// let config = create_default_config_builder(problem.clone(), environment, telemetry_mode)
/// .with_max_time(Some(60))
/// .with_max_generations(Some(100))
/// .build()?;
///
/// // run solver and get the best known solution.
/// let solution = Solver::new(problem, config).solve()?;
///
/// assert_eq!(solution.cost, 42.);
/// assert_eq!(solution.routes.len(), 1);
/// assert_eq!(solution.unassigned.len(), 0);
/// # Ok::<(), GenericError>(())
/// ```
pub struct Solver {
problem: Arc<Problem>,
config: EvolutionConfig<RefinementContext, GoalContext, InsertionContext>,
Expand Down

0 comments on commit 7556d72

Please sign in to comment.