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

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

После сборки модели — переменных, выражений, ограничений и (опционально) целевой функции — модель передаётся решателю. Возвращаемый объект решения предоставляет доступ к найденным значениям переменных, значению целевой функции и диагностическим данным.

Запуск решателя

Простейший способ запуска — метод Решить объекта модели:

Решение = Модель.Решить();

Эквивалентный вызов через менеджер библиотеки:

Решение = О2.РешитьМодель(Модель);

Метод РешитьМодель принимает не только объект модели, но и её сериализованное представление — путь к файлу или поток с двоичными данными:

ИмяФайлаМодели = "C:\path\to\my\model.o2m";
Решение = О2.РешитьМодель(ИмяФайлаМодели);

Это применяется при разделении подготовки модели и её решения: модель формируется на одном узле, сохраняется в файл, передаётся в кластер, где выполняется поиск.

Параметры запуска

Методы Решить и РешитьМодель принимают дополнительные параметры — размещение вычислений, ограничения решателя, условия лицензирования:

НастройкиРешателя = О2.СоздатьНастройкиРешателя();
НастройкиРешателя.ЛимитВремени = 10; // не более 10 секунд на поиск
НастройкиРешателя.КоличествоПотоков = 8; // не более 8 потоков

ПараметрыПоиска = О2.СоздатьПараметрыПоиска();

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

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

Поля параметров поиска:

Имя параметраОписание
СервисРазмещение вычислений — локально, в выделенной службе и т. п. См. раздел Программное использование.
НастройкиРешателяАлгоритм решения и его лимиты.
НастройкиЛицензированияПараметры лицензиата при использовании ёмкостных лицензий.

Настройки решателя

Имя параметраОписание
ЛимитВремениМаксимальное время поиска решения в секундах.
КоличествоПотоковМаксимальное число потоков. Решателями без параллельной обработки параметр игнорируется.

Настройки лицензирования

Имя параметраОписание
КодЛицензиатаКод клиента, к которому привязаны ёмкостные лицензии. Обязателен при их использовании.

Загрузка готового решения

Если решение модели было получено заранее (например, консольной утилитой и сохранено в файл), оно загружается без повторного запуска решателя:

ИмяФайлаРешения = "C:\path\to\my\solution.o2s";
Решение = О2.ЗагрузитьРешение(ИмяФайлаРешения);

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

Статус решения

После запуска проверяется статус решения. Статус описывает результат поиска и определяет, может ли результат использоваться:

Если Решение.Статус() = О2.СтатусыРешений().Оптимальное() Тогда
// ...
КонецЕсли;

Возможные значения:

СтатусРасшифровка
ОшибочнаяМодельПоиск не выполнен — в данных модели обнаружены ошибки (например, ссылка на незарегистрированную переменную).
РешениеОтсутствуетРешатель достоверно установил, что допустимого решения не существует — ограничения противоречивы.
ДопустимоеРешение найдено и удовлетворяет всем ограничениям; за отведённое время оптимальность по целевой функции не доказана. Если целевая функция не задана, статус является штатным результатом успешного поиска.
ОптимальноеРешение найдено, и доказано, что оно оптимально по целевой функции.

Различие между «допустимым» и «оптимальным» существенно. Допустимое решение удовлетворяет ограничениям, однако улучшение по целевой функции теоретически возможно — решатель не успел его доказать или опровергнуть. Оптимальное решение гарантирует отсутствие лучшего значения целевой функции.

Метод РешениеНайдено() соответствует проверке Статус() = Допустимое или Оптимальное. Применяется, когда оптимальность не критична. Если по задаче требуется строго оптимальное решение, статус проверяется явно.

Чтение значений

Объект решения предоставляет несколько методов чтения значений переменных и выражений:

  • ЗначениеПеременной — значение переменной модели. Аргумент — объект переменной, её имя или индекс (0-based):

    ЗначениеX = Решение.ЗначениеПеременной(Пx); // по объекту
    ЗначениеX = Решение.ЗначениеПеременной("x"); // по имени
    ЗначениеX = Решение.ЗначениеПеременной(0); // по индексу
  • ЗначениеВыражения — вычисление произвольного линейного выражения на найденном решении. Аргумент имеет ту же структуру, что и аргумент ограничений: строка, переменная, константа, объект линейного выражения. Метод позволяет получить производный показатель без введения дополнительной переменной в модель:

    // Стоимость проекта = 5·часов_разработчика + 8·часов_аналитика
    ОбщаяСтоимость = Решение.ЗначениеВыражения("5*разраб + 8*аналит");
  • ЗначениеЦелевойФункции — итоговое значение целевой функции на найденном решении. При отсутствии целевой функции метод возвращает 0.

  • КоличествоПеременных — общее число зарегистрированных в модели переменных, для которых в решении присутствуют значения. Применяется при программном обходе всех переменных по индексу.

Важно

Если в ЗначениеПеременной передаётся объект переменной, эта переменная должна быть зарегистрирована именно в той модели, для которой получено решение. При попытке прочитать переменную из другой модели метод возвращает Неопределено. Аналогично — при запросе несуществующего имени или индекса.

Метаданные решения

Метод МетаданныеРешения() возвращает структуру с диагностическими данными:

ПолеОписание
ИдентификаторМоделиУникальный идентификатор модели, присвоенный при её создании.
ТипМоделиТип модели.
ВерсияРасширенияВерсия расширения библиотеки O2.
ВерсияСовместимостиНомер мажорной версии, общий у расширения и решателя.
ИдентификаторРешенияУникальный идентификатор решения, присвоенный решателем.
ВерсияРешателяНомер версии решателя.
ТипРешателяАлгоритм, использованный при решении.

Метаданные применяются при сохранении нескольких решений в базе и их последующем сравнении (A/B-тестирование настроек, сбор статистики по запускам).

Результат проверки модели

Метод РезультатПроверки() возвращает результат валидации данных модели:

ПолеОписание
УспехИстина, если модель прошла проверку.
ОписаниеОшибкиТекст обнаруженных ошибок. Поле присутствует, если Успех = Ложь.

Применяется при отладке для определения причин статуса ОшибочнаяМодель.

Иллюстрация: разбор решения

Базовая структура чтения решения после поиска:

Решение = Модель.Решить();

Если Решение.РешениеНайдено() Тогда

Сообщить("Стоимость решения: " + Решение.ЗначениеЦелевойФункции());

// Производные показатели читаются через ЗначениеВыражения,
// без введения дополнительных переменных в модель
ОбщееВремяРаботы = Решение.ЗначениеВыражения(
"длит_операции_1 + длит_операции_2 + длит_операции_3"
);

Сообщить("Общее время выполнения: " + ОбщееВремяРаботы);

Иначе
Сообщить("Решение не найдено. Статус: " + Решение.Статус());
КонецЕсли;

Тот же приём применяется в произвольных задачах: после нахождения расписания через ЗначениеВыражения извлекаются производные показатели — простой оборудования, среднее время задержки, число просрочек. Полные примеры с обработкой решения приведены на странице Оперативное производственное планирование.

Полный перечень методов

Полный набор методов объекта решения с подробным описанием параметров приведён в разделе Программный интерфейс — Решение.