问一个组合的问题

JJYY0088 2016-08-19 04:20:16
最近遇到一个财务税务上的问题。
比如有一组整数(数量不固定),将这些整数按照一定规则进行组合在一起,组合数和总和是有规则限制的.

示例,有一组数: 8 , 11 , 21 , 24 , 30 , 46 , 53 , 73
规则:将这组数内的项组合,组合后每个组合的总和不能超过100,每个组合的项不能超过3,组合的数量要做到最少
结果:
组合1: 8 , 11 , 73 (总和:92)
组合2: 21 , 24 , 46(总和:91)
组合2: 30 , 53(总和:83)

注意:上面结果是我手动组合,结果不是唯一的。
请问怎么做 ??
...全文
237 8 打赏 收藏 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
xuzuning 2016-08-19
  • 打赏
  • 举报
回复
哦,是这个意思
            var a = new List<int>() {8, 11, 21, 24, 30, 46, 53, 73};

            var r = new List<List<int>[]>();
            foreach (var x in Combination(a, 3))
            {
                if (x.Sum() <= 100)
                {
                    var b = a.Except(x).ToList();
                    foreach (var y in Combination(b, 3))
                    {
                        var z = b.Except(y).ToList();
                        if (y.Sum() <= 100 && z.Sum() <= 100) r.Add(new List<int>[] { x, y, z });
                    }
                }
            }
            foreach (var x in r)
            {
                Console.WriteLine("[{0}] [{1}] [{2}]", string.Join(",", x[0]), string.Join(",", x[1]), string.Join(",", x[2]));
            }
[24,30,46] [8,21,53] [11,73]
[24,30,46] [8,11,73] [21,53]
[24,30,46] [8,11,53] [21,73]
[21,30,46] [11,24,53] [8,73]
[21,30,46] [8,24,53] [11,73]
[21,30,46] [8,11,73] [24,53]
[21,30,46] [8,11,53] [24,73]
[21,24,53] [11,30,46] [8,73]
[21,24,53] [8,30,46] [11,73]
[21,24,53] [8,11,73] [30,46]
[21,24,46] [11,30,53] [8,73]
[21,24,46] [8,30,53] [11,73]
[21,24,46] [8,11,73] [30,53]
[21,24,30] [8,11,73] [46,53]
[11,30,53] [21,24,46] [8,73]
[11,30,53] [8,24,46] [21,73]
[11,30,53] [8,21,46] [24,73]
[11,30,46] [21,24,53] [8,73]
[11,30,46] [8,24,53] [21,73]
[11,30,46] [8,21,53] [24,73]
[11,24,53] [21,30,46] [8,73]
[11,24,53] [8,30,46] [21,73]
[11,24,46] [8,30,53] [21,73]
[11,21,53] [24,30,46] [8,73]
[11,21,53] [8,30,46] [24,73]
[11,21,46] [8,30,53] [24,73]
[8,30,53] [21,24,46] [11,73]
[8,30,53] [11,24,46] [21,73]
[8,30,53] [11,21,46] [24,73]
[8,30,46] [21,24,53] [11,73]
[8,30,46] [11,24,53] [21,73]
[8,30,46] [11,21,53] [24,73]
[8,24,53] [21,30,46] [11,73]
[8,24,53] [11,30,46] [21,73]
[8,24,46] [11,30,53] [21,73]
[8,21,53] [24,30,46] [11,73]
[8,21,53] [11,30,46] [24,73]
[8,21,46] [11,30,53] [24,73]
[8,11,73] [24,30,46] [21,53]
[8,11,73] [21,30,46] [24,53]
[8,11,73] [21,24,53] [30,46]
[8,11,73] [21,24,46] [30,53]
[8,11,73] [21,24,30] [46,53]
[8,11,53] [24,30,46] [21,73]
[8,11,53] [21,30,46] [24,73]
seraphgxh 2016-08-19
  • 打赏
  • 举报
回复
同意3楼的观点。 建议用进化算法。
JJYY0088 2016-08-19
  • 打赏
  • 举报
回复
引用 4 楼 xuzuning 的回复:
            var a = new List<int>() {8, 11, 21, 24, 30, 46, 53, 73};
            var r = Combination(a, 3).Union(Combination(a, 2)).OrderByDescending(x => x.Sum());
            foreach (var x in r)
            {
                if(x.Sum() <= 100) Console.WriteLine(string.Join(",", x));
            }
24,30,46
46,53
21,24,53
21,30,46
24,73
11,30,53
21,73
8,11,73
21,24,46
8,30,53
11,24,53
11,30,46
11,21,53
8,24,53
8,30,46
11,73
30,53
8,21,53
11,24,46
8,73
11,21,46
8,24,46
24,53
30,46
21,24,30
8,21,46
21,53
8,11,53
24,46
21,46
11,24,30
8,11,46
11,53
11,21,30
8,24,30
8,53
8,21,30
11,46
11,21,24
24,30
8,46
8,21,24
21,30
8,11,30
21,24
8,11,24
11,30
8,11,21
8,30
11,24
11,21
8,24
8,21
8,11
这不符合组合规则呢,总的组合数量降到最少。 ... 8,30 11,24 11,21 8,24 8,21 8,11 ... 很多都可以再组合
JJYY0088 2016-08-19
  • 打赏
  • 举报
回复
引用 2 楼 yuankaiwsl 的回复:
需求不明确:“组合的数量要做到最少”那不就是组合中就一个数?
我上面组合了3组呀,组合总数就是3,不是说组合里面的项最少
xuzuning 2016-08-19
  • 打赏
  • 举报
回复
            var a = new List<int>() {8, 11, 21, 24, 30, 46, 53, 73};
            var r = Combination(a, 3).Union(Combination(a, 2)).OrderByDescending(x => x.Sum());
            foreach (var x in r)
            {
                if(x.Sum() <= 100) Console.WriteLine(string.Join(",", x));
            }
24,30,46
46,53
21,24,53
21,30,46
24,73
11,30,53
21,73
8,11,73
21,24,46
8,30,53
11,24,53
11,30,46
11,21,53
8,24,53
8,30,46
11,73
30,53
8,21,53
11,24,46
8,73
11,21,46
8,24,46
24,53
30,46
21,24,30
8,21,46
21,53
8,11,53
24,46
21,46
11,24,30
8,11,46
11,53
11,21,30
8,24,30
8,53
8,21,30
11,46
11,21,24
24,30
8,46
8,21,24
21,30
8,11,30
21,24
8,11,24
11,30
8,11,21
8,30
11,24
11,21
8,24
8,21
8,11
求组合(C(m,n))的算法很多这里给一种
        static IEnumerable<List<int>> Combination(List<int> src, int num)
        {
            int len = src.Count;
            int i = 0;
            for (i = 1; i < Math.Pow(2, len); i++)
            {
                var n = i;
                n = (n & 0x55555555) + ((n >> 1) & 0x55555555);
                n = (n & 0x33333333) + ((n >> 2) & 0x33333333);
                n = (n & 0x0f0f0f0f) + ((n >> 4) & 0x0f0f0f0f);
                n = (n & 0x00ff00ff) + ((n >> 8) & 0x00ff00ff);
                n = (n & 0x0000ffff) + ((n >> 16) & 0x0000ffff);
                if (n == num)
                {
                    var s = Convert.ToString(i, 2).PadLeft(len, '0');

                    var r = new List<int>();
                    for (int j = 0; j < s.Length; j++)
                    {
                        if (s[j] == '1') r.Add(src[j]);
                    }
                    //Console.WriteLine("{0} {1}", s, string.Join(",", r));
                    yield return r;
                }
            }
        }
xian_wwq 2016-08-19
  • 打赏
  • 举报
回复
这类问题是NP问题,即可以在多项式时间内验证一个解是否OK,但是不可以在多项式时间内求得该解。 装箱问题,有个近似解。
巴士上的邂逅 2016-08-19
  • 打赏
  • 举报
回复
需求不明确:“组合的数量要做到最少”那不就是组合中就一个数?
维秀斯丢丢 2016-08-19
  • 打赏
  • 举报
回复
太难了吧。这个。谁会的指教一下。

111,128

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧