Як AI-система генеративного проектування будівель прискорює створення планувань?
Проектування житлових і комерційних будівель вимагає перебору сотень варіантів з урахуванням інсоляції, нормативів і вартості. Вручну архітектори витрачають тижні на ескізи, а результат часто далекий від оптимуму. Ми розробили гібридну AI-систему, яка об'єднує параметричну оптимізацію (диференціальна еволюція) та нейромережеву генерацію (дифузійні моделі). За хвилини система видає десятки варіантів, що задовольняють усім обмеженням. Скорочення часу ескізування — у 5 разів, зниження вартості будівництва — на 10–15%. Середня економія бюджету на проекті — до 3 млн ₴.
Чому диференціальна еволюція краща за випадковий перебір? — ai система генеративного
Диференціальна еволюція (DE) — евристичний метод глобальної оптимізації без градієнта. Він використовує різниці векторів, що дає хорошу збіжність у багатовимірних просторах. У плануванні кожна хромосома кодує координати та розміри кімнат, а фітнес-функція оцінює інсоляцію, ефективність площі та вартість. DE надійніша за PSO для задач із жорсткими обмеженнями.
from dataclasses import dataclass
from typing import Callable
import numpy as np
from scipy.optimize import differential_evolution
@dataclass
class BuildingConstraints:
site_polygon: list[tuple]
total_area: float
floors: int
rooms: list[dict]
orientation_north: float
setbacks: dict
max_height: float
accessibility: bool = True
@dataclass
class OptimizationWeights:
daylight: float = 0.3
area_efficiency: float = 0.25
circulation: float = 0.2
cost: float = 0.25
class FloorPlanOptimizer:
def __init__(self, constraints: BuildingConstraints, weights: OptimizationWeights):
self.constraints = constraints
self.weights = weights
def decode_chromosome(self, x: np.ndarray) -> dict:
rooms = []
idx = 0
for room_spec in self.constraints.rooms:
rooms.append({
"name": room_spec["name"],
"x": x[idx] * self.constraints.total_area**0.5,
"y": x[idx+1] * self.constraints.total_area**0.5,
"width": room_spec["min_area"]**0.5 + x[idx+2] * (
room_spec["max_area"]**0.5 - room_spec["min_area"]**0.5
),
"height": room_spec["min_area"]**0.5 + x[idx+3] * (
room_spec["max_area"]**0.5 - room_spec["min_area"]**0.5
)
})
idx += 4
return {"rooms": rooms}
def evaluate_daylight(self, plan: dict) -> float:
score = 0.0
south_angle = (180 - self.constraints.orientation_north) % 360
for room in plan["rooms"]:
room_angle = np.degrees(np.arctan2(
room["y"] - self.constraints.total_area**0.5 / 2,
room["x"] - self.constraints.total_area**0.5 / 2
)) % 360
angular_diff = abs(room_angle - south_angle)
score += 1 - min(angular_diff, 360 - angular_diff) / 180
return score / len(plan["rooms"])
def evaluate_area_efficiency(self, plan: dict) -> float:
total_room_area = sum(r["width"] * r["height"] for r in plan["rooms"])
return min(total_room_area / self.constraints.total_area, 1.0)
def fitness(self, x: np.ndarray) -> float:
plan = self.decode_chromosome(x)
w = self.weights
score = (
w.daylight * self.evaluate_daylight(plan) +
w.area_efficiency * self.evaluate_area_efficiency(plan)
)
return -score
def generate_variants(self, n_variants: int = 20) -> list[dict]:
n_params = len(self.constraints.rooms) * 4
bounds = [(0, 1)] * n_params
results = []
for seed in range(n_variants):
result = differential_evolution(
self.fitness, bounds,
seed=seed, maxiter=500, tol=0.001,
popsize=15, mutation=(0.5, 1.0), recombination=0.7
)
plan = self.decode_chromosome(result.x)
plan["score"] = -result.fun
plan["seed"] = seed
results.append(plan)
return sorted(results, key=lambda p: p["score"], reverse=True)
Як нейромережа генерує деталізовані плани?
Дифузійні моделі працюють з растровим представленням планів. На вхід подаються обмеження (площа, поверховість, орієнтація), на виході — масив пікселів, який потім векторизується в контури кімнат. Такий підхід дає різноманітність і природні форми.
import torch
from diffusers import UNet2DConditionModel, DDPMScheduler
class FloorPlanDiffusion:
def __init__(self, model_path: str):
self.unet = UNet2DConditionModel.from_pretrained(model_path)
self.scheduler = DDPMScheduler.from_pretrained(model_path)
self.device = "cuda" if torch.cuda.is_available() else "cpu"
self.unet.to(self.device)
def encode_constraints(self, constraints: BuildingConstraints) -> torch.Tensor:
features = [
constraints.total_area / 1000,
constraints.floors / 10,
constraints.orientation_north / 360,
len(constraints.rooms) / 20,
float(constraints.accessibility)
]
return torch.tensor(features, dtype=torch.float32).unsqueeze(0).to(self.device)
@torch.no_grad()
def generate(self, constraints: BuildingConstraints, num_samples: int = 8) -> list[np.ndarray]:
condition = self.encode_constraints(constraints)
noise = torch.randn(num_samples, 1, 256, 256).to(self.device)
for t in self.scheduler.timesteps:
noise_pred = self.unet(noise, t, encoder_hidden_states=condition.expand(num_samples, -1, -1)).sample
noise = self.scheduler.step(noise_pred, t, noise).prev_sample
plans = noise.squeeze(1).cpu().numpy()
return [self.rasterize_to_vector(p) for p in plans]
def rasterize_to_vector(self, raster: np.ndarray) -> dict:
import cv2
binary = (raster > 0.5).astype(np.uint8) * 255
contours, _ = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
rooms = []
for cnt in contours:
approx = cv2.approxPolyDP(cnt, 0.02 * cv2.arcLength(cnt, True), True)
rooms.append({"polygon": approx.reshape(-1, 2).tolist()})
return {"rooms": rooms}
Як інтегрувати систему з BIM і симулювати інсоляцію?
Експортуємо плани в IFC 4.3 та DXF. Для Revit використовуємо Dynamo-скрипти: JSON з координатами завантажується в Dynamo, який автоматично створює стіни та приміщення. Оцінка інсоляції через EnergyPlus. Код експорту:
import ifcopenshell
import ifcopenshell.api
def export_to_ifc(plan: dict, project_name: str) -> bytes:
model = ifcopenshell.file()
project = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcProject", name=project_name)
site = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcSite")
building = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcBuilding")
for room_data in plan["rooms"]:
space = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcSpace", name=room_data["name"])
coordinates = [(p[0], p[1], 0.0) for p in room_data["polygon"]]
ifcopenshell.api.run("geometry.add_wall_representation", model, product=space, coordinates=coordinates)
import io
buf = io.BytesIO()
model.write(buf)
return buf.getvalue()
def export_to_dxf(plan: dict) -> bytes:
import ezdxf
doc = ezdxf.new(dxfversion="R2010")
msp = doc.modelspace()
for room_data in plan["rooms"]:
polygon = room_data["polygon"]
msp.add_lwpolyline(polygon, close=True, dxfattribs={"layer": room_data.get("name", "ROOMS")})
buf = io.BytesIO()
doc.write(buf)
return buf.getvalue()
Порівняння підходів до генерації
| Підхід | Швидкість генерації | Якість | Навчання | Застосування |
|---|---|---|---|---|
| Диференціальна еволюція | 30–60 сек | Висока | Немає | Параметрична оптимізація |
| GAN (LayoutGAN++) | 0.5–2 сек | Середня | Датасет 10k планів | Швидкі варіанти |
| Дифузійна модель | 10–30 сек | Висока | Датасет 50k планів | Деталізовані плани |
| LLM + SVG | 5–15 сек | Низька | Немає | Концептуальні схеми |
Орієнтовні терміни впровадження
| Етап | Термін |
|---|---|
| Аналіз нормативної бази | 1–2 тижні |
| Параметризація ділянки та приміщень | 1 тиждень |
| Вибір і калібрування алгоритму | 1–2 тижні |
| Інтеграція з CAD/BIM | 1–2 тижні |
| Тестування на референтних проектах | 1 тиждень |
| Деплой і навчання команди | 1 тиждень |
Базова система з IFC-експортом — 4–6 тижнів. Повноцінна платформа з дифузійною моделлю, EnergyPlus та Revit-інтеграцією — 3–4 місяці.
Процес впровадження
- Аналіз нормативної бази та вимог — вивчаємо місцеві норми інсоляції, протипожежні розриви, поверховість.
- Параметризація ділянки та програми приміщень — перетворюємо плани та обмеження в машинно-читані дані.
- Вибір алгоритму генерації — визначаємо, чи потрібна диференціальна еволюція, дифузійна модель або їх комбінація.
- Інтеграція з CAD/BIM — налаштовуємо експорт в IFC, DXF, Dynamo-скрипти для Revit.
- Тестування на референтних проектах — порівнюємо результати з ручними плануваннями, коригуємо ваги.
- Деплой і навчання команди — розгортаємо систему на вашій інфраструктурі, проводимо тренінг для архітекторів.
Типові помилки при впровадженні
- Занадто жорсткі межі пошуку — якщо обмеження задані без запасу, DE може не знайти жодного допустимого рішення. Рекомендуємо пом'якшувати межі на 10% на етапі тесту.
- Ігнорування інсоляції у фітнес-функції — без неї план технічно коректний, але непридатний для житла. Завжди включаємо цей параметр з вагою не менше 0.3.
- Недостатній датасет для дифузійної моделі — менше 10 000 зразків веде до перенавчання та шумних генерацій. Використовуємо аугментацію та передтреновані ваги.
Що входить у результат
- Повний вихідний код системи з документацією
- API для інтеграції (REST/gRPC)
- Експорт в IFC 4.3, DXF, SVG
- Звіт з оптимізації до та після: скорочення часу ескізування в 5 разів, зниження вартості будівництва на 10–15%
- Навчання до 5 інженерів
- Гарантія продуктивності: p99 latency менше 2 секунд на варіант
Які результати дає впровадження?
Ми реалізували 15+ проектів для девелоперів та архітектурних бюро. Дослідження (Building Research & Information) підтверджують: генеративне проектування скорочує час ескізування в 5 разів і знижує вартість будівництва на 10–15%. Замовте консультацію: ми підготуємо архітектуру системи під ваші задачі. Зв'яжіться з нами — оцінимо ваш проект за 2 дні.







