Untitled

 avatar
unknown
plain_text
7 days ago
5.1 kB
3
Indexable
import numpy as np

# Define demand probabilities
prob_low, prob_med, prob_high = 0.4, 0.2, 0.4

# Segment data
segments = [
    {
        'name': 'MultiBlend',
        'A': (6.0, 8.0, 10.0),
        'B': 2.0,
        'pL': 2.50,
        'pH': 3.00,
        'distcost': 0.65,
        'prodcost': 1.00,
        'salvage': 0.25
    },
    {
        'name': 'Potpuri',
        'A': (12.0, 16.0, 20.0),
        'B': 5.0,
        'pL': 1.50,
        'pH': 2.00,
        'distcost': 0.30,
        'prodcost': 1.00,
        'salvage': 0.25
    },
    {
        'name': 'MyMayim',
        'A': (8.0, 12.0, 16.0),
        'B': 2.75,
        'pL': 2.00,
        'pH': 2.50,
        'distcost': 0.05,
        'prodcost': 1.00,
        'salvage': 0.25
    }
]

def demand(segment, scenario, price):
    A = segment['A'][scenario]
    B = segment['B']
    return max(0.0, A - B * price)

def expected_profit(segment, Q, price):
    c = segment['prodcost']
    s = segment['salvage']
    d = segment['distcost']
    margin = price - c - d
    overage = c - s

    D = [demand(segment, i, price) for i in range(3)]
    probs = [prob_low, prob_med, prob_high]

    total_profit = 0.0
    for i in range(3):
        sold = min(Q, D[i])
        leftover = Q - sold
        profit = sold * margin - leftover * overage
        total_profit += profit * probs[i]
    return total_profit

def optimal_quantity(segment, price, max_qty=15.0, step=0.01):
    best_Q, best_EP = 0.0, -np.inf
    for Q in np.arange(0, max_qty + step, step):
        ep = expected_profit(segment, Q, price)
        if ep > best_EP:
            best_EP = ep
            best_Q = Q
    return best_Q, best_EP

def best_partial_quantity(segment, price, capacity, step=0.01):
    best_Q, best_EP = 0.0, -np.inf
    for Q in np.arange(0, capacity + step, step):
        ep = expected_profit(segment, Q, price)
        if ep > best_EP:
            best_EP = ep
            best_Q = Q
    return best_Q, best_EP

# Main optimization logic
price_options = [None, 'pL', 'pH']  # Do not serve, low, high price
best_config = None
configs = []

for p1 in price_options:
    for p2 in price_options:
        for p3 in price_options:
            if p1 == p2 == p3 == None:
                continue

            config_prices = []
            for p_opt, seg in zip([p1, p2, p3], segments):
                if p_opt == 'pL':
                    config_prices.append(seg['pL'])
                elif p_opt == 'pH':
                    config_prices.append(seg['pH'])
                else:
                    config_prices.append(None)

            Q_star, EP_star, margins = [], [], []
            for seg, p in zip(segments, config_prices):
                if p is None:
                    Q_star.append(0.0)
                    EP_star.append(0.0)
                    margins.append(0.0)
                else:
                    q, ep = optimal_quantity(seg, p)
                    Q_star.append(q)
                    EP_star.append(ep)
                    margins.append(p - seg['prodcost'] - seg['distcost'])

            capacity = 15.0
            Q_alloc, EP_alloc = [0.0]*3, [0.0]*3
            order = sorted(range(3), key=lambda i: margins[i], reverse=True)

            for i in order:
                if config_prices[i] is None:
                    continue
                if Q_star[i] <= capacity:
                    Q_alloc[i] = Q_star[i]
                    EP_alloc[i] = expected_profit(segments[i], Q_alloc[i], config_prices[i])
                    capacity -= Q_star[i]
                else:
                    q, ep = best_partial_quantity(segments[i], config_prices[i], capacity)
                    Q_alloc[i] = q
                    EP_alloc[i] = ep
                    capacity -= q

            total_EP = sum(EP_alloc)
            config = {
                'price_options': (p1, p2, p3),
                'allocated_Q': Q_alloc,
                'expected_profit': total_EP
            }
            configs.append(config)

            if best_config is None or total_EP > best_config['expected_profit']:
                best_config = config


# Output result
print("\nDetailed Results:")
total_capacity_used = 0.0
for i, seg in enumerate(segments):
    price_opt = best_config['price_options'][i]
    Q = best_config['allocated_Q'][i]
    if price_opt:
        price = seg[price_opt]
        margin = price - seg['prodcost'] - seg['distcost']
        ep = expected_profit(seg, Q, price)
        print(f"- {seg['name']}:")
        print(f"    Price: ${price:.2f}")
        print(f"    Margin: ${margin:.2f}")
        print(f"    Quantity Allocated: {Q:.2f}M lbs")
        print(f"    Expected Profit: ${ep:.2f}M")
        total_capacity_used += Q
    else:
        print(f"- {seg['name']}: Not served")

print(f"\nTotal Capacity Used: {total_capacity_used:.2f}M lbs")
print(f"Unused Capacity: {15.0 - total_capacity_used:.2f}M lbs")
print(f"Total Expected Profit: ${best_config['expected_profit']:.2f} million")
Editor is loading...
Leave a Comment