Anaplan Optimizer - Balanced Allocation
Hello everyone,
Really hoping one of you bright-minded individuals can help me progress on a persistent issue.
I am essentially doing a replica of the "T1.3 Allocation with Product & Line Compatibility" from the Optimizer Toolbox:
But! My objective is not to minimize cost. Instead I have a guideline allocation of the orders between the lines. So for each of the products I have target values for each of the lines in terms of how many they should have and the objective to minimize the deviation between the actual allocation of orders and the guideline regardless of whether it is above or below (as long as their total capacity is not exceeded of course).
Been working on some testing and also asked ChatGPT for advice, but keep hitting dead ends on this as I can not ensure linearity in my setup according to Optimizer. It does work in Excel using Simplex LP engine though? Have enclosed an example of the Excel setup that works. Problem in Optimizer seems to be these two constraints:
Variable Positive Deviation >= Auxiliary Positive Deviation
Variable Negative Deviation >= Auxiliary Negative Deviation
When trying to solve through Optimizer on the same setup as in Excel I get this error:
"The Constraint is invalid. It should be of the form Ax >= B, not Ax >= Bx.
Change your formula so that only one side of the Constraint is dependent on variables."
In case I change the constraints to
Variable Positive Deviation - Auxiliary Positive Deviation >= 0
Variable Negative Deviation - Auxiliary Negative Deviation >= 0
Then the error is on the Auxiliary calculations:
"There is an invalid term for Constraint 'A1 PosDev'.
Each Term must either be a Variable or a multiplication.
There is an invalid term for Constraint 'A2 NegDev'.
Each Term must either be a Variable or a multiplication."
Example images from one of the tests in Anaplan:
Best Answers
-
From the Module.png screenshot of the line item formulas, I see that A1 and A2 are functions of V0.
A1: V0 - Guideline
A2: Guideline - V0
So, your constraint C5 & C7 essentialy have the form"
C5: V1 - (V0 - Guideline) >= 0
C7: V1 - (Guideline - V0) >= 0
That's not allowed. The left side of the equation must only take the form a*V0 + b*V1 + c*V2 … and the right side of the equation must be a constant (not a function of any variables).
You may, restate the constraints as:
C5: V1 - V0 >= Guideline
C7: V1 + V0 >= - Guideline2 -
Hi Sir Valdemar. Once you have the syntax working, here are some suggestions for minimizing the variance to target. It may be similar to your setup:
V0 Allocation (what is allocated)
V1 PosDev — in the action, set the minimum as zero
V2 NegDev — in the action, set the maximum as zero
V3 Deviation — new variable, no min/max
- Constraint 1: V0 = Target Allocation - V3, or in Optimizer syntax: V3 + V0 = Target Allocation
- Constraint 2: V3 = V1 + V2, or in Optimizer syntax: V3 - V1 - V2 = 0
- Objective is to minimize (V1 - V2)
Explanation:
Constraint 1:
Let's say your target is 100 units, and you allocated 80. V0 = 80, and V0 + V3 (the deviation ) must sum up to 100. So 80 (V0) + 20 (V3) = 100 (Target)
Constraint 2:
V3 = 20. We want to put the positive value into V1, and negative into V2
V3 - V1 - V2 = 0, or 20 - V1 - V2 = 0. Since V2 values cannot be positive, the only way to get to zero is to have V1 = V3 = 20. 20 - 20 = 0
Optimizer can try to game this here by saying, 'well, why not 20 – 25 - (-5) = 0"
To guide the right behavior, the objective function to minimize V1 - V2 means to get the lowest value, we want V1 and V2 to be as close to zero as possible.
Having said that . . .
Another simpler way would be to take your Guide inputs % and turn them into hard min/max constraints. (This won't literally minimize the variance like above, but allows your users flexibility to adjust range tolerances with each subsequent run. This will free your objective function to be do something else other than minimize variance.)
For example, Order 1 should ideally be allocated to INT A, INT B, and INC at 31%, 38%, and 31% respectively.
So for OrderA, 374, you want to allocate 115.94 to INT A, 142.12 to INT B, and 115.94 to INT C. If your products are integers, then you don't want Optimizer to suggest decimal remainders in the allocation.
So, you can introduce a user tolerance input, say 10%. This means you would allow allocations up to +/- 10% of the target, and could also set them uniquely, let's say, -15% / + 5%
From your percentages, the INT A minimum should be 85% of the 115.94 target, or 98.55. This is the lowest you would allocate, so if your allocation is an INT, it is effectively 99. The max is 105% of 115.94, or 121.737. This gets rounded down to 121 since 122 would exceed the max.
The min/max bounds can be defined via formulas as input values, which simplifies the constraints to:
V0 >= INPUT1 Minimum Allocation
V0 <= INPUT2 Maximum Allocation
Then the user can adjust the min/max allowances to come up with a desirable allocation. If the tolerances are too strict, you will get an infeasibility error. This can be caught with an additional variable defined as "variance to min/max" which bridges the gap between the best solution and the variance to the upper or lower bound value. (Then you add a term in your objective function to penalize this situation.)
Hope these ideas help! There are lots of correct and fun ways to define problems, so hope you find one that works best for your situation!
2
Answers
-
Thank you @samaplan @hendersonmj - really really appreciate it!! :-)
I think I did myself a disservice by testing, and locking my mindset, on the solution in Excel first as the Solver Simplex LP engine accepts a different logic than the Optimizer. And thank you @samaplan for the elaborate response with suggestions on model improvements, excellent ideas that I will definitely try out.1