pub struct SingleBuilder(/* private fields */);
Expand description
Provides a way to build a Single job using the builder pattern.
Implementations§
Source§impl SingleBuilder
impl SingleBuilder
Sourcepub fn add_place(self, place: Place) -> Self
pub fn add_place(self, place: Place) -> Self
Adds a new place to single job’s places
collection. Use this api to add multiple places
which are used as alternative places (e.g. locations) to serve the job.
Sourcepub fn add_places(self, places: impl Iterator<Item = Place>) -> Self
pub fn add_places(self, places: impl Iterator<Item = Place>) -> Self
Adds new places to single job’s places
collection.
Sourcepub fn id(self, id: &str) -> Self
pub fn id(self, id: &str) -> Self
Sets a job id dimension.
Examples found in repository?
84fn define_problem(goal: GoalContext, transport: Arc<dyn TransportCost>) -> GenericResult<Problem> {
85 // create 4 jobs where two are having top prio
86 let single_jobs = (1..=4)
87 .map(|idx| {
88 SingleBuilder::default()
89 .id(format!("job{idx}").as_str())
90 .demand(Demand::delivery(1))
91 .dimension(|dimens| {
92 // mark two jobs as top priority (2 and 4 locations)
93 dimens.set_job_priority(idx % 2 == 0);
94 })
95 .location(idx)?
96 .build_as_job()
97 })
98 .collect::<Result<Vec<_>, _>>()?;
99
100 // define a single vehicle with limited capacity which doesn't need to return back to the depot
101 let vehicle = VehicleBuilder::default()
102 .id("v1".to_string().as_str())
103 .add_detail(VehicleDetailBuilder::default().set_start_location(0).build()?)
104 // only two jobs can be served by the vehicle
105 .capacity(SingleDimLoad::new(2))
106 .build()?;
107
108 ProblemBuilder::default()
109 .add_jobs(single_jobs.into_iter())
110 .add_vehicles(once(vehicle))
111 .with_goal(goal)
112 .with_transport_cost(transport)
113 .build()
114}
More examples
20fn define_problem(goal: GoalContext, transport: Arc<dyn TransportCost>) -> GenericResult<Problem> {
21 // create 4 jobs with location indices from 1 to 4
22 let single_jobs = (1..=4)
23 .map(|idx| {
24 SingleBuilder::default()
25 .id(format!("job{idx}").as_str())
26 // each job is delivery job with demand=1
27 .demand(Demand::delivery(1))
28 // job has location, which is an index in routing matrix
29 .location(idx)?
30 .build_as_job()
31 })
32 .collect::<Result<Vec<_>, _>>()?;
33
34 // create 4 vehicles
35 let vehicles = (1..=4)
36 .map(|idx| {
37 VehicleBuilder::default()
38 .id(format!("v{idx}").as_str())
39 .add_detail(
40 VehicleDetailBuilder::default()
41 // vehicle starts at location with index 0 in routing matrix
42 .set_start_location(0)
43 // vehicle should return to location with index 0
44 .set_end_location(0)
45 .build()?,
46 )
47 // each vehicle has capacity=2, so it can serve at most 2 jobs
48 .capacity(SingleDimLoad::new(2))
49 .build()
50 })
51 .collect::<Result<Vec<_>, _>>()?;
52
53 ProblemBuilder::default()
54 .add_jobs(single_jobs.into_iter())
55 .add_vehicles(vehicles.into_iter())
56 .with_goal(goal)
57 .with_transport_cost(transport)
58 .build()
59}
52fn define_problem(goal: GoalContext, transport: Arc<dyn TransportCost>) -> GenericResult<Problem> {
53 // create 4 jobs when second and forth have fridge requirement
54 let single_jobs = (1..=4)
55 .map(|idx| {
56 SingleBuilder::default()
57 .id(format!("job{idx}").as_str())
58 .demand(Demand::delivery(1))
59 .dimension(|dimens| {
60 // all jobs have fridge requirements, but only one vehicle will be allowed to serve them
61 dimens.set_job_hardware("fridge".to_string());
62 })
63 .location(idx)?
64 .build_as_job()
65 })
66 .collect::<Result<Vec<_>, _>>()?;
67
68 // create 2 vehicles
69 let vehicles = (1..=2)
70 .map(|idx| {
71 VehicleBuilder::default()
72 .id(format!("v{idx}").as_str())
73 .add_detail(
74 VehicleDetailBuilder::default()
75 // vehicle starts at location with index 0 in routing matrix
76 .set_start_location(0)
77 // vehicle should return to location with index 0
78 .set_end_location(0)
79 .build()?,
80 )
81 .dimension(|dimens| {
82 if idx % 2 == 0 {
83 // only one vehicle has a hardware requirement set to 'fridge'
84 dimens.set_vehicle_hardware(once("fridge".to_string()).collect());
85 }
86 })
87 // each vehicle has capacity=2, so it can serve at most 2 jobs
88 .capacity(SingleDimLoad::new(2))
89 .build()
90 })
91 .collect::<Result<Vec<_>, _>>()?;
92
93 ProblemBuilder::default()
94 .add_jobs(single_jobs.into_iter())
95 .add_vehicles(vehicles.into_iter())
96 .with_goal(goal)
97 .with_transport_cost(transport)
98 .build()
99}
Sourcepub fn demand<T: LoadOps>(self, demand: Demand<T>) -> Self
pub fn demand<T: LoadOps>(self, demand: Demand<T>) -> Self
A simple api to set a single job’s demand.
Examples found in repository?
84fn define_problem(goal: GoalContext, transport: Arc<dyn TransportCost>) -> GenericResult<Problem> {
85 // create 4 jobs where two are having top prio
86 let single_jobs = (1..=4)
87 .map(|idx| {
88 SingleBuilder::default()
89 .id(format!("job{idx}").as_str())
90 .demand(Demand::delivery(1))
91 .dimension(|dimens| {
92 // mark two jobs as top priority (2 and 4 locations)
93 dimens.set_job_priority(idx % 2 == 0);
94 })
95 .location(idx)?
96 .build_as_job()
97 })
98 .collect::<Result<Vec<_>, _>>()?;
99
100 // define a single vehicle with limited capacity which doesn't need to return back to the depot
101 let vehicle = VehicleBuilder::default()
102 .id("v1".to_string().as_str())
103 .add_detail(VehicleDetailBuilder::default().set_start_location(0).build()?)
104 // only two jobs can be served by the vehicle
105 .capacity(SingleDimLoad::new(2))
106 .build()?;
107
108 ProblemBuilder::default()
109 .add_jobs(single_jobs.into_iter())
110 .add_vehicles(once(vehicle))
111 .with_goal(goal)
112 .with_transport_cost(transport)
113 .build()
114}
More examples
20fn define_problem(goal: GoalContext, transport: Arc<dyn TransportCost>) -> GenericResult<Problem> {
21 // create 4 jobs with location indices from 1 to 4
22 let single_jobs = (1..=4)
23 .map(|idx| {
24 SingleBuilder::default()
25 .id(format!("job{idx}").as_str())
26 // each job is delivery job with demand=1
27 .demand(Demand::delivery(1))
28 // job has location, which is an index in routing matrix
29 .location(idx)?
30 .build_as_job()
31 })
32 .collect::<Result<Vec<_>, _>>()?;
33
34 // create 4 vehicles
35 let vehicles = (1..=4)
36 .map(|idx| {
37 VehicleBuilder::default()
38 .id(format!("v{idx}").as_str())
39 .add_detail(
40 VehicleDetailBuilder::default()
41 // vehicle starts at location with index 0 in routing matrix
42 .set_start_location(0)
43 // vehicle should return to location with index 0
44 .set_end_location(0)
45 .build()?,
46 )
47 // each vehicle has capacity=2, so it can serve at most 2 jobs
48 .capacity(SingleDimLoad::new(2))
49 .build()
50 })
51 .collect::<Result<Vec<_>, _>>()?;
52
53 ProblemBuilder::default()
54 .add_jobs(single_jobs.into_iter())
55 .add_vehicles(vehicles.into_iter())
56 .with_goal(goal)
57 .with_transport_cost(transport)
58 .build()
59}
52fn define_problem(goal: GoalContext, transport: Arc<dyn TransportCost>) -> GenericResult<Problem> {
53 // create 4 jobs when second and forth have fridge requirement
54 let single_jobs = (1..=4)
55 .map(|idx| {
56 SingleBuilder::default()
57 .id(format!("job{idx}").as_str())
58 .demand(Demand::delivery(1))
59 .dimension(|dimens| {
60 // all jobs have fridge requirements, but only one vehicle will be allowed to serve them
61 dimens.set_job_hardware("fridge".to_string());
62 })
63 .location(idx)?
64 .build_as_job()
65 })
66 .collect::<Result<Vec<_>, _>>()?;
67
68 // create 2 vehicles
69 let vehicles = (1..=2)
70 .map(|idx| {
71 VehicleBuilder::default()
72 .id(format!("v{idx}").as_str())
73 .add_detail(
74 VehicleDetailBuilder::default()
75 // vehicle starts at location with index 0 in routing matrix
76 .set_start_location(0)
77 // vehicle should return to location with index 0
78 .set_end_location(0)
79 .build()?,
80 )
81 .dimension(|dimens| {
82 if idx % 2 == 0 {
83 // only one vehicle has a hardware requirement set to 'fridge'
84 dimens.set_vehicle_hardware(once("fridge".to_string()).collect());
85 }
86 })
87 // each vehicle has capacity=2, so it can serve at most 2 jobs
88 .capacity(SingleDimLoad::new(2))
89 .build()
90 })
91 .collect::<Result<Vec<_>, _>>()?;
92
93 ProblemBuilder::default()
94 .add_jobs(single_jobs.into_iter())
95 .add_vehicles(vehicles.into_iter())
96 .with_goal(goal)
97 .with_transport_cost(transport)
98 .build()
99}
22fn define_problem(goal: GoalContext, transport: Arc<dyn TransportCost>) -> GenericResult<Problem> {
23 // build two PUDO (pick up/drop off) jobs with demand=1 and permissive time windows (just to show API usage)
24 let pudos = (1..=2)
25 .map(|idx| {
26 let location_idx = if idx == 1 { 1 } else { 3 };
27 MultiBuilder::default()
28 .id(format!("pudo{idx}").as_str())
29 .add_job(
30 SingleBuilder::default()
31 .demand(Demand::pudo_pickup(1))
32 .times(vec![TimeWindow::new(0., 1000.)])?
33 .duration(10.)?
34 .location(location_idx)?
35 .build()?,
36 )
37 .add_job(
38 SingleBuilder::default()
39 .demand(Demand::pudo_delivery(1))
40 .times(vec![TimeWindow::new(0., 1000.)])?
41 .duration(10.)?
42 .location(location_idx + 1)?
43 .build()?,
44 )
45 .build_as_job()
46 })
47 .collect::<Result<Vec<_>, _>>()?;
48
49 // define a single vehicle with limited capacity
50 let vehicle = VehicleBuilder::default()
51 .id("v1".to_string().as_str())
52 .add_detail(
53 VehicleDetailBuilder::default()
54 // vehicle starts at location with index 0 in routing matrix
55 .set_start_location(0)
56 .set_start_time(0.)
57 // vehicle should return to location with index 0
58 .set_end_location(0)
59 .set_end_time(10000.)
60 .build()?,
61 )
62 // the vehicle has capacity=1, so it is forced to do delivery after each pickup
63 .capacity(SingleDimLoad::new(1))
64 .build()?;
65
66 ProblemBuilder::default()
67 .add_jobs(pudos.into_iter())
68 .add_vehicles(once(vehicle))
69 .with_goal(goal)
70 .with_transport_cost(transport)
71 .build()
72}
Sourcepub fn dimension(self, func: impl FnOnce(&mut Dimensions)) -> Self
pub fn dimension(self, func: impl FnOnce(&mut Dimensions)) -> Self
A simple api to associate arbitrary property within the job.
Examples found in repository?
84fn define_problem(goal: GoalContext, transport: Arc<dyn TransportCost>) -> GenericResult<Problem> {
85 // create 4 jobs where two are having top prio
86 let single_jobs = (1..=4)
87 .map(|idx| {
88 SingleBuilder::default()
89 .id(format!("job{idx}").as_str())
90 .demand(Demand::delivery(1))
91 .dimension(|dimens| {
92 // mark two jobs as top priority (2 and 4 locations)
93 dimens.set_job_priority(idx % 2 == 0);
94 })
95 .location(idx)?
96 .build_as_job()
97 })
98 .collect::<Result<Vec<_>, _>>()?;
99
100 // define a single vehicle with limited capacity which doesn't need to return back to the depot
101 let vehicle = VehicleBuilder::default()
102 .id("v1".to_string().as_str())
103 .add_detail(VehicleDetailBuilder::default().set_start_location(0).build()?)
104 // only two jobs can be served by the vehicle
105 .capacity(SingleDimLoad::new(2))
106 .build()?;
107
108 ProblemBuilder::default()
109 .add_jobs(single_jobs.into_iter())
110 .add_vehicles(once(vehicle))
111 .with_goal(goal)
112 .with_transport_cost(transport)
113 .build()
114}
More examples
52fn define_problem(goal: GoalContext, transport: Arc<dyn TransportCost>) -> GenericResult<Problem> {
53 // create 4 jobs when second and forth have fridge requirement
54 let single_jobs = (1..=4)
55 .map(|idx| {
56 SingleBuilder::default()
57 .id(format!("job{idx}").as_str())
58 .demand(Demand::delivery(1))
59 .dimension(|dimens| {
60 // all jobs have fridge requirements, but only one vehicle will be allowed to serve them
61 dimens.set_job_hardware("fridge".to_string());
62 })
63 .location(idx)?
64 .build_as_job()
65 })
66 .collect::<Result<Vec<_>, _>>()?;
67
68 // create 2 vehicles
69 let vehicles = (1..=2)
70 .map(|idx| {
71 VehicleBuilder::default()
72 .id(format!("v{idx}").as_str())
73 .add_detail(
74 VehicleDetailBuilder::default()
75 // vehicle starts at location with index 0 in routing matrix
76 .set_start_location(0)
77 // vehicle should return to location with index 0
78 .set_end_location(0)
79 .build()?,
80 )
81 .dimension(|dimens| {
82 if idx % 2 == 0 {
83 // only one vehicle has a hardware requirement set to 'fridge'
84 dimens.set_vehicle_hardware(once("fridge".to_string()).collect());
85 }
86 })
87 // each vehicle has capacity=2, so it can serve at most 2 jobs
88 .capacity(SingleDimLoad::new(2))
89 .build()
90 })
91 .collect::<Result<Vec<_>, _>>()?;
92
93 ProblemBuilder::default()
94 .add_jobs(single_jobs.into_iter())
95 .add_vehicles(vehicles.into_iter())
96 .with_goal(goal)
97 .with_transport_cost(transport)
98 .build()
99}
Sourcepub fn location(self, location: Location) -> GenericResult<Self>
pub fn location(self, location: Location) -> GenericResult<Self>
A simple api to set location of the first place. Normally, location is represented as an index in routing matrix. Fails if used with more than one place, creates a new place if no places are specified.
Examples found in repository?
84fn define_problem(goal: GoalContext, transport: Arc<dyn TransportCost>) -> GenericResult<Problem> {
85 // create 4 jobs where two are having top prio
86 let single_jobs = (1..=4)
87 .map(|idx| {
88 SingleBuilder::default()
89 .id(format!("job{idx}").as_str())
90 .demand(Demand::delivery(1))
91 .dimension(|dimens| {
92 // mark two jobs as top priority (2 and 4 locations)
93 dimens.set_job_priority(idx % 2 == 0);
94 })
95 .location(idx)?
96 .build_as_job()
97 })
98 .collect::<Result<Vec<_>, _>>()?;
99
100 // define a single vehicle with limited capacity which doesn't need to return back to the depot
101 let vehicle = VehicleBuilder::default()
102 .id("v1".to_string().as_str())
103 .add_detail(VehicleDetailBuilder::default().set_start_location(0).build()?)
104 // only two jobs can be served by the vehicle
105 .capacity(SingleDimLoad::new(2))
106 .build()?;
107
108 ProblemBuilder::default()
109 .add_jobs(single_jobs.into_iter())
110 .add_vehicles(once(vehicle))
111 .with_goal(goal)
112 .with_transport_cost(transport)
113 .build()
114}
More examples
20fn define_problem(goal: GoalContext, transport: Arc<dyn TransportCost>) -> GenericResult<Problem> {
21 // create 4 jobs with location indices from 1 to 4
22 let single_jobs = (1..=4)
23 .map(|idx| {
24 SingleBuilder::default()
25 .id(format!("job{idx}").as_str())
26 // each job is delivery job with demand=1
27 .demand(Demand::delivery(1))
28 // job has location, which is an index in routing matrix
29 .location(idx)?
30 .build_as_job()
31 })
32 .collect::<Result<Vec<_>, _>>()?;
33
34 // create 4 vehicles
35 let vehicles = (1..=4)
36 .map(|idx| {
37 VehicleBuilder::default()
38 .id(format!("v{idx}").as_str())
39 .add_detail(
40 VehicleDetailBuilder::default()
41 // vehicle starts at location with index 0 in routing matrix
42 .set_start_location(0)
43 // vehicle should return to location with index 0
44 .set_end_location(0)
45 .build()?,
46 )
47 // each vehicle has capacity=2, so it can serve at most 2 jobs
48 .capacity(SingleDimLoad::new(2))
49 .build()
50 })
51 .collect::<Result<Vec<_>, _>>()?;
52
53 ProblemBuilder::default()
54 .add_jobs(single_jobs.into_iter())
55 .add_vehicles(vehicles.into_iter())
56 .with_goal(goal)
57 .with_transport_cost(transport)
58 .build()
59}
52fn define_problem(goal: GoalContext, transport: Arc<dyn TransportCost>) -> GenericResult<Problem> {
53 // create 4 jobs when second and forth have fridge requirement
54 let single_jobs = (1..=4)
55 .map(|idx| {
56 SingleBuilder::default()
57 .id(format!("job{idx}").as_str())
58 .demand(Demand::delivery(1))
59 .dimension(|dimens| {
60 // all jobs have fridge requirements, but only one vehicle will be allowed to serve them
61 dimens.set_job_hardware("fridge".to_string());
62 })
63 .location(idx)?
64 .build_as_job()
65 })
66 .collect::<Result<Vec<_>, _>>()?;
67
68 // create 2 vehicles
69 let vehicles = (1..=2)
70 .map(|idx| {
71 VehicleBuilder::default()
72 .id(format!("v{idx}").as_str())
73 .add_detail(
74 VehicleDetailBuilder::default()
75 // vehicle starts at location with index 0 in routing matrix
76 .set_start_location(0)
77 // vehicle should return to location with index 0
78 .set_end_location(0)
79 .build()?,
80 )
81 .dimension(|dimens| {
82 if idx % 2 == 0 {
83 // only one vehicle has a hardware requirement set to 'fridge'
84 dimens.set_vehicle_hardware(once("fridge".to_string()).collect());
85 }
86 })
87 // each vehicle has capacity=2, so it can serve at most 2 jobs
88 .capacity(SingleDimLoad::new(2))
89 .build()
90 })
91 .collect::<Result<Vec<_>, _>>()?;
92
93 ProblemBuilder::default()
94 .add_jobs(single_jobs.into_iter())
95 .add_vehicles(vehicles.into_iter())
96 .with_goal(goal)
97 .with_transport_cost(transport)
98 .build()
99}
22fn define_problem(goal: GoalContext, transport: Arc<dyn TransportCost>) -> GenericResult<Problem> {
23 // build two PUDO (pick up/drop off) jobs with demand=1 and permissive time windows (just to show API usage)
24 let pudos = (1..=2)
25 .map(|idx| {
26 let location_idx = if idx == 1 { 1 } else { 3 };
27 MultiBuilder::default()
28 .id(format!("pudo{idx}").as_str())
29 .add_job(
30 SingleBuilder::default()
31 .demand(Demand::pudo_pickup(1))
32 .times(vec![TimeWindow::new(0., 1000.)])?
33 .duration(10.)?
34 .location(location_idx)?
35 .build()?,
36 )
37 .add_job(
38 SingleBuilder::default()
39 .demand(Demand::pudo_delivery(1))
40 .times(vec![TimeWindow::new(0., 1000.)])?
41 .duration(10.)?
42 .location(location_idx + 1)?
43 .build()?,
44 )
45 .build_as_job()
46 })
47 .collect::<Result<Vec<_>, _>>()?;
48
49 // define a single vehicle with limited capacity
50 let vehicle = VehicleBuilder::default()
51 .id("v1".to_string().as_str())
52 .add_detail(
53 VehicleDetailBuilder::default()
54 // vehicle starts at location with index 0 in routing matrix
55 .set_start_location(0)
56 .set_start_time(0.)
57 // vehicle should return to location with index 0
58 .set_end_location(0)
59 .set_end_time(10000.)
60 .build()?,
61 )
62 // the vehicle has capacity=1, so it is forced to do delivery after each pickup
63 .capacity(SingleDimLoad::new(1))
64 .build()?;
65
66 ProblemBuilder::default()
67 .add_jobs(pudos.into_iter())
68 .add_vehicles(once(vehicle))
69 .with_goal(goal)
70 .with_transport_cost(transport)
71 .build()
72}
Sourcepub fn duration(self, duration: Duration) -> GenericResult<Self>
pub fn duration(self, duration: Duration) -> GenericResult<Self>
A simple api to set duration of the first place. Fails if used with more than one place, creates a new place if no places are specified.
Examples found in repository?
22fn define_problem(goal: GoalContext, transport: Arc<dyn TransportCost>) -> GenericResult<Problem> {
23 // build two PUDO (pick up/drop off) jobs with demand=1 and permissive time windows (just to show API usage)
24 let pudos = (1..=2)
25 .map(|idx| {
26 let location_idx = if idx == 1 { 1 } else { 3 };
27 MultiBuilder::default()
28 .id(format!("pudo{idx}").as_str())
29 .add_job(
30 SingleBuilder::default()
31 .demand(Demand::pudo_pickup(1))
32 .times(vec![TimeWindow::new(0., 1000.)])?
33 .duration(10.)?
34 .location(location_idx)?
35 .build()?,
36 )
37 .add_job(
38 SingleBuilder::default()
39 .demand(Demand::pudo_delivery(1))
40 .times(vec![TimeWindow::new(0., 1000.)])?
41 .duration(10.)?
42 .location(location_idx + 1)?
43 .build()?,
44 )
45 .build_as_job()
46 })
47 .collect::<Result<Vec<_>, _>>()?;
48
49 // define a single vehicle with limited capacity
50 let vehicle = VehicleBuilder::default()
51 .id("v1".to_string().as_str())
52 .add_detail(
53 VehicleDetailBuilder::default()
54 // vehicle starts at location with index 0 in routing matrix
55 .set_start_location(0)
56 .set_start_time(0.)
57 // vehicle should return to location with index 0
58 .set_end_location(0)
59 .set_end_time(10000.)
60 .build()?,
61 )
62 // the vehicle has capacity=1, so it is forced to do delivery after each pickup
63 .capacity(SingleDimLoad::new(1))
64 .build()?;
65
66 ProblemBuilder::default()
67 .add_jobs(pudos.into_iter())
68 .add_vehicles(once(vehicle))
69 .with_goal(goal)
70 .with_transport_cost(transport)
71 .build()
72}
Sourcepub fn times(self, times: Vec<TimeWindow>) -> GenericResult<Self>
pub fn times(self, times: Vec<TimeWindow>) -> GenericResult<Self>
A simple api to set time windows of the first place. Fails if used with more than one place, creates a new place if no places are specified.
Examples found in repository?
22fn define_problem(goal: GoalContext, transport: Arc<dyn TransportCost>) -> GenericResult<Problem> {
23 // build two PUDO (pick up/drop off) jobs with demand=1 and permissive time windows (just to show API usage)
24 let pudos = (1..=2)
25 .map(|idx| {
26 let location_idx = if idx == 1 { 1 } else { 3 };
27 MultiBuilder::default()
28 .id(format!("pudo{idx}").as_str())
29 .add_job(
30 SingleBuilder::default()
31 .demand(Demand::pudo_pickup(1))
32 .times(vec![TimeWindow::new(0., 1000.)])?
33 .duration(10.)?
34 .location(location_idx)?
35 .build()?,
36 )
37 .add_job(
38 SingleBuilder::default()
39 .demand(Demand::pudo_delivery(1))
40 .times(vec![TimeWindow::new(0., 1000.)])?
41 .duration(10.)?
42 .location(location_idx + 1)?
43 .build()?,
44 )
45 .build_as_job()
46 })
47 .collect::<Result<Vec<_>, _>>()?;
48
49 // define a single vehicle with limited capacity
50 let vehicle = VehicleBuilder::default()
51 .id("v1".to_string().as_str())
52 .add_detail(
53 VehicleDetailBuilder::default()
54 // vehicle starts at location with index 0 in routing matrix
55 .set_start_location(0)
56 .set_start_time(0.)
57 // vehicle should return to location with index 0
58 .set_end_location(0)
59 .set_end_time(10000.)
60 .build()?,
61 )
62 // the vehicle has capacity=1, so it is forced to do delivery after each pickup
63 .capacity(SingleDimLoad::new(1))
64 .build()?;
65
66 ProblemBuilder::default()
67 .add_jobs(pudos.into_iter())
68 .add_vehicles(once(vehicle))
69 .with_goal(goal)
70 .with_transport_cost(transport)
71 .build()
72}
Sourcepub fn build(self) -> GenericResult<Single>
pub fn build(self) -> GenericResult<Single>
Builds a Single job.
Examples found in repository?
22fn define_problem(goal: GoalContext, transport: Arc<dyn TransportCost>) -> GenericResult<Problem> {
23 // build two PUDO (pick up/drop off) jobs with demand=1 and permissive time windows (just to show API usage)
24 let pudos = (1..=2)
25 .map(|idx| {
26 let location_idx = if idx == 1 { 1 } else { 3 };
27 MultiBuilder::default()
28 .id(format!("pudo{idx}").as_str())
29 .add_job(
30 SingleBuilder::default()
31 .demand(Demand::pudo_pickup(1))
32 .times(vec![TimeWindow::new(0., 1000.)])?
33 .duration(10.)?
34 .location(location_idx)?
35 .build()?,
36 )
37 .add_job(
38 SingleBuilder::default()
39 .demand(Demand::pudo_delivery(1))
40 .times(vec![TimeWindow::new(0., 1000.)])?
41 .duration(10.)?
42 .location(location_idx + 1)?
43 .build()?,
44 )
45 .build_as_job()
46 })
47 .collect::<Result<Vec<_>, _>>()?;
48
49 // define a single vehicle with limited capacity
50 let vehicle = VehicleBuilder::default()
51 .id("v1".to_string().as_str())
52 .add_detail(
53 VehicleDetailBuilder::default()
54 // vehicle starts at location with index 0 in routing matrix
55 .set_start_location(0)
56 .set_start_time(0.)
57 // vehicle should return to location with index 0
58 .set_end_location(0)
59 .set_end_time(10000.)
60 .build()?,
61 )
62 // the vehicle has capacity=1, so it is forced to do delivery after each pickup
63 .capacity(SingleDimLoad::new(1))
64 .build()?;
65
66 ProblemBuilder::default()
67 .add_jobs(pudos.into_iter())
68 .add_vehicles(once(vehicle))
69 .with_goal(goal)
70 .with_transport_cost(transport)
71 .build()
72}
Sourcepub fn build_as_job(self) -> GenericResult<Job>
pub fn build_as_job(self) -> GenericResult<Job>
Builds a Job.
Examples found in repository?
84fn define_problem(goal: GoalContext, transport: Arc<dyn TransportCost>) -> GenericResult<Problem> {
85 // create 4 jobs where two are having top prio
86 let single_jobs = (1..=4)
87 .map(|idx| {
88 SingleBuilder::default()
89 .id(format!("job{idx}").as_str())
90 .demand(Demand::delivery(1))
91 .dimension(|dimens| {
92 // mark two jobs as top priority (2 and 4 locations)
93 dimens.set_job_priority(idx % 2 == 0);
94 })
95 .location(idx)?
96 .build_as_job()
97 })
98 .collect::<Result<Vec<_>, _>>()?;
99
100 // define a single vehicle with limited capacity which doesn't need to return back to the depot
101 let vehicle = VehicleBuilder::default()
102 .id("v1".to_string().as_str())
103 .add_detail(VehicleDetailBuilder::default().set_start_location(0).build()?)
104 // only two jobs can be served by the vehicle
105 .capacity(SingleDimLoad::new(2))
106 .build()?;
107
108 ProblemBuilder::default()
109 .add_jobs(single_jobs.into_iter())
110 .add_vehicles(once(vehicle))
111 .with_goal(goal)
112 .with_transport_cost(transport)
113 .build()
114}
More examples
20fn define_problem(goal: GoalContext, transport: Arc<dyn TransportCost>) -> GenericResult<Problem> {
21 // create 4 jobs with location indices from 1 to 4
22 let single_jobs = (1..=4)
23 .map(|idx| {
24 SingleBuilder::default()
25 .id(format!("job{idx}").as_str())
26 // each job is delivery job with demand=1
27 .demand(Demand::delivery(1))
28 // job has location, which is an index in routing matrix
29 .location(idx)?
30 .build_as_job()
31 })
32 .collect::<Result<Vec<_>, _>>()?;
33
34 // create 4 vehicles
35 let vehicles = (1..=4)
36 .map(|idx| {
37 VehicleBuilder::default()
38 .id(format!("v{idx}").as_str())
39 .add_detail(
40 VehicleDetailBuilder::default()
41 // vehicle starts at location with index 0 in routing matrix
42 .set_start_location(0)
43 // vehicle should return to location with index 0
44 .set_end_location(0)
45 .build()?,
46 )
47 // each vehicle has capacity=2, so it can serve at most 2 jobs
48 .capacity(SingleDimLoad::new(2))
49 .build()
50 })
51 .collect::<Result<Vec<_>, _>>()?;
52
53 ProblemBuilder::default()
54 .add_jobs(single_jobs.into_iter())
55 .add_vehicles(vehicles.into_iter())
56 .with_goal(goal)
57 .with_transport_cost(transport)
58 .build()
59}
52fn define_problem(goal: GoalContext, transport: Arc<dyn TransportCost>) -> GenericResult<Problem> {
53 // create 4 jobs when second and forth have fridge requirement
54 let single_jobs = (1..=4)
55 .map(|idx| {
56 SingleBuilder::default()
57 .id(format!("job{idx}").as_str())
58 .demand(Demand::delivery(1))
59 .dimension(|dimens| {
60 // all jobs have fridge requirements, but only one vehicle will be allowed to serve them
61 dimens.set_job_hardware("fridge".to_string());
62 })
63 .location(idx)?
64 .build_as_job()
65 })
66 .collect::<Result<Vec<_>, _>>()?;
67
68 // create 2 vehicles
69 let vehicles = (1..=2)
70 .map(|idx| {
71 VehicleBuilder::default()
72 .id(format!("v{idx}").as_str())
73 .add_detail(
74 VehicleDetailBuilder::default()
75 // vehicle starts at location with index 0 in routing matrix
76 .set_start_location(0)
77 // vehicle should return to location with index 0
78 .set_end_location(0)
79 .build()?,
80 )
81 .dimension(|dimens| {
82 if idx % 2 == 0 {
83 // only one vehicle has a hardware requirement set to 'fridge'
84 dimens.set_vehicle_hardware(once("fridge".to_string()).collect());
85 }
86 })
87 // each vehicle has capacity=2, so it can serve at most 2 jobs
88 .capacity(SingleDimLoad::new(2))
89 .build()
90 })
91 .collect::<Result<Vec<_>, _>>()?;
92
93 ProblemBuilder::default()
94 .add_jobs(single_jobs.into_iter())
95 .add_vehicles(vehicles.into_iter())
96 .with_goal(goal)
97 .with_transport_cost(transport)
98 .build()
99}
Trait Implementations§
Source§impl Debug for SingleBuilder
impl Debug for SingleBuilder
Auto Trait Implementations§
impl Freeze for SingleBuilder
impl !RefUnwindSafe for SingleBuilder
impl Send for SingleBuilder
impl Sync for SingleBuilder
impl Unpin for SingleBuilder
impl !UnwindSafe for SingleBuilder
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more