Multi-Commodity Flow Problem¶
In the minimum cost MCF the objective is to minimize the total cost of transporting commodities through a network from origin to destination vertices. The edges of the network are capacitated.
Let \(g(V,E)\) be a graph and let \(K\) be the set of commodities each with an origin \(o_k\) and destination \(d_k\) and a demand \(b_k\). Edge capacity is denoted by \(u_e\) for \(e \in E\).
where each path \(p \in P^k\) for commodity \(k \in K\) is feasible in \(g(V,E)\) with accumulated edge cost \(c_p = \sum_{e \in p} c_e\) and \(\alpha_p^e = |e \cap p|\) expresses \(p\)'s usage of edge \(e\).
import flowty
model = flowty.McfModel(flowty.McfModel.Type.Path)
# network: 5 vertices, 7 edges
sources = [0, 0, 1, 1, 2, 3, 3]
targets = [1, 2, 3, 2, 4, 2, 4]
costs = [4, 2, 3, 1, 5, 2, 6]
capacities = [5, 8, 4, 3, 6, 3, 5]
model.addEdges(sources, targets, costs, capacities)
# three commodities
origins = [0, 1, 3]
destinations = [4, 4, 4]
demands = [3, 2, 4]
model.addCommodities(origins, destinations, demands)
status = model.solve()
solution = model.getSolution()
if solution:
print(f"Cost: {solution.cost}")
print(f"Edge flows: {solution.edgeFlows}")
import flowty
model = flowty.McfModel(flowty.McfModel.Type.Tree)
sources = [0, 0, 1, 1, 2, 3, 3]
targets = [1, 2, 3, 2, 4, 2, 4]
costs = [4, 2, 3, 1, 5, 2, 6]
capacities = [5, 8, 4, 3, 6, 3, 5]
model.addEdges(sources, targets, costs, capacities)
origins = [0, 1, 3]
destinations = [4, 4, 4]
demands = [3, 2, 4]
model.addCommodities(origins, destinations, demands)
status = model.solve()
solution = model.getSolution()
if solution:
print(f"Cost: {solution.cost}")
print(f"Edge flows: {solution.edgeFlows}")
Using the general Model API with penalty variables and explicit capacity constraints:
import flowty
model = flowty.Model()
E = [(0, 1), (0, 2), (1, 3), (1, 2), (2, 4), (3, 2), (3, 4)]
C = [4.0, 2.0, 3.0, 1.0, 5.0, 2.0, 6.0]
U = [5.0, 8.0, 4.0, 3.0, 6.0, 3.0, 5.0]
graph = model.addGraph(edges=E, edgeCosts=C)
O = [0, 1, 3]
D = [4, 4, 4]
B = [3.0, 2.0, 4.0]
S = [
model.addSubproblem(graph, source=o, target=d, obj=0, lb=0, ub=b, domain="C")
for o, d, b in zip(O, D, B)
]
penalty = sum(C) + 1
Y = [model.addVariable(obj=penalty, lb=0, ub=b, domain="C") for b in B]
for s, y, b in zip(S, Y, B):
model += s + y >= b
lazy = True
for e, u in zip(graph.edges, U):
model += e <= u, lazy
status = model.solve()
solution = model.getSolution()
if solution:
print(f"Cost: {solution.cost}")
for path in solution.paths:
print(f"Commodity {path.subproblem.id}: {path.x}")
for edge in path.edges:
print(f" {edge}")