! Yield or revenue management model(yieldman.lng);
!  Basic problem: Given a) set of limited resources,
e.g., seats on airplane flights, hotel rooms, rental cars
over several days, and b) different types of customers
needing different combinations of our resources,
and c) each customer type having an amount they
are willing to pay for their needed combination,
what volumes should we sell of each product bundle
to each customer class?
  In practice, the dual or shadow prices on the
limited resources in the solution may be as useful
as the allocations to customers.  The prices can
be used to "price out" a new customer request for
a particular combination of resources to
decide if it is attractive relative to other 
opportunities to sell or rent our resources.
  Specific example: Consider an airline having a
set of three flights, A to C, B to C, and C to D 
to serve four cities, A, B, C, and D, in the network:
           A
             \
              C - D
             /
           B 
The airline uses a two-fare pricing structure. 
The decision of how many seats or capacity to 
allocate to each price class is sometimes called 
yield or revenue management. 
 The respective flight capacities are 100, 110, and 120.
How many seats should be allocated to each class on 
each of the three flights to each of the 5 itineraries?
 In the data below, for a given itinerary, a first
class customer always gives more revenue than a
second class customer. Thus, a plausible rule
would be to first satisfy first class as much as
possible, and then fill any remaining seats with 
second class.
Will this lead to the most profitable solution?																																																																																																																																																																																																																																																																																																																																																																																														;

! Keywords: Yield management, Revenue management, Airlines,
            Pricing, Marketing;
SETS:
 ! Identify the primitive and derived entities & attributes;
  ITNRY; ! Itineraries;
  CLASS; ! Customer price classes;
  LEG: TCAP; ! Legs and their capacities;
  IXL( ITNRY, LEG); !Itnry/Leg combos;
     ! Demands, Reservation prices, allocations;
  CXI( CLASS, ITNRY): DEM, RP, X; 
ENDSETS
DATA: LEG = AC BC CD; ! The legs in network, or objects to sell; TCAP = 100 110 120; ! Capacity or availability of each leg/object; CLASS = ONE TWO; ! The classes; ITNRY = IAC IBC IAD IBD ICD; ! The itineraries or bundles of objects; RP = 140 186 244 272 165 ! and the reservation ; 80 103 193 199 90; ! prices of 2 classes; DEM = 11 16 24 12 47 ! Max # people willing to buy an; 49 17 53 67 56; ! itinerary/bundle at that price. ! The (Itinerary, leg) combinations; IXL= IAC, AC IBC, BC IAD, AC IAD, CD IBD, BC IBD, CD ICD, CD ; ENDDATA SUBMODEL HOLDBACK: ! Variables: X(c,i) = how much we decide to sell to customer class c of itinerary/product bundle i. ; ! Maximize revenues over all classes and itineraries; MAX = OBJ; OBJ = @SUM( CXI(c,i): RP(c,i)*X(c,i)); ! Cannot sell more to class c, itinerary i than demand; @FOR( CXI(c,i): [IDEM] X(c,i) <= DEM(c,i); ); ! Cannot sell more of a Leg/object j than is available. The dual prices on these constraints can be used to check whether a particular offer to pay from a new customer is attractive. For each leg j, sum over itineraries/bundles i and classes c that use this leg ; @FOR( LEG(j): [LCAP] @SUM( IXL(i,j): @SUM(CLASS(c): X(c,i))) <= TCAP(j); ); ENDSUBMODEL
CALC: @SET( 'DUALCO', 1); ! Set dual computations (0:off, 1:On); @SOLVE( HOLDBACK); @WRITE(' Class Bundle Units_to_Sell Revenue', @NEWLINE(1)); @FOR( CXI(c,i): @WRITE( ' ',CLASS( c), ' ', ITNRY(i), ' ', @FORMAT(X(c,i),'10.0f'), ' ',@FORMAT(X(c,i)*RP(c,i),'12.2f'),@NEWLINE(1)); ); @WRITE(' Total expected revenue= ', @FORMAT(OBJ,'12.2f'), @NEWLINE(1)); @WRITE( @NEWLINE(1)); @WRITE(' Resource ShadowPrice', @NEWLINE(1)); @FOR( LEG(j): DP = @DUAL( LCAP(j)); @WRITE( ' ', LEG(j),' ', DP, @NEWLINE(1)); ); ENDCALC