Lindo Systems

MODEL:
 ! Product bundle pricing (PriceProdSimp);
 ! Producer wants to choose a price for each of a number of
   products, based on knowledge of the "willingness
   to pay" (Reservation price) of various market segments
   for each of the products. The producer wants to choose
   prices so as to maximize revenue minus costs.
   You can think of a product as a bundle of features.
   If the price of a product/bundle is > than a customer's 
   reservation price, then the customer will not buy that product.
     Each customer, i,  will buy the one product/bundle, j,
   that maximizes his consumer surplus 
     ( = reservation_price(i,j) minus price i must pay for j.)
     Each customer/market segment is described by:
       Its size,
       Reservation price for each product;


! Keywords: Bundling, Consumer Choice, Equilibrium, Pricing, 
  Product Management, Marketing, Uncertainty;
SETS:
 CUST: 
     SIZE, ! Each cust/market has a size;
     DISC, ! Discount off list price willing to give to I;
     DISD, ! Discount given to dealer(who sells full price); 
       FM, ! Fixed cost of developing market I;
       YM, ! = 1 if we develop market I, else 0;
      SRP; ! Consumer surplus achieved by customer I;
 BUNDLE:
     COST, ! Each product/bundle has a cost/unit to producer;
       FP, ! Fixed cost of developing product J;
       YP, ! = 1 if we develop product J, else 0;
    PRICE, ! List price of product J;
     PMAX; ! Max price that might be charged;

 CXB( CUST, BUNDLE): 
       RP, ! Reservation price of customer I for product J;
      EFP, ! Effective price I pays for J, = 0 if not bought;
        X; ! = 1 if I buys J, else 0; 
ENDSETS

DATA: 
   CUST = HOME    STUD    LEGL   BUSN; ! Customer/market segments;
   SIZE = 5900    3000    2000   3100; ! Customer/market segment sizes;
! Fixed market development costs;
    FM =    0      0        0     0;
! Discount off list price to each customer, 0 <= DISC < 1.
  Assumes grey marketers will not buy in cheaper market and
  sell in more expensive market;
  DISC =      0     0       0     0;
! Discount/tax off list to each dealer,  0 <= DISD < 1;
  DISD =     0      0       0     0;
! We sell three basic products: Spreadsheet, Wordprocessor, Presenter software,
   as well as all combinations of the three features;
  BUNDLE =   BS    BW    BP   BSW   BSP   BWP  BSWP; ! Products/bundles of products;
! Reservation/max_willing_to_pay prices of markets for products;
     RP =   190    90    50   280   240   140   330  ! Home;
            160   180    70   340   230   250   410  ! Student;
             50   250    85   300   135   335   385  ! Legal;
            300   100   120   400   420   220   520; ! General Business;
! Variable costs of each product;
   COST =   100    20    30   120   130    50   150;

! Fixed product development costs;
     FP =   0       0    0     0     0     0    0;
ENDDATA
!--------------------------------------------------------;

SUBMODEL BUNPRICE:
! Variables:
   X(i,j) = 1 if market segment i buys bundle j.
   YM( i) = 1 if market segment i buys a bundle (we market to segment i);

! The seller wants to maximize the profit contribution;
  [PROFIT] MAX = OBJ;
    OBJ =
    @SUM( CXB( I, J):
      SIZE( I) * EFP( I, J)              ! +Revenue;
      - COST( J)* SIZE( I) * X( I, J)    ! -Variable cost;
      - EFP( I, J) * SIZE( I) * DISD( I))! -Discount to dealers;
      - @SUM( BUNDLE: FP * YP)           ! -development cost; 
      - @SUM( CUST: FM * YM);            ! -Market development cost;

! Each customer can buy at most 1 bundle;
 @FOR( CUST( I):
    @SUM( BUNDLE( J) : X( I, J)) <= YM( I);
    @BIN( YM( I)); ! Must be 0 or 1;
  );

! Force development costs for j to be incurred
   if we sell it to any customer i;
   @FOR( CXB( I, J):   
      X( I, J) <= YP( J);    ! for product J;
!  The X's are binary, yes/no, 1/0 variables;
      @BIN( X( I, J));
     );
	
! Compute consumer surplus for customer I;
   @FOR( CUST( I):
       SRP( I) = @SUM( BUNDLE( J): RP( I, J) * X( I, J) - EFP( I, J));
! Customer chooses maximum consumer surplus;
     @FOR( BUNDLE( J):
        SRP( I) >= RP( I, J) - ( 1 - DISC( I)) * PRICE( J)
         );
       );
! Force effective price to take on proper value;
   @FOR( CXB( I, J):
!  zero if I does not buy J, at most reservation price;
    EFP( I, J) <= X( I, J) * RP( I, J);
!  cannot be greater than published price less discount;
    EFP( I, J) <= ( 1 - DISC( I)) * PRICE( J);
!  cannot be less than published price if bought less discount;
    EFP( I, J) >= ( 1 - DISC( I))* PRICE( J)
                   - ( 1 - X( I, J))* PMAX( J);
       );

! Compute upper bounds on prices;
 @FOR( BUNDLE( J): 
     PMAX( J) = @MAX( CUST( I): RP( I, J)/(1 - DISC( I)));
     );
ENDSUBMODEL

CALC:
  @SOLVE( BUNPRICE);
  
  @WRITE(@NEWLINE(1),' Max profit for vendor= ', OBJ, @NEWLINE(1)); 
  @WRITE(@NEWLINE(1),' Profit maximizing price for each bundle:',@NEWLINE(1));
  @WRITE('      ');
  @FOR( BUNDLE( j):
    @WRITE( @FORMAT( BUNDLE( j),'6s'));
     );
  @WRITE(@NEWLINE(1));
  @WRITE('      ');
  @FOR( BUNDLE( j):
    @WRITE( @FORMAT( PRICE( j),'6.0f'));
     );
  @WRITE(@NEWLINE(1));
  @WRITE(@NEWLINE(1),' Purchase matrix:',@NEWLINE(1));
  @WRITE('      ');
  @FOR( BUNDLE( j):
    @WRITE( @FORMAT( BUNDLE( j),'6s'));
     );
  @WRITE(@NEWLINE(1));
  @FOR( CUST(i):
    @WRITE( @FORMAT(CUST(i),'6s'));
    @FOR( BUNDLE( j):
      @IFC( X(i,j) #GT# 0.5:
          @WRITE('    1 ');
         @ELSE
          @WRITE('      ');
          );
        );
  @WRITE(@NEWLINE(1));
      );

  @WRITE(@NEWLINE(1));
  @WRITE(@NEWLINE(1),' Consumer surplus, Market segment vs. Product/Bundle:',@NEWLINE(1));
  @WRITE('      ');
  @FOR( BUNDLE( j):
    @WRITE( @FORMAT( BUNDLE( j),'6s'));
     );
  @WRITE(@NEWLINE(1));
  @FOR( CUST(i):
    @WRITE( @FORMAT(CUST(i),'6s'));
    @FOR( BUNDLE( j):
       @WRITE( @FORMAT( RP(i,j) - PRICE( j),'6.0f'));
        );
  @WRITE(@NEWLINE(1));
      );
ENDCALC
END