I developed an LP model where it allocates the number of cassava crackers to the declared number of stores depending on their minimum demand.

I have a concern because when I ran the code in AMPL, there's a negative value and I don't want to have negative values on the result.

Result after running the MOD FILE

ampl: include please.run;
CPLEX optimal solution; objective 606000
0 dual simplex iterations (0 in phase I)
X :=
1 1   40
1 2   80
2 1   60
2 2   30
3 1   60
3 2   40

Y :=
1 1 1    20
1 1 2    20
1 1 3     0
1 2 1    80
1 2 2     0
1 2 3     0
2 1 1    60
2 1 2     0
2 1 3     0
2 2 1   -10
2 2 2     0
2 2 3    40
3 1 1    20
3 1 2     0
3 1 3    40
3 2 1    20
3 2 2    20
3 2 3     0


param m; #cassava cracker types
param n; #periods
param o; #process
param r; #machines
param w; #store branches

set I := 1..m; #index of cassava crackers types
set J := 1..n; #index of periods
set K := 1..o; #index of process
set L := 1..r; #index of machines
set S := 1..w; #index of store branches

param Production_Cost {i in I, j in J}; #production cost of cassava crackers i per pack in period j
param Cassava_Produce {i in I, j in J}; #kg of cassava needed to produce crackers
param Cassava_Avail {j in J}; #availability of cassava in period j (kg) 
param Process_Time {k in K}; #process time k
param Man_HoursAvail {k in K, j in J}; #availability of man hours for process k in period j (hour)
param Machine_Processing {l in L}; #processing time of machine l
param Machine_HoursAvail {l in L, j in J}; #availablity of machine hours l in period j
param Lowest_Sales {i in I, j in J}; #lowest sales of cassava crackers i in period j
param Highest_Sales {i in I, j in J}; #highest sales of cassava crackers i in period j
param Min_Demand {s in S}; # minimum demand of store branch s

#Decision Variable
var X {i in I, j in J};
var Y {i in I, j in J, s in S};

#Objective Function
minimize Cost: sum {i in I, j in J} Production_Cost[i,j]*X[i,j];

s.t. Raw_Material {j in J}: sum {i in I} Cassava_Produce[i,j]*X[i,j] <= Cassava_Avail[j];
s.t. Man_Hours {k in K, j in J}: sum {i in I} Process_Time[k]*X[i,j] <= Man_HoursAvail[k,j];
s.t. Machine_Hours {l in L, j in J}: sum {i in I} Machine_Processing[l]*X[i,j] <= Machine_HoursAvail[l,j];
s.t. Product_Sale {i in I, j in J}: Lowest_Sales[i,j] <= X[i,j] <= Highest_Sales[i,j];
s.t. Nonnegative {i in I, j in J}: X[i,j] >= 0;

s.t. C1 {i in I, j in J}: sum {s in S} Y[i,j,s] = X[i,j];
s.t. C2 {j in J, s in S}: sum {i in I} Y[i,j,s] >= Min_Demand[s];
  • $\begingroup$ If you could provide a mathematical formulation instead of copying the code separately, will give you more chances to answer your question. :) $\endgroup$
    – A.Omidi
    Dec 6 '21 at 8:18
  • 3
    $\begingroup$ var Y {i in I, j in J, s in S} >= 0; $\endgroup$ Dec 6 '21 at 11:51

You are not bounding $Y_{i,j,s}$ from below and hence have to add a nonnegativity constraint similar to the one for $X_{i,j}$.

As long as $ \sum_{s \in S} Y_{i,j,s} $ is larger or equal to zero (ensured by C1), everything will work fine. However the individual values of $Y_{i,j,s}$ can take values smaller than zero.

Minimum working example: Lets assume that you have 5 $Y$ variables for a given $s$ and a minimum demand of $s$ of 100. By assumption one of the $Y$ variables takes a value of -100. As long as the remaining four values sum up to at least 200, no constraint will be violated.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.