You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

解决java.lang.IllegalStateException:重复@ValueRangeProvider ID问题

问题原因与修复方案

错误根源

报错java.lang.IllegalStateException: 2 members with a @ValueRangeProvider annotation must not have the same id (timeslotRangeLS)是因为:

  • 在TimeTable类和Lesson类中,同时定义了id为timeslotRangeLS的@value_range_provider
  • 在TimeTable类和Lab类中,同时定义了id为timeslotRangeLB的@value_range_provider

OptaPlanner要求全局范围内的value_range_provider id必须唯一,重复定义会触发该异常。

另外代码中还存在两个次要问题:

  1. Lesson和Lab类错误地将id标记为planning_variable(id是实体唯一标识,不需要被规划分配值)
  2. TimeTable类中get_lab_list方法拼写错误:return self.Lab_list应为return self.lab_list

修正后的代码

1. 修正TimeTable类

@planning_solution
class TimeTable:
    timeslot_list: list[Timeslot]
    timeslot_list1: list[Timeslot]
    room_list: list[Room]
    lesson_list: list[Lesson]
    lab_list: list[Lab]
    score: HardSoftScore

    def __init__(self, timeslot_list, timeslot_list1, room_list, lesson_list, lab_list, score=None):
        self.timeslot_list = timeslot_list
        self.timeslot_list1 = timeslot_list1
        self.room_list = room_list
        self.lesson_list = lesson_list
        self.lab_list = lab_list
        self.score = score

    @problem_fact_collection_property(Timeslot)
    @value_range_provider("timeslotRangeLS")
    def get_timeslot_list(self):
        return self.timeslot_list

    @problem_fact_collection_property(Timeslot)
    @value_range_provider("timeslotRangeLB")
    def get_timeslot_list1(self):
        return self.timeslot_list1

    @problem_fact_collection_property(Room)
    @value_range_provider("roomRange")
    def get_room_list(self):
        return self.room_list

    @planning_entity_collection_property(Lesson)
    def get_lesson_list(self):
        return self.lesson_list

    @planning_entity_collection_property(Lab)
    def get_lab_list(self):
        return self.lab_list  # 修正拼写错误

    @planning_score(HardSoftScore)
    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"timeslot_list1={format_list(self.timeslot_list1)},\n"
            f"room_list={format_list(self.room_list)},\n"
            f"lesson_list={format_list(self.lesson_list)},\n"
            f"lab_list={format_list(self.lab_list)},\n"
            f"score={str(self.score.toString()) if self.score is not None else 'None'}"
            f")"
        )

2. 修正Lab类

@planning_entity
class Lab(Base):
    id: int
    subject: str
    teacher: str
    student_group: str
    timeslot1: Timeslot
    room: Room

    def __init__(self, id, subject, teacher, student_group, timeslot1=None, room=None):
        self.id = id
        self.subject = subject
        self.teacher = teacher
        self.student_group = student_group
        self.timeslot1 = timeslot1
        self.room = room

    @planning_id  # 仅保留标识注解,移除错误的规划变量注解
    def get_id(self):
        return self.id

    @planning_variable(Timeslot, ["timeslotRangeLB"])
    def get_timeslot1(self):
        return self.timeslot1

    def set_timeslot1(self, new_timeslot):
        self.timeslot1 = new_timeslot

    @planning_variable(Room, ["roomRange"])
    def get_room(self):
        return self.room

    def set_room(self, new_room):
        self.room = new_room

    def __str__(self):
        return (
            f"Lab("
            f"id={self.id}, "
            f"timeslot1={self.timeslot1}, "
            f"room={self.room}, "
            f"teacher={self.teacher}, "
            f"subject={self.subject}, "
            f"student_group={self.student_group}"
            f")"
        )

3. 修正Lesson类

@planning_entity
class Lesson(Base):
    id: int
    subject: str
    teacher: str
    student_group: str
    timeslot: Timeslot
    room: Room

    def __init__(self, id, subject, teacher, student_group, timeslot=None, room=None):
        self.id = id
        self.subject = subject
        self.teacher = teacher
        self.student_group = student_group
        self.timeslot = timeslot
        self.room = room

    @planning_id  # 仅保留标识注解,移除错误的规划变量注解
    def get_id(self):
        return self.id

    @planning_variable(Timeslot, ["timeslotRangeLS"])
    def get_timeslot(self):
        return self.timeslot

    def set_timeslot(self, new_timeslot):
        self.timeslot = new_timeslot

    @planning_variable(Room, ["roomRange"])
    def get_room(self):
        return self.room

    def set_room(self, new_room):
        self.room = new_room

    def __str__(self):
        return (
            f"Lesson("
            f"id={self.id}, "
            f"timeslot={self.timeslot}, "
            f"room={self.room}, "
            f"teacher={self.teacher}, "
            f"subject={self.subject}, "
            f"student_group={self.student_group}"
            f")"
        )

核心修改点说明

  1. 删除Lesson和Lab类中重复的@value_range_provider注解及对应方法,直接引用TimeTable中定义的全局范围即可
  2. 移除实体类中错误标记的@planning_variable(Base, ...)注解,id仅作为实体标识,不需要参与规划分配
  3. 修正TimeTable类中get_lab_list的拼写错误,确保实体集合能正确加载

内容的提问来源于stack exchange,提问作者VijiS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 18:40:32