C# 树算法的c实现#

C# 树算法的c实现#,c#,algorithm,tree,C#,Algorithm,Tree,我在解决一个算法时遇到了一些问题,该算法用于从N个不同的列表中找到所有可能的组合元素(其中N>=2&&N这个数字是固定的,我可以为每个N创建一个不同的方法)。 问题是这样的: 我有五本字典: IDictionary<int, MyEnum> listOne; IDictionary<int, MyEnum> listTwo; IDictionary<int, MyEnum> listThree; IDictionary<int, MyEnum>

我在解决一个算法时遇到了一些问题,该算法用于从N个不同的列表中找到所有可能的组合元素(其中N>=2&&N这个数字是固定的,我可以为每个N创建一个不同的方法)。 问题是这样的: 我有五本字典:

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
   }

而且,由于这种组合可能出现多次(因为MyEnumOne值可能在listOne上出现多次,等等),我还必须记录这种组合发生的次数。

通常,对于此类问题,您应该尝试构造解决方案,而不是盲目地在整个搜索空间中寻找它们

我假设你真正需要做的是: -你有N个列表,每个列表i有L(i)个元素。 -您希望生成长度N的所有组合,其中第一个元素来自第一个列表,第二个元素来自第二个列表,依此类推

似乎没有任何方法可以避免艰难地生成所有组合。 所有100个元素^N~10^14。。。这将需要亿万年的时间


我支持对需要满足的小样本和条件的要求。

使用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 };
当然,这种方法是有效的,因为列表的数量在编译时是已知的。另一种方法是采用通用方法构建可能的组合,如图所示

查询中的所有中间
,其中
都将尽快过滤掉无效的组合

编辑

修正了忽略原始源的键,有效计算同一组合发生次数的解决方案

为了实现这一点,我将对每个字典应用一个转换。我将把每个字典转换成一个新的字典,其中键是enum值,该值是enum值在原始字典中出现的次数

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
                };
IDictionary countoccurrencess(IEnumerable值)
{
返回(从值组e中的e按e.ToDictionary返回)(grp=>grp.Key,grp=>grp.Count());
}
var solutions=从p1开始计数(listOne.Values)
其中IsCandidate(p1)
从计数中的p2(列表2.Values)
其中IsCandidate(p1,p2)
从p3开始计数发生次数(列出三个值)
其中,IsCandidate(p1、p2、p3)
来自CountOccurrencess中的p4(列表4.Values)
其中IsCandidate(p1、p2、p3、p4)
从计数中的p5(列表5.Values)
其中,IsCandidate(p1、p2、p3、p4、p5)
从计数中的p6开始(列表6.值)
其中,IsCandidate(p1、p2、p3、p4、p5、p6)
从第7页开始计数(列表7.Values)
式中为溶液(p1,p2,p3,p4,p5,p6,p7)
选择新的{
E1=p1.键,
E2=p2.键,
E3=p3.键,
E4=p4.键,
E5=p5.键,
E6=p6.键,
E7=p7.键,
时间=p1.值*p2.值*p3.值*p4.值*p5.值*p6.值*p7.值
};

您能否定义组合的外观,以及您在组合上使用的一些示例逻辑?你能定义所有可能的组合意味着什么吗?如果该方法是泛型的,你别无选择,只能检查每个组合,它将需要亿万年才能运行。一个简短但典型的输入->输出是必要的。这几乎解决了我的问题,现在,我如何满足我的上一次编辑,我只需要在该解决方案上有不同的组合,并且每个组合在该解决方案上出现的次数?每个字典的
int
键是否有意义?我的意思是,允许使用
int
检查候选解决方案有用吗?在返回每个组合之前可以对其进行过滤吗?此处不需要该键,可以忽略该键,它用于从应用程序中的整数元组中获取组合。再次读取您的编辑,我现在很困惑我的上一次编辑是否是您所需的,或者您是否需要告诉同一个组合可以发生多少次。告诉我你是否需要另一个。这是你提到我需要的第二件事:同一个组合可以发生多少次,但不是所有组合,只有相关的组合,另一个会增加垃圾组合的数量!
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
                };