多组合算法

时间:2016-12-08 05:45:04

标签: java algorithm combinations permutation

我正在尝试编写一个算法,告诉我可以使用来自多组值的项生成多少对。例如,我有以下几组: {1,2,3} {4,5} {6}

从这些集合中我可以生成11对: {1,4},{1,5},{1,6},{2,4},{2,5},{2,6},{3,4},{3,5},{3} ,6},{4,6},{5,6}

我写了以下算法:

int result=0;

for(int k=0;k<numberOfSets;k++){ //map is a list where I store all my sets
    int size1 = map.get(k);

    for(int l=k+1;l<numberOfSets;l++){
        int size2 = map.get(l);
        result += size1*size2;
    }
}

但是你可以看到算法的可扩展性不是很高。如果集合的数量增加,则算法开始执行得非常差。 我错过了什么吗?有没有一种算法可以帮我解决这个问题?我一直在寻找组合和置换算法,但我不太确定这是不是正确的道路。

非常感谢您提前

2 个答案:

答案 0 :(得分:1)

首先,如果配对中的顺序确实重要,那么在内循环中以int l=k+1开头是错误的。例如。如果您认为{4,1}{1,4}相同,那么您将失踪{1,2} , {2,3}, {4},那么结果是正确的,否则它就不是。

其次,为了使问题进一步复杂化,你不能说这些对是否必须是唯一的。例如。 {2,4}将生成Set<Pair<int,int>>两次 - 如果您需要将其计为唯一,则代码的结果不正确(并且您需要保留use Firebase\JWT\JWT; 以删除重复项和您将需要扫描这些集并实际生成对)。

好消息:虽然你不能比O(N 2 )更好地计算对,即使你有数千套,数百万的整数乘法/加法在现在的计算机上足够快 - 例如Eigen deals quite well with O(N^3) operations用于浮动乘法(参见矩阵乘法运算)。

答案 1 :(得分:0)

假设你只关心对的数量,并且正在计算重复数,那么有一个更有效的算法:

我们将跟踪当前的集合数量,以及到目前为止遇到的元素数量。

  1. 从头到尾查看列表
  2. 对于每个新集合,我们可以创建的新对的数量是集合的大小*遇到元素的大小。将其添加到当前的套数中。
  3. 将新集的大小添加到我们目前遇到的元素数量。
  4. 代码:

    int numberOfPairs=0;
    int elementsEncountered=0;
    
    for(int k = numberOfSets - 1 ; k >= 0 ; k--) { 
       int sizeOfCurrentSet = map.get(k);
       int numberOfNewPairs = sizeOfCurrentSet * elementsEncountered;
       numberOfPairs += numberOfNewPairs;
       elementsEncountered += sizeOfCurrentSet; 
    }
    

    重新定位的关键点在于,当我们计算每个集合所贡献的新对的数量时,我们选择该对的第二个元素与哪个集合无关紧要。也就是说,我们不需要跟踪我们已经分析过的任何集合。