Warning: You won't be able to copy directly from Word to Xpress (Strange, huh). So, copy from Word to the Notepad and from the Notepad to Xpress.
The Euing Model that crashes the system....
! Euing Gas from Winston
! Illustrates modeling a piecewise-linear objective function
LET NGas = 2
LET NOil = 2
LET NRange = 4
TABLES
Profit(NGas) ! $/Gal profit for each gas
MaxOil2 ! Maximum gals of Oil 2 available
MaxOil1(NRange) ! Cumulative limit for each price range in gals
PriceOil1(NRange)! $/Gal price for Oil 1 in each range
CostOil1(NRange) ! Total cost at each limit in $'s assumes cost at 0 is $0
MinOil1(NGas) ! Minumum gals of Oil 1 in each gal of each gas.
DATA
Profit(1) = .12 .14
MaxOil2 = 1000
MaxOil1(1) = 500 1000 1500 2000
PriceOil1(1) = 0 25 20 15
MinOil1(1) = 0.5 0.6
VARIABLES
Oil(NOil)! Gals of each oil used
Gas(NGas)! Gals of each gas produced
OilGas(NOil,NGas)! Gals of each oil used to make each gas
Fract(NRange)! The weight used to represent Oil1 as an average of the range maximums
InRange(NRange) ! 1 if Oil1 is in the range, 0 otherwise.
! The problem is here. Either it's the comment after the & or it's the range 2:1 when irange = 1
ASSIGN
! Calculate the cumulative cost at each maximum from the prices
CostOil1(irange=1:NRange) = &
! The first piece + sum over ranges after that of Unit price * Gals in the Range
PriceOil1(1)*MaxOil1(1) + SUM(jrange = 2:irange)PriceOil1(jrange)*(MaxOil1(jrange) - MaxOil1(jrange-1))
!CONSTRAINTS
! NetProfit: SUM(igas = 1:NGas)Profit(igas)*Gas(igas) - &The profit from sales ($'s)
! SUM(irange = 1:NRange) CostOil1(irange)*Fract(irange) $ ! The cost of the Oil 1 ($'s)
! Total gallons of oil = sum of gallons used in each gas (gallons)
! OilUses(ioil=1:NOil): SUM(igas = 1:NGas)OiilGas(ioil,igas) = Oil(ioil)
! Total gallons of Gas = sum of gallons of oils used to make it (gallons)
! GasProduction(igas = 1:NGas): SUM(ioil=1:NOil)OilGas(ioil,igas) = Gas(igas)
! Composition Constraints ensuring the appropriate gallons of oil 1 in each gas
! Composition(igas = 1:NGas): MinOil1(igas)*Gas(igas) < OilGas(1,igas)
! The "interesting stuff starts here: How to represent the piecewise linear costs of Oil 1
! Express Oil1 as a weighted average of the Maximums for each range
! Oil1Weights: Oil(1) = SUM(irange = 1:NRange) MaxOil1(irange)*Fract(irange)
! The weights used in Oil1Weights should add to one -- We have supressed the weight on 0 (the beginning of
! the first range) so the weights can add to something less than one.
! SumTo1: SUM(irange = 1:NRange) Fract(irange) < 1
! Limit the weights to two consecutive limits. We can use the weight for range irange (except the last one)
! if we are in irange or irange+1
! LimitWeights (irange = 1:NRange-1): Fract(irange) < InRange(irange) + InRange(irange+1)
! We can only use the last weight if we are in the last range
! LastLimit: Fract(NRange) < InRange(NRange)
! We can only be in one range
! OneRange: SUM(irange = 1:NRange) InRange(irange) = 1
! BOUNDS
! Oil(2) < MaxOil2 ! Gallons
! InRange(irange=1:NRange).BV. ! Binary
The Euing Model that runs, but gives the wrong answer: Fract(4) = .75 the rest of the Fract variables are 0
! Euing Gas from Winston
! Illustrates modeling a piecewise-linear objective function
LET NGas = 2
LET NOil = 2
LET NRange = 4
TABLES
Profit(NGas) ! $/Gal profit for each gas
MaxOil2 ! Maximum gals of Oil 2 available
MaxOil1(NRange) ! Cumulative limit for each price range in gals
PriceOil1(NRange)! $/Gal price for Oil 1 in each range
CostOil1(NRange) ! Total cost at each limit in $'s assumes cost at 0 is $0
MinOil1(NGas) ! Minumum gals of Oil 1 in each gal of each gas.
DATA
Profit(1) = .12 .14
MaxOil2 = 1000
MaxOil1(1) = 500 1000 1500 2000
PriceOil1(1) = 0 25 20 15
MinOil1(1) = 0.5 0.6
VARIABLES
Oil(NOil)! Gals of each oil used
Gas(NGas)! Gals of each gas produced
OilGas(NOil,NGas)! Gals of each oil used to make each gas
Fract(NRange)! The weight used to represent Oil1 as an average of the range maximums
InRange(NRange) ! 1 if Oil1 is in the range, 0 otherwise.
! We fix this and the model runs, but gives the wrong answer
ASSIGN
! Calculate the cumulative cost at each maximum from the prices
! The first piece + sum over ranges after that of Unit price * Gals in the Range
CostOil1(1) = PriceOil1(1)*MaxOil1(1)
CostOil1(irange=2:NRange) = &
PriceOil1(1)*MaxOil1(1) + SUM(jrange = 2:irange)PriceOil1(jrange)*(MaxOil1(jrange) - MaxOil1(jrange-1))
CONSTRAINTS
NetProfit: SUM(igas = 1:NGas)Profit(igas)*Gas(igas) - &The profit from sales ($'s)
SUM(irange = 1:NRange) CostOil1(irange)*Fract(irange) $ ! The cost of the Oil 1 ($'s)
! Total gallons of oil = sum of gallons used in each gas (gallons)
OilUses(ioil=1:NOil): SUM(igas = 1:NGas)OiilGas(ioil,igas) = Oil(ioil)
! Total gallons of Gas = sum of gallons of oils used to make it (gallons)
GasProduction(igas = 1:NGas): SUM(ioil=1:NOil)OilGas(ioil,igas) = Gas(igas)
! Composition Constraints ensuring the appropriate gallons of oil 1 in each gas
Composition(igas = 1:NGas): MinOil1(igas)*Gas(igas) < OilGas(1,igas)
! The "interesting stuff starts here: How to represent the piecewise linear costs of Oil 1
! Express Oil1 as a weighted average of the Maximums for each range
Oil1Weights: Oil(1) = SUM(irange = 1:NRange) MaxOil1(irange)*Fract(irange)
! The weights used in Oil1Weights should add to one -- We have supressed the weight on 0 (the beginning of
! the first range) so the weights can add to something less than one.
SumTo1: SUM(irange = 1:NRange) Fract(irange) < 1
! Limit the weights to two consecutive limits. We can use the weight for range irange (except the last one)
! if we are in irange or irange+1
LimitWeights (irange = 1:NRange-1): Fract(irange) < InRange(irange) + InRange(irange+1)
! We can only use the last weight if we are in the last range
LastLimit: Fract(NRange) < InRange(NRange)
! We can only be in one range
OneRange: SUM(irange = 1:NRange) InRange(irange) = 1
BOUNDS
Oil(2) < MaxOil2 ! Gallons
InRange(irange=1:NRange).BV. ! Binary
The Correct Euing Model
! Euing Gas from Winston
! Illustrates modeling a piecewise-linear objective function
LET NGas = 2
LET NOil = 2
LET NRange = 4
TABLES
Profit(NGas) ! $/Gal profit for each gas
MaxOil2 ! Maximum gals of Oil 2 available
MaxOil1(NRange) ! Cumulative limit for each price range in gals
PriceOil1(NRange)! $/Gal price for Oil 1 in each range
CostOil1(NRange) ! Total cost at each limit in $'s assumes cost at 0 is $0
MinOil1(NGas) ! Minumum gals of Oil 1 in each gal of each gas.
DATA
Profit(1) = .12 .14
MaxOil2 = 1000
MaxOil1(1) = 500 1000 1500 2000
PriceOil1(1) = 0 25 20 15
MinOil1(1) = 0.5 0.6
VARIABLES
Oil(NOil)! Gals of each oil used
Gas(NGas)! Gals of each gas produced
OilGas(NOil,NGas)! Gals of each oil used to make each gas
Fract0 ! The weight on 0 we ignored before
Fract(NRange)! The weight used to represent Oil1 as an average of the range maximums
InRange(NRange) ! 1 if Oil1 is in the range, 0 otherwise.
ASSIGN
! Calculate the cumulative cost at each maximum from the prices
! The first piece + sum over ranges after that of Unit price * Gals in the Range
CostOil1(1) = PriceOil1(1)*MaxOil1(1)
CostOil1(irange=2:NRange) = &
PriceOil1(1)*MaxOil1(1) + SUM(jrange = 2:irange)PriceOil1(jrange)*(MaxOil1(jrange) - MaxOil1(jrange-1))
CONSTRAINTS
NetProfit: SUM(igas = 1:NGas)Profit(igas)*Gas(igas) - &The profit from sales ($'s)
SUM(irange = 1:NRange) CostOil1(irange)*Fract(irange) $ ! The cost of the Oil 1 ($'s)
! Total gallons of oil = sum of gallons used in each gas (gallons)
OilUses(ioil=1:NOil): SUM(igas = 1:NGas)OiilGas(ioil,igas) = Oil(ioil)
! Total gallons of Gas = sum of gallons of oils used to make it (gallons)
GasProduction(igas = 1:NGas): SUM(ioil=1:NOil)OilGas(ioil,igas) = Gas(igas)
! Composition Constraints ensuring the appropriate gallons of oil 1 in each gas
Composition(igas = 1:NGas): MinOil1(igas)*Gas(igas) < OilGas(1,igas)
! The "interesting stuff starts here: How to represent the piecewise linear costs of Oil 1
! Express Oil1 as a weighted average of the Maximums for each range
Oil1Weights: Oil(1) = SUM(irange = 1:NRange) MaxOil1(irange)*Fract(irange)
! The weights used in Oil1Weights should add to one -- We have supressed the weight on 0 (the beginning of
! the first range) so the weights can add to something less than one.
SumTo1: Fract0 + SUM(irange = 1:NRange) Fract(irange) = 1
! Limit the weights to two consecutive limits. We can use the weight for range irange (except the last one)
! if we are in irange or irange+1
LimitWeights (irange = 1:NRange-1): Fract(irange) < InRange(irange) + InRange(irange+1)
! We can only use the last weight if we are in the last range
LastLimit: Fract(NRange) < InRange(NRange)
! We can only use the first weight if we are in the first range
LimitFirst: Fract0 < InRange(1)
! We can only be in one range
OneRange: SUM(irange = 1:NRange) InRange(irange) = 1
BOUNDS
Oil(2) < MaxOil2 ! Gallons
InRange(irange=1:NRange).BV. ! Binary