استخدام دفعة::عشوائية كما RNG من أجل std::random_shuffle

StackOverflow https://stackoverflow.com/questions/147391

  •  02-07-2019
  •  | 
  •  

سؤال

لدي برنامج يستخدم mt19937 مولد رقم عشوائي من دفعة::عشوائية.أنا بحاجة إلى القيام random_shuffle وتريد أرقام عشوائية ولدت على هذا أن يكون من هذه الدولة المشتركة بحيث يمكن القطعية فيما يتعلق ميرسين الإعصار ولدت سابقا الأرقام.

حاولت شيئا من هذا القبيل:

void foo(std::vector<unsigned> &vec, boost::mt19937 &state)
{
    struct bar {
        boost::mt19937 &_state;
        unsigned operator()(unsigned i) {
            boost::uniform_int<> rng(0, i - 1);
            return rng(_state);
        }
        bar(boost::mt19937 &state) : _state(state) {}
    } rand(state);

    std::random_shuffle(vec.begin(), vec.end(), rand);
}

ولكن يمكنني الحصول على قالب خطأ داعيا random_shuffle مع راند.ومع ذلك يعمل هذا:

unsigned bar(unsigned i)
{
    boost::mt19937 no_state;
    boost::uniform_int<> rng(0, i - 1);
    return rng(no_state);
}
void foo(std::vector<unsigned> &vec, boost::mt19937 &state)
{
    std::random_shuffle(vec.begin(), vec.end(), bar);
}

ربما لأنه هو الفعلي استدعاء دالة.ولكن من الواضح أن هذا لا تبقي الدولة من الأصل ميرسين الاعصار.ما يعطي ؟ هل هناك أي طريقة أن تفعل ما أحاول القيام به دون العالمية المتغيرات ؟

هل كانت مفيدة؟

المحلول

في C++03, لا يمكنك إنشاء قالب على أساس وظيفة-نوع محلي.إذا قمت بنقل راند الفصل من الوظيفة ، يجب أن تعمل بشكل جيد (تنويه:لم تختبر ، يمكن أن يكون هناك غيرها من الحشرات الشريرة).

تم تخفيف هذا الشرط في C++0x, ولكن أنا لا أعرف ما إذا كان التغيير قد تم تنفيذها في دول مجلس التعاون الخليجي C++0x الوضع الآن و أنا في غاية يفاجأ لتجد أنها موجودة في أي برنامج التحويل البرمجي.

نصائح أخرى

في التعليقات ، روبرت غولد طلب نسخة عمل للأجيال القادمة:

#include <algorithm>
#include <functional>
#include <vector>
#include <boost/random.hpp>

struct bar : std::unary_function<unsigned, unsigned> {
    boost::mt19937 &_state;
    unsigned operator()(unsigned i) {
        boost::uniform_int<> rng(0, i - 1);
        return rng(_state);
    }
    bar(boost::mt19937 &state) : _state(state) {}
};

void foo(std::vector<unsigned> &vec, boost::mt19937 &state)
{
    bar rand(state);
    std::random_shuffle(vec.begin(), vec.end(), rand);
}

أنا باستخدام tr1 بدلا من دفعة::عشوائية هنا, ولكن يجب أن لا يهم كثيرا.

التالية هي صعبة بعض الشيء ، لكنه يعمل.

#include <algorithm>
#include <tr1/random>


std::tr1::mt19937 engine;
std::tr1::uniform_int<> unigen;
std::tr1::variate_generator<std::tr1::mt19937, 
                            std::tr1::uniform_int<> >gen(engine, unigen);
std::random_shuffle(vec.begin(), vec.end(), gen);

ظننت أنه تجدر الإشارة إلى أن هذا هو الآن واضحة جدا في C++11 فقط باستخدام المكتبة القياسية:

#include <random>
#include <algorithm>

std::random_device rd;
std::mt19937 randEng(rd());
std::shuffle(vec.begin(), vec.end(), randEng);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top