!Two vendors each offer their own price discount schedule.	    (QdiscSupL.lng)
How much should we buy from each to minimize total cost?	
Vendor A gives discounts on all units.  
Vendor B gives discounts only on incremental units past breakpoint;	
!Keywords: Discount, Linearization, Non-convex Function, Purchasing, Quantity discount, Vendor selection;
SETS:
  POINT: AELVL, ARATE, AIQ, AICOST, ZA, 
         BELVL, BRATE, BIQ, BICOST, ZB, BIPRVCOST ;
ENDSETS
DATA: QNEED = 6000; ! Amount we need to buy; ! Entry level for each interval, and rate for the interval; AELVL, ARATE= 0 9 1000 8 2500 7 7500 5 15000 3 20000 99999; !<<==Max possible; BELVL, BRATE= 0 8 1200 7 3000 6 7500 4 14000 2 20000 99999; !<<==Max possible; ENDDATA ! Minimize the total cost from vendors A & B; MIN = TOTCOST; TOTCOST = ATCOST + BTCOST; ! Quantity from A and B must be >= amount we need; ATQ + BTQ >= QNEED; ! Model of Vendor A discount schedule (All Units); @FOR( POINT( i) | i #LT# @SIZE( POINT): @BIN( ZA( i)); ! Either use (1) or not use (0) this interval; ! AIQ( i) = amount purchased from A if in interval i, else 0; ! AIQ( i) must be large enough for this interval; AIQ( i) >= AELVL( i) * ZA( i); ! AIQ( i) must not be too large for interval; AIQ( i) <= AELVL( i+1 ) * ZA( i); ! Cost if we use this interval; AICOST( i) = ARATE( i) * AIQ( i); ); ! Tie all intervals for A together; ! Can choose at most 1 interval; @SUM( POINT( i) | i #LT# @SIZE( POINT): ZA( i)) <= 1; ! Quantity purchased from A; @SUM( POINT( i) | i #LT# @SIZE( POINT): AIQ( i)) = ATQ; ! Total cost of purchases from A; @SUM( POINT( i) | i #LT# @SIZE( POINT): AICOST( i)) = ATCOST; ! Model of Vendor B discount schedule (Incremental units); BIPRVCOST(1) = 0; ! Cost of purchase in previous intervals; @FOR( POINT( i) | i #LT# @SIZE( POINT): @BIN( ZB( i)); ! Either use (1) or not use (0) this interval; ! BIQ( i) = amount purchased from B if in interval i, else 0; ! BIQ( i) must be large enough for this interval; BIQ( i) >= BELVL( i) * ZB( i); ! BIQ( i) must not be too large for interval; BIQ( i) <= BELVL( i+1 ) * ZB( i); ! Cost of previous intervls + incremental cost in this interval; BICOST( i) = ( BIPRVCOST( i) - BRATE( i)* BELVL( i))* ZB( i) + BRATE( i)* BIQ( i); ! Get ready for next interval. Cost if we use this interval; BIPRVCOST( i+1) = BIPRVCOST( i) + BRATE( i)*( BELVL( i+1) - BELVL( i)); ); ! Tie all intervals for B together; ! Can choose at most 1 interval; @SUM( POINT( i) | i #LT# @SIZE( POINT): ZB( i)) <= 1; ! Quantity purchased from B; @SUM( POINT( i) | i #LT# @SIZE( POINT): BIQ( i)) = BTQ; ! Total cost of purchases from B; @SUM( POINT( i) | i #LT# @SIZE( POINT): BICOST( i)) = BTCOST;