树算法实现C#算法

2023-09-12 21:24:29 作者:我若不猖狂谁替我坚强

我有一些问题解决来找到所有更多钞票组合以元素的算法,从N个diferents列表(其中N> = 2及和放大器; N< = 7 - >这个数是固定的,我可以做一个diferent方法每个N)。 这些问题,就如同: 我有五个字典:

I have some issues resolving an algorithm used to find all posible combinations taking elements from N diferents lists (where N>=2 && N<=7 -> this number is fixed and I can make a diferent method for each N). The problems goes as this: I have five dictionaries:

IDictionary<int, MyEnum> listOne; 
IDictionary<int, MyEnum> listTwo;
IDictionary<int, MyEnum> listThree;
IDictionary<int, MyEnum> listFour;
IDictionary<int, MyEnum> listN;

enum MyEnum
    {
    MyEnumOne,
    MyEnumTwo,
    MyEnumThree,
    MyEnumFour,
    MyEnumFive,
    MyEnumOther
   }

其可以具有任意数量的元素(不是100以上,而且大部分的时间,他们将有32至64个元件) 并在MyEnum是一个简单的名称枚举的一些值。

which can have any number of elements (not more than 100, and most of the time they will have between 32 and 64 elements) and where MyEnum is a simple name enum with some values.

有关每个可能的组合,我有一些方法,该方法examinates组合并检查它是否满足某些条件​​,并且如果它们是满足存储基于所述组合的一些数据。

For each possible combination, I have some method which examinates the combination and checks if it satisfies some conditions,and if they are satisfied stores some data based on the combination.

我曾尝试使用foreachs每个列表,其中预期简单的嵌套迭代,拿亿万跑!

I have tried simple nested iterations using foreachs for each list, which as expected, take eons to run!

任何帮助,因为我应该在哪里开始,我该怎么办,或事件是我不应该做的会比欢迎更多!如果还需要更多信息,请随时问!

Any help, as where I should start, what should I do, or event what I should not do will be more than welcome!, also if more info is needed, please feel free to ask!

* 的*编辑: 的组合,基于五个如前所示列表将是,例如:

** a combination, based on five lists as shown before would be, for example:

(MyEnumOne, MyEnumOne, MyEnumFour, MyEnumFive, MyEnumTwo)

和,因为这样的组合,可以出现几次(如MyEnumOne值可以是很多次那么listOne,等等),我也必须,保持多少次这样的组合发生的记录。

and, as this combination, can appear several times (as MyEnumOne value can be many times on listOne, etc), I have to also, keep record of how many times does this combination happens.

推荐答案

您可以解决这类问题很容易地使用LINQ。

You can solve this kind of problems easily with LINQ.

var solutions = from pair1 in listOne
                where IsCandidate(pair1)
                from pair2 in listTwo
                where IsCandidate(pair1, pair2)
                from pair3 in listThree
                where IsCandidate(pair1, pair2, pair3)
                from pair4 in listFour
                where IsCandidate(pair1, pair2, pair3, pair4)
                from pair5 in listFive
                where IsCandidate(pair1, pair2, pair3, pair4, pair5)
                from pair6 in listSix
                where IsCandidate(pair1, pair2, pair3, pair4, pair5, pair6)
                from pair7 in listSeven
                where IsSolution(pair1, pair2, pair3, pair4, pair5, pair6, pair7)
                select new { pair1, pair2, pair3, pair4, pair5, pair6, pair7 };

当然这种方法是有效的,因为仅列出的数目在编译时已知。另一种方法是将有建立可能的组合的一个通用的方法,如埃里克利珀显示在他的帖子。

所有这些中间其中,遍布查询,要尽快筛选出无效组合。

All those intermediate where all over the query, are to filter out invalid combinations as soon as possible.

修改

固定解算效率有多少次同样的组合情况,忽略了原始来源的钥匙。

Fixed solution to count efficiently how many times a same combination happens, ignoring the keys of the original source.

要实现这一目标,我将转换应用到每个字典。我要去变换每个字典到一个新的字典,其中关键是枚举值,并且该值将是的次数是枚举值发生在原始词典

To achieve this, I'm going to apply a transformation to each dictionary. I'm going to transform each dictionary into a new dictionary, where the key would be the enum value, and the value would be the number of times that enum values happens in the original dictionary.

IDictionary<MyEnum, int> CountOccurrences(IEnumerable<MyEnum> values)
{
    return (from e in values group e by e).ToDictionary(grp => grp.Key, grp => grp.Count());
}

var solutions = from p1 in CountOccurrences(listOne.Values)
                where IsCandidate(p1)
                from p2 in CountOccurrences(listTwo.Values)
                where IsCandidate(p1, p2)
                from p3 in CountOccurrences(listThree.Values)
                where IsCandidate(p1, p2, p3)
                from p4 in CountOccurrences(listFour.Values)
                where IsCandidate(p1, p2, p3, p4)
                from p5 in CountOccurrences(listFive.Values)
                where IsCandidate(p1, p2, p3, p4, p5)
                from p6 in CountOccurrences(listSix.Values)
                where IsCandidate(p1, p2, p3, p4, p5, p6)
                from p7 in CountOccurrences(listSeven.Values)
                where IsSolution(p1, p2, p3, p4, p5, p6, p7)
                select new {
                    E1 = p1.Key,
                    E2 = p2.Key,
                    E3 = p3.Key,
                    E4 = p4.Key,
                    E5 = p5.Key,
                    E6 = p6.Key,
                    E7 = p7.Key,
                    Times = p1.Value * p2.Value * p3.Value * p4.Value * p5.Value * p6.Value * p7.Value
                };