I'm newbie here and my English isn't that good, so I hope what I want to explain can reach all of you. Now I am using Python library called Optapy, and I tried to try it to auto scheduling production in my factory.
I set Schedule Class as a planning entity with this code snippet:
from optapy import planning_entity, planning_variable
@planning_entity
class Schedule:
today_date:date
part:Part
machine:Machine
operator:Operator
timeslot:Timeslot
def __init__(self, id:int, today_date:date , part:Part = None, machine:Machine = None, operator: Operator = None, timeslot:Timeslot = None):
self.id = id
self.today_date = today_date
self.part = part
self.machine = machine
self.operator = operator
self.timeslot = timeslot
@planning_id
def get_id(self):
return self.id
@planning_variable(Part,["partRange"])
def get_part(self):
return self.part
def set_part(self, new_part):
self.part = new_part
@planning_variable(Machine,["machineRange"])
def get_machine(self):
return self.machine
def set_machine(self, new_machine):
self.machine = new_machine
@planning_variable(Timeslot,["timeslotRange"])
def get_timeslot(self):
return self.timeslot
def set_timeslot(self, new_timeslot):
self.timeslot = new_timeslot
def __str__(self) -> str:
return (
f"Production("
f"id={self.id},"
f"part={self.part},"
f"machine={self.machine},"
f"timeslot={self.timeslot},"
f"shift ={self.timeslot.shift.value}"
)
Then I set the constraint like this :
from optapy import constraint_provider
from optapy.score import HardSoftScore
from optapy.constraint import Joiners, ConstraintFactory
@constraint_provider
def define_constraints(constraint_factory: ConstraintFactory):
return [
# Hard constraints
machine_conflict(constraint_factory),
less_than_8_workhours(constraint_factory),
]
def machine_conflict(constraint_factory: ConstraintFactory):
return constraint_factory \
.from_(Schedule) \
.join(Schedule,
Joiners.equal(lambda schedule: schedule.timeslot),
Joiners.equal(lambda schedule: schedule.machine),
Joiners.equal(lambda schedule: schedule.today_date),
Joiners.less_than(lambda schedule: schedule.id)
) \
.penalize("Machine conflict", HardSoftScore.ONE_HARD)
#HARD
def less_than_8_workhours(constraint_factory: ConstraintFactory):
return constraint_factory \
.for_each(Schedule) \
.join(Schedule,
Joiners.equal(lambda schedule: schedule.operator),
Joiners.equal(lambda schedule: schedule.today_date)
) \
.filter(lambda schedule1, schedule2: sum(1 for slot in schedule2 if slot.operator == schedule1.operator and slot.today_date == schedule1.today_date)<4) \
.penalize("At least 8 Workhours a day", HardSoftScore.ONE_HARD)
#HARD
When I tried to verify the Less_than_8_workhours Constraint, I got this error messages : org.drools.modelcompiler.constraints.ConstraintEvaluationException: org.drools.modelcompiler.constraints.ConstraintEvaluationException: Error evaluating constraint '' in and in more rules
I think I had mistakes during constraint defining, but I dont know how to fix it. For further information, I use Timeslot in my problem_fact. 1 timeslot is about 2 hours long. With this being said, to prevent the computer to let 1 operator only work less than 8 hours a day, I want to join all Schedule with the same operator and today_date, and count it then check it, whether it is less than 4 or not. If it is, then it violates the constraint.