ADMM¶
The Alternating Direction Method of Multipliers (ADMM) is a convex optimization algorithm that decomposes a large problem into smaller subproblems solved locally, coordinated by a central update. Two ADMM variants are implemented: Sharing and Consensus.
Problem Forms¶
Consensus¶
The consensus form drives all agents to agree on a single global value \(z\):
The update iterations are:
Use create_consensus_target_reach_admm_coordinator()
and create_admm_start_consensus().
Local Model: Flexibility Actor¶
Each participant is a flexibility actor — a local resource with bounded and coupled decision variables. At each ADMM iteration it solves the QP:
where \(v\) is the correction sent by the coordinator, \(S\) is a priority penalty vector, and the constraints represent box and coupling feasibility.
One-to-Many Resource¶
A common model converts a single input (capacity in_capacity) into m outputs
with efficiency factors \(\eta \in \mathbb{R}^m\):
>>> from distributed_resource_optimization import create_admm_flex_actor_one_to_many
>>> actor = create_admm_flex_actor_one_to_many(10.0, [0.1, 0.5, -1.0])
>>> actor = create_admm_flex_actor_one_to_many(10.0, [0.1, 0.5, -1.0], P=[5.0, 0.0, 0.0])
After optimization, retrieve the result via actor.x.
Coordinator Parameters¶
Parameter |
Default |
Description |
|---|---|---|
|
|
Penalty parameter — larger values enforce constraints faster but may slow convergence |
|
|
Maximum number of ADMM iterations |
|
|
Absolute primal/dual residual tolerance |
|
|
Relative primal/dual residual tolerance |
Complete Example — ADMM Sharing¶
>>> from distributed_resource_optimization import (
... create_admm_flex_actor_one_to_many,
... create_sharing_target_distance_admm_coordinator,
... create_admm_sharing_data, create_admm_start,
... start_coordinated_optimization,
... )
>>> flex1 = create_admm_flex_actor_one_to_many(10.0, [0.1, 0.5, -1.0])
>>> flex2 = create_admm_flex_actor_one_to_many(15.0, [0.1, 0.5, -1.0])
>>> flex3 = create_admm_flex_actor_one_to_many(10.0, [-1.0, 0.0, 1.0])
>>> coordinator = create_sharing_target_distance_admm_coordinator()
>>> start = create_admm_start(create_admm_sharing_data([-4.0, 0.0, 6.0], [5, 1, 1]))
>>> asyncio.run(start_coordinated_optimization([flex1, flex2, flex3], coordinator, start))
[...]
>>> np.allclose(flex1.x, [0, 0, 0], atol=1e-2)
True
>>> np.allclose(flex3.x, [-3.983, 0, 3.983], atol=1e-2)
True
Complete Example — ADMM Consensus¶
>>> from distributed_resource_optimization import (
... create_admm_flex_actor_one_to_many,
... create_consensus_target_reach_admm_coordinator,
... create_admm_start_consensus,
... start_coordinated_optimization,
... )
>>> actor1 = create_admm_flex_actor_one_to_many(10.0, [0.6, 0.4])
>>> actor2 = create_admm_flex_actor_one_to_many(10.0, [0.6, 0.4])
>>> coordinator = create_consensus_target_reach_admm_coordinator()
>>> start = create_admm_start_consensus([1.0, 2.0])
>>> asyncio.run(start_coordinated_optimization([actor1, actor2], coordinator, start))
[...]
>>> np.allclose(actor1.x, actor2.x, atol=1e-2)
True
Tip
If ADMM diverges or converges slowly:
Reduce
rhowhen primal residuals dominate.Increase
rhowhen dual residuals dominate.Tighten
abs_tol/rel_tolfor higher precision.Increase
max_itersif the warning “reached max iterations” appears.
See Also¶
ADMMFlexActor,create_admm_flex_actor_one_to_many()create_sharing_target_distance_admm_coordinator(),create_admm_start(),create_admm_sharing_data()create_consensus_target_reach_admm_coordinator(),create_admm_start_consensus()