fix(769-1): 추천 4 갈래 = 계산 로직 결과 그대로 — 같은 쪽 곡선 합치기 · 측점 맞춤 뺌
- 요구 611: 추천노선 = 평면계획선을 긋는 가이드 선 · 합치기 · 스냅은 예정노선 수정 뒤 평면계획선에만 - _trace = 경로 탐색 → 곡선 넣기(curve_every_kink) → 큰 R(widen) 까지 · merge_same_side · settle 뺌 - 예상노선 추적(merged_follow) · 체인 · /route/plan · replan · follow 는 합치기 · 스냅 그대로 - Pool.snap · Pool.cross · build_pool snap · cross 인자 · 엔진 fit · route_earth · merge_delta 걷음(쓰는 곳 없음) - ALGO_VERSION 9 → 10 - 낡은 시험 고침: test_419_1 · test_351_2 추천 갈래 측점 위 기대 뺌(추적만 측점 위 · 갈래는 안 맞춤 확인 추가) · test_route_initial 영선 · test_351_2 비중 기울기 상한 기대 뺌(원지반 기울기 참고만 · 비중은 벌점만) · test_224_4 build_pool 엿봄 인자 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -28,7 +28,8 @@
|
||||
가파른 지형(옆경사 중앙값 67 %)에서는 제약 안의 길이 폭 10~20 m 한 띠뿐이라 갈래끼리 가까울 수
|
||||
있다 — 응답 `similar`(10 m 안인 다른 갈래) · `band_width_m`(띠 폭 어림)로 알린다(PLAN 23-4).
|
||||
|
||||
공통 제약(follow 밖 모든 갈래 · **넘지 못함**) — 최소 곡선반지름 · 계류 이격 · 곡선 MC = 일반측점:
|
||||
공통 제약(follow 밖 모든 갈래 · **넘지 못함** · 측점 맞춤 · 합치기 없음 = 가이드 선 · 요구 611) —
|
||||
최소 곡선반지름 · 계류 이격:
|
||||
· 종단기울기 — 지반 기울기가 상한을 넘는 링크는 탐색에서 뺌(비탈 곧장 오르는 길 막이). 곡선
|
||||
맞춤 뒤 측점(20 m) 사이 **원지반 기울기는 참고만**(계획선 높이로 푸는 값 · 요구 253-1 · 419) —
|
||||
못 지킨 곳 수(`over_limit.total`)에 안 듦 · 목록엔 남음. 시종점 높이 차가 상한을 넘으면
|
||||
@@ -64,11 +65,8 @@ import numpy as np
|
||||
from B05_Profile.B05_Profile_Engine_RouteInitial_CrossEarth import cross_earthwork
|
||||
from B05_Profile.B05_Profile_Engine_RouteInitial_Follow import (
|
||||
FollowLand,
|
||||
cross_delta,
|
||||
cross_total,
|
||||
merged_follow,
|
||||
)
|
||||
from B05_Profile.B05_Profile_Engine_RouteInitial_Merge import RouteEarth
|
||||
from B05_Profile.B05_Profile_Engine_RouteInitial_Metrics import GRADE_SMOOTH_M, route_metrics
|
||||
from B05_Profile.B05_Profile_Engine_RouteInitial_Pool import (
|
||||
Pool,
|
||||
@@ -94,7 +92,6 @@ from B05_Profile.B05_Profile_Engine_RouteInitial_Search import (
|
||||
)
|
||||
from B05_Profile.B05_Profile_Engine_RouteInitial_Station import (
|
||||
off_station_count,
|
||||
snap_curves_to_stations,
|
||||
with_station_misses,
|
||||
)
|
||||
|
||||
@@ -352,12 +349,6 @@ def generate_initial_route(
|
||||
)
|
||||
)
|
||||
|
||||
def fit(outline: Any, guard: Any = None) -> Any:
|
||||
# R = 일반측점(383-1) — 갈래 후보는 직접 잼(`guard` · 406 · 거리 한도 없음) · 추적은 제약을
|
||||
# 안 따짐(새 초기 노선 `snapped_initial` 과 같은 잣대 · 거리 한도 그대로).
|
||||
moved = snap_curves_to_stations(outline, min_radius_m, guard=guard)
|
||||
return outline if moved is None else moved
|
||||
|
||||
def follow_line(grid: Any = None) -> tuple[Any, dict[str, Any]]:
|
||||
# 예상노선 추적 = 전처리 초기값(`planned_route_initial.csv`)과 같은 함수(곡선 최적 · 측점
|
||||
# 맞춤 · 758-1 `..._Follow.merged_follow`) · 같은 입력 → 같은 선. 넘은 곳만 목록에 뜸.
|
||||
@@ -392,13 +383,6 @@ def generate_initial_route(
|
||||
design_curves=[curve.as_dict() for curve in line.curves],
|
||||
)
|
||||
|
||||
def route_earth(line: Any) -> float:
|
||||
# 합치기 멈춤 잣대 = 계획고 지반고 횡단(1차 종단 규칙 · 종단 끔과 같음)
|
||||
return cross_total(line, terrain, standard)
|
||||
|
||||
def merge_delta(before: Any, after: Any, window: tuple[float, float]) -> float:
|
||||
return cross_delta(before, after, window, terrain, standard)
|
||||
|
||||
def cross_score(route: Any, capped: bool) -> float:
|
||||
# 후보 줄 세움(419) — 켬 = 상한 누른 계획선(`_reference`) 횡단 · 끔 = 계획고 지반고 횡단
|
||||
held = pool.scores if pool is not None else {}
|
||||
@@ -446,16 +430,7 @@ def generate_initial_route(
|
||||
graph = RouteGraph(grid, expected, limit=max_grade, min_radius_m=min_radius_m)
|
||||
while len(_POOLS) >= POOL_CACHE_SIZE:
|
||||
_POOLS.pop(next(iter(_POOLS)))
|
||||
# 합치기 멈춤 토공 = 노선 횡단 + 바뀐 측점 횡단 차이(420 `..._CrossEarth` · 419)
|
||||
_POOLS[key] = build_pool(
|
||||
graph,
|
||||
follow_line(grid),
|
||||
max_grade,
|
||||
min_radius_m,
|
||||
measure,
|
||||
fit,
|
||||
cross=RouteEarth(route_earth, merge_delta),
|
||||
)
|
||||
_POOLS[key] = build_pool(graph, follow_line(grid), max_grade, min_radius_m, measure)
|
||||
pool = _POOLS[key]
|
||||
bound = pool.bound
|
||||
if target == "weighted":
|
||||
@@ -464,8 +439,7 @@ def generate_initial_route(
|
||||
# 토공 · 공사비 = 횡단 토공으로 줄 세움 · 종단 반영 켬이면 위 후보만 균형 종단(빠른
|
||||
# 판) · 고른 하나만 아래에서 바로 셈(419)
|
||||
outline, metrics = choose(target, pool.candidates, with_profile, quick, cross_score)
|
||||
# 후보는 이미 측점에 맞춘 선(383-1 · `..._Pool.settle` · 맞추기 전 선은 안 냄 · 419)
|
||||
snapped = (outline, metrics)
|
||||
# 추천 = 계산 로직 결과 그대로(합치기 · 측점 맞춤 없음 · 요구 611) · 추적만 평면계획선 길
|
||||
|
||||
def finish(route: tuple[Any, dict[str, Any]]) -> dict[str, Any]:
|
||||
# 정밀 종단은 낼 사본에만 — 묶음 캐시 후보는 빠른 판 그대로 둬 다음 고르기가 같은 잣대끼리
|
||||
@@ -486,7 +460,7 @@ def generate_initial_route(
|
||||
"metrics": values,
|
||||
}
|
||||
|
||||
shown = finish(snapped)
|
||||
shown = finish((outline, metrics))
|
||||
ends = ends_grade(expected, terrain, shown["metrics"]["length_m"])
|
||||
return {
|
||||
"mode": mode,
|
||||
|
||||
Reference in New Issue
Block a user