C# 在具有大K的N个元素的列表中获取K个元素和更少元素的所有组合
我希望在列表中包含所有元素的组合,结果如下: 列表:{1,2,3}C# 在具有大K的N个元素的列表中获取K个元素和更少元素的所有组合,c#,algorithm,permutation,C#,Algorithm,Permutation,我希望在列表中包含所有元素的组合,结果如下: 列表:{1,2,3} 1 2 3 1,2 1,3 2,3 我的问题是我有180个元素,我希望所有的组合最多有5个元素。我用4个元素进行测试,花了很长时间(2分钟),但都进行得很顺利。但对于5个元素,我得到了一个内存不足的异常 我目前的代码是: public IEnumerable<IEnumerable<Rondin>> getPossibilites(List<Rondin> rondins) { va
1
2
3
1,2
1,3
2,3
我的问题是我有180个元素,我希望所有的组合最多有5个元素。我用4个元素进行测试,花了很长时间(2分钟),但都进行得很顺利。但对于5个元素,我得到了一个内存不足的异常
我目前的代码是:
public IEnumerable<IEnumerable<Rondin>> getPossibilites(List<Rondin> rondins)
{
var combin5 = rondins.Combinations(5);
var combin4 = rondins.Combinations(4);
var combin3 = rondins.Combinations(3);
var combin2 = rondins.Combinations(2);
var combin1 = rondins.Combinations(1);
return combin5.Concat(combin4).Concat(combin3).Concat(combin2).Concat(combin1).ToList();
}
public IEnumerable getPossibilites(列表)
{
var combin5=rondins.组合(5);
var combin4=rondins.组合(4);
var combin3=rondins.组合(3);
var combin2=rondins.组合(2);
var combin1=rondins.组合(1);
返回combin5.Concat(combin4.Concat(combin3.Concat(combin2.Concat(combin1.ToList));
}
(摘自这个问题:)
公共静态IEnumerable组合(此IEnumerable元素,int k)
{
返回k==0?new[]{new T[0]}:
元素。选择多个((e,i)=>
元素.跳过(i+1).组合(k-1).选择(c=>(new[]{e}).Concat(c));
}
我需要在列表中搜索一个组合,其中每个元素加起来都接近一个值(具有一定的精度),这对于另一个列表中的每个元素都是如此。这部分有我的全部代码:
var possibilites = getPossibilites(opt.rondins);
possibilites = possibilites.Where(p => p.Sum(r => r.longueur + traitScie) < 144);
foreach(BilleOptimisee b in opt.billesOptimisees)
{
var proches = possibilites.Where(p => p.Sum(r => (r.longueur + traitScie)) < b.chute && Math.Abs(b.chute - p.Sum(r => r.longueur)) - (p.Count() * 0.22) < 0.01).OrderByDescending(p => p.Sum(r => r.longueur)).ElementAt(0);
if(proches != null)
{
foreach (Rondin r in proches)
{
opt.rondins.Remove(r);
b.rondins.Add(r);
possibilites = possibilites.Where(p => !p.Contains(r));
}
}
}
var possibilites=getPossibilites(opt.rondins);
可能性=可能性,其中(p=>p.Sum(r=>r.longueur+traitcie)<144);
foreach(可选账单优化视图中的账单优化对象b)
{
var proches=possibilites.Where(p=>p.Sum(r=>(r.longueur+traitScie))r.longueur))-(p.Count()*0.22)<0.01.OrderByDescending(p=>p.Sum(r=>r.longueur)).ElementAt(0);
if(进程!=null)
{
foreach(过程中的Rondin r)
{
选择rondins.移除(r);
b、 加上(r);
可能性=可能性,其中(p=>!p.Contains(r));
}
}
}
使用我的代码,我如何限制列表占用的内存?还是有更好的解决方案来搜索一组非常大的组合
如果我的问题不好,请告诉我原因,我会尽力学习,下次再问更好的问题;) 5个元素组合的输出列表将有大小为5的子列表~
1.5*10^9
(b为十亿)。如果您使用32位整数,即使忽略列表开销,并假设您有一个开销为0b的完美列表,也将是~200GB
您应该重新考虑,如果您真的需要像您那样生成列表,一些替代方案可能是:流式传输元素列表-即动态生成它们
这可以通过创建一个函数来实现,该函数获取最后一个组合作为参数,并输出下一个组合。(想一想是怎么做到的,想一想增加一个数字。你从最后一个到第一个,记住一个“结转”,直到你完成为止)
从4个流媒体中选择2个流媒体示例:
start: {4,3}
curr = start {4, 3}
curr = next(curr) {4, 2} // reduce last by one
curr = next(curr) {4, 1} // reduce last by one
curr = next(curr) {3, 2} // cannot reduce more, reduce the first by one, and set the follower to maximal possible value
curr = next(curr) {3, 1} // reduce last by one
curr = next(curr) {2, 1} // similar to {3,2}
done.
现在,您需要考虑如何对大小为2的列表执行此操作,然后将其推广到任意大小,并对流式组合生成器进行编程
祝你好运 5个元素组合的输出列表将有大小为5的子列表~
1.5*10^9
(b为十亿)。如果您使用32位整数,即使忽略列表开销,并假设您有一个开销为0b的完美列表,也将是~200GB
您应该重新考虑,如果您真的需要像您那样生成列表,一些替代方案可能是:流式传输元素列表-即动态生成它们
这可以通过创建一个函数来实现,该函数获取最后一个组合作为参数,并输出下一个组合。(想一想是怎么做到的,想一想增加一个数字。你从最后一个到第一个,记住一个“结转”,直到你完成为止)
从4个流媒体中选择2个流媒体示例:
start: {4,3}
curr = start {4, 3}
curr = next(curr) {4, 2} // reduce last by one
curr = next(curr) {4, 1} // reduce last by one
curr = next(curr) {3, 2} // cannot reduce more, reduce the first by one, and set the follower to maximal possible value
curr = next(curr) {3, 1} // reduce last by one
curr = next(curr) {2, 1} // similar to {3,2}
done.
现在,您需要考虑如何对大小为2的列表执行此操作,然后将其推广到任意大小,并对流式组合生成器进行编程
祝你好运 让您的精度在假想光谱中定义 使用实际索引访问叶,然后以所需的精度遍历叶 请参阅precisle@ 虽然实现并非100%完整,但您可以在此处找到我使用的类似概念:
使用这个概念,我能够重新排序H.264接入单元及其底层网络接入层组件,我认为这是一个非常有趣的方式…除此之外,它还可以在使用相同内存量的情况下提高效率
等等,例如,0可以按0.1或0.01或0.001进行,这取决于列表中键的类型(双精度、浮点、向量等),如果处理器支持,则使用FPU或甚至可能是内部函数可能会带来额外的好处,因此,无论底层存储机制如何,排序和索引的速度都比普通集合快得多 使用这个概念可以进行非常有趣的排序。。。特别是如果您提供了一种过滤精度的机制使用这种方法,我还能够在相当多的知名媒体库的位流解析器中找到几个bug…让您的精度在虚拟频谱中定义 使用实际索引访问叶,然后以所需的精度遍历叶 请参阅precisle@ 虽然实现并非100%完整,但您可以在此处找到我使用的类似概念:
使用这个概念,我能够重新排序H.264接入单元及其底层网络接入层组件,我认为这是一个非常有趣的方式…除此之外,它还可以在使用相同内存量的情况下提高效率
等,例如,0可以按0.1或0.01或0.001进行public List<IEnumerable<Rondin>> getPossibilites(IEnumerable<Rondin> rondins, int nbElements, double minimum, double maximum, int instance = 0, double longueur = 0)
{
if(instance == 0)
timer = DateTime.Now;
List<IEnumerable<Rondin>> liste = new List<IEnumerable<Rondin>>();
//Get all distinct rondins that can fit into the maximal length
foreach (Rondin r in rondins.Where(r => r.longueur < (maximum - longueur)).DistinctBy(r => r.longueur).OrderBy(r => r.longueur))
{
//Check the current length
double longueur2 = longueur + r.longueur + traitScie;
//If the current length is under the maximal length
if (longueur2 < maximum)
{
//Get all the possibilities with all rondins except the current one, and add them to the list
foreach (IEnumerable<Rondin> poss in getPossibilites(rondins.Where(rondin => rondin.id != r.id), nbElements - liste.Count, minimum, maximum, instance + 1, longueur2).Select(possibilite => possibilite.Concat(new Rondin[] { r })))
{
liste.Add(poss);
if (liste.Count >= nbElements && nbElements > 0)
break;
}
//If this the current length in higher than the minimum, add it to the list
if (longueur2 >= minimum)
liste.Add(new Rondin[] { r });
}
//If we have enough possibilities, we stop the research
if (liste.Count >= nbElements && nbElements > 0)
break;
//If the research is taking too long, stop the research and return the list;
if (DateTime.Now.Subtract(timer).TotalSeconds > 30)
break;
}
return liste;
}