Целевая функция
Стоимость решения — величина, которую решатель минимизирует. Она складывается из коэффициентов транзитов и ресурсов на каждом маршруте, фиксированных стоимостей задействованных транспортных средств, штрафов за нарушение мягких границ значений ресурсов в точках маршрута, штрафов за непосещение узлов в дизъюнкциях и штрафа балансировки между транспортными средствами.
Все средства настройки целевой функции собраны на одном менеджере — Модель.ЦелеваяФункция().
Коэффициент транзита
Привязывает зарегистрированный транзит к стоимости как «прирост на дуге, умноженный на коэффициент». Сумма таких приростов по всем дугам каждого маршрута попадает в общую стоимость.
Модель.ЦелеваяФункция().УстановитьКоэффициентТранзита(
Транзит,
Коэффициент = 1,
ТранспортноеСредство = Неопределено
)
Транзит— объект транзита, имя или индекс (см. Идентификация сущностей).Коэффициент— множитель (по умолчанию1).ТранспортноеСредство— если задано, коэффициент применяется только к этому ТС; иначе — ко всем.
Общая стоимость для всех ТС
Все транспортные средства используют один и тот же транзит как стоимостной:
Модель.Транзиты().ДобавитьМатрицу(Расстояния, "расстояния");
Модель.ЦелеваяФункция().УстановитьКоэффициентТранзита("расстояния", 1);
Применяется в большинстве задач VRP: машины однотипные, и стоимость километра у них одинакова.
Свой транзит для отдельных ТС
Каждое транспортное средство использует свой транзит. Это нужно, если стоимость километра у разных машин разная или если у разных средств разные пути по графу:
Модель.Транзиты().ДобавитьМатрицу(РасстоянияФуры, "расстояния_фура");
Модель.Транзиты().ДобавитьМатрицу(РасстоянияГазели, "расстояния_газель");
Фура = Модель.ТранспортныеСредства().Получить("ТС_фура");
Газель = Модель.ТранспортныеСредства().Получить("ТС_газель");
// Фура расходует ~25 руб на километр, газель — ~9 руб (значения в копейках, чтобы оставаться в целых)
Модель.ЦелеваяФункция().УстановитьКоэффициентТранзита("расстояния_фура", 25, Фура);
Модель.ЦелеваяФункция().УстановитьКоэффициентТранзита("расстояния_газель", 9, Газель);
Если для части транспортных средств используется индивидуальный коэффициент, а для остальных — общий, можно комбинировать: сначала установить общий, затем переопределить индивидуально.
Коэффициент ресурса
Привязывает ресурс к стоимости: к общей стоимости прибавляется значение ресурса в финишной точке маршрута, умноженное на коэффициент. Иначе говоря, чем больше ресурса «потрачено» на маршруте — тем выше штраф.
Модель.ЦелеваяФункция().УстановитьКоэффициентРесурса(
Ресурс,
Коэффициент,
ТранспортноеСредство = Неопределено
)
Прикладной сценарий: «штрафовать за каждый час сверхурочного времени на маршруте, даже если оно уложилось в ёмкость» — коэффициент по ресурсу «время».
Коэффициент балансировки
Прибавляет к общей стоимости величину «разница между максимальным и минимальным значениями ресурса на маршруте» × коэффициент. Применяется для балансировки нагрузки между транспортными средствами: при положительном коэффициенте решателю невыгодно «загружать» одно ТС сильно больше остальных — он раскладывает ресурс ровнее.
Модель.ЦелеваяФункция().УстановитьКоэффициентБалансировки(
Ресурс,
Коэффициент
)
Штраф за превышение границы (мягкая верхняя граница)
Позволяет значению ресурса в конкретной точке маршрута превысить заданную границу — с пропорциональным штрафом в стоимости. Используется, когда жёсткое ограничение делает задачу нерешаемой, но частичное нарушение приемлемо.
Модель.ЦелеваяФункция().УстановитьШтрафПревышения(
Ресурс,
ТочкаМаршрута,
Граница,
Коэффициент
)
Штраф = Коэффициент × max(0, ЗначениеРесурса − Граница).
Прикладной сценарий: «доставка в Клиент1 после 18:00 нежелательна, но допустима — за каждую минуту просрочки начисляется штраф 50».
Клиент1 = Модель.Узлы().Получить("Клиент1");
ТочкаКлиента1 = Модель.ТочкиМаршрута().ПолучитьПоУзлу(Клиент1);
Модель.ЦелеваяФункция().УстановитьШтрафПревышения(
"Время",
ТочкаКлиента1,
1080, // 18:00 в минутах от полуночи
50 // штраф за каждую минуту превышения
);
Штраф за недобор до границы (мягкая нижняя граница)
Зеркальное к штрафу превышения: значение ресурса в точке маршрута может «не дотянуть» до заданной границы с пропорциональным штрафом.
Модель.ЦелеваяФункция().УстановитьШтрафНедобора(
Ресурс,
ТочкаМаршрута,
Граница,
Коэффициент
)
Штраф = Коэффициент × max(0, Граница − ЗначениеРесурса).
Фиксированная стоимость использования ТС
Постоянная плата, добавляемая к общей стоимости один раз, если транспортное средство задействовано в решении (его маршрут содержит хотя бы один узел, отличный от стартового и конечного):
ТС = Модель.ТранспортныеСредства().Получить("ТС1");
Модель.ЦелеваяФункция().УстановитьФиксированнуюСтоимость(ТС, 1000);
Чем выше фиксированная стоимость, тем больше у решателя стимул разместить как можно больше клиентов на одном маршруте, а не дробить их между несколькими ТС.
Когда что применять
| Сценарий | Метод | Почему |
|---|---|---|
| Однотипный парк, минимизировать общий пробег | УстановитьКоэффициентТранзита("расстояния", 1) | Всем ТС один и тот же критерий, без индивидуализации. |
| Парк из машин разной грузоподъёмности и расхода | УстановитьКоэффициентТранзита(..., ТС) для каждого ТС | У каждой машины свой «стоимостный масштаб» километра. |
| Минимизировать число задействованных машин | Высокая УстановитьФиксированнуюСтоимость + умеренные коэф. транзита | Пока есть возможность не использовать ТС, для решателя это выгоднее, чем небольшой крюк. |
| Минимизировать общее время в пути | УстановитьКоэффициентТранзита("время", 1) | Стоимостной транзит — это любая величина, минимум суммы которой ищется. |
| Балансировка нагрузки между ТС | УстановитьКоэффициентБалансировки(Ресурс, Коэффициент) | Штрафует разброс значений ресурса на маршруте — раскладывает нагрузку ровнее. |
| Мягкие временные окна со штрафом за опоздание | УстановитьШтрафПревышения("Время", ТочкаМаршрута, ...) | Допускает нарушение жёсткого окна за плату. |
| Минимизировать суммарное использование ресурса | УстановитьКоэффициентРесурса(Ресурс, Коэффициент) | Штрафует «потраченный» ресурс на маршруте — полезно при пере-/недозагрузке. |
Полный перечень методов
Полный набор методов менеджера целевой функции — в разделе Программный интерфейс — Целевая функция.