|
|
""" |
|
|
Unit tests for NSGA-II Optimizer |
|
|
""" |
|
|
import pytest |
|
|
from shapely.geometry import box |
|
|
|
|
|
from src.models.domain import SiteBoundary, PlotType |
|
|
from src.algorithms.nsga2_optimizer import NSGA2Optimizer, IndustrialEstateProblem |
|
|
|
|
|
|
|
|
class TestNSGA2Optimizer: |
|
|
"""Test cases for NSGA2Optimizer""" |
|
|
|
|
|
@pytest.fixture |
|
|
def simple_site(self): |
|
|
"""Create a simple rectangular site for testing""" |
|
|
site_geom = box(0, 0, 500, 500) |
|
|
site = SiteBoundary( |
|
|
geometry=site_geom, |
|
|
area_sqm=site_geom.area |
|
|
) |
|
|
site.buildable_area_sqm = site.area_sqm |
|
|
return site |
|
|
|
|
|
def test_optimizer_initialization(self): |
|
|
"""Test that optimizer initializes correctly""" |
|
|
optimizer = NSGA2Optimizer() |
|
|
assert optimizer is not None |
|
|
assert optimizer.regulations is not None |
|
|
|
|
|
def test_problem_creation(self, simple_site): |
|
|
"""Test that optimization problem is created correctly""" |
|
|
problem = IndustrialEstateProblem( |
|
|
site_boundary=simple_site, |
|
|
regulations={}, |
|
|
n_plots=10 |
|
|
) |
|
|
|
|
|
assert problem.n_var == 50 |
|
|
assert problem.n_obj == 4 |
|
|
assert problem.n_plots == 10 |
|
|
|
|
|
def test_optimization_runs(self, simple_site): |
|
|
"""Test that optimization runs without errors (quick test)""" |
|
|
optimizer = NSGA2Optimizer() |
|
|
|
|
|
|
|
|
pareto_front = optimizer.optimize( |
|
|
site_boundary=simple_site, |
|
|
population_size=10, |
|
|
n_generations=5, |
|
|
n_plots=5 |
|
|
) |
|
|
|
|
|
assert pareto_front is not None |
|
|
assert len(pareto_front.layouts) > 0 |
|
|
assert pareto_front.generation_time_seconds >= 0 |
|
|
|
|
|
def test_pareto_front_layouts_have_metrics(self, simple_site): |
|
|
"""Test that generated layouts have calculated metrics""" |
|
|
optimizer = NSGA2Optimizer() |
|
|
|
|
|
pareto_front = optimizer.optimize( |
|
|
site_boundary=simple_site, |
|
|
population_size=10, |
|
|
n_generations=5, |
|
|
n_plots=5 |
|
|
) |
|
|
|
|
|
for layout in pareto_front.layouts: |
|
|
assert layout.metrics is not None |
|
|
assert layout.metrics.total_area_sqm > 0 |
|
|
|
|
|
|
|
|
def test_get_best_layouts(self, simple_site): |
|
|
"""Test retrieval of best layouts from Pareto front""" |
|
|
optimizer = NSGA2Optimizer() |
|
|
|
|
|
pareto_front = optimizer.optimize( |
|
|
site_boundary=simple_site, |
|
|
population_size=10, |
|
|
n_generations=5, |
|
|
n_plots=5 |
|
|
) |
|
|
|
|
|
max_sellable = pareto_front.get_max_sellable_layout() |
|
|
max_green = pareto_front.get_max_green_layout() |
|
|
balanced = pareto_front.get_balanced_layout() |
|
|
|
|
|
|
|
|
if len(pareto_front.layouts) > 0: |
|
|
assert max_sellable is not None |
|
|
assert max_green is not None |
|
|
assert balanced is not None |
|
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
|
pytest.main([__file__, "-v"]) |
|
|
|