Improve target range factor with relative distance

- Replace harsh 1/(1+distance) with bounded relative scoring
- Factor > 1.0 when moving toward target, < 1.0 when moving away
- Minimum factor 0.1 to avoid zero weights
- Test with max_path=150 shows reaching ~90% of 2-octave target
This commit is contained in:
Michael Winter 2026-03-14 03:05:23 +01:00
parent 737f1e4886
commit 2fe8737cfe

View file

@ -343,11 +343,11 @@ class PathFinder:
config: dict, config: dict,
cumulative_trans: "Pitch | None", cumulative_trans: "Pitch | None",
) -> float: ) -> float:
"""Returns 1.0 if at target, 0.0 if far from target. """Returns factor based on movement toward target.
Target progresses based on position in path. Target progresses based on position in path.
Factor > 1.0 if moving toward target, < 1.0 if moving away.
""" """
# Check weight - if 0, return 1.0 (neutral)
if config.get("weight_target_range", 1) == 0: if config.get("weight_target_range", 1) == 0:
return 1.0 return 1.0
@ -364,15 +364,27 @@ class PathFinder:
progress = len(path) / max_path progress = len(path) / max_path
current_target = progress * target_cents current_target = progress * target_cents
current_cumulative_cents = cumulative_trans.to_cents()
edge_trans = edge_data.get("transposition") edge_trans = edge_data.get("transposition")
new_cumulative = cumulative_trans.transpose(edge_trans) new_cumulative = cumulative_trans.transpose(edge_trans)
new_cumulative_cents = new_cumulative.to_cents() new_cumulative_cents = new_cumulative.to_cents()
# Closeness: 1.0 if at target, 0.0 if far
if current_target <= 0: if current_target <= 0:
return 1.0 return 1.0
distance = abs(new_cumulative_cents - current_target)
return 1.0 / (1.0 + distance) dist_before = abs(current_cumulative_cents - current_target)
dist_after = abs(new_cumulative_cents - current_target)
if dist_before == 0:
return 1.0
if dist_after < dist_before:
return 1.0 + (dist_before - dist_after) / dist_before
elif dist_after > dist_before:
return max(0.1, 1.0 - (dist_after - dist_before) / dist_before)
else:
return 1.0
def is_hamiltonian(self, path: list["Chord"]) -> bool: def is_hamiltonian(self, path: list["Chord"]) -> bool:
"""Check if a path is Hamiltonian (visits all nodes exactly once).""" """Check if a path is Hamiltonian (visits all nodes exactly once)."""