Особенности и скрытые проблемы алгоритмов пооперационного планирования (MES) в 1С:ERP

Программист 1С v8.3 (Управляемые формы) 1С:ERP Управление предприятием Управленческий учет Промышленность, строительство и АПК
← На главную

В подсистеме производственного планирования (MES) конфигурации «1С:ERP Управление предприятием» (в частности, в обработке ПооперационноеПланирование2_2) заложены сложные математические и эвристические алгоритмы. На практике разработчики и архитекторы часто сталкиваются с неочевидным поведением системы при составлении пооперационного расписания. В этой статье мы подробно разберем внутреннее устройство ключевых функций планирования, выясним причины «зацикливания» подбора интервалов при учете переналадки, проанализируем логарифмический алгоритм распределения приоритетов и решим проблему зависания начатых этапов в очереди к расчету.

Проблема подбора свободных интервалов с учетом переналадки оборудования

Рассмотрим, как система определяет, пригоден ли конкретный интервал работы рабочего центра (РЦ) для размещения технологической операции. За эту задачу отвечает функция ИнтервалПригоденДляРазмещенияОперации. Проанализируем ее исходный код:


Функция ИнтервалПригоденДляРазмещенияОперации(ПараметрыПланирования, ДоступныйInterval, ПараметрыПодбора)
    
    Результат = Истина;
    
    ВыполнениеПрерывается = ДоступныйInterval.Время < ПараметрыПодбора.ВремяПлан;
    Если ВыполнениеПрерывается Тогда
        
        Если ДоступныйInterval.Время < МинимальноеВремяОперации() Тогда
            Результат = Ложь;
        ИначеЕсли СледующийИнтервалЗагружен(ПараметрыПланирования, ПараметрыПодбора, ДоступныйInterval) Тогда
            Результат = Ложь;
        КонецЕсли;
        
    КонецЕсли;
    
    ИнтервалЗагруженСинхронно = ДоступныйИнтервалЗагруженСинхронно(ДоступныйInterval);
    Если ИнтервалЗагруженСинхронно 
        И Не ДоступныйInterval.Время = ПараметрыПодбора.ВремяПлан + ВремяПереналадкиОперации(ПараметрыПланирования, ДоступныйInterval, ПараметрыПодбора.Операция) Тогда
        
        Результат = Ложь;
        
    ИначеЕсли ПараметрыПодбора.ПараллельнаяЗагрузка
        И ЗначениеЗаполнено(ДоступныйInterval.ВариантНаладки)
        И Не ПараметрыПодбора.ВариантНаладки = ДоступныйInterval.ВариантНаладки Тогда
        
        Результат = Ложь;
        
    ИначеЕсли ПараметрыПодбора.ПараллельнаяЗагрузка
        И ПараметрыПодбора.ЗагрузкаКратность > ДоступныйInterval.ДоступнаяЗагрузка
        И ПараметрыПодбора.ЗагрузкаКратность <= ПараметрыПодбора.МаксимальнаяЗагрузка Тогда
        
        Результат = Ложь;
        
    КонецЕсли;
    
    Возврат Результат;
    
КонецФункции

Давайте разберем по шагам, к какому логическому противоречию ведет этот алгоритм на несинхронных рабочих центрах (например, на обычных станках, где ВариантЗагрузки не равен значению Синхронный).

Представим конкретный практический пример:

  1. Планируется операция со временем выполнения 30 минут (ПараметрыПодбора.ВремяПлан = 30).
  2. Для выполнения этой операции на станке требуется предварительная переналадка длительностью 40 минут.
  3. На рабочем центре в данный момент свободен интервал времени величиной 1 час (60 минут) (ДоступныйInterval.Время = 60).

Проанализируем, как поведет себя функция в этих условиях:

Однако при детальном размещении операции в процедуре РассчитатьГраницыИнтервалаРазмещенияОперации система пытается «вписать» операцию физически. На этом этапе выясняется, что суммарно для работы требуется 70 минут (30 минут операция + 40 минут наладка), а доступно всего 60 минут. В результате попытка размещения отклоняется, и этот интервал отбрасывается.

Посмотрим на основной цикл планирования:


Пока ПараметрыПодбора.ВремяПлан > 0 Цикл
        
    Отказ = Ложь;
    ПодобратьДоступныйДляРазмещенияИнтервал(ПараметрыПланирования, ПараметрыПодбора, Результат, Отказ);
    Если Отказ Тогда
        Возврат Неопределено;
    КонецЕсли;
    
    ОпределитьИнтервалРазмещения(ПараметрыПланирования, ПараметрыПодбора, Результат, Отказ);
    Если Отказ Тогда
        Продолжить;
    КонецЕсли;
    
    ОпределитьИнтервалРазмещенияВспомогательных(ПараметрыПланирования, ПараметрыПодбора, Результат, Отказ);
    Если Отказ Тогда
        Продолжить;
    КонецЕсли;
    
    СохранитьИнтервалРазмещения(ПараметрыПланирования, ПараметрыПодбора, Результат);
    
КонецЦикла;

В чем заключается главная опасность? Если производство загружено плотно и свободное время на РЦ разбито мелкими «окнами» (например, по 1-2 часа в разные дни из-за выполнения других приоритетных этапов), система попадает в бесконечный цикл планирования. На шаге 1 (ПодобратьДоступныйДляРазмещенияИнтервал) она находит подходящее окно, а на шаге 2 (ОпределитьИнтервалРазмещения) бракует его из-за нехватки времени на переналадку. После этого цикл начинается заново для следующего интервала, что приводит к критическому зависанию расчета пооперационного расписания.

Математика приоритетов: Почему используется логарифм?

Для оптимизации скорости расчета система распределяет этапы производства по группам (партиям) планирования. Проанализируем процедуру РассчитатьПриоритетЭтапов:


Процедура РассчитатьПриоритетЭтапов(Этапы)
    
    КолЭтапов = Этапы.Количество();
    
    Если КолЭтапов > 0 Тогда
        КолПартий = Окр(Log(КолЭтапов));
        КолПартий = ?(КолПартий > 0, КолПартий, 1);
    Иначе
        КолПартий = 1;
    КонецЕсли;
    
    РазмерПартии = Окр(КолЭтапов/КолПартий);
    
    СчЭтапов = 0;
    НомерПартии = 1;
    Для Каждого Строка Из Этапы Цикл
        Строка.Приоритет = НомерПартии;
        СчЭтапов = СчЭтапов + 1;
        
        Если СчЭтапов = РазмерПартии Тогда
            СчЭтапов = 0;
            НомерПартии = НомерПартии + 1;
        КонецЕсли;
    КонецЦикла;
    
КонецПроцедуры

Выясним причину использования натурального логарифма (Log) при расчете количества партий. Сложность размещения каждой последующей партии этапов на временной шкале возрастает нелинейно (экспоненциально), так как свободного времени на РЦ остается все меньше.

Применение логарифмического деления позволяет сбалансировать нагрузку на СУБД:

Обратная сторона медали: Из-за того, что размер партии растет пропорционально общему числу этапов, внутри одной большой партии оказывается огромное количество документов разной степени важности. При сортировке по приоритетам это может приводить к конкуренции за ключевые рабочие центры и неоптимальному выстраиванию очереди на производстве.

Проблема «зависания» начатых этапов в заданиях к расчету графика

Еще один архитектурный пробел кроется в механизме актуализации графика производства. При изменении доступности оборудования система регистрирует необходимость пересчета графика для этапов производства через регистр сведений ЗаданияКРасчетуГрафикаПроизводства. Однако для запущенных в работу этапов этот механизм дает сбой.

Проанализируем фрагмент запроса из процедуры проверки превышения доступности:


ГДЕ
    Доступность.Регистратор ССЫЛКА Документ.ЭтапПроизводства2_2
    И ВЫРАЗИТЬ(Доступность.Регистратор КАК Документ.ЭтапПроизводства2_2).Статус <> ЗНАЧЕНИЕ(Перечисление.СтатусыЭтаповПроизводства2_2.Завершен)

Запрос проверяет только то, что документ не завершен. При этом статус Начат никак не выделяется. Однако обратим внимание на функцию, определяющую, какие этапы система в принципе имеет право планировать:


Функция СтатусыЭтапМожетБытьЗапланирован() Экспорт
    
    Результат = Новый Массив;
    
    Результат.Добавить(Перечисления.СтатусыЭтаповПроизводства2_2.Формируется);
    Resultат.Добавить(Перечисления.СтатусыЭтаповПроизводства2_2.Сформирован);
    Результат.Добавить(Перечисления.СтатусыЭтаповПроизводства2_2.КВыполнению);
    
    Возврат Результат;
    
КонецФункции

Как мы видим, статус Начат здесь отсутствует. Логика разработчиков понятна: начатый на физическом оборудовании этап нельзя произвольно двигать по шкале времени вперед или назад, так как процесс уже запущен в цеху.

Но из-за этого возникает системное противоречие: задания для пересчета начатых этапов попадают в регистр ЗаданияКРасчетуГрафикаПроизводства, но никогда не могут быть обработаны планировщиком, поскольку их статус не позволяет выполнить расчет. В результате этот регистр бесконечно разрастается, постепенно замедляя общую производительность всей СУБД при расчете графиков.

Рекомендации по локализации и исправлению проблем

Для стабильной работы MES-системы в крупных базах данных рекомендуется выполнить следующие доработки и организационные мероприятия:

  1. Оптимизация расчета переналадок: Если на вашем предприятии длительность переналадки сопоставима со временем выполнения самих операций, старайтесь укрупнять партии запуска на межцеховом уровне. Это позволит избежать ситуации «дробления» доступных интервалов времени на мелкие отрезки, из-за которых зависает алгоритм подбора.
  2. Регламентная очистка зависших заданий: Разработайте регламентное задание, которое будет автоматически удалять из регистра сведений ЗаданияКРасчетуГрафикаПроизводства записи по документам ЭтапПроизводства2_2, находящимся в статусах Начат или Завершен. Это предотвратит деградацию производительности при расчете графика производства.
  3. Контроль запущенных этапов: Если запущенный в производство этап (в статусе Начат) действительно требует изменения сроков выполнения, его необходимо сначала вручную вернуть в статус К выполнению, запустить процедуру перепланирования и только после этого снова переводить в работу.
← На главную