Using expression constraints
In addition to the existing constraints that enable you to define bounds on flow, inventory and production values, you can combine two or more of these constraints to achieve more complex constraints. For example, you may want to create constraints to enforce conditions such as the following:
- The total flow quantity out of DC_A should be less than 20% of the total inventory quantity at DC_B during Period_003.
- The total flow volume value from DC_A to CZ_B should equal the total flow volume from DC_A.
The Expression Constraints table provides support for these cases. You can define Expression 1 or Expression 2 or both, as needed. These expression values can be one of the following:
- The Name from a Flow Constraint, Flow Count Constraint, Inventory Constraint, Inventory Count Constraint, Production Constraint, Production Count Constraint, Site Constraint or Work Center Constraint,
- The Name from an Expression Constraint (enabling you to nest constraints),
- The Name from an Expression Based Cost.
As part of the support for expression constraints, the Constraint Type column in each of the constraints tables includes a type called “Define” for use with Expression Constraints and Expression Based Costs. When “Define” is set as the Constraint Type, the Constraint Value is not used to satisfy the constraint. Instead, the Constraint Value is specified in the Expression Constraint.
When defining Expression Constraints based on constraint records, such as Flow Constraints, the basis for the constraint records must be the same or the Expression Constraint is not included in the problem formulation. For example, if you have two Flow Constraints, the Constraint Basis must be the same for both records (i.e. both set to quantity). You cannot create an Expression Constraint that uses a Flow Constraint and a Flow Count Constraint, since the Flow Constraint uses quantity as a basis and the Flow Count Constraint uses count.
You can still define standard constraints, such as the maximum flow from a DC to a particular customer in a specified period. In this case, the Flow Constraint record looks like the following:
Expression Name |
Period Name |
Source Site |
Destination Site |
Product Name |
Constraint Value |
Constraint Type |
|
Period_001 |
DC1 |
CZ5 |
Product1 |
100 |
Max |
The Expression Name is not required to create standard constraints.

In the simplest case, the new Expression Constraint table can be used to create the same standard constraint. In this case, the Flow Constraint record looks like the following. Note the use of “Define” and no Constraint Value value, as well as the Expression Name:
Expression Name |
Period Name |
Source Site |
Destination Site |
Product Name |
Constraint Value |
Constraint Type |
Flow1 |
Period_001 |
DC1 |
CZ5 |
Product1 |
|
Define |
You create an Expression Constraint that references the named Flow Constraint and sets the requirement:
Expression Name |
Coefficient 1 |
Expression 1 |
Coefficient 2 |
Expression 2 |
Expression Type |
Constraint Value |
FlowConstraint |
1 |
Flow1 |
|
|
Max |
100 |
However, the true benefit comes when defining expression constraints. You can use the new Expression Constraints table to:
- Define a constraint made up of one or two expressions
- Define an expression that is a function of two other expressions
For example, assume that you want to limit the total production and flow quantity for Product1 at DC1 to 150 units in Period_001. This is actually a constraint across two different conditions that you combine using the Expression Constraints table. First, you create the Flow Constraint and Production Constraint records. Unlike the standard constraints, these will not have an actual quantity value specified, since the quantity is based on the combination of the two. In this case, the Constraint Type in each constraint record is “Define”, since the value will be determined by the Expression Constraint.
Here is the Flow Constraint record:
Expression Name |
Period Name |
Source Site |
Destination Site |
Product Name |
Constraint Value |
Constraint Type |
Flow1 |
Period_001 |
DC1 |
CZ5 |
Product1 |
|
Define |
And this is the Production Constraint record:
Expression Name |
Period Name |
Site Name |
Product Name |
Process Name |
Constraint Value |
Constraint Type |
Prod1 |
Period_001 |
DC1 |
Product1 |
|
|
Define |
To combine these using an Expression Constraint, the record looks like the following:
Expression Name |
Coefficient 1 |
Expression 1 |
Coefficient 2 |
Expression 2 |
Expression Type |
Constraint Value |
LimitProd1 |
1 |
Flow1 |
1 |
Prod1 |
Max |
150 |
This is defining that (1 * Flow1) + (1 * Prod1) must be less than or equal to 150. In other words, the sum of the flow of Product1 and the production of Product1 at DC1 cannot exceed 150 in Period_001.

You can use the coefficient fields to weight the expressions used in the Expression Constraint. You must take care with the signs that you place on the coefficients. These will be evaluated algebraically as shown in the following examples.
Example 1:
We can require that the Flow from DC_A is twice the Inventory at DC_B over the model horizon. The Inventory Constraint is:
Expression Name |
Period Name |
Site Name |
Product Name |
Constraint Value |
Constraint Type |
Inv2 |
(ALL_Periods) (All) |
DC_B |
(ALL_Products) |
|
Define |
The Flow Constraint is:
Expression Name |
Period Name |
Source Site |
Destination Site |
Product Name |
Constraint Value |
Constraint Type |
Flow2 |
(ALL_Periods) (All) |
DC_A |
(ALL_Customers) |
(ALL_Products) |
|
Define |
The Expression Constraint would then be:
Expression Name |
Coefficient 1 |
Expression 1 |
Coefficient 2 |
Expression 2 |
Expression Type |
Constraint Value |
FlowInv2 |
2 |
Flow2 |
-1 |
Inv2 |
Fixed |
0 |
That is:
(2 * Flow) + (-1 * Inventory) >= 0
Rearranging the equation gives:
(2 * Flow) = (1 * Inventory)
Example 2:
Another example is a requirement that the Total Flow Quantity out of DC_A must be less than 20% of the Total Inventory Quantity at DC_B during Period_003. In this case, the Flow Constraint is:
Expression Name |
Period Name |
Source Site |
Destination Site |
Product Name |
Constraint Value |
Constraint Type |
Flow3 |
Period_003 |
DC_A |
(ALL_Customers) |
(ALL_Products) |
|
Define |
The Inventory Constraint is:
Expression Name |
Period Name |
Site Name |
Product Name |
Constraint Value |
Constraint Type |
Inv3 |
Period_003 |
DC_B |
(ALL_Products) |
|
Define |
The Expression Constraint would then be:
Expression Name |
Coefficient 1 |
Expression 1 |
Coefficient 2 |
Expression 2 |
Expression Type |
Constraint Value |
FlowInv3 |
0.2 |
Inv3 |
-1 |
Flow3 |
Min |
0 |
That is:
[0.2 * InventoryDC_B] - [1 * FlowDC_A] >= 0
Rearranging the equation gives:
0.2 InventoryDC_B >= FlowDC_A
If the Inventory at DC_B is 1000:
200 >= FlowDC_A
The Flow at DC_A can be no more than 200 units in Period_003.
Let’s change this example to say that the Total Flow Quantity out of DC_A must be at least 20% of the Total Inventory Quantity at DC_B during Period_003. The coefficients must be changed to set up the appropriate evaluation and the Expression Constraint would then be:
Expression Name |
Coefficient 1 |
Expression 1 |
Coefficient 2 |
Expression 2 |
Expression Type |
Constraint Value |
FlowInv3 |
-0.2 |
Inv3 |
1 |
Flow3 |
Min |
0 |
That is:
[-0.2 * InventoryDC_B] + [1 * FlowDC_A] >= 0
Rearranging the equation gives:
FlowDC_A >= 0.2 InventoryDC_B
If the Inventory at DC_B is 1000:
FlowDC_A >= 200
The Flow at DC_A must be at least 200 units in Period_003.
Example 3:
In another example, we want to control the flow over 3 Modes:
- 50% must go LTL (fixed).
- If Air is used, no more than 30% can be Air.
-
Ground can be used to serve what is not handled using LTL or Air.
We set up 4 Flow Constraint records:
Expression Name |
Period Name |
Source Site |
Destination Site |
Product Name |
Mode |
Constraint Value |
Constraint Type |
TotalFlow |
(ALL_Periods) (All) |
DC |
CZ |
P1 |
|
|
Define |
LTL |
(ALL_Periods) (All) |
DC |
CZ |
P1 |
LTL |
|
Define |
Ground |
(ALL_Periods) (All) |
DC |
CZ |
P1 |
Ground |
|
Define |
Air |
(ALL_Periods) (All) |
DC |
CZ |
P1 |
Air |
|
Define |
The Expression Constraints would then be:
Expression Name |
Coefficient 1 |
Expression 1 |
Coefficient 2 |
Expression 2 |
Expression Type |
Constraint Value |
LTL50 |
-0.5 |
TotalFlow |
1 |
LTL |
Fixed |
0 |
Air30AtMost |
0.3 |
TotalFlow |
-1 |
Air |
Min |
0 |
Let’s assume that the total flow in this model is 1000. For the LTL 50 constraint, this is a Fixed value, so:
LTL = 500
In other words, if Ground is used, it must account for 200 or more units.
For the Air30AtMost constraint, this is evaluated as:
0.3 * [Total Flow] - [Air Flow] >= 0
0.3 Total - Air >= 0
300 >= Air
If Air is more expensive than Ground, it will not be used and all non-LTL will go by Ground. If less expensive, Air can incur up to 300 units.

The way you define Expression Constraints when using “Cond Min” as the Constraint Type will depend on whether your constraint uses a single expression or a summation. For example, assume you have the following Production Constraints:
Expression Name |
Period Name |
Site Name |
Product Name |
Process Name |
Constraint Value |
Constraint Type |
TotalProduction |
(ALL_Periods) (All) |
MFGs |
Product1 |
|
|
Define |
ProductionMFG |
(ALL_Periods) (All) |
MFG |
Product1 |
|
|
Define |
Assume you want a constraint such that production from the single MFG and the total production is at least 110:
If the TotalProduction + ProductionMFG > 0, then TotalProduction + ProductionMFG > 110
The Expression Constraint would look like the following:
Expression Name |
Coefficient 1 |
Expression 1 |
Coefficient 2 |
Expression 2 |
Constraint Type |
Constraint Value |
Cond Min Summation |
1 |
TotalProduction |
1 |
ProductionMFG |
Cond Min |
110 |
This structure forces a minimum value to a summation expression (the coefficients can be negative).
In another case, assume that you want to ensure that if there is production from the single MFG, the volume is at least 10:
If the ProductionMFG > 0, then ProductionMFG > 10
This structure forces a minimum value to a single expression.
Conditional minimum with non-zero constraint value
When working with conditional minimum as the Constraint Type, keep in mind how such a constraint is evaluated:
Conditional Minimum: x >= Minimum Amount or x = 0
For example, if you define a regular product constraint with a conditional minimum of 100, the production amount (x) has to be greater than or equal to 100 units (minimum amount) or the production will be 0 units.
This is significant because it means that the overall expression will meet either the Constraint Value minimum or a minimum of 0.
As an example, consider the following constraints:
First, we have Flow Constraint to define the flow of a product from all plants to all customers:
Expression Name |
Period Name |
Source Site |
Destination Site |
Product Name |
Constraint Value |
Constraint Type |
Total_FG_1001 |
(ALL_Periods) (All) |
All_Plant |
All_CZ |
FG_1001 |
|
Define |
There is also a Production Constraint to define the production of the finished good product at one of the plants:
Expression Name |
Period Name |
Source Site |
Product Name |
Constraint Value |
Constraint Type |
Total_P104_FG_1001 |
(ALL_Periods) (All) |
Plant_104 |
FG_1001 |
|
Define |
In the first case, the goal of the Expression Constraint is to ensure that 5% of the total flow (Total_FG_1001) is greater than or equal to the production at Plant_104 (Total_P104_FG_1001). The Expression Constraint looks like this:
Expression Name |
Coefficient 1 |
Expression 1 |
Coefficient 2 |
Expression 2 |
Constraint Type |
Constraint Value |
Exp_P104_FG_1001 |
0.05 |
Total_FG_1001 |
-1 |
Total_P104_FG_1001 |
Cond Min |
0 |
Assume that the model has demand of 100. In this case:
- Total Flow (Total_FG_1001) = 100
- Production at Plant_104 (Total_P104_FG_1001) = 5
- and the Expression Constraint (Exp_P104_FG_1001) = 0
Now, let’s change the Expression Constraint so that we compare 5% of the flow to production at Plant_104 less 3 units. We change the Constraint Value to 3:
Expression Name |
Coefficient 1 |
Expression 1 |
Coefficient 2 |
Expression 2 |
Constraint Type |
Constraint Value |
Exp_P104_FG_1001 |
0.05 |
Total_FG_1001 |
-1 |
Total_P104_FG_1001 |
Cond Min |
3 |
Depending on the costs and other constraints in the model, the Constraint Value of 3 on the conditional minimum may not be enforced (remember that it is conditional). If the minimum is used, the Expression Constraint (Exp_P104_FG_1001) will be greater than or equal to 3. If it is not used the Expression Constraint is evaluated as 0 and the results will look the same as the initial example, where Constraint Value was 0.
If you use Min rather than Cond Min and using Plant_104 is cost-effective, you will see:
- Total Flow (Total_FG_1001) = 100
- Production at Plant_104 (Total_P104_FG_1001) = 2
- and the Expression Constraint (Exp_P104_FG_1001) = 3
If you use Min and using Plant_104 is not cost-effective, you will see:
- Total Flow (Total_FG_1001) = 100
- Production at Plant_104 (Total_P104_FG_1001) = 0
- and the Expression Constraint (Exp_P104_FG_1001) = 5
In this case, Production is 0 at Plant_104, but the Expression Constraint value is greater than the minimum of 3, so the Expression Constraint is satisfied.
If the minimum is over-constraining, the model will be infeasible.

You can also combine expression constraints. For example, let’s go back to our earlier example where we limit the total production and flow quantity for Product1 at DC1 to 150 units in Period_001. We now want to combine that with a constraint on the total production quantity at the MFG site for all products over the model horizon so that the total for all 3 considerations is 5000. The new Production Constraint at the MFG site would be:
Expression Name |
Period Name |
Site Name |
Product Name |
Process Name |
Constraint Value |
Constraint Type |
MfgProd1 |
(ALL_Periods) (All) |
MFG |
(All) |
|
|
Define |
We add a second Expression Constraint that uses the existing Expression Constraint:
Expression Name |
Coefficient 1 |
Expression 1 |
Coefficient 2 |
Expression 2 |
Expression Type |
Constraint Value |
LimitProd1 |
1 |
Flow1 |
1 |
Prod1 |
Max |
150 |
LimitAll |
1 |
LimitProd1 |
1 |
MfgProd1 |
Max |
5000 |
Current limitations of expression constraints
The following is a current limitation in the use of Expression Constraints:
- The constraints that are referenced in an Expression Constraint must use the same unit of measure (Quantity, Weight, or Volume). For example, if you have an Expression Constraint that uses one Flow Constraint and one Inventory Constraint, if the Flow Constraint Constraint Value is set to a weight unit of measure, then the Inventory Constraint Constraint Value must also be a weight unit of measure. This is also true if both constraints are of the same type (i.e. both Flow Constraints).
Handling invalid expressions
-
If Expression 1 is invalid, it will cause Expression 2 defined in the Expression Constraint to be invalid.
-
Similarly if Expression 2 is invalid, it will cause Expression 1 defined in the Expression Constraint to be invalid.
Once an expression is deemed to be invalid, it is invalid in all Expression Constraint records. For example, assume the following records where Expression 1 (No_Prod) in the Test 3 record is invalid:
Name | Coefficient 1 | Expression 1 | Coefficient 2 | Expression 2 | Constraint Type | Constraint Value | Status |
---|---|---|---|---|---|---|---|
Test1 | 1 | All_Flow | -1 | All_Prod | Min | 1 | Include |
Test2 | 2 | All_Prod | -2 | All_Process | Min | 2 | Include |
Test3 | 3 | No_Prod | -3 | All_Inv | Min | 3 | Include |
Test4 | 4 | All_Flow | -4 | All_Inv | Min | 4 | Include |
In this case, the invalid Expression 1 results in Expression 2 (All_Inv) being invalid in Test3. Since All_Inv is now invalid, the Test4 Expression Constraint is also considered invalid. Neither Test3 nor Test4 will be written when the model is run.
Last modified: Friday May 12, 2023