The Dantzig-Wolfe Decomposition Algorithm

Example 18.9 ATM Cash Management in Single-Machine Mode

This example describes an optimization model that is used in the management of cash flow for a bank’s automated teller machine (ATM) network. The goal of the model is to determine a replenishment schedule for the bank to use in allocating cash inventory at its branches when servicing a preassigned subset of ATMs. Given a history of withdrawals per day for each ATM, the bank can use SAS forecasting tools to predict the expected cash need. The modeling of this prediction depends on various seasonal factors, including the days of the week, weeks of the month, holidays, typical salary disbursement days, location of the ATMs, and other demographic data. The prediction is a parametric mixture of models whose parameters depend on each ATM.

The optimization model performs a polynomial regression that minimizes the error (measured by the upper L 1 norm) between the predicted and actual withdrawals. The parameter settings in the regression determine the replenishment policy. The amount of cash that is allocated to each day is subject to a budget constraint. In addition, a constraint for each ATM limits the number of days that a cash-out (a situation in which the cash flow is less than the predicted withdrawal) can occur. The goal is to determine a policy for cash distribution that balances the predicted inventory levels while satisfying the budget and cash-out constraints. By keeping too much cash on hand for ATM fulfillment, the bank loses an investment opportunity. Moreover, regulatory agencies in many countries enforce a minimum cash reserve ratio at branch banks; according to regulatory policy, the cash in ATMs or in transit does not contribute toward this threshold.

Mixed Integer Nonlinear Programming Formulation

The most natural formulation for this model is in the form of a mixed integer nonlinear program (MINLP). Let A denote the set of ATMs and D denote the set of days that are used in the training data. The predictive model fit is defined by the following data for each ATM a on each day d: c Subscript a d Baseline comma c Subscript a d Superscript x Baseline comma c Subscript a d Superscript y Baseline comma c Subscript a d Superscript z, and c Subscript a d Superscript u. The model-fitting parameters define the variables left-parenthesis x Subscript a Baseline comma y Subscript a Baseline comma u Subscript a Baseline right-parenthesis for each ATM that, when applied to the predictive model, estimate the necessary cash flow per day per ATM. In addition, define a surrogate variable f Subscript a d for each ATM on each day that defines the cash inventory (replenished from the branch) minus withdrawals. The variable f Subscript a d also represents the error in the regression model. Let upper B Subscript d define the budget per day, upper K Subscript a define the limit on cash-outs per ATM, and w Subscript a d define the historical withdrawals at a particular ATM on a particular day. Then the following MINLP models this problem:

StartLayout 1st Row 1st Column Blank 2nd Column minimize 3rd Column sigma-summation Underscript a element-of upper A Endscripts sigma-summation Underscript d element-of upper D Endscripts StartAbsoluteValue f Subscript a d Baseline EndAbsoluteValue 2nd Row 1st Column Blank 2nd Column subject to 3rd Column c Subscript a d Superscript x Baseline x Subscript a plus c Subscript a d Superscript y Baseline y Subscript a plus 3rd Row 1st Column Blank 2nd Column Blank 3rd Column c Subscript a d Superscript z Baseline x Subscript a Baseline y Subscript a plus c Subscript a d Superscript u Baseline u Subscript a plus c Subscript a d minus w Subscript a d 4th Column equals f Subscript a d Baseline 5th Column Blank 6th Column a element-of upper A comma d element-of upper D 7th Column Blank 8th Column left-parenthesis CashFlowDefCon right-parenthesis 4th Row 1st Column Blank 2nd Column Blank 3rd Column sigma-summation Underscript a element-of upper A Endscripts left-parenthesis f Subscript a d Baseline plus w Subscript a d Baseline right-parenthesis 4th Column less-than-or-equal-to upper B Subscript d Baseline 5th Column Blank 6th Column d element-of upper D 7th Column Blank 8th Column left-parenthesis BudgetCon right-parenthesis 5th Row 1st Column Blank 2nd Column Blank 3rd Column StartAbsoluteValue StartSet d element-of upper D vertical-bar f Subscript a d Baseline less-than 0 EndSet EndAbsoluteValue 4th Column less-than-or-equal-to upper K Subscript a Baseline 5th Column Blank 6th Column a element-of upper A 7th Column Blank 8th Column left-parenthesis CashOutLimitCon right-parenthesis 6th Row 1st Column Blank 2nd Column Blank 3rd Column x Subscript a Baseline comma y Subscript a Baseline 4th Column element-of left-bracket 0 comma 1 right-bracket 5th Column Blank 6th Column a element-of upper A 7th Row 1st Column Blank 2nd Column Blank 3rd Column u Subscript a 4th Column greater-than-or-equal-to 0 5th Column Blank 6th Column a element-of upper A 8th Row 1st Column Blank 2nd Column Blank 3rd Column f Subscript a d 4th Column greater-than-or-equal-to minus w Subscript a d Baseline 5th Column Blank 6th Column a element-of upper A comma d element-of upper D EndLayout

The CashFlowDefCon constraint defines the surrogate variable f Subscript a d, which gives the estimated net cash flow. The BudgetCon and CashOutLimitCon constraints ensure that the solution satisfies the budget and cash-out constraints, respectively.

To express this model in a more standard form, you can first use some standard model reformulations to linearize the absolute value and the CashOutLimitCon constraint.

Linearization of Absolute Value

A well-known reformulation for linearizing the absolute value of a variable is to introduce one variable for each side of the absolute value. The following systems are equivalent:

StartLayout 1st Row 1st Column minimize 2nd Column StartAbsoluteValue y EndAbsoluteValue 2nd Row 1st Column subject to 2nd Column upper A y 3rd Column less-than-or-equal-to 4th Column b EndLayout is equivalent to StartLayout 1st Row 1st Column minimize 2nd Column y Superscript plus Baseline plus y Superscript minus Baseline 2nd Row 1st Column subject to 2nd Column upper A left-parenthesis y Superscript plus Baseline minus y Superscript minus Baseline right-parenthesis 3rd Column less-than-or-equal-to 4th Column b 3rd Row 1st Column Blank 2nd Column y Superscript plus Baseline comma y Superscript minus Baseline 3rd Column greater-than-or-equal-to 4th Column 0 EndLayout

Let f Subscript a d Superscript plus and f Subscript a d Superscript minus represent the positive and negative parts, respectively, of the net cash flow f Subscript a d. Then you can rewrite the model, removing the absolute value, as the following:

StartLayout 1st Row 1st Column Blank 2nd Column minimize 3rd Column sigma-summation Underscript a element-of upper A Endscripts sigma-summation Underscript d element-of upper D Endscripts left-parenthesis f Subscript a d Superscript plus Baseline plus f Subscript a d Superscript minus Baseline right-parenthesis 2nd Row 1st Column Blank 2nd Column subject to 3rd Column c Subscript a d Superscript x Baseline x Subscript a plus c Subscript a d Superscript y Baseline y Subscript a plus 3rd Row 1st Column Blank 2nd Column Blank 3rd Column c Subscript a d Superscript z Baseline x Subscript a Baseline y Subscript a plus c Subscript a d Superscript u Baseline u Subscript a plus c Subscript a d minus w Subscript a d 4th Column equals f Subscript a d Superscript plus Baseline minus f Subscript a d Superscript minus Baseline 5th Column Blank 6th Column a element-of upper A comma d element-of upper D 4th Row 1st Column Blank 2nd Column Blank 3rd Column sigma-summation Underscript a element-of upper A Endscripts left-parenthesis f Subscript a d Superscript plus Baseline minus f Subscript a d Superscript minus Baseline plus w Subscript a d Baseline right-parenthesis 4th Column less-than-or-equal-to upper B Subscript d Baseline 5th Column Blank 6th Column d element-of upper D 5th Row 1st Column Blank 2nd Column Blank 3rd Column StartAbsoluteValue StartSet d element-of upper D vertical-bar left-parenthesis f Subscript a d Superscript plus Baseline minus f Subscript a d Superscript minus Baseline right-parenthesis less-than 0 EndSet EndAbsoluteValue 4th Column less-than-or-equal-to upper K Subscript a Baseline 5th Column Blank 6th Column a element-of upper A 6th Row 1st Column Blank 2nd Column Blank 3rd Column x Subscript a Baseline comma y Subscript a Baseline 4th Column element-of left-bracket 0 comma 1 right-bracket 5th Column Blank 6th Column a element-of upper A 7th Row 1st Column Blank 2nd Column Blank 3rd Column u Subscript a 4th Column greater-than-or-equal-to 0 5th Column Blank 6th Column a element-of upper A 8th Row 1st Column Blank 2nd Column Blank 3rd Column f Subscript a d Superscript plus 4th Column greater-than-or-equal-to 0 5th Column Blank 6th Column a element-of upper A comma d element-of upper D 9th Row 1st Column Blank 2nd Column Blank 3rd Column f Subscript a d Superscript minus 4th Column element-of left-bracket 0 comma w Subscript a d Baseline right-bracket 5th Column Blank 6th Column a element-of upper A comma d element-of upper D EndLayout
Modeling the Cash-Out Constraints

To count the number of times a cash-out occurs, you need to introduce a binary variable to keep track of when this event occurs. Let v Subscript a d be an indicator variable that takes the value 1 when the net cash flow is negative. You can model the implication f Subscript a d Superscript minus Baseline greater-than 0 right double arrow v Subscript a d Baseline equals 1, or its contrapositive v Subscript a d Baseline equals 0 right double arrow f Subscript a d Superscript minus Baseline less-than-or-equal-to 0, by adding the constraint

f Subscript a d Superscript minus Baseline less-than-or-equal-to w Subscript a d Baseline v Subscript a d Baseline a element-of upper A comma d element-of upper D

Now you can model the cash-out constraint by counting the number of days that the net-cash flow is negative for each ATM, as follows:

sigma-summation Underscript d element-of upper D Endscripts v Subscript a d Baseline less-than-or-equal-to upper K Subscript a Baseline a element-of upper A

The MINLP model can now be written as follows:

StartLayout 1st Row 1st Column Blank 2nd Column minimize 3rd Column sigma-summation Underscript a element-of upper A Endscripts sigma-summation Underscript d element-of upper D Endscripts left-parenthesis f Subscript a d Superscript plus Baseline plus f Subscript a d Superscript minus Baseline right-parenthesis 2nd Row 1st Column Blank 2nd Column subject to 3rd Column c Subscript a d Superscript x Baseline x Subscript a plus c Subscript a d Superscript y Baseline y Subscript a plus 3rd Row 1st Column Blank 2nd Column Blank 3rd Column c Subscript a d Superscript z Baseline x Subscript a Baseline y Subscript a plus c Subscript a d Superscript u Baseline u Subscript a plus c Subscript a d minus w Subscript a d 4th Column equals f Subscript a d Superscript plus Baseline minus f Subscript a d Superscript minus Baseline 5th Column Blank 6th Column a element-of upper A comma d element-of upper D 4th Row 1st Column Blank 2nd Column Blank 3rd Column sigma-summation Underscript a element-of upper A Endscripts left-parenthesis f Subscript a d Superscript plus Baseline minus f Subscript a d Superscript minus Baseline plus w Subscript a d Baseline right-parenthesis 4th Column less-than-or-equal-to upper B Subscript d Baseline 5th Column Blank 6th Column d element-of upper D 5th Row 1st Column Blank 2nd Column Blank 3rd Column f Subscript a d Superscript minus 4th Column less-than-or-equal-to w Subscript a d Baseline v Subscript a d Baseline 5th Column Blank 6th Column a element-of upper A comma d element-of upper D 6th Row 1st Column Blank 2nd Column Blank 3rd Column sigma-summation Underscript d element-of upper D Endscripts v Subscript a d 4th Column less-than-or-equal-to upper K Subscript a Baseline 5th Column Blank 6th Column a element-of upper A 7th Row 1st Column Blank 2nd Column Blank 3rd Column x Subscript a Baseline comma y Subscript a Baseline 4th Column element-of left-bracket 0 comma 1 right-bracket 5th Column Blank 6th Column a element-of upper A 8th Row 1st Column Blank 2nd Column Blank 3rd Column u Subscript a 4th Column greater-than-or-equal-to 0 5th Column Blank 6th Column a element-of upper A 9th Row 1st Column Blank 2nd Column Blank 3rd Column f Subscript a d Superscript plus 4th Column greater-than-or-equal-to 0 5th Column Blank 6th Column a element-of upper A comma d element-of upper D 10th Row 1st Column Blank 2nd Column Blank 3rd Column f Subscript a d Superscript minus 4th Column element-of left-bracket 0 comma w Subscript a d Baseline right-bracket 5th Column Blank 6th Column a element-of upper A comma d element-of upper D 11th Row 1st Column Blank 2nd Column Blank 3rd Column v Subscript a d 4th Column element-of StartSet 0 comma 1 EndSet 5th Column Blank 6th Column a element-of upper A comma d element-of upper D EndLayout

This MINLP is difficult to solve, in part because the prediction function is not convex. Another approach is to use mixed integer linear programming (MILP) to formulate an approximation of the problem, as described in the next section.

Mixed Integer Linear Programming Approximation

Because the predictive model is a forecast, finding the optimal parameters that are based on nondeterministic data is not of primary importance. Rather, you want to provide as good a solution as possible in a reasonable amount of time. So using MILP to approximate the MINLP is perfectly acceptable. In the original problem you have products of two continuous variables that are both bounded by 0 (lower bound) and 1 (upper bound). This arrangement enables you to create an approximate linear model by using a few standard modeling reformulations.

Discretization of Continuous Variables

The first step is to discretize one of the continuous variables x Subscript a. The goal is to transform the product x Subscript a Baseline y Subscript a of a continuous variable and another continuous variable instead to the product of a continuous variable and a binary variable. This transformation enables you to linearize the product form.

You must assume some level of approximation by defining a binary variable (from some discrete set) for each possible setting of the continuous variable For example, if you let n equals 10, then you allow x to be chosen from the set StartSet 0.0 comma 0.1 comma 0.2 comma 0.3 comma ellipsis comma 1.0 EndSet. Let upper T equals StartSet 0 comma 1 comma 2 comma ellipsis comma n EndSet represent the possible steps and c Subscript t Baseline equals t slash n. Then you apply the following transformation to variable x Subscript a:

StartLayout 1st Row 1st Column sigma-summation Underscript t element-of upper T Endscripts c Subscript t Baseline x Subscript a t 2nd Column equals x Subscript a Baseline 2nd Row 1st Column sigma-summation Underscript t element-of upper T Endscripts x Subscript a t 2nd Column equals 1 3rd Row 1st Column x Subscript a t 2nd Column element-of StartSet 0 comma 1 EndSet t element-of upper T EndLayout

The MINLP model can now be approximated as the following:

StartLayout 1st Row 1st Column Blank 2nd Column minimize 3rd Column sigma-summation Underscript a element-of upper A Endscripts sigma-summation Underscript d element-of upper D Endscripts left-parenthesis f Subscript a d Superscript plus Baseline plus f Subscript a d Superscript minus Baseline right-parenthesis 2nd Row 1st Column Blank 2nd Column subject to 3rd Column c Subscript a d Superscript x Baseline sigma-summation Underscript t element-of upper T Endscripts c Subscript t Baseline x Subscript a t plus c Subscript a d Superscript y Baseline y Subscript a plus 3rd Row 1st Column Blank 2nd Column Blank 3rd Column c Subscript a d Superscript z Baseline sigma-summation Underscript t element-of upper T Endscripts c Subscript t Baseline x Subscript a t Baseline y Subscript a plus c Subscript a d Superscript u Baseline u Subscript a plus c Subscript a d minus w Subscript a d 4th Column equals f Subscript a d Superscript plus Baseline minus f Subscript a d Superscript minus Baseline 5th Column Blank 6th Column a element-of upper A comma d element-of upper D 4th Row 1st Column Blank 2nd Column Blank 3rd Column sigma-summation Underscript t element-of upper T Endscripts x Subscript a t 4th Column equals 1 5th Column Blank 6th Column a element-of upper A 5th Row 1st Column Blank 2nd Column Blank 3rd Column sigma-summation Underscript a element-of upper A Endscripts left-parenthesis f Subscript a d Superscript plus Baseline minus f Subscript a d Superscript minus Baseline plus w Subscript a d Baseline right-parenthesis 4th Column less-than-or-equal-to upper B Subscript d Baseline 5th Column Blank 6th Column d element-of upper D 6th Row 1st Column Blank 2nd Column Blank 3rd Column f Subscript a d Superscript minus 4th Column less-than-or-equal-to w Subscript a d Baseline v Subscript a d Baseline 5th Column Blank 6th Column a element-of upper A comma d element-of upper D 7th Row 1st Column Blank 2nd Column Blank 3rd Column sigma-summation Underscript d element-of upper D Endscripts v Subscript a d 4th Column less-than-or-equal-to upper K Subscript a Baseline 5th Column Blank 6th Column a element-of upper A 8th Row 1st Column Blank 2nd Column Blank 3rd Column y Subscript a 4th Column element-of left-bracket 0 comma 1 right-bracket 5th Column Blank 6th Column a element-of upper A 9th Row 1st Column Blank 2nd Column Blank 3rd Column u Subscript a 4th Column greater-than-or-equal-to 0 5th Column Blank 6th Column a element-of upper A 10th Row 1st Column Blank 2nd Column Blank 3rd Column f Subscript a d Superscript plus 4th Column greater-than-or-equal-to 0 5th Column Blank 6th Column a element-of upper A comma d element-of upper D 11th Row 1st Column Blank 2nd Column Blank 3rd Column f Subscript a d Superscript minus 4th Column element-of left-bracket 0 comma w Subscript a d Baseline right-bracket 5th Column Blank 6th Column a element-of upper A comma d element-of upper D 12th Row 1st Column Blank 2nd Column Blank 3rd Column v Subscript a d 4th Column element-of StartSet 0 comma 1 EndSet 5th Column Blank 6th Column a element-of upper A comma d element-of upper D 13th Row 1st Column Blank 2nd Column Blank 3rd Column x Subscript a t 4th Column element-of StartSet 0 comma 1 EndSet 5th Column Blank 6th Column a element-of upper A comma t element-of upper T EndLayout
Linearization of Products

You still need to linearize the product terms x Subscript a t Baseline y Subscript a in the cash flow constraint. Because these terms are products of a bounded continuous variable and a binary variable, you can linearize them by introducing for each product another variable, z Subscript a t, which serves as a surrogate. In general, you know the following relationship between the original variables and their surrogates:

StartLayout 1st Row 1st Column z Subscript t Baseline 2nd Column equals 3rd Column x Subscript t Baseline y 4th Column t element-of upper T 2nd Row 1st Column sigma-summation Underscript t element-of upper T Endscripts x Subscript t Baseline 2nd Column equals 3rd Column 1 3rd Row 1st Column x Subscript t Baseline 2nd Column element-of 3rd Column StartSet 0 comma 1 EndSet 4th Column t element-of upper T 4th Row 1st Column y 2nd Column element-of 3rd Column left-bracket 0 comma 1 right-bracket EndLayout is equivalent to StartLayout 1st Row 1st Column z Subscript t Baseline 2nd Column greater-than-or-equal-to 3rd Column 0 4th Column t element-of upper T 2nd Row 1st Column z Subscript t Baseline 2nd Column less-than-or-equal-to 3rd Column x Subscript t Baseline 4th Column t element-of upper T 3rd Row 1st Column sigma-summation Underscript t element-of upper T Endscripts x Subscript t Baseline 2nd Column equals 3rd Column 1 4th Row 1st Column sigma-summation Underscript t element-of upper T Endscripts z Subscript t Baseline 2nd Column equals 3rd Column y 5th Row 1st Column x Subscript t Baseline 2nd Column element-of 3rd Column StartSet 0 comma 1 EndSet 4th Column t element-of upper T 6th Row 1st Column y 2nd Column element-of 3rd Column left-bracket 0 comma 1 right-bracket EndLayout

Using this relationship to replace each product form, you now can write the problem as an approximate MILP as follows:

StartLayout 1st Row 1st Column Blank 2nd Column minimize 3rd Column sigma-summation Underscript a element-of upper A Endscripts sigma-summation Underscript d element-of upper D Endscripts left-parenthesis f Subscript a d Superscript plus Baseline plus f Subscript a d Superscript minus Baseline right-parenthesis 2nd Row 1st Column Blank 2nd Column subject to 3rd Column c Subscript a d Superscript x Baseline sigma-summation Underscript t element-of upper T Endscripts c Subscript t Baseline x Subscript a t plus c Subscript a d Superscript y Baseline y Subscript a plus 3rd Row 1st Column Blank 2nd Column Blank 3rd Column c Subscript a d Superscript z Baseline sigma-summation Underscript t element-of upper T Endscripts c Subscript t Baseline z Subscript a t plus c Subscript a d Superscript u Baseline u Subscript a plus c Subscript a d minus w Subscript a d 4th Column equals f Subscript a d Superscript plus Baseline minus f Subscript a d Superscript minus Baseline 5th Column Blank 6th Column a element-of upper A comma d element-of upper D 4th Row 1st Column Blank 2nd Column Blank 3rd Column sigma-summation Underscript t element-of upper T Endscripts x Subscript a t 4th Column equals 1 5th Column Blank 6th Column a element-of upper A 5th Row 1st Column Blank 2nd Column Blank 3rd Column sigma-summation Underscript a element-of upper A Endscripts left-parenthesis f Subscript a d Superscript plus Baseline minus f Subscript a d Superscript minus Baseline plus w Subscript a d Baseline right-parenthesis 4th Column less-than-or-equal-to upper B Subscript d Baseline 5th Column Blank 6th Column d element-of upper D 7th Column Blank 8th Column left-parenthesis BudgetCon right-parenthesis 6th Row 1st Column Blank 2nd Column Blank 3rd Column f Subscript a d Superscript minus 4th Column less-than-or-equal-to w Subscript a d Baseline v Subscript a d Baseline 5th Column Blank 6th Column a element-of upper A comma d element-of upper D 7th Row 1st Column Blank 2nd Column Blank 3rd Column sigma-summation Underscript d element-of upper D Endscripts v Subscript a d 4th Column less-than-or-equal-to upper K Subscript a Baseline 5th Column Blank 6th Column a element-of upper A 8th Row 1st Column Blank 2nd Column Blank 3rd Column z Subscript a t 4th Column less-than-or-equal-to x Subscript a t Baseline 5th Column Blank 6th Column a element-of upper A comma t element-of upper T 9th Row 1st Column Blank 2nd Column Blank 3rd Column sigma-summation Underscript t element-of upper T Endscripts z Subscript a t 4th Column equals y Subscript a Baseline 5th Column Blank 6th Column a element-of upper A 10th Row 1st Column Blank 2nd Column Blank 3rd Column z Subscript a t 4th Column greater-than-or-equal-to 0 5th Column Blank 6th Column a element-of upper A comma t element-of upper T 11th Row 1st Column Blank 2nd Column Blank 3rd Column y Subscript a 4th Column element-of left-bracket 0 comma 1 right-bracket 5th Column Blank 6th Column a element-of upper A 12th Row 1st Column Blank 2nd Column Blank 3rd Column u Subscript a 4th Column greater-than-or-equal-to 0 5th Column Blank 6th Column a element-of upper A 13th Row 1st Column Blank 2nd Column Blank 3rd Column f Subscript a d Superscript plus 4th Column greater-than-or-equal-to 0 5th Column Blank 6th Column a element-of upper A comma d element-of upper D 14th Row 1st Column Blank 2nd Column Blank 3rd Column f Subscript a d Superscript minus 4th Column element-of left-bracket 0 comma w Subscript a d Baseline right-bracket 5th Column Blank 6th Column a element-of upper A comma d element-of upper D 15th Row 1st Column Blank 2nd Column Blank 3rd Column v Subscript a d 4th Column element-of StartSet 0 comma 1 EndSet 5th Column Blank 6th Column a element-of upper A comma d element-of upper D 16th Row 1st Column Blank 2nd Column Blank 3rd Column x Subscript a t 4th Column element-of StartSet 0 comma 1 EndSet 5th Column Blank 6th Column a element-of upper A comma t element-of upper T EndLayout

PROC OPTMODEL Code

Because it is difficult to solve the MINLP model directly, the approximate MILP formulation is attractive. Unfortunately, the approximate MILP is much larger than the associated MINLP. Direct methods for solving this MILP do not work well. However, the problem is nicely suited for the Dantzig-Wolfe decomposition algorithm.

When you examine the structure of the MILP model, you see clearly that the constraints can be easily decomposed by ATM. In fact, the only set of constraints that involve decision variables across ATMs is the BudgetCon constraint. That is, if you relax the budget constraint, you are left with independent blocks of constraints, one for each ATM.

To show how this is done in PROC OPTMODEL, consider the following data sets, which describe an example that tracks 20 ATMs over a period of 100 days. This particular example was submitted to MIPLIB 2010, which is a collection of difficult MILPs in the public domain (Koch et al. 2011).

The first data set, budget_data, provides the cash budget on each particular day:

data budget_data;
   input d $ budget;
   datalines;
DATE0      70079
DATE1      66418
DATE10     52656
DATE11     50439
DATE12     58688
DATE13     45002
DATE14     52369
...
;

The second data set, cashout_data, provides the limit on the number of cash-outs that are allowed at each ATM:

data cashout_data;
   input a $ cashOutLimit;
   datalines;
ATM0            31
ATM1            24
ATM2            41
ATM3            43
ATM4            29
ATM5            24
ATM6            52
ATM7            44
ATM8            35
ATM9            48
ATM10           31
ATM11           47
ATM12           26
ATM13           34
ATM14           29
ATM15           32
ATM16           33
ATM17           32
ATM18           43
ATM19           28
;

The final data set, polyfit_data, provides the polynomial fit coefficients for each ATM on each date. It also provides the historical cash withdrawals.

data polyfit_data;
   input a $ d $ cx cy cz cu c withdrawal;
   datalines;
ATM0     DATE0       2822     1984    -1984    1045    1373        780
ATM0     DATE1       1337     2530    -2530    1510     174       2351
ATM0     DATE2       2685      -67       67     145    2820       2288
ATM0     DATE3       -595    -3135     3135     581    3319       1357
...
ATM19    DATE96      -734     3392    -3392     162    1648        914
ATM19    DATE97     -1062      969     -969     444    1746       2264
ATM19    DATE98      7676     2308    -2308      59    1388        972
ATM19    DATE99      3062     1308    -1308    1080     654        698
;

The following PROC OPTMODEL statements read in the data and define the necessary sets and parameters:

proc optmodel;
   set<str> DATES;
   set<str> ATMS;

   /* cash budget per date */
   num budget{DATES};

   /* maximum number of cash-outs allowed at each atm */
   num cashOutLimit{ATMS};

   /* historical withdrawal amount per atm each date */
   num withdrawal{ATMS, DATES};

   /* polynomial fit coefficients for predicted cash flow needed */
   num c {ATMS, DATES};
   num cx{ATMS, DATES};
   num cy{ATMS, DATES};
   num cz{ATMS, DATES};
   num cu{ATMS, DATES};

   /* number of points used in approximation of continuous range */
   num nSteps = 10;
   set STEPS = {0..nSteps};

   read data budget_data into DATES=[d] budget;
   read data cashout_data into ATMS=[a] cashOutLimit;
   read data polyfit_data into [a d] cx cy cz cu c withdrawal;

The following statements declare the variables:

   var x{ATMS,STEPS}                 binary;
   var v{ATMS,DATES}                 binary;
   var z{ATMS,STEPS}                 >= 0 <= 1;
   var y{ATMS}                       >= 0 <= 1;
   var u{ATMS}                       >= 0;
   var fPlus{ATMS,DATES}             >= 0;
   var fMinus{a in ATMS, d in DATES} >= 0 <= withdrawal[a,d];

The following statements declare the objective and the constraints:

   min CashFlowDiff =
      sum{a in ATMS, d in DATES} (fPlus[a,d] + fMinus[a,d]);

   con BudgetCon{d in DATES}:
      sum{a in ATMS} (fPlus[a,d] - fMinus[a,d] + withdrawal[a,d])
          <= budget[d];

   con CashFlowDefCon{a in ATMS, d in DATES}:
      cx[a,d] * sum{t in STEPS} (t/nSteps) * x[a,t] +
      cy[a,d] * y[a]                                +
      cz[a,d] * sum{t in STEPS} (t/nSteps) * z[a,t] +
      cu[a,d] * u[a]                                +
      c[a,d] - withdrawal[a,d] = fPlus[a,d] - fMinus[a,d];

   con PickOneStepCon{a in ATMS}:
      sum{t in STEPS} x[a,t] = 1;

   con CashOutLinkCon{a in ATMS, d in DATES}:
      fMinus[a,d] <= withdrawal[a,d] * v[a,d];

   con CashOutLimitCon{a in ATMS}:
      sum{d in DATES} v[a,d] <= cashOutLimit[a];

   con Linear1Con{a in ATMS, t in STEPS}:
      z[a,t] <= x[a,t];

   con Linear2Con{a in ATMS}:
      sum{t in STEPS} z[a,t] = y[a];

The following statements define the block decomposition by ATM. The .block suffix expects numeric indices, whereas the set<str> ATMS statement declares a set of strings. You can create a mapping from the string identifier to a numeric identifier as follows:

   /* create numeric block index */
   num blockIndex {ATMS};
   num index init 0;
   for{a in ATMS} do;
      blockIndex[a] = index;
      index = index + 1;
   end;

Then, each constraint can be added to its associated ATM block as follows:

   /* define blocks for each ATM */
   for{a in ATMS} do;
      PickOneStepCon[a].block  = blockIndex[a];
      CashOutLimitCon[a].block = blockIndex[a];
      Linear2Con[a].block      = blockIndex[a];
      for{d in DATES} do;
         CashFlowDefCon[a,d].block = blockIndex[a];
         CashOutLinkCon[a,d].block = blockIndex[a];
      end;
      for{t in STEPS}
         Linear1Con[a,t].block = blockIndex[a];
   end;

The budget constraint links all the ATMs, and it remains in the master problem. Finally, the following statements use the Dantzig-Wolfe decomposition algorithm to solve the problem to within 1% of proven optimality:

   /* solve with the Dantzig-Wolfe decomposition algorithm */
   solve with milp / nthreads=4 relobjgap=0.01 decomp;

The solution summary is displayed in Output 18.9.1.

Output 18.9.1: Solution Summary Table

The OPTMODEL Procedure

Solution Summary
SolverMILP
AlgorithmDecomposition
Objective FunctionCashFlowDiff
Solution StatusOptimal within Relative Gap
Objective Value2467580.6742
  
Relative Gap0.0099855377
Absolute Gap24396.507699
Primal Infeasibility9.134164E-11
Bound Infeasibility2.220446E-16
Integer Infeasibility2.220446E-16
  
Best Bound2443184.1665
Nodes1
Solutions Found6
Iterations11
Presolve Time0.90
Solution Time25.20


The iteration log, which contains the problem statistics, the progress of the solution, and the optimal objective value, is shown in Output 18.9.2.

Output 18.9.2: Log

NOTE: There were 100 observations read from the data set WORK.BUDGET_DATA.                      
NOTE: There were 20 observations read from the data set WORK.CASHOUT_DATA.                      
NOTE: There were 2000 observations read from the data set WORK.POLYFIT_DATA.                    
NOTE: Problem generation will use 4 threads.                                                    
NOTE: The problem has 6480 variables (0 free, 0 fixed).                                         
NOTE: The problem has 2220 binary and 0 integer variables.                                      
NOTE: The problem has 4380 linear constraints (2340 LE, 2040 EQ, 0 GE, 0 range).                
NOTE: The problem has 58878 linear constraint coefficients.                                     
NOTE: The problem has 0 nonlinear constraints (0 LE, 0 EQ, 0 GE, 0 range).                      
NOTE: The initial MILP heuristics are applied.                                                  
NOTE: The MILP presolver value AUTOMATIC is applied.                                            
NOTE: The MILP presolver removed 562 variables and 390 constraints.                             
NOTE: The MILP presolver removed 21280 constraint coefficients.                                 
NOTE: The MILP presolver modified 0 constraint coefficients.                                    
NOTE: The presolved problem has 5918 variables, 3990 constraints, and 37598 constraint          
      coefficients.                                                                             
NOTE: The MILP solver is called.                                                                
NOTE: The Decomposition algorithm is used.                                                      
NOTE: The Decomposition algorithm is executing in single-machine mode.                          
NOTE: The DECOMP method value USER is applied.                                                  
NOTE: The problem has a decomposable structure with 20 blocks. The largest block covers 5.138%  
      of the constraints in the problem.                                                        
NOTE: The decomposition subproblems cover 5918 (100%) variables and 3890 (97.49%) constraints.  
NOTE: The deterministic parallel mode is enabled.                                               
NOTE: The Decomposition algorithm is using up to 4 threads.                                     
      Iter         Best       Master         Best       LP       IP  CPU Real                   
                  Bound    Objective      Integer      Gap      Gap Time Time                   
NOTE: Starting phase 1.                                                                         
         1       0.0000       1.1767            . 1.18e+00        .   29   10                   
         2       0.0000       0.0000            .    0.00%        .   29   10                   
         3       0.0000       0.0000            .    0.00%        .   29   10                   
NOTE: Starting phase 2.                                                                         
         .   2.4432e+06   2.5664e+06   2.5671e+06    5.04%    5.07%   31   12                   
         8   2.4432e+06   2.4764e+06   2.4808e+06    1.36%    1.54%   64   24                   
        10   2.4432e+06   2.4640e+06   2.4676e+06    0.85%    1.00%   65   25                   
NOTE: The Decomposition algorithm stopped on the integer RELOBJGAP= option.                     
        11   2.4432e+06   2.4640e+06   2.4676e+06    0.85%    1.00%   65   25                   
         Node  Active   Sols         Best         Best      Gap    CPU   Real                   
                                  Integer        Bound            Time   Time                   
            0       1      6   2.4676e+06   2.4432e+06    1.00%     65     25                   
NOTE: The Decomposition algorithm used 4 threads.                                               
NOTE: The Decomposition algorithm time is 25.20 seconds.                                        
NOTE: Optimal within relative gap.                                                              
NOTE: Objective = 2467580.6742.                                                                 


Last updated: June 22, 2026