На першому занятті ми розглянули класичну постановку задачі, а на другому цю ж задачу, але з урахуванням обмежень.
Визначення оптимального обсягу замовлення з урахуванням знижки
Задача 3. Постачальник запропонував нову систему лояльності. Якщо ви замовляєте стандартну партію, ціна одиниці товару залишається 50 грн. Проте, якщо обсяг одного замовлення Q перевищує 500 одиниць, постачальник надає знижку 5% на всю партію.
Проблема: З одного боку, велика партія зменшує ціну товару та витрати на доставку, а з іншого боку – вона різко збільшує витрати на зберігання (склад стає переповненим). Чи варто замовляти 500 одиниць заради знижки, якщо наш ідеальний розрахунок показував 400?
Умови задачі: річна потреба D: 10 000 од.; вартість замовлення K: 40 грн.; базова ціна P1: 50 грн, якщо Q<500; акційна ціна P2 47.5 грн, якщо Q³500; вартість утримання h: 5 грн/од., залишаємо сталою.
Завдання: порівняти загальні річні витрати (включаючи ціну товару) для двох сценаріїв та визначити найбільш вигідну стратегію.
Ця задача цікава тим, що функція витрат стає «розривною» (має стрибок у точці 500). Ми порівняємо два локальних мінімуми.
Нижче наведено лістинг.
import numpy as np
import matplotlib.pyplot as plt
# 1. Параметри
D = 10000
K = 40
h = 5
P_normal = 50
P_discount = 47.5 # Знижка 3%
threshold = 500 # Межа для знижки
def total_cost_with_discount(Q):
if Q <= 0: return np.inf
# Визначаємо ціну залежно від обсягу
current_P = P_discount if Q >= threshold else P_normal
# Повна формула витрат (з ціною товару!)
return (D * K) / Q + (h * Q) / 2 + (D * current_P)
# 2. Розрахунок двох варіантів
# Варіант А: Оптимум без знижки (ми знаємо, що це 400)
cost_at_400 = total_cost_with_discount(400)
# Варіант Б: Мінімально можливе замовлення для отримання знижки
cost_at_500 = total_cost_with_discount(500)
# 3. Вивід аналітики
print(f"Витрати при Q=400 (без знижки): {cost_at_400:,.2f} грн")
print(f"Витрати при Q=500 (зі знижкою): {cost_at_500:,.2f} грн")
savings = cost_at_400 - cost_at_500
if savings > 0:
print(f"РЕЗУЛЬТАТ: Вигідно перейти на 500 од. Економія: {savings:,.2f} грн/рік")
else:
print(f"РЕЗУЛЬТАТ: Краще лишитися на 400 од. Знижка не покриває витрати складу.")
# 4. Візуалізація розривної функції
Q_range = np.linspace(100, 800, 500)
costs = [total_cost_with_discount(q) for q in Q_range]
plt.figure(figsize=(12, 7))
plt.plot(Q_range, costs, color='black', lw=2)
# Позначаємо точку розриву
plt.axvline(threshold, color='orange', linestyle='--', label='Точка активації знижки')
plt.scatter([400, 500], [cost_at_400, cost_at_500], color=['blue', 'red'], s=100, zorder=5)
plt.annotate('Локальний мінімум 1', xy=(400, cost_at_400), xytext=(300, cost_at_400+5000),
arrowprops=dict(arrowstyle='->'))
plt.annotate('Локальний мінімум 2 (Акція)', xy=(500, cost_at_500), xytext=(550, cost_at_500+5000),
arrowprops=dict(arrowstyle='->'))
plt.title('Оптимізація з ціновими розривами (Quantity Discounts)', fontsize=14)
plt.xlabel('Обсяг замовлення (Q)')
plt.ylabel('Загальні річні витрати, грн')
plt.grid(True, alpha=0.3)
plt.show()
На рис. 1.8 показано графічний розв’язок задачі.

Рисунок 1.8 – Графічний розв’язок задачі про оптимальний обсяг виробництва з урахуванням знижок
В результаті розв’язку видно, що при наявності знижки у 5% доцільно перейти до збільшення обсягів замовлення, адже стрибкоподібно зменшуються загальні річні витрати. Програма дозволяє визначити річний обсяг економії. Програмна реалізація передбачає вивід в консоль величини економічного ефекту (рис. 1.9).

Рисунок 1.9 – Результат вирішення задачі про оптимальний обсяг замовлення при наявності знижок
Аналогічним чином, можна здійснити розрахунки і для інших обсягів знижок. Для цього в блоці коду #1. Параметри слід змінити P_discount = 47.5 # Знижка 5% на P_discount = 48.5 # Знижка 3% (рис. 1.10).

Рисунок 1.10 – Редагування коду
При показнику знижки у 3% економія становить 14950.00 грн/рік (рис. 1.11).

Рисунок 1.11 – Результат виконання програми

Рисунок 1.12 – Графічний розв’язок задачі про визначення обсягів замовлення з урахуванням знижки
Адекватність запропонованої реалізації можна перевірити задавши граничне значення знижки рівним нормальному (рис. 1.13). За результатами розрахунку витрати при Q=500 од. будуть більшими ніж при Q=400 од. (рис. 1.14). Це видно із графіку зображеного на рис. 1.15.

Рисунок 1.13 – Перевірка коду

Рисунок 1.14 – Результат виконання програми

Рисунок 1.15 – Графічний розв’язок задачі
Таким чином, в наведеному розділі нами розглянуто оптимізацію одновимірних функцій за допомогою мови програмування Python.