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

Целевая функция

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

Все средства настройки целевой функции собраны на одном менеджере — Модель.ЦелеваяФункция().

Коэффициент транзита

Привязывает зарегистрированный транзит к стоимости как «прирост на дуге, умноженный на коэффициент». Сумма таких приростов по всем дугам каждого маршрута попадает в общую стоимость.

Модель.ЦелеваяФункция().УстановитьКоэффициентТранзита(
Транзит,
Коэффициент = 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)Стоимостной транзит — это любая величина, минимум суммы которой ищется.
Балансировка нагрузки между ТСУстановитьКоэффициентБалансировки(Ресурс, Коэффициент)Штрафует разброс значений ресурса на маршруте — раскладывает нагрузку ровнее.
Мягкие временные окна со штрафом за опозданиеУстановитьШтрафПревышения("Время", ТочкаМаршрута, ...)Допускает нарушение жёсткого окна за плату.
Минимизировать суммарное использование ресурсаУстановитьКоэффициентРесурса(Ресурс, Коэффициент)Штрафует «потраченный» ресурс на маршруте — полезно при пере-/недозагрузке.

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

Полный набор методов менеджера целевой функции — в разделе Программный интерфейс — Целевая функция.