问题描述
我正在尝试进行复制研究,并且多次运行有问题的代码而没有出现错误。我花了一点时间来处理其他一些项目,但它突然不起作用,每次我尝试运行代码时都会遇到以下错误(具有不同的键号)。
我尝试过从 docplex 导入不同的内容,如果为 False,我尝试使用带有 pass 语句的 dict.get,如果为 False,我尝试使用带有 break 语句的 dict.get。所有要么使代码崩溃,要么在 break 语句的情况下使结果输出无用。我也试过卸载和重新安装python包,卸载和重新安装anaconda。
这里是似乎导致错误的代码,这是从论文的github中提取的。
def _choose_actions_ILP(self,agent_action_choices: List[List[Tuple[Action,float]]],get_noise: Callable[[Var],float]=lambda x: 0) -> List[Tuple[Action,float]]:
# Model as ILP
model = Model()
# For converting Action -> action_id and back
action_to_id: Dict[Action,int] = {}
id_to_action: Dict[int,Action] = {}
current_action_id = 0
# For constraint 2
requests: Set[Request] = set()
# Create decision variables and their coefficients in the objective
# There is a decision variable for each (Action,Agent).
# The coefficient is the value associated with the decision variable
decision_variables: Dict[int,Dict[int,Tuple[Any,float]]] = {}
for agent_idx,scored_actions in enumerate(agent_action_choices):
for action,value in scored_actions:
# Convert action -> id if it hasn't already been done
if action not in action_to_id:
action_to_id[action] = current_action_id
id_to_action[current_action_id] = action
current_action_id += 1
action_id = current_action_id - 1
decision_variables[action_id] = {}
else:
action_id = action_to_id[action]
# Update set of requests in actions
for request in action.requests:
if request not in requests:
requests.add(request)
# Create variable for (action_id,agent_id)
variable = model.binary_var(name='x{},{}'.format(action_id,agent_idx))
# Save to decision_variable data structure
decision_variables[action_id][agent_idx] = (variable,value)
# Create Constraint 1: Only one action per Agent
for agent_idx in range(len(agent_action_choices)):
agent_specific_variables: List[Any] = []
for action_dict in decision_variables.values():
if agent_idx in action_dict:
agent_specific_variables.append(action_dict[agent_idx])
model.add_constraint(model.sum(variable for variable,_ in agent_specific_variables) == 1)
# Create Constraint 2: Only one action per Request
for request in requests:
relevent_action_dicts: List[Dict[int,float]]] = []
for action_id in decision_variables:
if (request in id_to_action[action_id].requests):
relevent_action_dicts.append(decision_variables[action_id])
model.add_constraint(model.sum(variable for action_dict in relevent_action_dicts for variable,_ in action_dict.values()) <= 1)
# Create Objective
score = model.sum((value + get_noise(variable)) * variable for action_dict in decision_variables.values() for (variable,value) in action_dict.values())
model.maximize(score)
# Solve ILP
solution = model.solve()
assert solution # making sure that the model doesn't fail
# Get vehicle specific actions from ILP solution
assigned_actions: Dict[int,int] = {}
for action_id,action_dict in decision_variables.items():
for agent_idx,(variable,_) in action_dict.items():
if (solution.get_value(variable) == 1):
assigned_actions[agent_idx] = action_id
final_actions: List[Tuple[Action,float]] = []
for agent_idx in range(len(agent_action_choices)):
assigned_action_id = assigned_actions[agent_idx]
assigned_action = id_to_action[assigned_action_id]
scored_final_action = None
for action,score in agent_action_choices[agent_idx]:
if (action == assigned_action):
scored_final_action = (action,score)
break
assert scored_final_action is not None
final_actions.append(scored_final_action)
return final_actions
这是我第一次使用 docplex,所以我什至不确定这是否是问题所在。任何建议都会非常有帮助,谢谢。
解决方法
在不运行代码的情况下猜测问题并不简单。不过,有一行对我来说似乎很可疑,这个测试:
if (solution.get_value(variable) == 1):
不稳健:CPLEX 处理浮点数,并且整数/二进制变量产生在(小)容差范围内的整数值。偏差可能会随版本和平台而变化。换句话说,一个二元变量最终可能以 0.9999991 作为解决方案中的值,这与容差一致,但不会通过“==1”测试。 此测试的可靠版本是:
if ( abs(solution[variable] -1 ) <= 1e-6):
1e-6 是 CPLEX 中的默认完整性容差。