• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            Error

            C++博客 首頁 新隨筆 聯(lián)系 聚合 管理
              217 Posts :: 61 Stories :: 32 Comments :: 0 Trackbacks
            // RandomTest.cpp : Defines the entry point for the console application.
            //

            #include "stdafx.h"

            #include <iostream>
            #include <cmath>
            #include <random>
            #include <cstdint>
            #include <ctime>
            #include <algorithm>
            #include <numeric>
            #include <cassert>
            #include <climits>
            #include <thread>

            #define XASSERT(exp) assert(exp)
            #define XASSERT_MSG(exp, msg) assert(exp)
            #define X_DEFAULT_FLOAT_PRECISION (0.00000001)

            // @in: 總次數(shù)、目標(biāo)比例(千分比)、算法類型(1.c標(biāo)準(zhǔn)庫rand; 2.cpp11 mt19937)
            // @out: 實際命中次數(shù)、實際命中概率
            bool RandomHitTest(int32_t nTotalCount, float fHitRate, int32_t nAlgorithmType, int32_t& nRealHitCount, float& fRealHitRate);
            void RandomHitTest_std_mt19937(int32_t nTotalCount, float fHitRate, int32_t& nRealHitCount, float& fRealHitRate);
            void RandomHitTest_std_rand(int32_t nTotalCount, float fHitRate, int32_t& nRealHitCount, float& fRealHitRate);
            // 簡化std::rand獲取[nMin, nMax]區(qū)間的一個數(shù)字
            uint32_t StdRandEx(uint32_t nMin, uint32_t nMax);


            int _tmain(int argc, _TCHAR* argv[])
            {
                //std::thread srandThread([](){ std::this_thread::sleep_for(std::chrono::seconds(1));});
                
            //srandThread.detach();

                std::vector<std::tuple<floatfloat>> vecResult;

                for (int n = 0; n < 1000; n++)
                {
                    uint32_t nTotalCount = 100000;  // 基數(shù)100000次

                    for (float fHitRate = 0.001f; 1.f - fHitRate >= 0; fHitRate = fHitRate + 0.101f)
                    {
                        int32_t nRealHitCount = 0;
                        float fRealHitRate = 0;

                        // std::rand測試
                        RandomHitTest(nTotalCount, fHitRate, 1, nRealHitCount, fRealHitRate);
                        //std::cout << "AlgorithmType=" << 1 << ",TotlaCount=" << nTotalCount << ",HitRate=" << 
                        
            //    fHitRate  << ",ReahHitRate=" << std::fixed << fRealHitRate << ",RealHitCount=" << nRealHitCount << std::endl;


                        int32_t nRealHitCount1 = 0;
                        float fRealHitRate1 = 0;

                        // cpp11 mt19937
                        RandomHitTest(nTotalCount, fHitRate, 2, nRealHitCount1, fRealHitRate1);
                        //std::cout << "AlgorithmType=" << 2 << ",TotlaCount=" << nTotalCount << ",HitRate=" << 
                        
            //    fHitRate  << ",ReahHitRate=" << std::fixed << fRealHitRate1 << ",RealHitCount=" << nRealHitCount1 << std::endl;
                        
            //std::cout << "---differ rate=" << std::fixed << fRealHitRate1 - fRealHitRate << ", differ count=" 
                        
            //    << nRealHitCount1 - nRealHitCount << std::endl;

                        std::tuple<floatfloat> tupleResult = std::make_tuple(fHitRate, std::fabsf(fRealHitRate1 - fRealHitRate));
                        vecResult.push_back(tupleResult);
                    }
                }

                std::sort(vecResult.begin(), vecResult.end(), 
                    [](std::tuple<floatfloat>& tupLeft, std::tuple<floatfloat>& tupRight)->bool{
                        //float fHitRateL = 0;
                        
            //float fRealRateL = 0;

                        
            //float fHitRateR = 0;
                        
            //float fRealRateR = 0;
                        return std::get<1>(tupLeft) - std::get<1>(tupRight) > 0;;
                });

                auto tupleFirst = vecResult[0];

                return 0;
            }


            uint32_t StdRandEx(uint32_t nMin, uint32_t nMax)
            {
                XASSERT((nMin >= 0) && (nMax >= 0) && (nMin <= nMax));

                uint32_t nRandVal = 0;

                if (nMin == nMax)
                {
                    nRandVal = nMax;
                }
                else if (nMin < nMax)
                {
                    nRandVal = rand() % (nMax - nMin + 1) + nMin;
                }
                else
                {
                    XASSERT_MSG(0, _T("參數(shù)異常"));
                }

                return nRandVal;
            }

            void RandomHitTest_std_rand(int32_t nTotalCount, float fHitRate, int32_t& nRealHitCount, float& fRealHitRate)
            {
                nRealHitCount = 0;
                fRealHitRate = 0;

                if (nTotalCount <= 0 || fHitRate <= 0)
                {
                    return;
                }

                // 計算浮點小數(shù)點個數(shù)
                int32_t nWeCount = 3;  // 位數(shù)(三位數(shù),千分比精度)
                XASSERT((fHitRate * std::pow(10, nWeCount)) - std::numeric_limits<uint64_t>::max() <= X_DEFAULT_FLOAT_PRECISION);  // 永不溢出
                int64_t nHitRateIntHelp = static_cast<uint64_t>(fHitRate * std::pow(10, nWeCount));  // 概率轉(zhuǎn)整數(shù)輔助計算

                
            // 根據(jù)位數(shù)決定隨機數(shù)范圍
                int32_t nRandMin = 0;
                int32_t nRandMax = std::pow(10, nWeCount);

                // 開始測試
                auto nTestCount = nTotalCount;
                while (nTestCount-- > 0)
                {
                    // 生成隨機數(shù)
                    int32_t nRandVal = StdRandEx(nRandMin, nRandMax);

                    // 命中判定
                    if (nRandVal < nHitRateIntHelp)
                    {
                        nRealHitCount++;
                    }
                }

                fRealHitRate = float(nRealHitCount)/float(nTotalCount);
            }

            void RandomHitTest_std_mt19937(int32_t nTotalCount, float fHitRate, int32_t& nRealHitCount, float& fRealHitRate)
            {
                nRealHitCount = 0;
                fRealHitRate = 0;

                if (nTotalCount <= 0 || fHitRate <= 0)
                {
                    return;
                }

                // 計算浮點小數(shù)點個數(shù)
                int32_t nWeCount = 3;  // 位數(shù)(三位數(shù),千分比精度)
                XASSERT((fHitRate * std::pow(10, nWeCount)) - std::numeric_limits<uint64_t>::max() <= X_DEFAULT_FLOAT_PRECISION);  // 永不溢出
                int64_t nHitRateIntHelp = static_cast<uint64_t>(fHitRate * std::pow(10, nWeCount));  // 概率轉(zhuǎn)整數(shù)輔助計算

                
            // 根據(jù)位數(shù)決定隨機數(shù)范圍
                int32_t nRandMin = 0;
                int32_t nRandMax = std::pow(10, nWeCount);

                // 設(shè)置隨機數(shù)生成器
                std::random_device rd;
                std::mt19937_64 gen(rd());
                std::uniform_int_distribution<> dis(nRandMin, nRandMax);
                
                // 重設(shè)種子應(yīng)該使用這個api:::CryptGenRandom
                
            // linux也有相應(yīng)的高精度隨機數(shù)
                gen.seed(uint32_t(time(NULL)));

                // 開始命中測試
                auto nTestCount = nTotalCount;
                while (nTestCount-- > 0)
                {
                    // 生成隨機數(shù)
                    uint32_t randVal = dis(gen);

                    if (randVal < nHitRateIntHelp)
                    {
                        nRealHitCount++;
                    }
                }

                fRealHitRate = float(nRealHitCount)/float(nTotalCount);
            }


            bool RandomHitTest(int32_t nTotalCount, float fHitRate, int32_t nAlgorithmType, int32_t& nRealHitCount, float& fRealHitRate)
            {
                if (nTotalCount <= 0)
                {
                    return false;
                }

                bool bRet = true;
                switch (nAlgorithmType)
                {
                case 1:
                    RandomHitTest_std_rand(nTotalCount, fHitRate, nRealHitCount, fRealHitRate);
                    break;
                case 2:
                    RandomHitTest_std_mt19937(nTotalCount, fHitRate, nRealHitCount, fRealHitRate);
                    break;
                default:
                    bRet = false;
                    break;
                }

                return true;
            }

            posted on 2017-01-22 12:28 Enic 閱讀(1327) 評論(0)  編輯 收藏 引用 所屬分類: 從零開始寫棋牌游戲平臺
            国产亚洲精久久久久久无码AV| 色综合久久中文字幕综合网| 嫩草伊人久久精品少妇AV| 国产精品久久久久a影院| 99久久综合国产精品免费| 久久国产精品一国产精品金尊| 国产精品久久久久久福利69堂| 成人精品一区二区久久久| 伊人色综合久久天天人守人婷| 久久婷婷五月综合色高清| 久久国产V一级毛多内射| 久久午夜伦鲁片免费无码| 一本色道久久88综合日韩精品 | 久久综合色老色| 青青草原综合久久大伊人精品| 久久婷婷五月综合成人D啪 | 久久婷婷五月综合97色直播| 久久精品国产91久久麻豆自制| 久久亚洲精品国产精品婷婷| 久久国产精品一区二区| 少妇内射兰兰久久| 久久久久青草线蕉综合超碰| 精品久久久久中文字幕一区| 69国产成人综合久久精品| 中文成人久久久久影院免费观看| 久久久无码精品亚洲日韩按摩| 亚洲欧洲久久av| 久久久精品久久久久特色影视| 99久久人妻无码精品系列蜜桃| 性做久久久久久久| 中文字幕精品久久久久人妻| 性做久久久久久久久| 久久久久一本毛久久久| 久久精品免费大片国产大片| 国产精品成人无码久久久久久| 日韩亚洲欧美久久久www综合网| 国内精品九九久久久精品| 亚洲av成人无码久久精品| 国产午夜福利精品久久2021| 国产精品天天影视久久综合网| av国内精品久久久久影院|