如何返回包含给定*部分*组合的所有组合?

时间:2012-06-27 18:12:33

标签: c# permutation combinations

我有这个计算 n选择k 的c#类,然后按字典顺序生成所有可能的组合。它还可以返回每个组合的订单号,例如:如果选择k(30,5),则传递[1,2,3,4,5]将返回1,而[26,27,28,则为142506, 29,30]。

有没有办法退回包含部分组合的所有订单号?因此,如果我通过[1,2,3,4],它将返回:1,2,3,... 25,26。

1: [1,2,3,4,5]
2: [1,2,3,4,6]
3: [1,2,3,4,7]
...
25: [1,2,3,4,29]
26: [1,2,3,4,30]

我需要这个用于抽奖。我希望每张票都有它的组合号码,我需要在绘制5个球的每一个时显示可能的赢家总数。现在每张票都有实际的组合,我运行一个查询来获得部分获胜者,但我想优化这个过程。

2 个答案:

答案 0 :(得分:3)

您需要的是一个函数,对于组合[a,b,c,d,e],返回该组合的订单号。然后你可以得到组合集(可能数字的集合减去已经选择的数字)选择(你还没有选择的数量),添加已经选择到每个组合的数字,重新排序每个组合,并使用获取订单号的功能。

编辑:这可能会有所帮助:saliu.com/bbs/messages/348.html

EDIT2:答案就在这里:How to calculate the index (lexicographical order) when the combination is given

EDIT3:我为此尝试了一些C#代码:

private IEnumerable<int[]> CombinationsFor(int n, int k);
private int CombinationsCount(int n, int k);

private int IndexFor(int n, int[] combination)
{
    int k = combination.Count();
    int ret = 0;

    int j = 0;
    for (int i = 0; i < k; i++)
    {
        for (j++; j < combination[i]; j++)
        {
            ret += CombinationsCount(n - j, k - i - 1);
        }
    }

    return ret;
}

private IEnumerable<int> PossibleCombinations(int n, int k, int[] picked)
{
    int m = picked.Count();

    int[] reverseMapping = Enumerable.Range(0, n)
        .Where(i=>!picked.Contains(i))
        .ToArray();

    return CombinationsFor(n-m, k-m)
        .Select(c => c
            .Select(x=>reverseMapping[x])
            .Concat(picked)
            .OrderBy(x=>x)
            .ToArray()
        )
        .Select(c => IndexFor(n, c));
}

答案 1 :(得分:3)

您需要的组合是(n-d) choose (k-d),其中d是固定抽奖的数量。

当你生成它们时,它们将没有正确的数字(它们正在跳过最后的d数字而不是你想要的数字),而只是使用子列表的反向顺序映射来重新组合你的组合:

(在伪python代码中,因为这与C#完全无关)

listing = [1, 2, ..., 30]
partial = [4, 7, 25]
draw_size = 5
remaining = listing - partial
reverse_order_mapping = [(index, item) in remaining.items_and_indexes]

n = listing.size  // 30
k = draw_size     // 5
d = partial.size  // 3

for comb in ((n-d) choose (k-d))
  actual_comb = comb.map(reverse_order_mapping)
  print actual_comb
end

然后,您只需使用生成的组合调用您的函数(在需要时对其进行排序)。