
在许多场景中,我们可能需要从多个来源获取对一组对象的排名信息。例如,在产品评审、内容评级或竞赛评分中,多位评审员(或裁判)可能只评估了部分对象,并对他们所见的子集进行了排名。这些局部排名可能存在以下挑战:
我们的目标是,在这些限制条件下,综合所有局部排名,生成一个“最佳”的全局排名列表。
考虑一个具体示例:假设有六个物品['a', 'b', 'c', 'd', 'e', 'f'],由四位评委进行评审。每位评委只评审了三个物品,且每个物品至少被两位评委评审过。
items = ['a', 'b', 'c', 'd', 'e', 'f'] # 评委1的排名(从高到低) j1_rank = ['a', 'c', 'e'] # 评委2的排名(从高到低) j2_rank = ['b', 'd', 'f'] # 评委3的排名(从高到低) j3_rank = ['a', 'b', 'c'] # 评委4的排名(从高到低) j4_rank = ['d', 'e', 'f']
我们的任务是根据这些局部排名,推导出一个全局的、一致的排名列表。
解决这类问题的有效方法是采用基于位置分数的累加策略。其核心思想是为每个评委列表中的对象赋予一个分数,该分数反映其在该列表中的相对位置。然后,将所有评委对同一对象的得分累加起来,最终根据累加总分对所有对象进行排序。
我们将使用 collections.defaultdict 来方便地累加分数。
from collections import defaultdict
# 初始数据
items = ['a', 'b', 'c', 'd', 'e', 'f']
j1_rank = ['a', 'c', 'e']
j2_rank = ['b', 'd', 'f']
j3_rank = ['a', 'b', 'c']
j4_rank = ['d', 'e', 'f']
# 步骤1: 将每个评委的排名列表转换为字典,赋予位置分数
# 假设列表中的第一个元素排名最高,分数最高
def assign_scores(rank_list):
"""
将排名列表转换为 (item, score) 字典。
列表中位置越靠前,得分越高。
"""
return dict(map(lambda x: (x, len(rank_list) - rank_list.index(x)), rank_list))
j1_scores = assign_scores(j1_rank) # {'a': 3, 'c': 2, 'e': 1}
j2_scores = assign_scores(j2_rank) # {'b': 3, 'd': 2, 'f': 1}
j3_scores = assign_scores(j3_rank) # {'a': 3, 'b': 2, 'c': 1}
j4_scores = assign_scores(j4_rank) # {'d': 3, 'e': 2, 'f': 1}
# 步骤2: 累加所有对象的总分数
total_scores = defaultdict(int)
all_judge_scores = [j1_scores, j2_scores, j3_scores, j4_scores]
for item in items:
for judge_score_dict in all_judge_scores:
total_scores[item] += judge_score_dict.get(item, 0) # 如果评委未排名,则得分为0
# 累加后的分数示例: {'a': 6, 'b': 5, 'c': 3, 'd': 5, 'e': 3, 'f': 2}
# 步骤3: 根据总分数进行降序排序
# 将 defaultdict 转换为普通字典,然后按值降序排序
sorted_items_by_score = dict(sorted(total_scores.items(), key=lambda item: item[1], reverse=True))
# 提取排序后的键作为最终的全局排名列表
global_ranked_list = list(sorted_items_by_score.keys())
print("最终全局排名列表:", global_ranked_list)
# 预期输出: ['a', 'b', 'd', 'c', 'e', 'f'] 或 ['a', 'b', 'c', 'd', 'e', 'f']
# 在本例中,'b'和'd'分数相同,Python的稳定排序会保留原始插入顺序或字典内部顺序。
# 如果需要特定 tie-breaking 规则,则需额外处理。通过上述算法,我们得到了一个综合性的全局排名。在这个示例中,['a', 'b', 'd', 'c', 'e', 'f'] 是一个可能的输出。值得注意的是,如果多个对象获得相同的总分数(例如,本例中 'b' 和 'd' 都获得了 5 分),它们的相对顺序将取决于排序算法的稳定性或后续的 tie-breaking 规则。
从多个局部且可能存在分歧的排名列表中重构一个全局排名是一个常见的挑战。本文介绍了一种基于位置分数累加的有效算法,该算法通过为每个局部排名中的对象赋予分数,然后汇总并排序这些分数来生成最终的全局排名。这种方法不仅易于理解和实现,而且能够有效处理数据的不完整性和不一致性,提供了一个相对公平和综合的排名结果。在实际应用中,可以根据具体需求对分数分配和权重机制进行调整,以优化排名结果。
以上就是从多个局部排名列表重构全局排名列表的算法实践的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号