CQL & MixedTrainer — Centralized and Per-Team Learning¶
Where IQL gives every agent its own table, Centralized Q-Learning (CQL) treats a whole team as a single decision-maker with one shared Q-table over the joint state and joint action. MixedTrainer then lets you assign IQL or CQL to each team independently.
CQL theory¶
Instead of per-agent \(Q_i\), CQL learns a single joint action-value \(Q(\mathbf{s}, \mathbf{a})\) where \(\mathbf{s}\) is every agent's observation stacked together and \(\mathbf{a} = (a_1, \dots, a_n)\) is the joint action. The learning signal is the team's total reward \(r_\text{team} = \sum_i r_i\):
Because it optimizes the joint value with a shared reward, CQL can represent coordinated strategies that IQL cannot. The price is size: the joint action space is the Cartesian product of every agent's actions.
Acting from a joint table (marginalization)¶
At execution each agent must choose its own action from the joint Q-values. CQL
marginalizes: reshape the joint Q-vector to a tensor of shape
\((\text{action\_dim})^{n}\), then for agent \(i\) average over every other agent's
axis to get a per-agent Q-vector, and take its argmax.
flowchart LR
JS["joint state s"] --> QT["shared joint Q-table<br/>vector of length action_dim^n"]
QT --> RS["reshape → tensor (action_dim,)ⁿ"]
RS --> M1["mean over other agents' axes → Q for agent 1 → argmax → a₁"]
RS --> M2["mean over other agents' axes → Q for agent 2 → argmax → a₂"]
How CQL works here¶
Implementation: src/ppage/baselines/CQL/cql.py.
- One shared table
self.q_table: encoded joint state →np.zeros(action_dim ** n_agents). - Joint state
_joint_state()= tuple of each agent's_encode_state()(same recursive encoding as IQL). - Joint action index
_joint_action_index()packs the per-agent actions into a single base-action_diminteger. - Update — central reward = sum of all agents' rewards; the target uses
maxover the whole joint action vector, with the bootstrap cut only on a true terminal:
central_r = sum(float(rewards[aid]) for aid in self.agent_ids)
q_next_max = 0.0 if terminal else float(np.max(self.q_table[joint_s_next]))
td_error = central_r + self.gamma * q_next_max - self.q_table[joint_s][joint_a]
self.q_table[joint_s][joint_a] += self.alpha * td_error
- Execution —
select_actions()reshapes to(action_dim,) * n_agentsand averages over the other axes (q_tensor.mean(axis=other_axes)).
This is a classic joint-action learner, not a modern CTDE method (QMIX, MADDPG). It trades scalability for an exact, inspectable joint table — see MARL Theory.
The cost of centralization¶
The table stores action_dim ^ n_agents values per joint state. With 5
actions:
| Agents | Values per joint state |
|---|---|
| 2 | 25 |
| 4 | 625 |
| 6 | 15,625 |
Keep grids and agent counts small when using CQL.
MixedTrainer¶
MixedTrainer (src/ppage/baselines/MIXED/mix_train.py) assigns an algorithm to each
team separately: predators and prey can each be iql or cql. CQL teams share one
joint table over that team's joint space; IQL teams keep per-agent tables. Both
update kinds run inside each step.
flowchart TB
S["env.step()"] --> P{"predator team algo"}
S --> R{"prey team algo"}
P -->|cql| PC["shared joint table (predators)"]
P -->|iql| PI["per-predator tables"]
R -->|cql| RC["shared joint table (prey)"]
R -->|iql| RI["per-prey tables"]
This is the tool for asymmetry experiments — e.g. centralized predators versus independent prey — which is exactly the comparison the research study built on this environment investigates.
Configuration¶
# CQL
experiment:
algorithm:
name: cql
params: { alpha: 0.1, gamma: 0.99, epsilon: 1.0, episodes: 5000, seed: 42 }
# MixedTrainer: centralized predators, independent prey
experiment:
algorithm:
name: mixed
params:
predator_algo: cql
prey_algo: iql
alpha: 0.1
gamma: 0.99
episodes: 5000
Papers¶
- Busoniu et al. (2008), A Comprehensive Survey of Multiagent RL — joint-action learners and the centralized/independent axis.
- Claus & Boutilier (1998), The Dynamics of RL in Cooperative Multiagent Systems.
- CTDE successors (context, not implemented here): Lowe et al. (2017, MADDPG), Rashid et al. (2018, QMIX), Sunehag et al. (2018, VDN).
Full list: Papers & Further Reading.