mathematical-optimizationlinear-programmingmoselxpress-optimizer

Xpress Mosel returning zeroes for all rows


I am an absolute beginner at Xpress Mosel and Linear Programming in general so please forgive me if I made any obvious mistakes. That being said, I am currently in the process of making up a problem and implementing it in Xpress Workbench.

The problem:

Let's say there's a scenario where a small chess manufacturer makes chess sets A and B. Chess Set A is priced at $30 while Chess Set B is priced at $40. The chess set manufacturer has received orders from 10 retailers who want to buy both chess sets, with each retailer incurring different amounts of shipping costs for each chess set sold. If the chess set manufacturer can only sell a minimum of 100 chess sets and a maximum of 300 chess sets to each retailer , how many of each chess set should the chess manufacturer sell to each retailer to maximize profits?

If I'm not mistaken, the objective function would be:

Profit = (30 * x1 - s * x1) + (40 * x2 - s * x2)

where x1 is the number of Chess Sets A, X2 is the number of Chess Sets B and s is shipping costs.

Constraints are:

x1, x2 <= 300

x1, x2 >= 100

x1, x2 >= 0

The shipping costs for each retailer is:

Shipping Costs

My attempt at implementing this problem in Mosel is shown in the following code.

model "CHESS PROBLEM"
uses "mmxprs"

declarations
  SCN = 1..10
  PROFITOFCHESSA : integer
  PROFITOFCHESSB : integer
  UPPERLIMIT = 300
  LOWERLIMIT = 100
  CHESSA: array(SCN) of mpvar
  CHESSB: array(SCN) of mpvar
  S_COSTS: array(SCN) of real
end-declarations

initializations from "C:/Users/Admin/Downloads/Chess2.dat"
  S_COSTS
end-initializations

profit:= sum(A in SCN) ((CHESSA(A) * PROFITOFCHESSA + CHESSB(A) * PROFITOFCHESSB) - (CHESSA(A) * S_COSTS(A) +CHESSB(A) * S_COSTS(A)))

  forall(A in SCN) (CHESSA(A)) <= UPPERLIMIT
  forall(A in SCN) (CHESSA(A)) >= LOWERLIMIT
  forall(A in SCN) (CHESSB(A)) <= UPPERLIMIT
  forall(A in SCN) (CHESSB(A)) >= LOWERLIMIT
  forall(A in SCN) (CHESSA(A)) >= 0
  forall(A in SCN) (CHESSB(A)) >= 0

 maximize(profit)
 writeln("Solution:\Objective: ", getobjval)
 forall(A in SCN) writeln("Number of Chess Sets A to be sold to Retailer (" + A + ") is: ", getsol(CHESSA(A)))
 forall(A in SCN) writeln("Number of Chess Sets B to be sold to Retailer (" + A + ") is: ", getsol(CHESSB(A)))

end-model

Where CHESSA and CHESSB are the number of chess sets to be sold, PROFITOFCHESSA and PROFITOFCHESSB are the profits for selling each chess set and S_COSTS is shipping costs.

Running this problem however returned zeroes for all retailers. I'd very much appreciate some feedback on what it is that I'm doing wrong here.


Solution

  • There are two issues with your model:

    First, you don't initialize PROFITOFCHESSA or PROFITOFCHESSB. So they will both be 0, i.e., no profit is gained from producing any models. Even worse, for each model produced you have to pay the shipping cost. Since the goal is to maximize the profit, the solver will choose to produce as few models as possible. The minimum number of models to produce is 100 for each retailer (as by your constraint). So the solver goes with this minimal amount for each retailer.

    The second problem is that your model is a bit too simplistic: For each piece you produce, you get some profit and pay some shipping cost. If the profit is bigger than the shipping cost then the best solution is to produce as many items as possible (in your case 300 per retailer). If the profit is smaller than the shipping cost then the best solution is to produce as few items as possible (in your 100 per retailer). So there is not much to optimize here.