【问题标题】:Finding all possible combinations with repitition of selected items allowed查找所有可能的组合并允许重复所选项目
【发布时间】:2017-08-25 07:43:28
【问题描述】:

我有一个对象列表,这些对象的数量是动态的。我需要找到这些对象的所有可能组合。

我目前处于获取对象列表并使用以下代码返回所有可能的组合而不重复的阶段:

    static void Main(string[] args)
    {
        //Say, inputList contains randomObject1,randomObject2 and randomObject3 
        List<List<RandomObject>> AllCombos = ItemCombinations(inputList);

    }

    //maxComboCount denotes the maximum number of elements that can be in the combination
    public static List<List<T>> ItemCombinations<T>(List<T> inputList, int maxComboCount)
    {
        
        int nonEmptyCombinations = (int)Math.Pow(2, inputList.Count) - 1;

        List<List<T>> listOfCombinations = new List<List<T>>();
        

        for (int i = 1; i <= nonEmptyCombinations; i++)
        {
            List<T> thisCombination = new List<T>();
            for (int j = 0; j < inputList.Count; j++)
            {
                if ((i >> j) % 2 != 0)
                {
                    thisCombination.Add(inputList[j]);
                }
            }

            if (thisCombination.Count <= maxComboCount)
            {
                listOfCombinations.Add(thisCombination);
            }
        }                     
        return listOfCombinations;
    }
    

如何获得重复项目的所有其他组合,maxComboCount 将始终存在,否则我所需的场景可能会陷入无限循环(如果我错了,请纠正我)。

例如输入列表:{r1,r2,r3}

当前阶段:{r1},{r2},{r3},{r1,r2},{r2,r3},{r3,r1},{r1,r2,r3}

想要的阶段(给定 maxComboCount 约束 = 4):{r1},{r2},{r3},{r1,r1},{r1,r2},{r1,r3},{r2,r2},{ r2,r3},{r3,r3} {r1,r1,r1}, {r1,r1,r2} ,{r1,r1,r3},{r1,r2,r3} 等等...

我尝试过的一件事是,

我迭代到 maxBaseCardCount 并在每次迭代时将 inputList 添加到另一个 tempList,然后我将此 tempList 作为参数传递给 ItemCombinations 方法。

     //The loop will be constrained by the maximum number of objects allowed
        for (int i = 0; i < maxComboCount; i++)
        {
            tempList.AddRange(inputList);
        }

       List<List<RandomObject>> AllCombos = ItemCombinations(tempList);

这应该是一个快速而肮脏的工作,并且确实给了我所需的输出(有很多重复值),但我不太确定它在中断之前可以容纳多少。因此,任何比我的方法更可靠的方法都将不胜感激。

编辑

我正在添加对问题的解释,如果需要任何其他简化,请告诉我

InputList : 它是一个对象列表,可以从中进行组合

ItemCombinations:此函数返回给定列表中的所有组合而不重复(不是我想要的)

对于 inputList = {1,2},ItemCombination 返回:空、{1}、{2}、{1,2},即任何给定长度为 n 的列表中的所有 2^n 个唯一组合

现在,我希望将允许重复的项目组合起来,并且组合的长度是动态的。

例子:

例如输入列表:{r1,r2,r3}

ItemCombination 函数最初返回:{r1},{r2},{r3},{r1,r2},{r2,r3},{r3,r1},{r1,r2,r3}

现在,我想要的是,如果每个对象可以使用多少次没有限制,可以进行的所有组合

我想要什么(给定 maxComboCount 约束 = 4):{r1},{r2},{r3},{r1,r1},{r1,r2},{r1,r3},{r2,r2}, {r2,r3},{r3,r3} {r1,r1,r1}, {r1,r1,r2} ,{r1,r1,r3},{r1,r2,r3} 等等...

maxComboCount 约束确保返回 size>4 的 no 列表

基本上,我想要从 n 个对象中选择的 k 个对象的组合,其中 k 的范围可以从 1 到 x(任何数字)

【问题讨论】:

  • “没有重复的可能组合”是什么意思?你的意思是排列还是别的什么?
  • 你能用简单的英语写出你想要的东西吗?我不想检查您的代码以了解您要实现的目标。
  • “我需要的场景可能会陷入无限循环”这意味着你做错了,因为无论有没有重复元素,组合的数量总是有限的(尽管它可能会变得非常大非常快)。
  • @oerkelens 如果我有三个对象并且我允许重复,但不对所需列表中可以有多少个对象提供任何限制,则没有什么可以阻止代码与无限组合复述。这就是为什么我认为它可能会卡住
  • 这就是为什么你需要更清楚你想要什么。 “不重复”的正常解释是 123, 132, 213, 231, 312, 321,重复是 111, 112, 113, 121, 122, 123, 131.... - 表示每个项目中的重复顺序。那么你在说什么重复,项目是否允许重复?请使用该信息编辑您的问题,并举例说明。

标签: c# algorithm


【解决方案1】:

您想从n 重复项的池中找出最多m 项的组合。项目集合中的顺序无关紧要,因此{1, 2, 2} 和{2, 2, 1} 是等价的;只应添加其中之一。 (理想情况下,这是项目按升序排列的地方。)

假设您有一个包含三个项目的池,并且想要创建最多两个项目的集合。将空集添加到结果中:

{}

通过迭代没有项目的集合和项目池并添加项目来创建一个项目的集合:

{} + {1} = {1}
{} + {2} = {2}
{} + {3} = {3}

现在从一个项目的集合中创建两个项目的集合,但只有当它们等于或大于每个集合中的最后一个和最大的项目时才添加项目:

{1} -> {1, 1}, {1, 2}, {1, 3}
{2} -> {2, 2}, {2, 3}
{3} -> {3, 3}

现在你有一组 T(1) + T(2) + T(3) = 10 个项目:

{}
{1}, {2}, {3}
{1, 1}, {1, 2}, {1, 3}, {2, 2}, {2, 3}, {3, 3}

(T(n) 是第 n 个三角形数,¹ ⁄₂·n·(n + 1)。)

我不懂 C#,但在伪代码中,您的算法如下所示:

var m = 3                                   // max. items
var pool = {1, 2, 3}                        // item pool
var res = {{}}                              // results,
                                            // start with empty list

var k = 0                                   // starting index of subarray
                                            // with one fewer item

while (m--) {                               // loop m times
    var kk = res.length()                   // current result array length

    for (var i = k; i < kk; i++) {
        var j0 = 0

        if (res[i].length() > 0) {          // find index of largest item
            j0 = pool.index(res[i].last())  // from the set in pool
        }

        for (var j = j0; j p in pool {      // add new set
            res.add(res[i] + {pool[j]})
        }
    }

    k = kold
}

这也可以递归实现,您可以跟踪每个级别中的最后一个项目索引,这样您就不必搜索它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-20
    • 1970-01-01
    • 1970-01-01
    • 2015-10-08
    相关资源
    最近更新 更多