Hi, I’m a developer new to optaplanner & been working on a FJS problem. Here’s the simplified domain classes for information:
Activity (fact): step of a job. Activities of each jobs have a duration, and they have to be done in a specified sequence. Each activities require different skills to complete.
public
class Activity
{
Long
id;
EnumSet<Skill>
skills;
Duration
duration;
//Other
fields, getter setters
}
public
class Job
{
String
name;
LocalDateTime
due;
List<Activity>
activities;
//Other fields, getter setters
}
Resources (fact): provide different skills & have a set of available timeslots.
public
class Timeslot
{
LocalDateTime
start;
LocalDateTime
end;
}
public
class Resource
{
EnumSet<Skill>
skills;
}
public
class ResourceTimeslot
extends
Timeslot
{
Resource
resource;
}
Allocation (entity): planning resource + occupied timeslot for each activities.
@PlanningEntity
public
class Allocation
{
@PlanningId
Long
id;
@PlanningVariable(valueRangeProviderRefs
= "timeslotRange")
ResourceTimeslot
resourceTimeslot;
//Other
fields, getter setters
}
ScheduleTable (solution):
@PlanningSolution
public
class ScheduleTable {
@ProblemFactCollectionProperty
@ValueRangeProvider(id = "jobRange")
List<Job>
jobs;
@ProblemFactCollectionProperty
@ValueRangeProvider(id = "activityRange")
List<Activity>
activities;
@ProblemFactCollectionProperty
@ValueRangeProvider(id = "timeslotRange")
List<ResourceTimeslot>
resourceTimeslots;
@PlanningEntityCollectionProperty
List<Allocation>
allocations;
@PlanningScore
private HardSoftScore
score;
}
I need to allocate activities to resource timeslots. For this domain design I’ve solved the case where each activities have just one allocation: each activity is allocated to a resource timeslot. The number of allocation is known beforehand.
My problem is how to solve two more complex situations:
1. Multiple activites can occupy the same resource timeslot, as long
as their duration fit into the timeslot. I need to dynamically
calculate each activities starts/stops.
My first approach is to use shadow variable + a map to keep track their activity order since they can be deduced from current solution:
@PlanningEntity
public
class Allocation
{
private
static Map<ResourceTimeslot,
List<Timeslot>>
allocatedTimeslots
=
new
ConcurrentHashMap<>();
@PlanningId
Long
id;
Activity
activity;
@CustomShadowVariable(variableListenerClass
= AllocationVariableListener.class,
sources = {@PlanningVariableReference(variableName
= "resourceTimeslot")})
ActivityTimeslot
ActivityTimeslot;
@PlanningVariable(valueRangeProviderRefs
= "timeslotRange")
ResourceTimeslot
resourceTimeslot;
//Other
fields, getter setters
}
Is the use of static variable acceptable in optaplanner?
2. One activity can have multiple allocations e.g activities can be
split between multiple resources for parallel processing. The number
of allocation therefore are not known beforehand. Is there a way to add/remove entities dynamically?
Regards,
Quan