You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现不枚举的排列组合问题正确答案数量计算函数?

问题描述

需要实现一个Python函数get_combinations,无需枚举所有可能(保证计算效率),计算符合条件的正确组合数量。函数结构参考:

from itertools import combinations_with_replacement
from itertools import permutations

def get_combinations(event, population):    
    # "calculate number of answers"
    return nr_correct_answers

参数示例

  • 纯颜色列表形式:

    # event参数
    event_1 = ["Red", "Blue", "Black"]
    event_2 = ["Red", "Red", "Blue"]
    # population参数
    population = ["Red", "Red", "Blue", "Blue", "Black", "Black"]
    

    预期结果:event_1返回8,event_2返回2。

  • (数量,颜色)元组形式:

    event_1 = [(1,"Red"), (1,"Blue"), (1,"Black")]
    event_2 = [(2,"Red"), (1,"Blue")]
    population = [(2,"Red"), (2,"Blue"), (2,"Black")]
    

    预期结果同上。

需求补充

  • 不考虑选球顺序,但种群中每个元素是唯一带编号的球,仅关注颜色匹配;
  • 需支持两种参数输入格式;
  • 已尝试itertools.permutations和product但未成功,寻求正确实现方式。

解决方案

核心思路是通过组合数公式直接计算,避免枚举所有可能,大幅提升计算效率。

1. 统一输入格式

先把两种输入格式转换为颜色计数字典,方便后续统一计算:

from collections import defaultdict
import math

def _to_count_dict(items):
    count_dict = defaultdict(int)
    for item in items:
        if isinstance(item, tuple):
            # 处理(数量,颜色)格式
            cnt, color = item
            count_dict[color] += cnt
        else:
            # 处理纯颜色列表格式
            count_dict[item] += 1
    return count_dict

2. 完整函数实现

对每个颜色,计算从种群中选取对应数量的组合数,再将所有颜色的组合数相乘得到最终结果:

from collections import defaultdict
import math

def _to_count_dict(items):
    count_dict = defaultdict(int)
    for item in items:
        if isinstance(item, tuple):
            cnt, color = item
            count_dict[color] += cnt
        else:
            count_dict[item] += 1
    return count_dict

def get_combinations(event, population):
    event_counts = _to_count_dict(event)
    pop_counts = _to_count_dict(population)
    
    total = 1
    for color, needed in event_counts.items():
        available = pop_counts.get(color, 0)
        if available < needed:
            return 0
        # 计算组合数C(available, needed):从available个元素中选needed个的组合数
        total *= math.comb(available, needed)
    
    return total

3. 验证效果

# 测试列表格式参数
event_1 = ["Red", "Blue", "Black"]
event_2 = ["Red", "Red", "Blue"]
population = ["Red", "Red", "Blue", "Blue", "Black", "Black"]
print(get_combinations(event_1, population))  # 输出8
print(get_combinations(event_2, population))  # 输出2

# 测试元组格式参数
event_1_t = [(1,"Red"), (1,"Blue"), (1,"Black")]
event_2_t = [(2,"Red"), (1,"Blue")]
population_t = [(2,"Red"), (2,"Blue"), (2,"Black")]
print(get_combinations(event_1_t, population_t))  # 输出8
print(get_combinations(event_2_t, population_t))  # 输出2

关键说明

  • 使用math.comb(Python 3.10+支持)直接计算组合数,无需枚举所有可能,效率极高;
  • 兼容两种输入格式,通过_to_count_dict做统一转换;
  • 若任意颜色的需求数量超过种群中该颜色的存量,直接返回0,逻辑严谨。

内容的提问来源于stack exchange,提问作者B.abba

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 01:55:00