具有随机数的唯一向量

时间:2019-03-28 14:09:14

标签: c++ random

我的程序是编写一个c ++程序,初始化一个大小为SIZE的整数向量v,每个向量均具有[0,2 * SIZE]范围内的不同随机整数,如何确保向量中的所有数字都是唯一的 我该如何编辑初始化向量以使其正常工作,但我的逻辑存在缺陷。无法使用随机播放。

#include <iostream>
#include <ctime>
#include <vector>
#include <iomanip>
#include<algorithm>

const int SIZE =10;
unsigned int seed = (unsigned)time(0);
using namespace std;

double random (unsigned int &seed);
void print_vector (vector<int> :: iterator b,
                   vector<int> :: iterator e );
void initialize_vector(vector<int> &v);
vector<int>v;

int main()
{
    cout << endl;
    initialize_vector(v);
    cout << "Vector : " << endl;
    print_vector(v.begin(), v.end());
    return 0;
}

double random(unsigned int &seed)
{
    const int MODULUS = 15749;
    const int MULTIPLIER = 69069;
    const int INCREMENT = 1;
    seed = ((MULTIPLIER*seed)+INCREMENT)%MODULUS;
    return double (seed)/MODULUS;
}

void initialize_vector(vector<int> &v)
{
    vector<int> used;
    int count_unused, k;
    for (int i=0; i<2*SIZE; i++)
    {
        used.push_back(0);
    }
    for (int i=0; i<SIZE; i++)
    {
        int j= (random(seed)*(2*SIZE+1-i)) + 1;
        count_unused = 0;
        k = 0;
        while (count_unused != j)
        {
            if (used[k] == 0)
                count_unused++;
            k++;
        }
        used[k] = 1;
        v.push_back(j);
    }

}

void print_vector (vector<int> :: iterator b,
                   vector<int> :: iterator e )
{
    vector<int> :: iterator p =b;
    while(p<e)
        cout << setw(3) << (*p++);
    cout << endl;
}

3 个答案:

答案 0 :(得分:5)

std::iotastd::random_shuffle 1 可以达到目的:

constexpr int SIZE = 10;
std::vector<int> values(2*SIZE+1);
std::iota(begin(values), end(values), 0);
std::random_shuffle(begin(values), end(values));
values.resize(SIZE);

完整演示:http://coliru.stacked-crooked.com/a/0caca71a15fbd698

它如何工作?

首先,创建2*SIZE+1的向量...

std::vector<int> values(2*SIZE+1);

...,并用02*SIZE的连续整数填充。

std::iota(begin(values), end(values), 0);

我们将这些值洗牌了……

std::random_shuffle(begin(values), end(values));

...并删除第二部分。

values.resize(SIZE);

Voila。


1)注意:这是C ++ 11/14解决方案,因为std::random_shuffle自C ++ 14起已弃用,而在c ++ 17中已删除。

答案 1 :(得分:1)

好的,这是没有任何存储和基于Reservoir Sampling进行检查的解决方案。我们用0到2 * SIZE(含0和2 * SIZE)的值模拟流,并用相等的概率填充储层。无需预填充,然后擦除数据,一次通过采样。没事!代码,Visual C ++ 2019

#include <iostream>
#include <vector>
#include <random>

constexpr int SIZE = 10;
constexpr int EOS = -1; // end-of-stream marker

static int s = 0;

void init_stream() {
    s = 0;
}

int next_stream() {
    if (s > 2 * SIZE)
        return EOS;
    return s++;
}

std::mt19937_64 rng{ 1792837ULL };

int random(int lo, int hi) {
    std::uniform_int_distribution<int> ud{ lo, hi };
    return ud(rng);
}

std::vector<int> reservoir(int size) {
    std::vector<int> r(size, 0);
    auto v = next_stream(); // value from stream
    for (int k = 0; v != EOS; ++k, v = next_stream()) {

        if (k < r.size()) { // fill reservoir
            r[k] = v;
        }
        else { // replace elements with gradually decreasing probability
            unsigned int idx = random(0, k);
            if (idx < r.size()) {
                r[idx] = v;
            }
        }
    }
    return r;
}

int main() {
    std::vector<int> h(2*SIZE+1, 0);

    for (int k = 0; k != 100000; ++k) {
        init_stream();
        std::vector<int> r{ reservoir(SIZE) };
        for (auto v : r) {
            h[v] += 1;
        }
    }

    for (auto v : h) {
        std::cout << v << '\n';
    }

    return 0;
}

打印的直方图显示非常均匀的分布。

答案 2 :(得分:0)

As mentioned by sv90在没有PN | LastS | CurrentS | Price 111111 | 100001 | 100002 | 28 111111 | 100001 | 100001 | 32 111111 | 100001 | 100004 | 48 111111 | 100001 | 100003 | 19 222222 | 100004 | 100001 | 200 222222 | 100004 | 100003 | 236 222222 | 100002 | 100005 | 397 222222 | 100003 | 100006 | 302 的情况下,或者在PN | LastS | CurrentS | Price | New Price 111111 | 100001 | 100002 | 28 | 32 111111 | 100001 | 100001 | 32 | 32 111111 | 100001 | 100004 | 48 | 32 111111 | 100001 | 100003 | 48 | 32 222222 | 100004 | 100001 | 200 | 236 222222 | 100004 | 100003 | 236 | 236 222222 | 100002 | 100005 | 397 | 236 222222 | 100003 | 100006 | 302 | 236 非常大的情况下,您可能希望使用shuffle来确保唯一的数字。用uniform_int_distribution初始化SIZE,然后用unordered_set初始化unordered_set。像这样:

vector

Live Example