1

What is the most efficient way to find all combinations of n choose 2 for 2 <= n <= 100000?

For example, 5 choose 2 is

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

This is what I have so far for testing the worst case:

#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++;
        }
    }
}

OUTPUT

Time taken 28 seconds 799 milliseconds
Pairs = 4999950000

I could be mistaken but time complexity is O(n^2).

Is there a more efficient algorithm to handle the worst case?

turion
  • 21
  • 6
  • 1
    you should look at this post - http://stackoverflow.com/questions/127704/algorithm-to-return-all-combinations-of-k-elements-from-n – Matt. Stroh Jul 03 '16 at 21:51
  • 1
    How about `(n * (n-1)) / 2`? Or are you after the actual pairs? If so, O(n^2) is the best you can do. – aioobe Jul 03 '16 at 21:51
  • @aioobe Yes, I need the actual pairs. – turion Jul 03 '16 at 23:58
  • @turion If you need to print / store all actual pairs, (n*(n-1))/2 = O(n^2) is the best you can do as it is the exact I/O time you need, make sense? – shole Jul 04 '16 at 02:11

2 Answers2

2

There is no "best case" or "worst case". You need to generate exactly (n * (n - 1)) / 2 pairs, and your current program generates exactly those pairs and nothing else. Thus your program is optimal (in the algorithmic analysis sense) and is θ(n^2).

Some optimizations may be possible using various tricks (e.g. bitwise operations to go from one pair to the next, generating bulk pairs in one iteration, compiler optimizations, etc) but none would affect the time complexity of the algorithm.

wookie919
  • 2,864
  • 18
  • 27
-1

Look at it this way, what if "n" was the number of pairs not the original size of the chose array. The complexity of your approach is O(n), not O (n^2). Notice you fill one index of the array for each iteration of the inner loop, regardless of your outter loop.

Given that, i dont think you can do significantly better. This is going to be a lower bound, you cant produce two pairs per step!! There for i would guess this is an optimal solution.

To continue -- if the output is n^2 the size of the input then your lower bound is always n^2 assuming you must touch every data point once. Which here you do.

gbtimmon
  • 3,863
  • 1
  • 17
  • 31