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

Транзиты

Транзит — это правило, по которому при переходе транспортного средства из узла i в узел j рассчитывается прирост ресурса (расстояние, время, груз, число остановок). Один и тот же транзит может использоваться как источник прироста для нескольких ресурсов и как коэффициент стоимости в целевой функции.

Зарегистрированный транзит сам по себе ничего не задаёт — он становится приростом конкретного ресурса или коэффициентом стоимости в целевой функции только при явной привязке к этим объектам. Один транзит может использоваться сразу в нескольких местах: например, матрица расстояний — и как стоимость дуги, и как прирост ресурса «пробег».

Формы задания транзита

Менеджер транзитов поддерживает три формы:

Матрица — ДобавитьМатрицу

Квадратная таблица размера N×N, где N — число узлов модели. Каждой паре (i, j) соответствует своё значение. Используется, когда прирост зависит от обоих узлов — конкретной пары «откуда — куда».

Типовое применение: расстояния, времена в пути.

Вектор — ДобавитьВектор

Одномерный массив из N значений. Значение i — прирост при выходе из узла i, независимо от того, в какой узел переходит транспортное средство. Используется, когда прирост зависит только от узла-источника.

Типовое применение: время обслуживания на узле, вес заказа клиента.

Константа — ДобавитьКонстанту

Единое значение на все дуги графа. Эквивалентно «однотонной» функции прироста.

Типовое применение: счётчик остановок (прирост +1 на каждой дуге), фиксированный сбор за переход.

Сигнатуры

Модель.Транзиты().ДобавитьМатрицу(Значения, Имя = Неопределено)
Модель.Транзиты().ДобавитьВектор(Значения, Имя = Неопределено)
Модель.Транзиты().ДобавитьКонстанту(Значение, Имя = Неопределено)

Все три метода возвращают объект транзита. Если имя не указано, оно генерируется автоматически по шаблону _<индекс>.

К зарегистрированному транзиту обращаются по объекту, имени или индексу (см. Идентификация сущностей):

Транзит = Модель.Транзиты().Получить(0); // по индексу
Транзит = Модель.Транзиты().Получить("расстояния"); // по имени
Количество = Модель.Транзиты().Количество();

Симметричные и асимметричные матрицы

Матрица называется симметричной, если матрица[i][j] = матрица[j][i] — то есть переход в обе стороны имеет один и тот же прирост. Это часто верно для расстояний по прямой.

Матрица называется асимметричной, если значения в обе стороны различаются. Это типично для:

  • городского движения с односторонними улицами;
  • времени в пути с учётом пробок (по одному и тому же маршруту утром и вечером время разное);
  • стоимости погрузки/разгрузки, зависящей от направления.

Менеджер одинаково работает с обоими видами — пользователь сам формирует таблицу нужной симметрии.

Целочисленность значений

Все значения транзитов — целые числа в диапазоне Int64. Если в прикладной задаче значения вещественные, их нужно масштабировать:

  • расстояние в километрах × 1000 → метры;
  • время в часах × 3600 → секунды;
  • стоимость в рублях × 100 → копейки.

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

Поведение при попытке передать нецелое значение определяется параметром КонтрольЦелыхЧисел модели — см. раздел Создание объекта модели.

Пример

В модели четыре узла: Депо, Клиент1, Клиент2, Клиент3. Регистрируем матрицу расстояний и вектор времени обслуживания:

Построитель = О2
.Модели()
.МодельМаршрутизации()
.СоздатьПостроительПараметровМодели();

Построитель.ДобавитьУзел("Депо");
Построитель.ДобавитьУзел("Клиент1");
Построитель.ДобавитьУзел("Клиент2");
Построитель.ДобавитьУзел("Клиент3");

Модель = Построитель.СоздатьМодель();

// Симметричная матрица расстояний (метры)
Расстояния = О2.Утилиты().Массив(
О2.Утилиты().Массив( 0, 5400, 9700, 7100),
О2.Утилиты().Массив( 5400, 0, 6800, 8200),
О2.Утилиты().Массив( 9700, 6800, 0, 4500),
О2.Утилиты().Массив( 7100, 8200, 4500, 0)
);

Модель.Транзиты().ДобавитьМатрицу(Расстояния, "расстояния");

// Унарный вектор времени обслуживания (секунды)
Обслуживание = О2.Утилиты().Массив(0, 600, 900, 450);

Модель.Транзиты().ДобавитьВектор(Обслуживание, "обслуживание");

// Константа «+1 на каждом переходе» для счётчика остановок
Модель.Транзиты().ДобавитьКонстанту(1, "+1");

// !node: имя объекта не может содержать спецсимволы "+1". Отредактировать.

В этом примере:

  • порядок строк и столбцов матрицы совпадает с порядком добавления узлов: первая строка — Депо (узел 0), вторая — Клиент1 (узел 1) и т. д.;
  • диагональ матрицы расстояний — нули: переход узла «в самого себя» не имеет физического смысла;
  • в Депо время обслуживания нулевое: туда не нужно ничего разгружать, поэтому простоя нет.

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

Полный набор методов менеджера транзитов — в разделе Программный интерфейс — Транзиты.