I am trying to solve the exercises from AMPL: A Modeling Language for Math Programming Package, but I am stuck on Exercise 1-4(e). My code so far looks like this:
.mod-file:
# Set of cars we can produce
set CAR;
# Parameters
param amount {CAR} > 0; # Amount of cars produced (for each car in CAR)
param time {CAR} > 0; # Time it takes to produce (for each car in CAR) in hours
param fac_time > 0; # Factory-time to use next week
param profit {CAR} > 0; # Profit (for each car in CAR)
param lower {CAR} >= 0; # Lower limit of amount of cars to be produced (for each car in CAR)
# Define var
var Make {c in CAR} >= lower[c];
# Obj. function
maximize Total_Cars: sum {c in CAR} Make[c];
# Constraits
s.t. Time: sum {c in CAR} time[c] * Make[c] = fac_time;
.dat-file:
set CAR := T C L;
param: time profit lower :=
T 1 200 10
C 2 500 20
L 3 700 15 ;
param fac_time := 120;
The task:
Each kind of car achieves a certain fuel efficiency, and the manufacturer is required by law to maintain a certain ‘‘fleet average’’ efficiency. The fleet average is computed by multiplying the efficiency of each kind of car times the number of that kind produced, summing all of the resulting products, and dividing by the total of all cars produced. Extend your AMPL model to contain a minimum fleet average efficiency constraint. Rearrange the constraint as necessary to make it linear — no variables divided into other variables.
So I changed my code to this:
.mod-file:
# Set of cars we can produce
set CAR;
# Parameters
param amount {CAR} > 0; # Amount of cars produced (for each car in CAR)
param time {CAR} > 0; # Time it takes to produce (for each car in CAR) in hours
param fac_time > 0; # Factory-time to use next week
param profit {CAR} > 0; # Profit (for each car in CAR)
param lower {CAR} >= 0; # Lower limit of amount of cars to be produced (for each car in CAR)
param fuel_eff {CAR} > 0; # Fuel efficiency (for each car in CAR)
param fleet_avg > 0; # Fleet average efficiency
# Define var
var Make {c in CAR} >= lower[c];
# Obj. function
maximize Total_Cars: sum {c in CAR} Make[c];
# Constraits
s.t. Time: sum {c in CAR} time[c] * Make[c] = fac_time;
s.t. Efficiency: **HERE** >= fleet_avg;
.dat-file:
set CAR := T C L;
param: time profit lower fuel_eff:=
T 1 200 10
C 2 500 20
L 3 700 15 ;
param fac_time := 120;
param fleet_eff := (sum {c in CAR} amount[c] * fuel_eff[c])/Total_Cars;
I do not have access to the solutions so my question here is: What should be written inside the constraint for efficiency? Have I defined the parameter fleet_avg
correctly? If not, what is the proper way to solve this?
You are on the right track.
Your efficiency constraint is mathematically correct. You don't say so in the problem, but I think it is assumed that Total Cars
is a variable, just the sum of Make[c]
, correct?
So what's the problem then?
Well you have just made your linear program non-linear by dividing by total cars because you have a variable divided by another variable in that fraction. (Aside: remember we are only talking about "linear" in terms of the variables so we want to avoid dividing, multiply variables with each other... parameters are fixed and are fair game).
So what's the fix?
They hint at this in the text by reminding you not to do what you just did above. Realize that with a little algebra, we can multiply both sides of that equation by Total Cars
(or more accurately sum(Make[c])
to get rid of the division... So I would expect something like this (in pseudocode):
sum(Make[c]) * fleet_efficiency >= sum(Make[c] * fuel_eff[c])
Which is linear in terms of the variables.