Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我怎样才能将费舍尔·耶茨·克努斯应用于有限制的洗牌?或者还有其他有效的方法吗?_C#_Algorithm_Shuffle - Fatal编程技术网

C# 我怎样才能将费舍尔·耶茨·克努斯应用于有限制的洗牌?或者还有其他有效的方法吗?

C# 我怎样才能将费舍尔·耶茨·克努斯应用于有限制的洗牌?或者还有其他有效的方法吗?,c#,algorithm,shuffle,C#,Algorithm,Shuffle,例如,我想洗牌4副牌,并确保: 任何连续的4张牌都不会来自同一副牌 当然,我可以先洗牌,然后过滤掉不好的排列,但是如果限制很强(例如,任何连续的两张牌都不会来自同一副牌),那么失败的次数就会太多 如果我不介意,如果它是稍微公正的,(当然,偏见越少越好),我应该怎么做 编辑:澄清 是的,我希望尽可能统一地从所有完整洗牌中挑选,以便应用此附加标准。我将按以下方式处理: 首先,您可以洗牌每4个牌组(使用FYK算法) 然后在每套分区中不超过3个元素的约束下,在4副牌的52张牌中生成4个分区(*我在下面定

例如,我想洗牌4副牌,并确保:

任何连续的4张牌都不会来自同一副牌

当然,我可以先洗牌,然后过滤掉不好的排列,但是如果限制很强(例如,任何连续的两张牌都不会来自同一副牌),那么失败的次数就会太多

如果我不介意,如果它是稍微公正的,(当然,偏见越少越好),我应该怎么做

编辑:澄清


是的,我希望尽可能统一地从所有完整洗牌中挑选,以便应用此附加标准。

我将按以下方式处理:

首先,您可以洗牌每4个牌组(使用FYK算法)

然后在每套分区中不超过3个元素的约束下,在4副牌的52张牌中生成4个分区(*我在下面定义了分区):

例如:

(1,3,0,3,2,0,1) would be a partition of 10 with this constraint
(1,1,1,1,1,1,1,1,1,1) would be a partition of 10 too with this constraint
(3,0,0,3)
(0,3,3,0)
然后根据这些分区混合4个甲板。

from random import randint,choice

def randomPartition(maxlength=float('inf'),N=52): 
    '''
    the max length is the last constraint in my expanation:
      you dont want l[maxlength:len(l)]) to be more than 3
 in this case we are going to randomly add +1 to all element in the list that are less than 3

    N is the number of element in the partition
     '''
    l=[] # it's your result partition
    while(sum(l)<N ):
        if (len(l)>maxlength and sum(l[maxlength:len(l)])>=3): #in the case something goes wrong 
            availableRange=[i for i in range(len(l)) if l[i]<3] #create the list of available elements to which you can add one
            while(sum(l)<N):
                temp=choice(availableRange) #randomly pick element in this list
                l[temp]+=1
                availableRange=[i for i in range(len(l)) if l[i]<3] #actualize the list
                if availableRange==[]: #if this list gets empty your program cannot find a solution
                    print "NO SOLUTION" 
                    break
            break
        else:
            temp=randint(0,min(N-sum(l),3)) # If everything goes well just add the next  element in the list until you get a sum of N=52
            l.append(temp)
    return l
例如,如果您有:

(3,2,1)
(2,2,2)
你先乘一号甲板的3号甲板,然后乘二号甲板的2号甲板,然后乘一号甲板的2号甲板,然后乘一号甲板的1号甲板,然后乘二号甲板的2号甲板。(好吗?)

所有分区都无效,因此需要再添加一个约束:

例如,使用此方法:

(1,2,1,1,1,1,1,1) 
(3,3,3)
最终将有甲板1的4个元素

所以最后一个分区必须满足一个约束,我编写了一个小python程序来生成这些分区。

from random import randint,choice

def randomPartition(maxlength=float('inf'),N=52): 
    '''
    the max length is the last constraint in my expanation:
      you dont want l[maxlength:len(l)]) to be more than 3
 in this case we are going to randomly add +1 to all element in the list that are less than 3

    N is the number of element in the partition
     '''
    l=[] # it's your result partition
    while(sum(l)<N ):
        if (len(l)>maxlength and sum(l[maxlength:len(l)])>=3): #in the case something goes wrong 
            availableRange=[i for i in range(len(l)) if l[i]<3] #create the list of available elements to which you can add one
            while(sum(l)<N):
                temp=choice(availableRange) #randomly pick element in this list
                l[temp]+=1
                availableRange=[i for i in range(len(l)) if l[i]<3] #actualize the list
                if availableRange==[]: #if this list gets empty your program cannot find a solution
                    print "NO SOLUTION" 
                    break
            break
        else:
            temp=randint(0,min(N-sum(l),3)) # If everything goes well just add the next  element in the list until you get a sum of N=52
            l.append(temp)
    return l
根据其定义,这4个分区始终是允许的

注意:

可能会有更多不可接受的情况,例如:

(1,3,0,3,2,0,1) would be a partition of 10 with this constraint
(1,1,1,1,1,1,1,1,1,1) would be a partition of 10 too with this constraint
(3,0,0,3)
(0,3,3,0)
我想这段代码需要修改一下,以考虑更多的约束

但删除不需要的零应该很容易,如下所示:

(3,0,3)
(0,3,3,0)

希望它是可以理解的并且有帮助的

我将按以下方式处理:

首先,您可以洗牌每4个牌组(使用FYK算法)

然后在每套分区中不超过3个元素的约束下,在4副牌的52张牌中生成4个分区(*我在下面定义了分区):

例如:

(1,3,0,3,2,0,1) would be a partition of 10 with this constraint
(1,1,1,1,1,1,1,1,1,1) would be a partition of 10 too with this constraint
(3,0,0,3)
(0,3,3,0)
然后根据这些分区混合4个甲板。

from random import randint,choice

def randomPartition(maxlength=float('inf'),N=52): 
    '''
    the max length is the last constraint in my expanation:
      you dont want l[maxlength:len(l)]) to be more than 3
 in this case we are going to randomly add +1 to all element in the list that are less than 3

    N is the number of element in the partition
     '''
    l=[] # it's your result partition
    while(sum(l)<N ):
        if (len(l)>maxlength and sum(l[maxlength:len(l)])>=3): #in the case something goes wrong 
            availableRange=[i for i in range(len(l)) if l[i]<3] #create the list of available elements to which you can add one
            while(sum(l)<N):
                temp=choice(availableRange) #randomly pick element in this list
                l[temp]+=1
                availableRange=[i for i in range(len(l)) if l[i]<3] #actualize the list
                if availableRange==[]: #if this list gets empty your program cannot find a solution
                    print "NO SOLUTION" 
                    break
            break
        else:
            temp=randint(0,min(N-sum(l),3)) # If everything goes well just add the next  element in the list until you get a sum of N=52
            l.append(temp)
    return l
例如,如果您有:

(3,2,1)
(2,2,2)
你先乘一号甲板的3号甲板,然后乘二号甲板的2号甲板,然后乘一号甲板的2号甲板,然后乘一号甲板的1号甲板,然后乘二号甲板的2号甲板。(好吗?)

所有分区都无效,因此需要再添加一个约束:

例如,使用此方法:

(1,2,1,1,1,1,1,1) 
(3,3,3)
最终将有甲板1的4个元素

所以最后一个分区必须满足一个约束,我编写了一个小python程序来生成这些分区。

from random import randint,choice

def randomPartition(maxlength=float('inf'),N=52): 
    '''
    the max length is the last constraint in my expanation:
      you dont want l[maxlength:len(l)]) to be more than 3
 in this case we are going to randomly add +1 to all element in the list that are less than 3

    N is the number of element in the partition
     '''
    l=[] # it's your result partition
    while(sum(l)<N ):
        if (len(l)>maxlength and sum(l[maxlength:len(l)])>=3): #in the case something goes wrong 
            availableRange=[i for i in range(len(l)) if l[i]<3] #create the list of available elements to which you can add one
            while(sum(l)<N):
                temp=choice(availableRange) #randomly pick element in this list
                l[temp]+=1
                availableRange=[i for i in range(len(l)) if l[i]<3] #actualize the list
                if availableRange==[]: #if this list gets empty your program cannot find a solution
                    print "NO SOLUTION" 
                    break
            break
        else:
            temp=randint(0,min(N-sum(l),3)) # If everything goes well just add the next  element in the list until you get a sum of N=52
            l.append(temp)
    return l
根据其定义,这4个分区始终是允许的

注意:

可能会有更多不可接受的情况,例如:

(1,3,0,3,2,0,1) would be a partition of 10 with this constraint
(1,1,1,1,1,1,1,1,1,1) would be a partition of 10 too with this constraint
(3,0,0,3)
(0,3,3,0)
我想这段代码需要修改一下,以考虑更多的约束

但删除不需要的零应该很容易,如下所示:

(3,0,3)
(0,3,3,0)

希望这是可以理解的,并且有助于

为什么不能从同一副牌中获得四张连续的牌?您确定这是一个有效的约束吗?在真正的随机(诚实)洗牌中,一副牌中可能有任意顺序的牌。任何像普通FYK一样“无状态”的牌都会有问题,因为如果我们一开始就完全不受约束,我们会陷入一种只有一副牌的情况,我们还有3张卡要输出。现在,我想不出任何办法来避免这样的可能性,有时我们不得不中止并重新启动。但同样,算法设计者是一个有创造力的群体……安东尼,亨克,我认为阿斯克想从所有的全洗牌中统一挑选,这样就可以应用这个额外的标准。@Hans不,他没有要求将偏差作为一个特征。我的理解是,他希望在满足标准的所有配置中均匀分布。为什么不能从同一个牌组中获得四张连续的牌?你确定这是一个有效的约束吗?在真正的随机(诚实)洗牌中,一副牌中可能有任意顺序的牌。任何像普通FYK一样“无状态”的牌都会有问题,因为如果我们一开始就完全不受约束,我们会陷入一种只有一副牌的情况,我们还有3张卡要输出。现在,我想不出任何办法来避免这样的可能性,有时我们不得不中止并重新启动。但同样,算法设计者是一个有创造力的群体……安东尼,亨克,我认为阿斯克想从所有的全洗牌中统一挑选,这样就可以应用这个额外的标准。@Hans不,他没有要求将偏差作为一个特征。我的理解是,他希望在满足标准的所有配置中均匀分布。当你说“生成4个分区”时,你实际上生成的不止这些-你将集合划分为最多4个组。@NickJohnson我生成了最多4个组,总计52个。我使用了单词partition,因为我使用这个组来划分一组卡片的分区。(在混合之前)。所有的组块都扮演着对称的角色,因此结果应该是相当一致的。如果我正确地阅读了你的答案,你生成的分区数量最多是四个元素,而不仅仅是四个元素。@NickJohnson我会在有时间时尝试澄清我的答案,因为这不是我的意思。当你说“生成四个分区”时,您实际上生成的不止这些—您将集合划分为最多4个组。@NickJohnson我生成了最多4个组,总计52个。我使用了单词partition,因为我使用这个组来分区创建