• <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++博客 首頁 新隨筆 聯系 聚合 管理
              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: 總次數、目標比例(千分比)、算法類型(1.c標準庫rand; 2.cpp11 mt19937)
            // @out: 實際命中次數、實際命中概率
            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]區間的一個數字
            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;  // 基數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("參數異常"));
                }

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

                // 計算浮點小數點個數
                int32_t nWeCount = 3;  // 位數(三位數,千分比精度)
                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));  // 概率轉整數輔助計算

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

                // 開始測試
                auto nTestCount = nTotalCount;
                while (nTestCount-- > 0)
                {
                    // 生成隨機數
                    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;
                }

                // 計算浮點小數點個數
                int32_t nWeCount = 3;  // 位數(三位數,千分比精度)
                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));  // 概率轉整數輔助計算

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

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

                // 開始命中測試
                auto nTestCount = nTotalCount;
                while (nTestCount-- > 0)
                {
                    // 生成隨機數
                    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 閱讀(1314) 評論(0)  編輯 收藏 引用 所屬分類: 從零開始寫棋牌游戲平臺
            99久久精品国产一区二区 | 久久久久久久久无码精品亚洲日韩 | 久久精品国产91久久综合麻豆自制| 人妻精品久久无码区| 久久免费美女视频| 久久无码人妻精品一区二区三区| 狠狠色噜噜色狠狠狠综合久久| 国产∨亚洲V天堂无码久久久| 久久精品国产亚洲精品| 亚洲精品tv久久久久久久久| 91精品久久久久久无码| 区亚洲欧美一级久久精品亚洲精品成人网久久久久| 久久97久久97精品免视看| 亚洲狠狠婷婷综合久久蜜芽 | 亚洲国产精品无码久久久久久曰| 亚洲国产另类久久久精品黑人| 日韩精品国产自在久久现线拍| 中文字幕乱码人妻无码久久| 国产亚洲美女精品久久久| 久久精品99久久香蕉国产色戒| 无码国内精品久久综合88| 久久93精品国产91久久综合| 久久久亚洲欧洲日产国码二区| 精品伊人久久久| 久久婷婷五月综合色99啪ak| 草草久久久无码国产专区| 国产美女久久久| 东京热TOKYO综合久久精品| 亚洲中文字幕久久精品无码APP | 亚洲精品国产综合久久一线| 国产国产成人久久精品| 久久久精品免费国产四虎| 久久精品国产亚洲AV无码麻豆| 伊人久久精品无码二区麻豆| 亚洲精品WWW久久久久久| 色综合合久久天天给综看| 亚洲AV伊人久久青青草原| 老司机午夜网站国内精品久久久久久久久 | 国产V亚洲V天堂无码久久久| 久久亚洲欧美国产精品| 久久精品青青草原伊人|