fix: use equal weight sharing for remaining 15% and quantize min_rate floor comparison to 2 decimal places
This commit is contained in:
@@ -71,15 +71,9 @@ def calculate_target_rate(values: list[Any], percent: Any = 0, algorithm: str =
|
||||
if N == 1:
|
||||
base = rates_sorted[0]
|
||||
else:
|
||||
base = Decimal("0")
|
||||
remaining = Decimal("1.0")
|
||||
for i in range(N):
|
||||
if i == N - 1:
|
||||
weight = remaining
|
||||
else:
|
||||
weight = remaining * Decimal("0.85")
|
||||
remaining -= weight
|
||||
base += rates_sorted[i] * weight
|
||||
w1 = Decimal("0.85")
|
||||
w_others = Decimal("0.15") / Decimal(N - 1)
|
||||
base = rates_sorted[0] * w1 + sum(rates_sorted[1:], Decimal("0")) * w_others
|
||||
else:
|
||||
raise WebsiteError(f"不支持的算法:{algorithm}")
|
||||
pct = Decimal(str(percent or 0))
|
||||
@@ -87,9 +81,9 @@ def calculate_target_rate(values: list[Any], percent: Any = 0, algorithm: str =
|
||||
raise WebsiteError("百分比不能为负数")
|
||||
target_rate = (base * (Decimal("1") + pct / Decimal("100"))).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
|
||||
if algorithm == "priority_weighted_plus_percent":
|
||||
min_rate = min(rates)
|
||||
if target_rate < min_rate:
|
||||
target_rate = min_rate
|
||||
min_rate_2d = min(rates).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
|
||||
if target_rate < min_rate_2d:
|
||||
target_rate = min_rate_2d
|
||||
return target_rate
|
||||
|
||||
|
||||
|
||||
@@ -406,8 +406,17 @@ def test_calculate_target_rate_priority_weighted():
|
||||
assert calculate_target_rate(["0.18", "0.25"], 50, "priority_weighted_plus_percent") == Decimal("0.29")
|
||||
# 单来源时等同于该来源倍率 + 百分比
|
||||
assert calculate_target_rate(["0.18"], 50, "priority_weighted_plus_percent") == Decimal("0.27")
|
||||
# 多来源时权重按低倍率优先,最高倍率不会主导价格
|
||||
assert calculate_target_rate(["0.18", "0.25", "0.38"], 50, "priority_weighted_plus_percent") == Decimal("0.29")
|
||||
# 多来源时最低倍率占 85%,其余平分 15%:
|
||||
# 0.18 * 0.85 + (0.25 + 0.38) * 0.075 = 0.20025 -> 0.20025 * 1.5 = 0.300375 -> 0.30
|
||||
assert calculate_target_rate(["0.18", "0.25", "0.38"], 50, "priority_weighted_plus_percent") == Decimal("0.30")
|
||||
|
||||
# 4 个来源以锁定均分 15% 的权重语义:
|
||||
# 0.18 * 0.85 + (0.24 + 0.30 + 0.36) * 0.05 = 0.198 -> 0.198 * 1.5 = 0.297 -> 0.30
|
||||
assert calculate_target_rate(["0.18", "0.24", "0.30", "0.36"], 50, "priority_weighted_plus_percent") == Decimal("0.30")
|
||||
assert calculate_target_rate(["0.18", "0.24", "0.30", "0.36"], 0, "priority_weighted_plus_percent") == Decimal("0.20")
|
||||
|
||||
# 验证保护线与精度保护:最低来源 0.124,应当四舍五入并返回两位小数
|
||||
assert calculate_target_rate(["0.124"], 0, "priority_weighted_plus_percent") == Decimal("0.12")
|
||||
|
||||
# 无可用正数倍率时报错
|
||||
with pytest.raises(WebsiteError, match="没有可用的正数上游倍率"):
|
||||
|
||||
Reference in New Issue
Block a user