"""偏好重排纯函数合同:分列计数、有界惩罚、确定性探索位与权重护栏。""" import pytest from muse.上下文.偏好重排 import ( 偏好信号, 偏好值, 合并信号表, 应用拒绝惩罚, 权重表, 构建偏好路, 注入探索位, ) @pytest.mark.case_id( "NC-w32-a10015", environment="离线", given="挑选信号行与消费统计", when="合并信号表", then=["弱强信号分列计数不混算;同版本两路信号并存"], contract="docs/系统架构/新版设计/模块设计/B09-上下文.md#偏好重排通路", ) def test_合并信号表分列不混算__a10015(): 表 = 合并信号表( [ {"method_version_id": "v1", "选用次数": 3, "拒绝次数": 1, "选中位次": [1, 2]}, {"method_version_id": "v2", "选用次数": 0, "拒绝次数": 2, "选中位次": []}, ], {"v1": 5, "v3": 2}, ) assert 表["v1"] == 偏好信号(3, 1, 5, (1, 2)) assert 表["v2"] == 偏好信号(0, 2, 0, ()) assert 表["v3"] == 偏好信号(0, 0, 2, ()) # 分列:选用与消费不互相折算 assert 偏好值(表["v1"]) == pytest.approx(3 * 0.05 + 1 * -0.08 + 5 * 0.10) @pytest.mark.case_id( "NC-w32-a10016", environment="离线", given="正负偏好信号与双路融合分", when="构建偏好路并应用拒绝惩罚", then=["只有正偏好进路;惩罚有界且不超过偏好路末位贡献"], contract="docs/系统架构/新版设计/模块设计/B09-上下文.md#偏好重排通路", ) def test_正偏好进路负偏好有界惩罚__a10016(): 信号表 = { "v1": 偏好信号(选用次数=2), "v2": 偏好信号(拒绝次数=3), "v3": 偏好信号(), } 路 = 构建偏好路(信号表) assert set(路) == {"v1"} and 路["v1"] > 0 融合 = {"v1": 0.03, "v2": 0.03, "v3": 0.03} 调整 = 应用拒绝惩罚(融合, 信号表) assert 调整["v1"] == 0.03 and 调整["v3"] == 0.03 assert 调整["v2"] < 0.03 # 惩罚上界 = 路权重/61(偏好路末位贡献量级) assert 0.03 - 调整["v2"] <= 权重表["路权重"] / 61.0 + 1e-12 # 大量拒绝也不能把惩罚推出上界(有界归一) 巨量 = {"v9": 偏好信号(拒绝次数=10000)} 融合巨量 = {"v9": 0.03} assert 0.03 - 应用拒绝惩罚(融合巨量, 巨量)["v9"] < 权重表["路权重"] / 61.0 @pytest.mark.case_id( "NC-w32-a10017", environment="离线", given="含已探索头部与未探索尾部的排名", when="注入探索位", then=["至多两个未探索版本晋升,替换头部末尾已探索项,结果确定"], contract="docs/系统架构/新版设计/模块设计/B09-上下文.md#偏好重排通路", ) def test_探索位晋升确定且有界__a10017(): 信号表 = {"a": 偏好信号(选用次数=1), "b": 偏好信号(消费次数=1), "c": 偏好信号(拒绝次数=1)} 排名 = [("a", 0.9), ("b", 0.8), ("c", 0.7), ("d", 0.6), ("e", 0.5)] 新排名, 探索集 = 注入探索位(排名, 信号表, 3) 头部 = [vid for vid, _ in 新排名[:3]] # d、e 未探索:晋升两个,替换头部末尾的已探索项(c、b) assert 头部[0] == "a" and set(头部[1:]) == {"d", "e"} assert 探索集 == {"d", "e"} # 未晋升的尾部按原序接回,候选回填链完整、总长度不变 assert [vid for vid, _ in 新排名] == ["a", "d", "e", "b", "c"] # 确定性:同输入同输出 assert 注入探索位(排名, 信号表, 3)[0] == 新排名 # 头部已含足量未探索项时不动 不动, 集 = 注入探索位([("d", 0.9), ("e", 0.8), ("a", 0.7)], 信号表, 3) assert [vid for vid, _ in 不动] == ["d", "e", "a"] and 集 == {"d", "e"} # 全已探索且无尾部候选时不动 全探索 = [("a", 0.9), ("b", 0.8)] assert 注入探索位(全探索, 信号表, 2)[0] == 全探索 @pytest.mark.case_id( "NC-w32-a10018", environment="离线", given="版本化权重表", when="核对权重护栏", then=["偏好路权重不超过0.25,权重表带版本标识"], contract="docs/系统架构/新版设计/模块设计/B09-上下文.md#偏好重排通路", ) def test_权重表护栏__a10018(): assert 权重表["version"] == "preference-rerank-v1" assert 0 < 权重表["路权重"] <= 0.25 assert 权重表["种类权重"]["拒绝"] < 0 < 权重表["种类权重"]["选用"] assert 权重表["探索位"] in (1, 2)