!"Network" revenue management.
We have a set of resources we can sell to customers.
Customers buy our resources in "packages". A package
is a combination of one or more resources.
In airlines, a package is a set of one or more flights that get a customer
from his origin to his destination.
  In a hotel setting, a package is a set of one or more nights in a room
needed for a vacation or a meeting of some sort.
  In a rental car setting, a package is a set of one or more days of use
of a car.
  In a course registration system, a package is a set of (non-conflicting)courses
a student  would like to take.
In practice, a problem like the following is solved every day with updated data on the 
   a) units still available of each resource,
   b) forecasts of remaining demand of each type.
In many situations it makes sense to base acceptance or rejection on
the shadow prices of the scarce resources. This is call bid price control;

! References:
    Talluri, K., and G. van Ryzin(2005), 
"Theory and Practice of Revenue Management", Springer.
    Graves, R. J. Sankaran, and L. Schrage(1993) 
"An Auction Method for Course Registration", Interfaces, vol 23. no. 5, pp. 81-95;

! Keywords: Network Revenue Management, Revenue Management, Airline, Hotel,
  Bid price control, Course registration;
SETS:
 RESOURCE: CAP;
 PACKAGE: REV, DEM, SELL, LOLIM;
 PXR( PACKAGE, RESOURCE);
ENDSETS
DATA: ! A set of flights involving Gainesville, Atlanta, Chicago, New York. The network looks like this; ! C / / ! G-->A \ \ N ; ! The legs; RESOURCE = GA AC AN; ! The legs; CAP = 110 130 111; ! and their current capacities; ! The trips customers would like to take; PACKAGE = GA1 GA2 GC1 GC2 GN1 GN2 AC1 AC2 AN1 AN2; ! and revenued from each; REV = 190 90 264 229 261 219 140 95 186 103; ! The current forecasts of remaining demands; DEM = 49 90 24 43 12 67 44 69 16 17; ! Lower limit on sales we may arbitrarily require; LOLIM= 0 0 0 0 0 0 0 0 0 0; ! A plausible solution is to first try to satisfy all the Type 1 demand, i.e., first satisfy the GA1, GC1, GN1, AC1, etc. demands. This leads to a total revenue of 41,030. Can we do better? ; ! This LOLIM forces us to serve class 1 demand first; ! LOLIM= 49 0 24 0 12 0 44 0 16 0; ! Which legs each trip uses (1 of each); PXR = GA1 GA GA2 GA GC1 GA GC1 AC GC2 GA GC2 AC GN1 GA GN1 AN GN2 GA GN2 AN AC1 AC AC2 AC AN1 AN AN2 AN; ENDDATA SUBMODEL GETPRICES: ! Maximize total expected revenue; MAX = TOTEREV; TOTEREV = @SUM( PACKAGE( p): REV(p)*SELL(p)); ! Cannot sell more than demand; @FOR( PACKAGE( p): [DEMC] SELL( p) <= DEM( p); ! Must sell min quantity if specified; [DEMLO] SELL( p) >= LOLIM( p); ); ! Cannot use more of a resource than available, summing over all packages that use resource r; @FOR( RESOURCE( r): [RESC] @SUM( PXR( p,r): SELL( p)) <= CAP ( r); ); ENDSUBMODEL
CALC: @SET( 'DUALCO', 1); ! Make sure dual computations are (0:off, 1:On); @SOLVE( GETPRICES); @WRITE(' Total expected revenue= ', @FORMAT( TOTEREV,'10.2f'), @NEWLINE(1)); @WRITE(' Resource Shadow price', @NEWLINE(1)); @FOR( RESOURCE( r): @WRITE( @FORMAT( RESOURCE(r), '10s'), @FORMAT( @DUAL( RESC( r)), '11.2f'), @NEWLINE(1)); ); @WRITE( @NEWLINE(1),' Package Opportunity cost Sell Demand', @NEWLINE(1)); @FOR( PACKAGE( p): OC = @SUM( PXR( p, r): @DUAL( RESC(r))) - REV( p); @WRITE( @FORMAT( PACKAGE( p), '10s'), @FORMAT( OC, '12.2f'), @FORMAT( SELL( p), '12.1f'), @FORMAT( DEM( p), '10.1f'), @NEWLINE(1)); ); ENDCALC