! Consumer Choice and Assortment model,  (ProdPortStrict.lng)
  with consumer strict preference order. Choose a product
  portfolio, taking into account consumer preferences.
1) Consumer Choice portion of model:
 Each market segment i has preference
 RP(i,j), for buying product type j. Consumer
 i buys that product j for which: j is offered,
 and i's preference for j is higher than for
 any other offered product, and RP(i,j) > 0.
2) Assortment portion of model:
 Given the set of all possible products a vendor might
 carry, what subset should be carried, taking into account
 the consumer's preferences?
 It costs money to introduce lots of products, so we
 want to offer a product only if profitable to do so.
 Each segment i has a size, NUM(i), the total unit sales 
 to that segment if it buys.
 Specifically, if the vendor carries only product j,
 then the unit sales to segment i will be
    NUM(i) if RP(i,j) > 0, else 0;
! This model takes into account that adding more products may
    help by capturing demand otherwise going to a competitor, but may
    hurt by "cannibalizing" sales of one of our more profitable products;
! Keywords: Consumer Choice, Marketing, Demand Substitution, Assortment Planning,
     Preference ordering;
SETS:
  SEG: NUM;            ! Market segments;
  PROD: PC, FXC, Y, VOL;  ! Products possible;
  SXP( SEG, PROD): RP, ZPR;! Combinations;
  ENDSETS
DATA: SEG = 1..8; ! The market segments; ! and their sizes; NUM = 19 13 24 39 11 12 14 19; PROD = A B C D E F; ! The products; ! Profit contribution per unit each product; PC = 16 16 15 18 14 19; ! Fixed cost of introducing each product; FXC = 10 10 10 10 10 10; ! Relative preference of customer segment i for product j. Bigger => more preferred. A 0 means will not buy, e.g., prefers competitor; RP = 5 2 4 3 9 0 ! Segment 1; 0 0 9 0 4 0 0 5 9 0 0 0 3 4 0 0 9 0 ! Segment 4; 0 0 0 9 0 6 9 0 5 2 0 3 0 6 0 0 4 0 9 0 0 0 0 0;! Segment 8; NPT = 4; ! We want to carry at most NPT products; ENDDATA SUBMODEL CHUZPRODS: ! Parameters: NUM(i) = number people in segment i, PC(j) = profit contribution per unit of product j sold, FXC(j) = fixed cost of introducing product j, RP(i,j) = relative attractiveness to segment i of product j, NPT = number products that can be carried. Variables: Y(j) = 1 if we carry product j, else 0, VOL(j) = volume, or units, sold of product j, ZPR(i,j) = 1 if segment i buys product j (and j only) ! Model Seller behavior; ! Maximize profit contribution from sales minus fixed cost of introducing the products; MAX = OBJ1; OBJ1 = @SUM( PROD(j): PC(j)*VOL(j) - FXC(j)*Y(j)); ! Y(j) = 1 if we introduce product j, else 0; @FOR( PROD(j): @BIN(Y(j))); ! Volume sold of product j; @FOR( PROD(j): VOL(j) = @SUM( SEG(i): NUM(i)*ZPR(i,j)); ); ! Limit on products carried; @SUM( PROD(j): Y(j)) <= NPT; ! Modeling customer behavior; @FOR( SXP(i,j): ! If product j is available, then customer i will not buy any product k that is less preferable than j. Customer i buys at most one product; @SUM( PROD( k) | RP(i,k) #LT# RP(i,j): ZPR(i,k)) <= 1 - Y(j); ! If customer segment i buys product j, then j must be available; ZPR(i,j) <= Y( j); @BIN( ZPR(i,j)); ! Must be 0 or 1; ); ! Cannot sell customer i a product not liked; @FOR( SEG(i): @SUM( SXP(i,j) | RP(i,j) #EQ# 0: ZPR(i,j)) = 0; ); ENDSUBMODEL
CALC: @SET( 'TERSEO',3); ! Output level (0:verb,1:terse,2:errors,3:none); @SOLVE( CHUZPRODS); @WRITE(' Choosing which products to offer, given consumer preferences.', @NEWLINE(1)); @WRITE(' Profit contribution', @NEWLINE(1)); @WRITE(' Product', @NEWLINE(1), 'Segment'); @FOR( PROD(j): @WRITE( @FORMAT( PROD(j), '9s')); ); @WRITE( @NEWLINE(1)); @FOR( SEG( i): @WRITE( @FORMAT( SEG(i), '6s'),':'); @FOR( PROD( j): @IFC( ZPR( i,j) #GT# 0.5: @WRITE( ' ',@FORMAT( PC( j)*NUM(i),'8.0f')); @ELSE @WRITE( ' '); ); ); @WRITE( @NEWLINE(1)); ); @WRITE(' Total fixed cost= ', @FORMAT( @SUM( PROD(j): FXC(j)*Y(j)),'8.0f'), @NEWLINE(1)); @WRITE(' Net total profit contribution=', @FORMAT( OBJ1, '8.0f'), @NEWLINE(1)); ENDCALC