I am trying to run a replication study, and I have run the code in question multiple times without error. I took a little time off to work on some other projects, and it suddenly doesn't work, I have run into the following error (with different key numbers) every time I have tried to run the code subsequently.
<class 'KeyError'> Traceback (most recent call last): File "main.py", line 145, in total_requests_served = run_epoch(envt, oracle, central_agent, value_function, day, is_training=True) File "main.py", line 58, in run_epoch scored_final_actions = central_agent.choose_actions(scored_actions_all_agents, is_training=is_training, epoch_num=envt.num_days_trained) File "C:\Users\src\CentralAgent.py", line 33, in choose_actions return self._choose(agent_action_choices, is_training, epoch_num) File "C:\Users\src\CentralAgent.py", line 53, in _additive_noise final_actions = self._choose_actions_ILP(agent_action_choices, get_noise=get_noise) File "C:\Users\src\CentralAgent.py", line 132, in _choose_actions_ILP assigned_action_id = assigned_actions[agent_idx] KeyError: 579
I have tried different imports from docplex, I have tried to use dict.get with a pass statement if False, I have tried dict.get with a break statement if False. All either crash the code or in the case of the break statement make the resulting output useless. I have also tried uninstalling and reinstalling python packages, uninstalling and reinstalling anaconda altogether.
Here is the code that seems to cause the error, which was taken from the github for the paper.
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, Tuple[Any, 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
This is my first time working with docplex so I'm not really even sure if this is the problem or not. Any advice would be incredibly helpful, thanks.