How to define a constraint in OptaPy for a list of element

Issue

I have some difficult to create one of my constraint. The structure of my problem is something like this

class ToolFact:
    id : str
    type : str
    
@planning_entity
class SubObjectFact:
    id : str
    tool : ToolFact

@planning_entity
class ObjectFact:
    id : str
    sub_objects : list[SubObjectFact]
    

And I want a constraint that will do something like this

for each ObjectFact -> object
   for each SubOjectFact in object.sub_object -> sub_object 
       penalize if sub_object.tool is None 

But I can’t find a way to do this with the constraint_factory.
Does anyone know how please ?

Solution

This is how you would do it with constraint streams:

from java.util import ArrayList

def penalize_subs_without_tools(constraint_factory: ConstraintFactory):
    return constraint_factory.forEach(get_class(ObjectFact)) \
        .flattenLast(lambda fact: ArrayList(fact.sub_objects)) \
        .filter(lambda sub_object: sub_object.tool is None) \
        .penalize("SubObjectFact without tool", HardSoftScore.ONE_HARD)

I will try to make it so the ArrayList is not necessary in a later version.

Answered By – Christopher Chianelli

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published