Skip to content

Commit

Permalink
Merge pull request #3 from open-rmf/devel
Browse files Browse the repository at this point in the history
More documentation and refactors
  • Loading branch information
arjo129 authored May 9, 2024
2 parents 35082be + c49853d commit e293a3f
Show file tree
Hide file tree
Showing 9 changed files with 45 additions and 41 deletions.
8 changes: 4 additions & 4 deletions examples/benchmark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use std::{fs::OpenOptions, time::SystemTime};

use fnv::FnvHashMap;
use rmf_reservations::algorithms::greedy_solver::ConflictTracker;
use rmf_reservations::algorithms::sat::{generate_sat_devil, SATSolver};
use rmf_reservations::algorithms::sat::{generate_sat_devil, FixedTimeSATSolver};
use rmf_reservations::discretization;

fn main() {
Expand All @@ -29,18 +29,18 @@ fn main() {

let timer = SystemTime::now();

SATSolver::without_optimality_check(soln.clone());
FixedTimeSATSolver::without_optimality_check(soln.clone());
let optimality_proof_dur = timer.elapsed();

let timer = SystemTime::now();
SATSolver::from_hill_climber(soln.clone());
FixedTimeSATSolver::from_hill_climber(soln.clone());
let brute_force_proof_dur = timer.elapsed();

let hint = FnvHashMap::default();
let timer = SystemTime::now();

let stop = Arc::new(AtomicBool::new(false));
soln.solve(hint, stop);
soln.naive_greedy_solver(hint, stop);
let greedy_dur = timer.elapsed();

println!(
Expand Down
4 changes: 2 additions & 2 deletions examples/discrete_vs_nodiscrete.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use chrono::TimeZone;
use chrono::Utc;
use rmf_reservations::algorithms::greedy_solver::ConflictTracker;
use rmf_reservations::algorithms::greedy_solver::Problem;
use rmf_reservations::algorithms::sat::{generate_sat_devil, SATSolver};
use rmf_reservations::algorithms::sat::{generate_sat_devil, FixedTimeSATSolver};
use rmf_reservations::algorithms::sat_flexible_time_model;
use rmf_reservations::algorithms::sat_flexible_time_model::SATFlexibleTimeModel;
use rmf_reservations::cost_function::static_cost::StaticCost;
Expand Down Expand Up @@ -105,7 +105,7 @@ fn main() {
let soln = system.generate_literals_and_remap_requests();

let timer = SystemTime::now();
SATSolver::without_optimality_check(soln.clone());
FixedTimeSATSolver::without_optimality_check(soln.clone());
let optimality_proof_dur = timer.elapsed();

let sat_flexible_time_problem = sat_flexible_time_model::Problem { requests };
Expand Down
6 changes: 3 additions & 3 deletions readme.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# RMF Reservations

This is a library that provides resource optimization constraints for multi-robot applications. More specifcally,
This is a library that provides a solver for constrained resource scheduling for multi-robot applications. More specifically,
we provide a very simple formulation for resource optimization and scheduling. A robot may request the use of a
resource like a charger for a fixed duration of time within a given time range. The system will then assign the robot
to said resource.
Expand Down Expand Up @@ -36,9 +36,9 @@ Alternatives:
- Cost: My own cost function
```

The requests can come in asynchronously. We can solve both optimally and suboptimally depoending on the complexity of the problem.
The requests can come in asynchronously. We can solve both optimally and sub-optimally depending on the complexity of the problem.

A variety of algorithms have been implmented in this library including SAT based algorithms and greedy algorithms.
A variety of algorithms have been implemented in this library including SAT based algorithms and greedy algorithms.

For more details take a look at the tutorial:

Expand Down
27 changes: 6 additions & 21 deletions src/algorithms/greedy_solver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -529,8 +529,9 @@ impl Problem {
conflicts
}

/// Check conflict by remapping timelines
pub fn solve(
/// This solves reservation related problems by using a very simple greedy algorithm.
/// Only use this if the problem has an obvious solution.
pub fn naive_greedy_solver(
&self,
hint: HashMap<usize, usize, FnvBuildHasher>,
stop: Arc<AtomicBool>,
Expand Down Expand Up @@ -592,22 +593,6 @@ impl Problem {

positive_constraints.insert(req_id, alt);

// Check starvation sets
/* let starved: bool = {
let mut val = false;
for starvation_group in &starvation_sets {
let mut hashset = FnvHashSet::from_iter(positive_constraints.iter().map(|(k,v)| (*k, *v)));
if hashset.intersection(&starvation_group.positive).count() == starvation_group.positive.len() {
val =true;
}
}
val
};
if starved {
println!("Dropping solution cause it will starve resources");
continue;
}*/

if let Some(banned_resources) = implications.get(&(req_id, alt)) {
negative_constraints.extend(
banned_resources
Expand Down Expand Up @@ -717,7 +702,7 @@ fn test_conflict_checker() {
//println!("Generated literals");
solver.debug_print();
let stop = Arc::new(AtomicBool::new(false));
let (solution, _) = solver.solve(FnvHashMap::default(), stop).unwrap();
let (solution, _) = solver.naive_greedy_solver(FnvHashMap::default(), stop).unwrap();
println!("{:?}", solution);
assert!((solution.cost.0 - 8.0).abs() < 1.0);
}
Expand All @@ -742,7 +727,7 @@ fn test_generation() {
let soln = system.generate_literals_and_remap_requests();
soln.debug_print();
let arc = Arc::new(AtomicBool::new(false));
let _ = soln.solve(FnvHashMap::default(), arc).unwrap();
let _ = soln.naive_greedy_solver(FnvHashMap::default(), arc).unwrap();
// Ok(())
//});
}
Expand All @@ -757,7 +742,7 @@ impl SolverAlgorithm<Problem> for GreedySolver {
problem: Problem,
) {
let hint = FnvHashMap::default();
let solution = problem.solve(hint, stop);
let solution = problem.naive_greedy_solver(hint, stop);

if let Some((_, solution)) = solution {
let solution = solution
Expand Down
6 changes: 4 additions & 2 deletions src/algorithms/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! This module provides you with a list of potential algorithms you may use to solve a reservation problem
use std::sync::mpsc::Receiver;
use std::{
collections::HashMap,
Expand Down Expand Up @@ -243,7 +245,7 @@ fn test_multisolver_algorithm_pool() {
scenario_generation::generate_test_scenario_with_known_best,
};

use self::sat::SATSolver;
use self::sat::FixedTimeSATSolver;

let (requests, resources) = //generate_sat_devil(5,3);
generate_test_scenario_with_known_best(10, 10, 5);
Expand All @@ -256,7 +258,7 @@ fn test_multisolver_algorithm_pool() {
let problem = system.generate_literals_and_remap_requests();

let mut pool = AlgorithmPool::default();
pool.add_algorithm(Arc::new(SATSolver));
pool.add_algorithm(Arc::new(FixedTimeSATSolver));
pool.add_algorithm(Arc::new(GreedySolver));
let mtx = Arc::new(Mutex::new(AlgorithmState::NotFound));
pool.solve(problem, mtx);
Expand Down
13 changes: 8 additions & 5 deletions src/algorithms/sat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,12 @@ struct AssumptionList {
assumptions: Vec<Vec<Lit>>,
}

pub struct SATSolver;

impl SolverAlgorithm<Problem> for SATSolver {
/// This solver assumes that each alternative has a fixed starting time. However, it does take into account
/// the cost and can use an aribitrary cost function to solve.
pub struct FixedTimeSATSolver;

impl SolverAlgorithm<Problem> for FixedTimeSATSolver {
fn iterative_solve(
&self,
result_channel: Sender<AlgorithmState>,
Expand All @@ -56,8 +59,8 @@ impl SolverAlgorithm<Problem> for SATSolver {
}
}

impl SATSolver {
/// Set up the problem and solve it without any optimality check.
impl FixedTimeSATSolver {
/// Set up the problem and find a feasible solution,
pub fn without_optimality_check(problem: Problem) {
let conflicts = problem.get_banned_reservation_combinations();
let score_cache = problem.score_cache();
Expand Down Expand Up @@ -493,6 +496,6 @@ fn test_sat() {
let timer = SystemTime::now();
let (sender, rx) = mpsc::channel();
let stop = Arc::new(AtomicBool::new(false));
SATSolver::from_hill_climber_with_optimality_proof(soln.clone(), sender, stop);
FixedTimeSATSolver::from_hill_climber_with_optimality_proof(soln.clone(), sender, stop);
let optimality_proof_dur = timer.elapsed();
}
2 changes: 1 addition & 1 deletion src/algorithms/sat_flexible_time_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ fn shrink_reservation_request(
}

/// Solver for scenarios where there is a starting time range instead of a fixed starting time.
/// Note: The solvers in this class currently ignore thestarting time range.
/// Note: The solvers in this class currently ignore the cost of an alternative.
/// You need to implement a clock source. The reason is that we needto have the current time as a starting point.
pub struct SATFlexibleTimeModel<CS: ClockSource + std::marker::Send + std::marker::Sync> {
pub clock_source: CS,
Expand Down
10 changes: 7 additions & 3 deletions src/database/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
//! This module handles state management of a system that turns the algorithms into an online
//! reservation system. This part of the library is still unstable and undergoing frequent reworks.
//! Ultimately this will be the module exposed to end users.
use std::{collections::HashMap, default, fs::Metadata, hash::Hash, sync::Arc};

use chrono::{DateTime, Duration, Utc};
Expand All @@ -6,7 +10,7 @@ use serde_derive::{Deserialize, Serialize};
use crate::{
algorithms::{
greedy_solver::{ConflictTracker, GreedySolver, Problem},
sat::SATSolver,
sat::FixedTimeSATSolver,
sat_flexible_time_model::{Assignment as FlexibleAssignment, SATFlexibleTimeModel},
AlgorithmPool, AsyncExecutor,
},
Expand Down Expand Up @@ -45,7 +49,7 @@ pub(crate) struct Snapshot<P, T = ()> {
pub(crate) metadata: T,
}

/// A reservation system that
/// This provides an abstract interface to the
pub struct FixedTimeReservationSystem {
resources: Vec<String>,
record: HashMap<usize, Vec<ReservationRequestAlternative>>,
Expand All @@ -57,7 +61,7 @@ pub struct FixedTimeReservationSystem {
impl FixedTimeReservationSystem {
pub fn create_with_resources(resources: Vec<String>) -> Self {
let mut alg_pool = AlgorithmPool::<Problem>::default();
alg_pool.add_algorithm(Arc::new(SATSolver));
alg_pool.add_algorithm(Arc::new(FixedTimeSATSolver));
alg_pool.add_algorithm(Arc::new(GreedySolver));

Self {
Expand Down
10 changes: 10 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
//! This is a library that provides a solver for constrained resource scheduling for multi-robot applications. More specifically,
//! we provide a very simple formulation for resource optimization and scheduling. A robot may request the use of a
//! resource like a charger for a fixed duration of time within a given time range. The system will then assign the robot
//! to said resource.
//!
//! At 10,000ft the library solves the following problem:
//! > Suppose you have n robots declaring that “I'd like to use one of (resource 1, resource 2, resource 3) for (d1, d2, d3) minutes starting at a certain time. Each alternative has some cost c(t).”
//!
//! To specify such a problem take a look at [ReservationRequestAlternative] which provides a wrapper around one such alternative.
#![feature(btree_cursors)]
#![feature(hasher_prefixfree_extras)]
#![feature(test)]
Expand Down

0 comments on commit e293a3f

Please sign in to comment.