Транзиты
Транзит — это правило, по которому при переходе транспортного средства из узла 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) и т. д.; - диагональ матрицы расстояний — нули: переход узла «в самого себя» не имеет физического смысла;
- в Депо время обслуживания нулевое: туда не нужно ничего разгружать, поэтому простоя нет.
Полный перечень методов
Полный набор методов менеджера транзитов — в разделе Программный интерфейс — Транзиты.