找到n的所有组合的最有效方法选择2

时间:2016-07-03 21:48:21

标签: c algorithm performance combinatorics

查找n choose 2 2 <= n <= 100000的所有组合的最有效方法是什么?

例如,5 choose 2

1 2
1 3
1 4
1 5
2 3
2 4
2 5
3 4
3 5
4 5

这是我到目前为止测试最坏情况的原因:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define MAX_ITEMS 100000

void combinations(int[], int);

long long count = 0;

int main(void) {
    int *arr = (int*) calloc(MAX_ITEMS, sizeof(int));
    if (!arr) {
        printf("Error allocating memory.");
        exit(1);
    }

    int i, n = MAX_ITEMS;

    for (i = 0; i < MAX_ITEMS; i++) {
        arr[i] = i + 1;
    }

    clock_t start, diff;
    int msec;

    start = clock();
    combinations(arr, n);
    diff = clock() - start;

    msec = diff * 1000 / CLOCKS_PER_SEC;
    printf("\n\nTime taken %d seconds %d milliseconds", msec / 1000, msec % 1000);
    printf("\n\nPairs = %lld\n", count);

    return 0;
}

void combinations(int arr[], int n) {
    int i, j, comb1, comb2, end = n - 1;

    for (i = 0; i < end; i++) {
        for (j = i + 1; j < n; j++) {
            // simulate doing something with data at these indices
            comb1 = arr[i];
            comb2 = arr[j];
            // printf("%d %d\n", arr[i], arr[j]);
            count++;
        }
    }
}

输出

Time taken 28 seconds 799 milliseconds
Pairs = 4999950000

我可能会弄错,但时间复杂度为O(n ^ 2)。

是否有更有效的算法来处理最坏的情况?

2 个答案:

答案 0 :(得分:2)

没有&#34;最好的情况&#34;或者&#34;最坏的情况&#34;。您需要准确生成(n * (n - 1)) / 2对,并且您当前的程序正好生成这些对,而不是其他任何对。因此,您的程序是最优的(在算法分析意义上)并且是θ(n^2)

使用各种技巧可能有一些优化(例如逐位操作从一对到下一对,在一次迭代中生成批量对,编译器优化等)但没有一种会影响算法的时间复杂度。

答案 1 :(得分:-1)

以这种方式看待它,如果&#34; n&#34;对数的数量不是所选数组的原始大小。您的方法的复杂性是O(n),而不是O(n ^ 2)。请注意,无论外部循环如何,都要为内循环的每次迭代填充数组的一个索引。

鉴于此,我认为你不能做得更好。这将是一个下限,你不能每步产生两对!!因为我猜这是一个最佳的解决方案。

要继续 - 如果输出的大小为n ^ 2,则输入的下限始终为n ^ 2,假设您必须触摸每个数据点一次。你在这做什么。