# In this fifth example will add general link weights to the third model.
# Network optimization model based a single type of line in the
# network. Unidirectional model with bi-directional
# constraints.
#
# Note that the "check" statements kick in when the solver is run and not when the data is built.
# The nodes in the network will be listed in the data file.
set NODES;
# The set of source-destination pair traffic that we want to route.
set SD_PAIRS within {NODES, NODES}; # will explicitly list the pairs we want to route for
# The traffic demand between the source and destination
param demand {SD_PAIRS};
check {(s,d) in SD_PAIRS }: demand[s,d] = demand[d,s];
# The set of unidirectional links. This must be a symmetric set.
set LINKS within {NODES, NODES};
check {(i,j) in LINKS }: ( (j,i) in LINKS); #(i,j) in LINKS and
# The set of flow variables,i.e., the amount of traffic on a particular link dedicated
# to a particular source-destination communication path.
var flow {LINKS, SD_PAIRS}>=0;
# Bi-directional constraint, the flow between s and d over link (i,j) must be the same as
# the flow between d and s over link (j,i).
subject to Bidirectional {(s,d)in SD_PAIRS, (i,j) in LINKS }:
flow[i,j,s,d] = flow[j,i,d,s];
# May need some extra variables for piecewise linear formulations
var total_flow {LINKS} >= 0;
# Total flow variable is just the flow over the link. This seems to be needed due to restrictions on
# argument to piecewise linear
subject to TotalFlow { (i, j) in LINKS }:
total_flow[i,j] = sum { (s, d) in SD_PAIRS } flow[i,j,s,d];
# For right now minimize over the sum of all flows:
param usage_cost{LINKS} >= 0; # Normal cost of using the link
param link_size > 0; # Size of the links, e.g., 48 for OC-48
minimize UsageCost: sum {(i,j) in LINKS}
usage_cost[i,j]*total_flow[i,j];
# Node balance equations. We need these at every node for every source-destination pair.
# May be easiest to break into three cases: (i) where the node the equation being written for
# is neither the source or destination of the flow, (ii) where the node for the equation is
# the source for the flow, (iii) where the node for the equation is the destination for the flow.
subject to BalanceNull {n in NODES, (s,d) in SD_PAIRS: s<>n and d<>n }:
sum {(n, i) in LINKS} flow[n,i,s,d] - sum {(i,n) in LINKS} flow[i,n,s,d] = 0;
subject to BalanceSource {n in NODES, (n,d) in SD_PAIRS}:
sum {(n, i) in LINKS} flow[n,i,n,d] - sum {(i,n) in LINKS} flow[i,n,n,d] = demand[n,d];
subject to BalanceDest {n in NODES, (s, n) in SD_PAIRS}:
sum {(n, i) in LINKS} flow[n,i,s,n] - sum {(i,n) in LINKS} flow[i,n,s,n] = -demand[s,n];
subject to LinkConstraint {(i, j) in LINKS }:
total_flow[i,j] <= link_size;