模拟纸牌游戏。堕落的西装

时间:2014-12-08 14:49:17

标签: optimization combinations mathematical-optimization

这可能有点神秘,但我有一个非常具体的问题。首先是我当前的设置

即在我的卡片模拟器中,我以4套8个牌向4名玩家交易32张牌。所以每位玩家8张牌。 有4种标准套装(黑桃,帽子等) 我目前的实施周期投出了32个中的8个的所有组合 女巫给了我很多可能性。 即第一个玩家可以拥有10518300个不同的牌。 然后第二个可以发出735471个不同的牌。 第三名玩家然后是12870手。 最后第四个只能有1个 给了我一个总共9.9561092e + 16种不同的独特方式来处理一副32张牌给4名玩家。如果卡的顺序无关紧要。

在4 Ghz处理器上,即使每次可能有1个滴答,我也需要半年时间。

然而,我想通过交换钻石,黑客和黑桃来简化这种卡的交易。这意味着向玩家1处理8个仇恨相当于交易8个黑桃。 (请注意,这不适用于俱乐部)

我正在寻找一种方法来生成它。因为这会将第一只手的可能性降低至少6倍。我目前的实现是在c ++中。 但请随意用不同的语言回答

/** http://stackoverflow.com/a/9331125 */
unsigned cjasMain::nChoosek( unsigned n, unsigned k )
{
    //assert(k < n);
    if (k > n) return 0;
    if (k * 2 > n) k = n-k;
    if (k == 0) return 1;

    int result = n;
    for( int i = 2; i <= k; ++i ) {
        result *= (n-i+1);
        result /= i;
    }
    return result;
}
/** [combination c n p x]
 * get the [x]th lexicographically ordered set of [r] elements in [n]
 * output is in [c], and should be sizeof(int)*[r]
 * http://stackoverflow.com/a/794 */
void cjasMain::Combination(int8_t* c,unsigned n,unsigned r, unsigned x){
    ++x;
    assert(x>0);
    int i,p,k = 0;
    for(i=0;i<r-1;i++){
        c[i] = (i != 0) ? c[i-1] : 0;
        do {
            c[i]++;
            p = nChoosek(n-c[i],r-(i+1));
            k = k + p;
        } while(k < x);
        k = k - p;
    }
    c[r-1] = c[r-2] + x - k;
}
/**http://stackoverflow.com/a/9430993 */
template <unsigned n,std::size_t r>
void cjasMain::Combinations()
{
    static_assert(n>=r,"error n needs to be larger then r");
    std::vector<bool> v(n);
    std::fill(v.begin() + r, v.end(), true);
    do
    {
        for (int i = 0; i < n; ++i)
        {
            if (!v[i])
            {
                COUT << (i+1) << " ";
            }
        }
        static int j=0;
        COUT <<'\t'<< j++<< "\n";
    }
    while (std::next_permutation(v.begin(), v.end()));
    return;
}

要求是从词典编号我可以取回原始数组。 即便是最轻微的优化也可以帮助我的蒙托卡罗模拟我希望。

0 个答案:

没有答案