ЛР-02: Лекарства в районные больницы#

Student notebook: civil 01#

Этот notebook предназначен для самостоятельного решения.

Готового оптимального плана и заполненного решателя здесь нет.

1. Зачем нужен этот кейс#

Три аптечных склада распределяют партии лекарств между четырьмя больницами.

После этого notebook-а студент должен уметь:

  1. проверять, закрытая это задача или открытая;

  2. правильно записывать ограничения по строкам и столбцам;

  3. собирать c, A_eq, b_eq, bounds для linprog;

  4. объяснять смысл маршрутов и итоговой стоимости.

2. Исходные данные#

Тип задачи: закрытая.

Запасы#

Поставщик

Объём

Склад A

30

Склад B

40

Склад C

35

Спрос#

Потребитель

Объём

Больница 1

20

Больница 2

25

Больница 3

30

Больница 4

30

Матрица затрат#

Откуда / Куда

Больница 1

Больница 2

Больница 3

Больница 4

Склад A

5

7

6

10

Склад B

8

4

5

7

Склад C

6

6

4

5

3. Что нужно сделать#

  1. Проверьте баланс запасов и спроса.

  2. Если задача открытая, добавьте фиктивный узел и поясните его смысл.

  3. Запишите математическую модель через переменные \(x_{ij}\).

  4. Сформируйте c, A_eq, b_eq, bounds для linprog.

  5. После собственной попытки решите задачу через Python.

  6. Кратко объясните, какие маршруты оказались ключевыми.

import numpy as np
from scipy.optimize import linprog

supplies = np.array([30, 40, 35], dtype=float)
demands = np.array([20, 25, 30, 30], dtype=float)
costs = np.array([[5, 7, 6, 10], [8, 4, 5, 7], [6, 6, 4, 5]], dtype=float)

print('sum supply =', supplies.sum())
print('sum demand =', demands.sum())

4. Шаблон для самостоятельной сборки модели#

Сначала аккуратно сбалансируйте задачу, а потом переходите к linprog. Не подставляйте готовый ответ до своей попытки.

# TODO: при необходимости добавьте фиктивного поставщика или потребителя.
balanced_supplies = supplies.copy()
balanced_demands = demands.copy()
balanced_costs = costs.copy()

# TODO: заполните элементы транспортной модели.
c = None
A_eq = None
b_eq = None
bounds = None

# TODO: только после заполнения модели запускайте solver.
# result = linprog(c, A_eq=A_eq, b_eq=b_eq, bounds=bounds, method='highs')
# plan = result.x.reshape(len(balanced_supplies), len(balanced_demands))

5. Что должно быть в отчёте#

  1. Таблица исходных данных и проверка баланса.

  2. Математическая постановка транспортной задачи.

  3. Пояснение, нужен ли фиктивный узел.

  4. Проверка через linprog.

  5. Содержательная интерпретация ненулевых маршрутов.

6. Контрольный чек-лист#

  • [ ] Я сам проверил баланс до запуска solver-а.

  • [ ] Я осмысленно собрал A_eq и b_eq.

  • [ ] Я отличаю реальные маршруты от фиктивного узла.

  • [ ] Я объяснил полученный план простыми словами.