Django集成Pulp优化时出现AttributeError:'str'对象无'hash'属性
问题根源
报错AttributeError: 'str' object has no attribute 'hash'的核心原因是:你在构建目标函数obj_func时,传入的是变量名字符串,而Pulp的LpAffineExpression需要的是实际的LpVariable对象。
你用exec创建了变量,但把变量名存在var_names列表里,之后构建目标函数时用了这些字符串,而不是对应的LpVariable实例,Pulp在处理时把字符串当成变量来操作,自然会报错。另外,exec在Django视图环境的命名空间和Jupyter Notebook不同,变量可能没有被正确注册到当前作用域,进一步加剧了问题。
解决方案
完全抛弃exec,用字典存储所有LpVariable对象,既能统一管理变量,避免命名空间问题,也让约束和目标函数的构建更清晰。
1. 重构变量创建逻辑
用字典variables存储每个变量,键是你原来的var_name,值是LpVariable对象:
variables = {} # 存储所有LpVariable对象 var_coefficients = [] # 存储变量对应的系数 for _foo_ in list_1: for _bar_ in list_2: for _var_ in list_3: for _eet_ in list_4: var_name = f"{_foo_}{_bar_}{_var_}{_eet_}" # 直接创建变量并存入字典,无需exec variables[var_name] = LpVariable(var_name, lowBound=0, cat='Integer') # 获取数据库中的系数值 db_entry = DataBase.objects.get(column_A=f"{_foo_}{_var_}") var_coefficients.append(db_entry.value)
2. 构建正确的目标函数
从字典中取出LpVariable对象,和系数配对构建目标函数:
# 变量与系数一一对应,生成目标函数项 obj_terms = [(variables[var_name], var_coefficients[i]) for i, var_name in enumerate(variables.keys())] obj_func = LpAffineExpression(obj_terms) problem = LpProblem(name="name", sense=LpMinimise) problem += obj_func
3. 重构约束条件(抛弃exec)
直接用字典里的变量构建约束表达式,避免exec带来的风险:
# 替换原来的exec约束示例 # 假设function(a1,b1,c1)返回变量名字符串,比如"foo1bar2var3eet4" var1 = variables[function(a1, b1, c1)] var2 = variables[function(a1, b1, c2)] threshold = Database_2.objects.get(column_A=z1).value problem += (var1 + var2 >= threshold)
如果function是复杂的表达式生成逻辑,同样基于variables字典拼接即可,完全不需要exec。
4. 求解并获取结果
之后正常调用求解,从字典中提取变量结果:
problem.solve() # 整理求解结果 results = {var_name: var.varValue for var_name, var in variables.items()}
为什么之前的尝试没解决?
- 用
exec存到globals/local字典:本质还是依赖字符串引用变量,不如直接用字典管理对象可靠。 LpVariable.dict:你遇到的未定义错误,是因为约束里仍用字符串而非字典中的变量,只要约束也从字典取变量就能解决。
内容的提问来源于stack exchange,提问作者James
相关产品推荐
相关产品推荐

