Разработка AI-системы оптимизации строительного графика
Строительный график — сотни взаимосвязанных работ с ресурсными ограничениями. Традиционные инструменты (MS Project, Primavera P6) требуют ручного планирования. AI автоматизирует создание оптимального графика и динамически пересчитывает его при отклонениях.
Автоматическое составление графика
Resource-Constrained Project Scheduling (RCPSP):
Задача строительного расписания: N работ с predecessor/successor зависимостями, R видов ресурсов (бригады, краны, опалубка) с ограниченной доступностью → минимизировать общий срок.
from ortools.sat.python import cp_model
def schedule_construction_project(tasks, dependencies, resources, resource_limits):
"""
tasks: [{'id', 'duration_days', 'resource_demand': {type: qty}}]
dependencies: [(task_a, task_b)] — b начинается после a
resources: {'rebar_crew': 5, 'formwork_crew': 3, 'tower_crane': 2}
"""
model = cp_model.CpModel()
horizon = sum(t['duration_days'] for t in tasks) + 10 # мин. возможный срок
task_vars = {}
for task in tasks:
start = model.NewIntVar(0, horizon, f"start_{task['id']}")
end = model.NewIntVar(0, horizon, f"end_{task['id']}")
interval = model.NewIntervalVar(start, task['duration_days'], end, f"interval_{task['id']}")
task_vars[task['id']] = {'start': start, 'end': end, 'interval': interval}
# Зависимости (precedence constraints)
for pred_id, succ_id in dependencies:
model.Add(task_vars[succ_id]['start'] >= task_vars[pred_id]['end'])
# Ресурсные ограничения: кумулятивная нагрузка не превышает лимит
for resource_type, capacity in resource_limits.items():
intervals = []
demands = []
for task in tasks:
if resource_type in task.get('resource_demand', {}):
intervals.append(task_vars[task['id']]['interval'])
demands.append(task['resource_demand'][resource_type])
if intervals:
model.AddCumulative(intervals, demands, capacity)
# Целевая функция: минимизировать время завершения проекта
project_end = model.NewIntVar(0, horizon, 'project_end')
model.AddMaxEquality(project_end, [task_vars[t['id']]['end'] for t in tasks])
model.Minimize(project_end)
solver = cp_model.CpSolver()
solver.parameters.max_time_in_seconds = 60.0
status = solver.Solve(model)
if status in [cp_model.OPTIMAL, cp_model.FEASIBLE]:
return {t['id']: solver.Value(task_vars[t['id']]['start']) for t in tasks}
return None
Прогноз нарушений графика
Early Warning система:
ML-модель предсказывает работы, которые задержатся:
- Признаки: текущий процент выполнения vs. плановый, темп выполнения последних 5 дней
- Доступность ресурсов: погода (рабочих дней меньше), поставки материалов
- Тип работы: бетонные (зависят от погоды), монтаж (зависят от поставок)
import lightgbm as lgb
import pandas as pd
def predict_schedule_delay(task_progress_df, project_context):
"""
Прогноз задержки для каждой незавершённой работы.
task_progress_df: ежедневные отчёты о выполнении работ
"""
features = task_progress_df.copy()
# Ключевые признаки
features['planned_vs_actual'] = (features['actual_pct'] -
features['planned_pct_today'])
features['velocity_7d'] = features['actual_pct'].diff(7) / 7 # % в день
features['required_velocity'] = ((100 - features['actual_pct']) /
(features['days_remaining'] + 1))
features['velocity_gap'] = features['required_velocity'] - features['velocity_7d']
# Контекстные признаки
features['rain_days_forecast'] = project_context.get('rain_days_next7', 0)
features['resource_availability'] = project_context.get('crew_availability', 1.0)
features['material_on_site'] = features['material_stock_days']
model = lgb.LGBMRegressor() # предобученная модель
delay_predictions = model.predict(features[feature_cols])
return delay_predictions # в рабочих днях
Динамический пересчёт при отклонениях
Сценарный анализ:
При задержке критической работы — автоматический пересчёт:
- Определить affected downstream tasks (все последователи)
- Проверить: есть ли буфер (float) или критический путь?
- Предложить варианты recovery:
- Добавить ресурсы на задержавшуюся работу
- Перепланировать параллельные работы
- Скорректировать scope (если допустимо)
Crash Analysis:
Что если сжать сроки: какие работы сжимать при минимальных дополнительных затратах?
- Crash cost per day для каждой работы (удвоить бригаду = +N руб/день, -M дней)
- Linear Programming: минимизировать дополнительные затраты для достижения target срока
Управление ресурсами
Планирование поставок:
Look-ahead schedule: какие материалы нужны через 2–4 недели → автоматические заявки на поставку:
- Реестр работ + нормы расхода → ведомость материалов по периодам
- Буфер: 10–15% запас на складе от недельной потребности
- Alert: материал заканчивается через 5 дней, а lead time поставщика 7 дней
Workforce planning:
Прогноз потребности в бригадах и специальностях по дням:
- Пик в опалубочных работах: нужны 3 бригады × 5 человек
- Спад: 1 бригада на зачистку
- Вывод: предупредить прораба о пиках за 2 недели для найма/привлечения
Срок разработки: 3–5 месяцев для системы автоматического планирования графика, прогноза задержек и динамического пересчёта с интеграцией в Primavera P6 / MS Project.







