Перейти к основному содержимому

Модель задачи рюкзака

Задача о рюкзаке (англ. Knapsack Problem) — это классическая проблема выбора оптимального набора предметов с ограниченной вместимостью. Название связано с наглядной аналогией: как уместить в рюкзак наиболее ценные вещи при ограниченном объёме.

Первые исследования проблемы появились в XX веке, а в 1950-х годах задача получила формальное описание и методы решения, в том числе на основе динамического программирования.

В прикладных задачах 1С задача о рюкзаке актуальна для автоматизации управленческих решений при ограниченных ресурсах: выборе поставок, загрузке транспорта, планировании ассортимента, распределении бюджета и др.

Создание модели

Создание через менеджер моделей:

Модель = О2
.Модели()
.МодельЗадачиРюкзака()
.СоздатьМодель();

Создание через менеджер библиотеки:

Модель = О2.СоздатьМодель(
О2.ТипыМоделей().МодельЗадачиРюкзака()
);

Установка ограничений

МаксимальныйВес = 100;

Модель.Ограничения().Установить(МаксимальныйВес);

Для получения текущих установленных ограничений:

Ограничения = Модель.Ограничения().Получить(); // <-- всегда массив чисел

Добавление элементов

Имя         = "Шкаф";   // <-- имя элемента (опционально)
Ценность = 10; // <-- ценность элемента
Вес = 35;

Элемент = Модель.Элемент(Ценность, Вес, Имя);

Решение модели

Решение = Модель.Решить();
НастройкиРешателя = О2.СоздатьНастройкиРешателя();
НастройкиРешателя.ТипРешателя = О2
.Модели()
.МодельЗадачиРюкзака()
.ТипыРешателей()
.DP(); // <-- метод динамического программирования

ПараметрыРешения = О2.СоздатьПараметрыРешения();
ПараметрыРешения.НастройкиРешателя = НастройкиРешателя;

Решение = Модель.Решить(ПараметрыРешения);

Обработка результата

СтатусРешения       = Решение.Статус();                 // <-- "Оптимальное" или "Допустимое"
СуммарнаяЦенность = Решение.Ценность(); // <-- значение целевой функции
КоличествоЭлементов = Решение.КоличествоЭлементов(); // <-- количество элементов, поместившихся в рюкзак

Сообщить(
СтрШаблон("Использовано элементов: %1. Суммарная ценность: %2.", КоличествоЭлементов, СуммарнаяЦенность)
);

Сообщить("Использованы следующие элементы:");

Для Каждого Элемент Из Элементы Цикл // <-- Элементы - это массив элементов, добавленных в модель
ЭлементПрисутсвует = Решение.ЭлементПрисутсвует(Элемент);

Если ЭлементПрисутсвует Тогда
Сообщить(Элемент.Имя);
КонецЕсли;
КонецЦикла;