微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何将此C#代码排序为广度优先的收益率? 问题简化示例解决方案...但是对于较大的序列却不是很有效

如何解决如何将此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 举报,一经查实,本站将立刻删除。