Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.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 - Fatal编程技术网

C# 将字符串列表随机分组

C# 将字符串列表随机分组,c#,algorithm,C#,Algorithm,给定一个n项的字符串列表,我希望将其划分为b组(b=I)项 例如: 说 划分为组(lst,3,1,2)的一个可能结果是 {"a"}, {"b","c"}, {"d"} 我应该如何编写dividentogroup函数?我不是C#专家,所以我会给你一个纯数学的解决方案,希望你能用你的语言翻译它 基本上,您的任务由两个独立的部分组成:选择b组,每组i到j个元素,以及随机性。第二种方法应该很简单——首先随机洗牌元素,然后进行分组。让我们进入有趣的部分: 如何将包含i的b组中的n个元素拆分为j组? 一个

给定一个
n
项的字符串列表,我希望将其划分为
b
(b=I)

例如: 说

划分为组(lst,3,1,2)
的一个可能结果是

{"a"},
{"b","c"},
{"d"}
我应该如何编写dividentogroup函数?

我不是C#专家,所以我会给你一个纯数学的解决方案,希望你能用你的语言翻译它

基本上,您的任务由两个独立的部分组成:选择b组,每组i到j个元素,以及随机性。第二种方法应该很简单——首先随机洗牌元素,然后进行分组。让我们进入有趣的部分:

如何将包含
i
b
组中的n个元素拆分为
j
组? 一个直接的解决方案是在
i
j
之间随机选取第一组元素的数量,然后是第二组元素的数量。但是,不能保证这样做不会让最后一组元素的数量不在
i
j
之间。这样的解决方案也不是做纯随机分布

正确的方法是获得第一组的元素数量,考虑到当你取尽可能多的元素时整体组分裂的解的概率-你基本上感兴趣的是
任务(n,b,i,j)
的总体解有多少,以及
任务(n-k,b-1,i,j)的总体解有多少
如果我们假设在第一组中取
k
元素。如果我们能够计算出解的个数,你可以取每个k及其各自的概率,对第一组k进行随机抽样,然后对第二组k进行随机抽样,依此类推

所以现在的问题是:
任务(n,b,i,j)
有多少种解决方案? 注意到
task(n,b,i,j)=sum(k=i到j)task(n-k,b-1,i,j)
使用递归可以很容易地找到这些数字(使用动态优化,因此无需多次计算值)

PS:对于解决方案的数量,可能有一个封闭形式的解决方案,但我不能马上计算出来,只要
n*b
保持相对较小(<10^6),递归解决方案应该可以工作

编辑

PS2:实际上,在<代码>任务(n,b,i,j)< /代码>中的数字可能非常大,所以考虑使用大整数。

我将做为一个解决方案是这样的,这当然是伪代码:

func( n, b, i, j )
{
    if(n == 0)
        return //finished
    if(i>j or i>min(j,n))
        return //no solution possible down this path
    out = choose_random_between (i , min(j,n)) 
    current_ave_of_cells_per_group = ( (n - out) / (b - 1) )
    if current_ave_of_cells_per_group < i
        func ( n, b, i, min(out-1,n) )
    else if current_ave_of_cells_per_group > j
        func ( n, b, out+1, min(j,n) )
    else    
        **form the group consisting of 'out' numbers**
        func ( n-out, b-1, i, min(j,n-out) )
}
func(n,b,i,j)
{
如果(n==0)
返回//已完成
如果(i>j或i>min(j,n))
return//此路径下没有可能的解决方案
out=在(i,min(j,n))之间选择随机
每组单元的当前平均值=((n-out)/(b-1))
如果每组的电池的当前值j
func(n,b,out+1,min(j,n))
其他的
**组成由“out”数字组成的组**
func(n-out,b-1,i,min(j,n-out))
}

如果
b>=n
,没有太多的方法将元素分成
b
组:)你的意思是
b错了:
List lst=new List(新字符串[]{“a”、“b”、“c”、“d”})似乎是一个家庭作业问题。对列表进行排序并将其分组?@dasblinkenlight是的,你是对的,我编辑了问题。我认为这不是均匀随机的。它是均匀随机的,因为每次随机选择数字,如果某个阶段的数字不可能,它将尝试选择一个不同的数字,该数字现在被限定为一个较小的边界,以适应更多的约束,其他数字,现在不可能被选择是数字,不能被选择,以适应这个解决方案,无论什么,这样就不会伤害随机性。这样做,直到无论他选择什么数字,约束都不会通过。。或更可能,直到他完成他的所有数字成组,并且没有更多的数字证明是不正确的:考虑一个情况下,i=1,j=7,n=43,b=7。您将选择概率为1/7的大小为1的第一组,而462个解决方案中只有1个是从第一组1开始的。好吧,但您不明白的是,这不是唯一的一条路径,因为递归如果失败会返回,因此,如果我选择第一组7号,并继续选择7号,最终将失败,因此将有另一个机会从1-6号中选择一组。此外,你说了462个解决方案,但没有提到全部解决方案。正如你所看到的,因为它是递归的,所以给出一个概率来选择第一个概率,并把它作为总概率是不正确的。而且现在我想起来了,我没有看到他说任何关于使它均匀随机的事情。。
{"a"},
{"b","c"},
{"d"}
func( n, b, i, j )
{
    if(n == 0)
        return //finished
    if(i>j or i>min(j,n))
        return //no solution possible down this path
    out = choose_random_between (i , min(j,n)) 
    current_ave_of_cells_per_group = ( (n - out) / (b - 1) )
    if current_ave_of_cells_per_group < i
        func ( n, b, i, min(out-1,n) )
    else if current_ave_of_cells_per_group > j
        func ( n, b, out+1, min(j,n) )
    else    
        **form the group consisting of 'out' numbers**
        func ( n-out, b-1, i, min(j,n-out) )
}