生成篮子中所有可能的数字分布

问题描述 投票:0回答:2

有 8 个数字(即 1、2、3、4、5、6、7、8,)和 5 个篮子。 如何生成篮子中所有可能的数字分布?我看到了关于篮子里苹果的案例,但这个案例不一样:苹果 - 只是一些,而这里每个数字都是唯一的。

我找到了 Adrian Akison 的 greate package Combinatorics,但不清楚如何在我的案例中使用它......

即使是关于如何使用包逻辑的建议也会有所帮助。预期输出示例:

  • 0|0|0|0|1,2,3,4,5,6,7,8
  • 0|0|0|1|2,3,4,5,6,7,8
  • 0|0|0|2|1,3,4,5,6,7,8
  • 0|0|0|3|1,2,4,5,6,7,8
  • 0|0|0|4|1,2,3,5,6,7,8
  • 0|0|0|5|1,2,3,4,6,7,8
  • 0|0|0|6|1,2,3,4,5,7,8
  • 0|0|0|1,2|3,4,5,6,7,8
  • 0|0|0|1,3|2,4,5,6,7,8
  • 0|0|0|1,4|2,3,5,6,7,8
  • 0|0|0|1,5|2,3,4,6,7,8
c# combinatorics
2个回答
0
投票

你可以试试这个:

using System;
using System.Collections.Generic;
using System.Linq;
using Combinatorics.Collections;

class Program
{
    static void Main(string[] args)
    {
        int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8 };
        int numBaskets = 5;
        var baskets = Enumerable.Repeat(0, numBaskets).ToList();

        var combinations = new Combinations<int>(numbers, numBaskets, GenerateOption.WithoutRepetition);

        foreach (var combination in combinations)
        {
            var currBaskets = new List<List<int>>(numBaskets);
            for (int i = 0; i < numBaskets; i++)
            {
                currBaskets.Add(new List<int>());
            }

            for (int i = 0; i < numBaskets; i++)
            {
                currBaskets[i].Add(combination[i]);
                baskets[i] = 1;
            }

            var remainingNumbers = numbers.Except(combination);

            foreach (var number in remainingNumbers)
            {
                var minIndex = baskets.IndexOf(baskets.Min());
                currBaskets[minIndex].Add(number);
                baskets[minIndex]++;
            }

            Console.WriteLine(string.Join("|", baskets) + "|" + string.Join(",", currBaskets.Select(b => string.Join(",", b))));
            baskets = Enumerable.Repeat(0, numBaskets).ToList();
        }
    }
}

0
投票

所以对于每个数字,我们应该想出一个属于它的篮子:

   12345678 
   --------
   00000000 <- all in basket #0
   00000001 <- all in basket #0, except number 8 which is in basket #1
   ...
   00000004 <- all in basket #0, except number 8 which is in basket #4
   00000010 <- all in basket #0, except number 7 which is in basket #1
   00000011 <- all in basket #0, except numbers 7 and 8 which are in basket #1
   ...
   44444444 <- all in basket #4

到目前为止一切顺利,我们有

8^5 == 32768
的可能性。他们在这里:

using System.Linq;

...

private static IEnumerable<int[]> SolveMe(int numbers, int baskets) {
  int[] solution = new int[numbers];

  do {
     yield return solution.ToArray();

     for (int i = solution.Length - 1; i >= 0; --i)
       if (solution[i] == baskets - 1) 
         solution[i] = 0;
       else {
         solution[i] += 1;

         break;  
       }
  }
  while (solution.Any(item => item != 0));
}

一起来看看:

var result = string.Join(Environment.NewLine,
  SolveMe(8, 5).Select(solution => string.Join(", ", solution)));

Console.Write(result);

输出:

0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0, 1
0, 0, 0, 0, 0, 0, 0, 2
0, 0, 0, 0, 0, 0, 0, 3
0, 0, 0, 0, 0, 0, 0, 4
0, 0, 0, 0, 0, 0, 1, 0
...
1, 1, 0, 4, 1, 2, 1, 3
1, 1, 0, 4, 1, 2, 1, 4
...
4, 4, 4, 4, 4, 4, 4, 3
4, 4, 4, 4, 4, 4, 4, 4
© www.soinside.com 2019 - 2024. All rights reserved.