ANurbaev
ANurbaev

Reputation: 17

How to generate different pairs of unequal numbers?

I want to create N different pairs and want the numbers in the pairs to be unequal. The numbers in the pairs are in the range from 0 to K - 1.

vector<pair<int, int> > p;
pair<int, int> temp;
int N = 8;
int K = 7;
int c = 0;
for (int i = 0; i < N; i++) {
    int f = random(0, K-1);
    int s = random(0, K-1);
    p.push_back({ f, s });
}
temp = p[c];
for (int i = 0; i < N; i++) {
    if (temp != p[i]) {
        c++;
    }
    else {
        while (temp == p[i]) {
            temp.first = random(0, K - 1);
        }
        c++;
    }
}

I want to have such pairs of numbers: Output: (0, 4) (0, 3) (1, 2) (1, 4) (1, 5) (2, 3) (5, 3) (5, 4)

Upvotes: 2

Views: 252

Answers (3)

Javier Silva Ort&#237;z
Javier Silva Ort&#237;z

Reputation: 2982

You can use std::set as your unique pairs container and use std::pair to represent your pairs. Then, you can enter a while loop that inserts random pairs into your set while its .size() < N. It's simpler and will yield a cleaner solution since std::set automatically handles duplicates by eliminating them. The code would look like this:

set<pair<int, int>> unique_pairs;

int a, b;
while (unique_pairs.size() < N)
{
    a = random(0, K - 1);
    b = random(0, K - 1);

    //Prevents sets like (a, a).
    while (a == b) b = random(0, K - 1);

    //Prevents sets like (a, b) and (b, a).
    unique_pairs.insert(make_pair(min(a, b), max(a, b)));
}

If you don't care for the order of your pairs inside the set, then you can use unordered_set instead of set. Be sure to read the references as there are some differences you need to be aware of.

Upvotes: 0

Sebastian
Sebastian

Reputation: 795

Are (a,b) and (b,a) considered the same pair? Do you disallow pairs like (a,a)?

If so, here's a way to generate N distinct pairs from the numbers 0 through to K:

#include <cmath>
#include <iostream>
#include <random>
#include <set>
#include <tuple>
#include <vector>

std::random_device rd;
std::mt19937 gen(rd());

std::set<std::pair<int, int>> generate_pairs(int N, int K) {
    std::uniform_int_distribution<> dis(0, K-1);

    std::set<std::pair<int, int>> pairs;
    int f, s;
    while (pairs.size() < N) {
        // Generate the first element of the pair.
        f = dis(gen);

        // Generate the second element of the pair.
        // This could be improved, but simply assures we don't get pairs (a,a).
        for (s = f; s == f; s = dis(gen));

        // Make sure we can't get both (f,s) and (s,f) in our set of pairs.
        pairs.emplace(std::make_pair(std::min(f, s), std::max(f, s)));
    }
    return pairs;
}

int main() {
    const auto pairs = generate_pairs(10,10);
    for (const auto p: pairs)
        std::cout << "(" << p.first << "," << p.second << ")\n";
}

Upvotes: 1

Jesper Juhl
Jesper Juhl

Reputation: 31459

A simple approach: Put your number pairs in a std::set (which will eliminate duplicates). Keep generating pairs until the .size() of your set is your desired amount of unique pairs.

Upvotes: 3

Related Questions