From 3082007dba365255e437a9dab13d28866d82e889 Mon Sep 17 00:00:00 2001 From: umsangdon Date: Sun, 18 Oct 2026 13:26:18 +0900 Subject: [PATCH] =?UTF-8?q?fix(B05=20=EB=85=B8=EC=84=A0=20=EC=B6=94?= =?UTF-8?q?=EC=B2=9C=20[=EC=A0=81=EC=9A=A9]=20=EC=A2=85=EB=8B=A8):=20?= =?UTF-8?q?=EC=A7=81=EC=84=A0=20=EA=B8=B0=EC=9A=B8=EA=B8=B0=20=EB=88=84?= =?UTF-8?q?=EB=A5=BC=20=EB=95=8C=20=ED=91=9C=EA=B3=A0=20=EB=B0=98=EC=98=AC?= =?UTF-8?q?=EB=A6=BC=20=EC=97=AC=EC=9C=A0=200.1=20mm=20=C2=B7=20=EC=83=81?= =?UTF-8?q?=ED=95=9C=EA=B3=BC=20=EA=B0=99=EC=9D=80=20=EA=B7=A0=ED=98=95=20?= =?UTF-8?q?=EC=A2=85=EB=8B=A8=EC=9D=80=20=EC=83=81=ED=95=9C=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20(419-3)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 검증_sub4 [적용] 뒤 종단 최대 14.47 % → 14.001 %(정본 0.1 mm 반올림 몫) → 14.0 %(넘음 표시 없음) - test_74 변화점 계획고 비교를 0.5 mm 허용차로 Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_014utrjfoW831Vc5wJUd13kL --- .../B05_Profile_Engine_RouteInitial_Profile.py | 12 +++++++++--- resources/tester/test_419_1_recommend_engine.py | 1 + resources/tester/test_74_route_confirm_initial.py | 5 ++++- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/B05_Profile/B05_Profile_Engine_RouteInitial_Profile.py b/B05_Profile/B05_Profile_Engine_RouteInitial_Profile.py index aa0d43615..8b58087b3 100644 --- a/B05_Profile/B05_Profile_Engine_RouteInitial_Profile.py +++ b/B05_Profile/B05_Profile_Engine_RouteInitial_Profile.py @@ -63,6 +63,8 @@ LAMBDA_STEPS = 14 EXACT_STEPS = 6 # 고른 계획선의 실제 누가토량으로 λ 를 더 좁히는 횟수 PIPE_SNAP_M = 5.0 # 관 자리가 노선에서 이 안이면 그 노선의 관으로 봄 GRADE_EPS = 1e-6 +# [적용] 종단 꼭짓점 표고 반올림(0.1 mm) 두 끝 몫 — 직선 기울기 누를 때 남기는 여유(m · 419-3) +ROUND_SLACK_M = 1e-4 def _sample( @@ -251,10 +253,11 @@ def _reference(ground: np.ndarray, spans: np.ndarray, max_grade: float) -> np.nd def _hold(s: np.ndarray, z: np.ndarray, limit: float) -> np.ndarray: """변화점 사이 직선 기울기를 `limit` 안으로 — 시종점은 그대로 두고 앞으로 · 뒤로 누름(시종점 - 사이가 상한 안이면 몇 번 안에 둘 다 맞음).""" + 사이가 상한 안이면 몇 번 안에 둘 다 맞음). 마디마다 `ROUND_SLACK_M` 남김 — 종단 정본이 표고를 + 0.1 mm 로 반올림해도 상한 안(검증_sub4 14.001 %).""" z = z.copy() start, end = z[0], z[-1] - rise = limit * np.diff(s) + rise = np.maximum(limit * np.diff(s) - ROUND_SLACK_M, 0.0) for _ in range(4): z[0] = start for i in range(1, len(z)): @@ -278,7 +281,10 @@ def held_pass_through( from B05_Profile.B05_Profile_Engine_Grade_Alignment import build_curves, evaluate stations_a, plan_a = np.asarray(stations, float), np.asarray(plan, float) - limit = float(np.abs(np.diff(plan_a) / np.diff(stations_a)).max()) + GRADE_EPS + limit = float(np.abs(np.diff(plan_a) / np.diff(stations_a)).max()) + # 계획고 1 mm 반올림(`plan_m`)으로 상한을 살짝 넘은 몫은 상한으로 + legal = policy.max_grade_pct / 100.0 + limit = legal if legal <= limit <= legal + 1e-4 else limit + GRADE_EPS target = np.interp(base_s, stations_a, plan_a) base_z = _hold(base_s, target, limit) for _ in range(12): diff --git a/resources/tester/test_419_1_recommend_engine.py b/resources/tester/test_419_1_recommend_engine.py index dbaa0e4a4..89ca5bceb 100644 --- a/resources/tester/test_419_1_recommend_engine.py +++ b/resources/tester/test_419_1_recommend_engine.py @@ -274,4 +274,5 @@ def test_419_3_applied_profile_holds_grade() -> None: assert steepest(pass_through(s, plan, policy)) > 0.15 # 옛 맞춤 = 상한 넘음(재현) held = held_pass_through(s, list(s), list(plan), policy) assert steepest(held) <= 0.14 + 1e-5 + assert steepest(np.round(held, 4)) <= 0.14 # 정본 0.1 mm 반올림 뒤도 상한 안 assert held[0] == pytest.approx(plan[0]) and held[-1] == pytest.approx(plan[-1]) diff --git a/resources/tester/test_74_route_confirm_initial.py b/resources/tester/test_74_route_confirm_initial.py index 1c79e715b..089e1dbfa 100644 --- a/resources/tester/test_74_route_confirm_initial.py +++ b/resources/tester/test_74_route_confirm_initial.py @@ -6,6 +6,8 @@ import json from pathlib import Path +import pytest + from B05_Profile.B05_Profile_Router_Replan import RouteReplanRequest from B05_Profile.B05_Profile_Router_RouteInitial import _set_base_pvi from B06_Section.B06_Section_Router_Design import CARRY_INPUT_KEYS @@ -47,7 +49,8 @@ def test_변화점_계획고를_균형_종단으로(tmp_path: Path) -> None: p["elevation_m"] for p in json.loads(path.read_text("utf-8"))["profile_alignment"]["base_pvi"] ] - assert got == [10.0, 12.0, 13.0, 14.0] # 구조물 측점(30 m)은 직선 보간 + # 구조물 측점(30 m)은 직선 보간 · 상한 누를 때 반올림 여유 0.1 mm 몫(419-3) + assert got == pytest.approx([10.0, 12.0, 13.0, 14.0], abs=5e-4) def test_확인_요청_기본은_끔() -> None: