Generating Permutations using LINQ

后端 未结 8 1986
我寻月下人不归
我寻月下人不归 2020-12-01 04:59

I have a set of products that must be scheduled. There are P products each indexed from 1 to P. Each product can be scheduled into a time period 0 to T. I need to construct

8条回答
  •  佛祖请我去吃肉
    2020-12-01 05:33

    The output from the answer of Mr Lippert can be seen as all the possible distributions of elements among 0 and 2 in 4 slots.
    For instance
    0 3 1
    reads as "no 0, three 1 and one 2"
    This is nowhere near as elegant as the answer of Mr Lippert, but at least not less efficient

    public static void Main()
    {
      var distributions = Distributions(4, 3);
      PrintSequences(distributions);
    }
    
    /// 
    /// Entry point for the other recursive overload
    /// 
    /// Number of elements in the output
    /// Number of distinct values elements can take
    /// 
    static List Distributions(int length, int range)
    {
      var distribution = new int[range];
      var distributions = new List();
      Distributions(0, length, distribution, 0, distributions);
      distributions.Reverse();
      return distributions;
    }
    
    /// 
    /// Recursive methode. Not to be called directly, only from other overload
    /// 
    /// Value of the (possibly) last added element
    /// Number of elements in the output
    /// Distribution among element distinct values
    /// Exit condition of the recursion. Incremented if element added from parent call
    /// All possible distributions
    static void Distributions(int index,
                              int length,
                              int[] distribution,
                              int sum,
                              List distributions)
    {
      //Uncomment for exactness check
      //System.Diagnostics.Debug.Assert(distribution.Sum() == sum);
      if (sum == length)
      {
        distributions.Add(distribution.Reverse().ToArray());
    
        for (; index < distribution.Length; index++)
        {
          sum -= distribution[index];
          distribution[index] = 0;
        }
        return;
      }
      if (index < distribution.Length)
      {
        Distributions(index + 1, length, distribution, sum, distributions);
        distribution[index]++;
        Distributions(index, length, distribution, ++sum, distributions);
      }
    }
    
    static void PrintSequences(List distributions)
    {
      for (int i = 0; i < distributions.Count; i++)
      {
        for (int j = distributions[i].Length - 1; j >= 0; j--)
          for (int k = 0; k < distributions[i][j]; k++)
            Console.Write("{0:D1} ", distributions[i].Length - 1 - j);
        Console.WriteLine();
      }
    }
    

提交回复
热议问题