Теперь я застрял с сообщением об ошибке, которое, похоже, не связано с указанным LOC, но, возможно, с чем-то внутри JVM. Кажется, мне пока не удалось включить ведение журнала DEBUG для "timefold.solver".
Есть какие-нибудь указания, как это диагностировать?
Код: Выделить всё
Traceback (most recent call last):
File "/home/***/git/optapy-pplan/optapy-test/src/main2.py", line 426, in
solution = solver.solve(generate_problem(sservice.context._inputfile))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/***/.virtualenvs/timefold/lib/python3.11/site-packages/timefold/solver/_solver.py", line 109, in solve
java_solution = self._delegate.solve(java_problem)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: expected string or bytes-like object, got 'ai.timefold.jpyinterpreter.types.PythonString'
Объекты домена взяты из примера школьного расписания Optapy. Для краткости я несколько сократил количество методов.
Код: Выделить всё
class RoomGroup:
id : Annotated[int, PlanningId]
size : int
def __init__(self, group):
if group==None:
# a NoneRoom, which does not create conflict
self.id = 0
self.name = "None"
self.group = []
self.size = 65535
self.rooms = 0
self.penalty = 0
self.nextMinSize = 0
else:
self.id = reduce(lambda x,y: x+2**y.id, group, 0)
self.name = ",".join([room.name for room in group])
self.group = group
self.size = reduce(lambda x,y: x+y.size, group, 0)
self.rooms = len(self.group)
self.penalty = 0
# the next smaller size of this group (remove smallest room)
self.nextMinSize = self.size - min([r.size for r in group])
def get_id(self) -> int:
return self.id
def equalGroup(self, other):
return self.id == other.get_id() # encoding! nice!
def __str__(self):
return f"RoomGroup(id={self.id}, name={self.name} {self.size}P)"
class Timeslot:
id : Annotated[int, PlanningId]
grain:datetime.timedelta=None
time_max=datetime.time.max
def __init__(self, ident, start_time, end_time):
self.id = ident
self.start_time = start_time
self.end_time = end_time
self.day_of_week = start_time.weekday()
def theGrain(self) -> datetime.timedelta: return self.grain
def theTimeMax(self) -> datetime.time: return self.time_max
def get_id(self) -> int:
return self.id
def matches(self, dt : datetime.datetime):
return self.start_time Optional[Timeslot]:
return self.timeslot
def set_timeslot(self, new_timeslot:Timeslot):
self.timeslot = new_timeslot
def get_room(self) -> Optional[RoomGroup]:
return self.room
def is_moved(self) -> bool:
return ( self.timeslot != None and self.timeslot_orig_id != None
and (self.timeslot.get_id() != self.timeslot_orig_id))
def is_moved_dist(self) -> int:
if self.is_moved():
return (self.timeslot.get_id() - self.timeslot_orig_id)
else:
return 0
def is_moved_days(self) -> int:
if self.is_moved():
return (self.timeslot.start_time.date() - self.timeslot_orig.start_time.date()).days
else:
return 0
def is_pinned(self)->bool:
return self.pinned
def set_room(self, new_room:RoomGroup):
self.room = new_room
def __str__(self):
return (
f"Exam("
f"id={self.id}, "
f"timeslot={self.timeslot}, "
f"timeslot_orig_id={self.timeslot_orig_id}, "
f"room={self.room}, "
f"rooms={','.join([str(r.id) for r in self.room_list])}, "
f"teacher={self.teacher}, "
f"subject={self.subject}, "
f"student_group={self.student_group}, "
f"sem={self.sem}, "
f"participants={self.participants}"
f")"
)
def format_list(a_list):
return ',\n'.join(map(str, a_list))
@planning_solution
class TimeTable:
lesson_list : Annotated[list[Exam], PlanningEntityCollectionProperty]
timeslot_list : Annotated[list[Timeslot], ProblemFactCollectionProperty, ValueRangeProvider]
room_list : Annotated[list[RoomGroup], ProblemFactCollectionProperty, ValueRangeProvider]
score: Annotated[HardSoftScore, PlanningScore] = field(default=None)
solver_status: Annotated[SolverStatus, Field] = field(default=SolverStatus.NOT_SOLVING)
def __init__(self, timeslot_list, room_list, lesson_list, score=None):
self.timeslot_list = timeslot_list
self.room_list = room_list
self.lesson_list = lesson_list
self.score = score
def __hash__(self): return super(TimeTable, self).__hash__()
def get_timeslot_list(self):
return self.timeslot_list
def get_room_list(self):
return self.room_list
def get_lesson_list(self):
return self.lesson_list
def get_score(self):
return self.score
def set_score(self, score):
self.score = score
def __str__(self):
return (
f"TimeTable("
f"timeslot_list={format_list(self.timeslot_list)},\n"
f"room_list={format_list(self.room_list)},\n"
f"lesson_list={format_list(self.lesson_list)},\n"
f"score={str(self.score) if self.score is not None else 'None'}"
f")"
)
Подробнее здесь: https://stackoverflow.com/questions/786 ... jpype-glue