Skip to main content

ferrox/jobshop/
problem.rs

1use serde::{Deserialize, Serialize};
2
3/// One operation within a job: must execute on `machine_id` for `duration` units.
4#[derive(Debug, Clone, Serialize, Deserialize)]
5pub struct Operation {
6    pub machine_id: usize,
7    pub duration: i64,
8}
9
10/// A job is an ordered sequence of operations; each must complete before the next begins.
11#[derive(Debug, Clone, Serialize, Deserialize)]
12pub struct Job {
13    pub id: usize,
14    pub name: String,
15    /// Operations in their required execution order.
16    pub operations: Vec<Operation>,
17}
18
19/// Seeded into `ContextKey::Seeds` with id prefix `"jspbench-request:"`.
20#[derive(Debug, Clone, Serialize, Deserialize)]
21pub struct JobShopRequest {
22    pub id: String,
23    pub jobs: Vec<Job>,
24    pub num_machines: usize,
25    #[serde(default = "default_time_limit")]
26    pub time_limit_seconds: f64,
27}
28
29fn default_time_limit() -> f64 {
30    30.0
31}
32
33impl JobShopRequest {
34    /// Trivial upper bound on makespan: sum of all operation durations.
35    pub fn horizon(&self) -> i64 {
36        self.jobs.iter().flat_map(|j| j.operations.iter()).map(|o| o.duration).sum()
37    }
38}
39
40/// A scheduled operation with resolved timing.
41#[derive(Debug, Clone, Serialize, Deserialize)]
42pub struct ScheduledOp {
43    pub job_id: usize,
44    pub job_name: String,
45    pub machine_id: usize,
46    pub op_index: usize,
47    pub start: i64,
48    pub end: i64,
49}
50
51/// Written to `ContextKey::Strategies` with id prefix `"jspbench-plan-<solver>:"`.
52#[derive(Debug, Clone, Serialize, Deserialize)]
53pub struct JobShopPlan {
54    pub request_id: String,
55    pub schedule: Vec<ScheduledOp>,
56    pub makespan: i64,
57    /// Proven lower bound (available when status is `"optimal"`).
58    pub lower_bound: Option<i64>,
59    pub solver: String,
60    /// `"optimal"`, `"feasible"`, or `"error"`.
61    pub status: String,
62    pub wall_time_seconds: f64,
63}