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

Python CSP学生任务调度器开发遭遇KeyError问题求助

问题原因分析
  • 变量定义错误:你将学生和任务的元组拼接后作为变量名,既不符合约束库的使用逻辑,还导致后续约束无法正确关联变量;更关键的是addConstraint的第二个参数传错——该参数需要传入约束作用的变量列表,但你直接传入了变量本身,触发了库内部的KeyError。
  • 约束逻辑错误:lambda函数的参数接收的是变量的取值(True/False),而非你拼接的元组,所以访问variable[2]完全无效,布尔值没有索引属性。
修正后的代码
from constraint import *

# 学生:(姓名, 可用时长, 能力)
students = (("Name1", 10, "Competence1"), ("Name2", 8, "Competence2"))
# 任务:(名称, 所需时长, 所需能力)
tasks = (("Task1", 4, "Competence1"), ("Task2", 2, "Competence2"))

# 构建问题实例
problem = Problem()

# 1. 定义变量:每个变量表示「学生是否分配到该任务」,变量名用"学生-任务"格式
assignment_vars = []
for student in students:
    student_name, _, student_competence = student
    for task in tasks:
        task_name, task_duration, task_competence = task
        var_name = f"{student_name}-{task_name}"
        assignment_vars.append((var_name, student, task))
        problem.addVariable(var_name, [False, True])

# 2. 添加约束1:能力不匹配的任务不能分配给学生
for var_name, student, task in assignment_vars:
    if student[2] != task[2]:
        # 能力不匹配,变量必须为False
        problem.addConstraint(lambda x: x == False, [var_name])

# 3. 添加约束2:每个学生的总任务时长不能超过可用时长
for student in students:
    student_name, available_hours, _ = student
    # 找到该学生对应的所有分配变量和对应任务时长
    student_vars = []
    task_durations = []
    for var_name, s, task in assignment_vars:
        if s[0] == student_name:
            student_vars.append(var_name)
            task_durations.append(task[1])
    
    # 定义总时长约束:sum(变量值 * 任务时长) <= 可用时长
    def total_hours_constraint(*args):
        total = 0
        for i in range(len(args)):
            if args[i]:
                total += task_durations[i]
        return total <= available_hours
    
    problem.addConstraint(total_hours_constraint, student_vars)

# 获取所有解
solutions = problem.getSolutions()

if solutions:
    print("分配方案:")
    for idx, solution in enumerate(solutions, 1):
        print(f"\n方案{idx}:")
        for var_name, assigned in solution.items():
            if assigned:
                student_name, task_name = var_name.split("-")
                print(f"  {student_name} → {task_name}")
else:
    print("无可行分配方案")
关键修正点
  • 变量规范化:用学生名-任务名的字符串作为变量名,清晰且符合约束库的要求。
  • 约束分层处理:
    • 先过滤能力不匹配的分配,直接将对应变量设为False;
    • 针对每个学生计算总任务时长,确保不超过可用时长。
  • 正确传递约束参数:addConstraint的第二个参数始终是约束作用的变量列表,lambda函数接收的是对应变量的取值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 22:32:34