See below three ways to create a flow balance constraint with different levels of details.
Set j = Set("j").Represents("Nodes of the network.").HasElementsUntil(data.NumNodes);
Set i = Set("i").Represents("Tails of edges incoming to j").DependsOn(j).HasElements(data.TailsOf);
Set k = Set("k").Represents("Heads of edges outgoing from j").DependsOn(j).HasElements(data.HeadsOf);
ParD1 demand = Parameter("dem").Represents("Node demand; i.e., amount of flow that needs to be transported to each node.")
.HasIndices(i).HasValues(data.NodeDemand);
// no details
Constraint flowBalance =
forall(j)
| sum(over(i), x[i, j]) - sum(over(k), x[j, k]) == demand[j];
// only with constraint key; this enables matching the constraint in the lp files;
// also makes automatically generated LaTeX, html or text documentation easier to read.
Constraint flowBalance =
key("flowbal")
| forall(j)
| sum(over(i), x[i, j]) - sum(over(k), x[j, k]) == demand[j];
// or with definition to be included in the documentations
Constraint flowBalance =
key("flowbal")
| "Flow balance constraints for every node j."
| forall(j)
| sum(over(i), x[i, j]) - sum(over(k), x[j, k]) == demand[j];
Similarly, keys and definitions can be included in or omitted from objective function definitions.
// no details
Objective minTotalCost =
minimize
| sum(over(j, i), costFlow[i, j] * x[i, j]);
// only key
Objective minTotalCost =
key("totalcost")
| minimize
| sum(over(j, i), costFlow[i, j] * x[i, j]);
// with definition to be included in the documentations
Objective minTotalCost =
key("totalcost")
| "Total flow cost of all edges."
| minimize
| sum(over(j, i), costFlow[i, j] * x[i, j]);
public static SymbolKey key(
string key
)