optapy / optapy

OptaPy is an AI constraint solver for Python to optimize planning and scheduling problems.

Home Page:https://www.optapy.org/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Implement remaining OptaPlanner's API

Christopher-Chianelli opened this issue · comments

This issue will act as an epic, to keep track of OptaPlanner API that is currently not implemented in OptaPy:

  • #75
  • #107
  • Benchmarker
  • Planning Entity difficulty
  • Planning Value strength
  • Filtered Selection
  • Nearby Selection
  • Custom Moves
  • Custom Termination
  • Custom Move Seletor
  • Custom Entity Selector
  • Custom Value Selector
  • Custom Acceptor
  • Partitioned Search

Hi I would like to check in on planning entity difficulty - is there a development branch with this enabled and / or is it possible to contribute to this?

@jarrelscy there is no development branch where it is enabled. To implement it, you would need to add a difficulty_comparator parameter to

def planning_entity(entity_class: Type = None, /, *, pinning_filter: Callable = None) -> Union[Type,
Callable[[Type], Type]]:
"""Specifies that the class is a planning entity. Each planning entity must have at least
1 PlanningVariable property.
The class MUST allow passing None to all of __init__ arguments, so it can be cloned.
(ex: this is allowed:
def __init__(self, a_list):
self.a_list = a_list
this is NOT allowed:
def __init__(self, a_list):
self.a_list = a_list
self.list_length = len(a_list)
)
Optional Parameters: @:param pinning_filter: A function that takes the @planning_solution class and an entity,
and return true if the entity cannot be changed, false otherwise
"""
ensure_init()
from org.optaplanner.core.api.domain.entity import PlanningEntity as JavaPlanningEntity
annotation_data = {
'annotationType': JavaPlanningEntity,
'pinningFilter': _PythonPinningFilter(pinning_filter) if pinning_filter is not None else None,
'difficultyComparatorClass': None,
'difficultyWeightFactoryClass': None,
}
def planning_entity_wrapper(entity_class_argument):
from jpyinterpreter import force_update_type
out = JImplements('org.optaplanner.jpyinterpreter.types.wrappers.OpaquePythonReference')(entity_class_argument)
out.__optapy_java_class = _generate_planning_entity_class(entity_class_argument, annotation_data)
out.__optapy_is_planning_clone = True
_add_shallow_copy_to_class(out)
force_update_type(out, out.__optapy_java_class.getField('$TYPE').get(None))
return out
if entity_class: # Called as @planning_entity
return planning_entity_wrapper(entity_class)
else: # Called as @planning_entity(pinning_filter=some_function)
return planning_entity_wrapper
. It probably should be a function. Then that function need to be converted to a java.util.Comparator. You could reuse the jpyinterpreter work for that (i.e. import jpyinterpreter and use the corresponding function), in particular,
def translate_python_code_to_java_class(python_function, java_function_type, *type_args):
from org.optaplanner.jpyinterpreter import PythonBytecodeToJavaBytecodeTranslator # noqa
if (python_function, java_function_type, type_args) in function_interface_pair_to_class:
return function_interface_pair_to_class[(python_function, java_function_type, type_args)]
python_compiled_function = get_code_bytecode_object(python_function)
if len(type_args) == 0:
out = PythonBytecodeToJavaBytecodeTranslator.translatePythonBytecodeToClass(python_compiled_function,
java_function_type)
function_interface_pair_to_class[(python_function, java_function_type, type_args)] = out
return out
else:
out = PythonBytecodeToJavaBytecodeTranslator.translatePythonBytecodeToClass(python_compiled_function,
java_function_type,
copy_iterable(type_args))
function_interface_pair_to_class[(python_function, java_function_type, type_args)] = out
return out
should do the job.