feat(B05 노선 추천 엔진): 합치기 판정 = 바뀐 측점 횡단 차이 · 후보 줄 세움 = 노선 횡단 토공 · 균형 종단 위 5 개 (419-1)
- 420 cross_earthwork · cross_earthwork_delta 이음 — 합치기 멈춤 = 계획고 지반고 노선 횡단 +10 % - 토공 · 공사비 줄 세움 = 상한 누른 계획선 횡단(종단 켬) · 지반고 횡단(종단 끔) - 위 후보 수 3 → 5(검증_sub4 균형 종단 토공 최소 = 줄 세움 5 위) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014utrjfoW831Vc5wJUd13kL
This commit is contained in:
@@ -40,9 +40,9 @@ def runs() -> dict:
|
||||
caught: dict = {}
|
||||
real = engine.build_pool
|
||||
|
||||
def spy(graph, follow, max_grade, min_radius_m, measure, snap):
|
||||
def spy(graph, follow, max_grade, min_radius_m, measure, snap, **kw):
|
||||
caught["measure"] = measure
|
||||
caught["pool"] = real(graph, follow, max_grade, min_radius_m, measure, snap)
|
||||
caught["pool"] = real(graph, follow, max_grade, min_radius_m, measure, snap, **kw)
|
||||
return caught["pool"]
|
||||
|
||||
engine._POOLS.clear()
|
||||
|
||||
@@ -17,6 +17,7 @@ from B05_Profile.B05_Profile_Engine_RouteInitial import ends_grade, generate_ini
|
||||
from B05_Profile.B05_Profile_Engine_RouteInitial_Merge import (
|
||||
TOTAL_EARTH_TOL,
|
||||
Guard,
|
||||
RouteEarth,
|
||||
merge_same_side,
|
||||
)
|
||||
from B05_Profile.B05_Profile_Engine_RouteInitial_Pool import SHORTLIST, choose, hard_limits
|
||||
@@ -113,7 +114,7 @@ def _merge(earth_base: float, delta: float):
|
||||
outline = build_planned_polyline(
|
||||
SAME, min_radius_m=RADIUS, simplify=False, curve_flags=[True] * len(SAME)
|
||||
)
|
||||
base = {**FLAT, "cut_m3": earth_base, "fill_m3": 0.0}
|
||||
base = {**FLAT, "cut_m3": 0.0, "fill_m3": 0.0} # 띠 가늠은 안 씀
|
||||
calls = []
|
||||
|
||||
def cross(before, after, window):
|
||||
@@ -121,7 +122,8 @@ def _merge(earth_base: float, delta: float):
|
||||
return delta
|
||||
|
||||
guard = Guard(SearchGrid(SAME, _flat_terrain(402.0, 262.0), [], stream_offset_m=100.0), 0.14)
|
||||
merged = merge_same_side((outline, base), guard, RADIUS, lambda line: base, cross)[0]
|
||||
earth = RouteEarth(lambda line: earth_base, cross)
|
||||
merged = merge_same_side((outline, base), guard, RADIUS, lambda line: base, earth)[0]
|
||||
return merged, calls
|
||||
|
||||
|
||||
@@ -148,22 +150,31 @@ def _route(name: str, earth: float, station: int = 0):
|
||||
|
||||
|
||||
def test_choose_profiles_only_shortlist() -> None:
|
||||
"""종단 반영 켬 토공 = 상한 누른 계획선 토공 위 3 개만 균형 종단 · 그 사이에서 고름."""
|
||||
routes = [_route(f"r{i}", 100.0 + 10 * i) for i in range(8)] + [_route("off", 1.0, 1)]
|
||||
"""종단 반영 켬 토공 = 노선 횡단 토공(줄 세움) 위 `SHORTLIST` 개만 균형 종단 · 그 사이에서 고름 ·
|
||||
줄 세움 = `earth`(켬 = 상한 누른 계획선 · 끔 = 지반고) · 없으면 띠 가늠."""
|
||||
routes = [_route(f"r{i}", 100.0 + 10 * i) for i in range(12)] + [_route("off", 1.0, 1)]
|
||||
last = f"r{SHORTLIST - 1}"
|
||||
profiled = []
|
||||
|
||||
def profile(route):
|
||||
profiled.append(route[1]["name"])
|
||||
# 균형 종단 토공은 순서가 바뀜 — 셋째가 가장 작음
|
||||
earth = {"r0": 900.0, "r1": 800.0, "r2": 300.0}.get(route[1]["name"], 50.0)
|
||||
# 균형 종단 토공은 순서가 바뀜 — 줄 세운 마지막이 가장 작음 · 밖은 더 작아도 안 봄
|
||||
earth = 300.0 if route[1]["name"] == last else 900.0
|
||||
route[1]["profile"] = {"cut_m3": earth, "fill_m3": 0, "borrow_m3": 0, "spoil_m3": 0}
|
||||
|
||||
chosen = choose("earthwork", routes, True, profile)
|
||||
assert profiled == ["r0", "r1", "r2"] and len(profiled) == SHORTLIST
|
||||
assert chosen[1]["name"] == "r2"
|
||||
assert profiled == [f"r{i}" for i in range(SHORTLIST)]
|
||||
assert chosen[1]["name"] == last
|
||||
# 종단 끔 = 줄 세우기 값 그대로 · 종단 안 붙임
|
||||
profiled.clear()
|
||||
assert choose("earthwork", routes, False, profile)[1]["name"] == "r0" and not profiled
|
||||
# 횡단 줄 세움이 띠 가늠과 다르면 그것을 따름(끔 = 지반고 횡단 하나로 고름)
|
||||
cross = {f"r{i}": 1000.0 - i for i in range(12)}
|
||||
|
||||
def earth(route, capped):
|
||||
return cross.get(route[1]["name"], 0.0) + (0.0 if capped else 5.0)
|
||||
|
||||
assert choose("earthwork", routes, False, None, earth)[1]["name"] == "r11"
|
||||
|
||||
|
||||
def test_ends_grade() -> None:
|
||||
|
||||
Reference in New Issue
Block a user