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
相关产品推荐
相关产品推荐

