如何解决如何将此C#代码排序为广度优先的收益率? 问题简化示例解决方案...但是对于较大的序列却不是很有效
问题
我正在创建一个 IEnumerable 集合,其中包含所有可以传递给 Task.Run(); 的值的可能组合。 尽管我想更改项目的顺序而不使其变得不懒惰,因为一次计算整个列表会花费几秒钟。
简化示例
这是代码的简化示例(在最终产品中,Items.Count和sequence.Count最多可以达到〜100。)
int[] Items = new int[] { 1,2,3,4 }; //* for example there are only four items,imagine this to be over ~20
IEnumerable<List<int>> GetAllSequences(List<int> sequence,int index)
{
yield return sequence;
if (sequence.Count < 3)
{
for (int i = index; i < Items.Length; i++)
{
List<int> newSequence = new List<int>(sequence)
{
Items[i]
};
foreach (List<int> result in GetAllSequences(newSequence,i + 1))
{
yield return result;
}
}
}
}
这将产生以下列表,在此列表旁边,是我想要的“宽度优先的收益率回报”所需的输出:
# | CURRENT output | DESIRED output | ALTERNATIVE output
___|________________|________________|___________________
0 | 1 | 1 | 1
1 | 1,2 | 2 | 2
2 | 1,3 | 3 | 3
3 | 1,4 | 4 | 4
4 | 1,3 | 1,2 | 1,2
5 | 1,4 | 1,3 | 2,3
6 | 1,4 | 1,4 | 3,4
7 | 2 | 2,3
8 | 2,4 | 2,4
9 | 2,4 | 3,4
10 | 2,4 | 1,3 | 1,3
11 | 3 | 1,4 | 2,4
...
我尝试了各种排序方法,但是所有方法都要求我将最终的IEnumerable更改为List,要求对它进行完整的评估(轻松评估为20)! (= 2.432902e + 18)个项目。这样会使整个程序冻结几秒钟。
我想通过在递归方法中对其进行排序来获得所需的解决方案,从而以最小的延迟获得所需的输出。
那么,如何将C#代码排序为广度优先的收益率回报?
编辑:对IEnumerable集合的任何项目进行评估时,无需花费大量时间即可进行排序。
我从“ spzvtbg”中获取了代码,以显示在当前方法中评估每个项目的时间非常短。排序项目的评估应类似:
using System;
using System.Collections.Generic;
using System.Diagnostics;
namespace ConsoleApp2
{
class Program
{
public static void Main()
{
var sw = Stopwatch.StartNew();
var desiredCollection = GetAllSequences(new List<int>(),0);
var e = desiredCollection.GetEnumerator();
e.MoveNext();
Console.WriteLine(string.Join(",",e.Current));
sw.Stop();
Console.WriteLine(sw.Elapsed);
for (int i = 0; i < 10; i++)
{
sw = Stopwatch.StartNew();
e.MoveNext();
Console.WriteLine(string.Join(",e.Current));
sw.Stop();
Console.WriteLine(sw.Elapsed);
}
}
static int[] Items = new int[] { 1,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20 };
static IEnumerable<List<int>> GetAllSequences(List<int> sequence,int index)
{
yield return sequence;
if (sequence.Count < 20)
{
for (int i = index; i < Items.Length; i++)
{
List<int> newSequence = new List<int>(sequence)
{
Items[i]
};
foreach (List<int> result in GetAllSequences(newSequence,i + 1))
{
yield return result;
}
}
}
}
}
}
解决方案...但是对于较大的序列却不是很有效
根据“ spzvtbg”的想法,我添加了一个“帮助器”功能,该功能在每次要求输出不同大小的输出时启动递归功能。这样就可以首先按计数大小对所有输出进行排序。但是,这意味着要对大小为“ n”的序列进行一些计算,还需要计算所有以前的大小序列!!这对于较大的大小可能会非常繁琐。
using System;
using System.Collections.Generic;
using System.Diagnostics;
namespace ConsoleApp2
{
class Program
{
public static void Main()
{
var sw = Stopwatch.StartNew();
var desiredCollection = GetAllSequences(new List<int>(),e.Current));
sw.Stop();
Console.WriteLine(sw.Elapsed);
for (int i = 0; i < 10000; i++)
{
sw = Stopwatch.StartNew();
e.MoveNext();
Console.WriteLine(string.Join(",20};
static IEnumerable<List<int>> GetAllSequences(List<int> sequence,int index,int sizeReq)
{
if (sizeReq == sequence.Count)
yield return sequence;
if (sequence.Count < 20)
{
for (int i = index; i < Items.Length; i++)
{
List<int> newSequence = new List<int>(sequence)
{
Items[i]
};
foreach (List<int> result in GetAllSequences(newSequence,i + 1,sizeReq))
{
yield return result;
}
}
}
}
static IEnumerable<List<int>> GetAllSequences(List<int> sequence,int index)
{
for (int i = 1; i < 15; i++)
{
foreach (List<int> result in GetAllSequences(sequence,index,i))
{
yield return result;
}
}
}
}
}
如何构建/回收先前的序列?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。