首页 新闻 会员 周边

组合问题算法

0
悬赏园豆:50 [待解决问题]

有一个 值
List<List<string>> l=new List<List<string>>();
l.Add(new List<string>(new string[] {"1", "5", "6", "7", "8", "9" }));//6个元素
l.Add(new List<string>(new string[] { "1", "5", "6", "7", "8"}));//5个元素
l.Add(new List<string>(new string[] { "5"}));
...省略多个

要求,对 l 进行全组合,并且组合后,每个组合 元素个数不能超过10,例如 l[0] 和 l[1]组合后,元素是 11,就不合格!

求算法!性能要好!!!!

☆绿茶☆的主页 ☆绿茶☆ | 初学一级 | 园豆:76
提问于:2015-04-01 17:39
< >
分享
所有回答(3)
0

1、对l的元素的子元素长度排序

2、优先对子元素数量满足匹配条件的最多和最少的子元素集合进行组合

3、重复以上循环。

 

这个算法不是最优的。

最优的算法应该是:对所有子元素长度进行组合,使得组合之后的长度刚好是10。

519740105 | 园豆:5810 (大侠五级) | 2015-04-01 17:46

兄弟,怎么写。。。我研究一下

支持(0) 反对(0) ☆绿茶☆ | 园豆:76 (初学一级) | 2015-04-01 17:48

@☆绿茶☆: 下面代码给你参考(未验证):

 

            List<List<string>> l = new List<List<string>>();
            l.Add(new List<string>(new string[] { "1", "5", "6", "7", "8", "9" }));//6个元素
            l.Add(new List<string>(new string[] { "1", "5", "6", "7", "8" }));//5个元素
            l.Add(new List<string>(new string[] { "5" }));
            Func<List<List<string>>, List<List<string>>, List<List<string>>> funcCombine = (source, dest) =>
                {
                    var groups = source.GroupBy(x => x.Count, x => x).OrderByDescending(x => x.Key).ToList();
                    List<List<string>> tmp = new List<List<string>>();
                    groups.Where(x => x.Key >= 10).ToList().ForEach(x => { groups.Remove(x); dest.Add(x as List<string>); });
                    for (int i = 10; i >= 5; i--)
                    {
                        foreach (var group in groups.Where(x => (x as List<string>).Count > 0))
                        {
                            var key = group.Key;
                            var sub = groups.Where(x => x.Key + key == i).SingleOrDefault();
                            if (sub != null)
                            {
                                for (int j = 0; i < Math.Min(key, sub.Key); j++)
                                {
                                    var left = group.First();
                                    var right = sub.First();
                                    var combine = new List<string>(left);
                                    combine.AddRange(right);
                                    (group as List<List<string>>).Remove(left);
                                    (sub as List<List<string>>).Remove(right);
                                    tmp.Add(combine);
                                }
                            }
                        }
                    }
                    if (tmp.Count > 0)
                    {
                        foreach (var group in groups)
                        {
                            tmp.AddRange(group);
                        }
                    }
                    else
                    {
                        foreach (var group in groups)
                        {
                            dest.AddRange(group);
                        }
                    }
                    return tmp;
                };
            var result = new List<List<string>>();
            List<List<string>> current;
            while((current = funcCombine(l, result)).Count > 0);
支持(0) 反对(0) 519740105 | 园豆:5810 (大侠五级) | 2015-04-01 18:25

@519740105: 额,看来我水平不够,我写习惯2.0的,还有并不是 一定要等于10 小于10也是可以的。。。我研究一下,非常谢谢你!

支持(0) 反对(0) ☆绿茶☆ | 园豆:76 (初学一级) | 2015-04-01 19:35

@☆绿茶☆: 你参考就好。这个性能不好。

支持(0) 反对(0) 519740105 | 园豆:5810 (大侠五级) | 2015-04-01 19:53
0

static void Main(string[] args)
        {
            List<List<string>> l = new List<List<string>>();
            //
            //给l添加元素
            //
            for (int x = 0; x < l.Count; x++)
            {
                for (int y = x + 1; y < l.Count; y++)
                {
                    if (l[x].Count + l[y].Count > 10)
                    {
                        Console.WriteLine("不合格");
                    }
                }
            }
        }

Firen | 园豆:5385 (大侠五级) | 2015-04-01 17:46

兄弟,你这是干嘛。。。。好像答非所问

支持(0) 反对(0) ☆绿茶☆ | 园豆:76 (初学一级) | 2015-04-01 17:48

@☆绿茶☆: 把算法写出来了啊。

支持(0) 反对(0) Firen | 园豆:5385 (大侠五级) | 2015-04-01 17:51

@Firen: 兄弟,你这不对。。。。

支持(0) 反对(0) ☆绿茶☆ | 园豆:76 (初学一级) | 2015-04-01 17:52

@☆绿茶☆: 对不对拿实际数据测一下不就清楚了。

支持(0) 反对(0) Firen | 园豆:5385 (大侠五级) | 2015-04-01 19:30

@Firen: 兄弟,谢谢你,确实不对,不好意思

支持(0) 反对(0) ☆绿茶☆ | 园豆:76 (初学一级) | 2015-04-01 19:37

@☆绿茶☆: 你说的全组合是两两组合还是包括两个以上元素的组合?

支持(0) 反对(0) Firen | 园豆:5385 (大侠五级) | 2015-04-01 21:08

@Firen: 所有的组合,不重复,也就是数学上面的 c(m,n) 

支持(0) 反对(0) ☆绿茶☆ | 园豆:76 (初学一级) | 2015-04-01 21:57

@☆绿茶☆: 建議你看下Firen的思路,個人覺得是正確的思路。雙重循環就行全部組合。

支持(0) 反对(0) 幻天芒 | 园豆:37175 (高人七级) | 2015-04-02 10:29

@☆绿茶☆: c(m,n) 你n取值多少呢?  我的写法是c(m,2)

支持(0) 反对(0) Firen | 园豆:5385 (大侠五级) | 2015-04-02 11:14

@Firen: c(m,2)你这样写可以,但是有一个问题,这个样写性能可能不行,太慢了。。。。我做出来了,但是计算一次要80多秒,c(42,10);

支持(0) 反对(0) ☆绿茶☆ | 园豆:76 (初学一级) | 2015-04-02 19:32
0

谢谢,我自己换了种方式实现了!

☆绿茶☆ | 园豆:76 (初学一级) | 2015-04-13 11:58
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册