找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 478|回复: 1

[分享] 随机数

[复制链接]

已领礼包: 1268个

财富等级: 财源广进

发表于 2017-1-20 09:36:40 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×

cRandom.h

  1. #ifndef CRANDOM_H
  2. #define CRANDOM_H
  3. #include<iostream>
  4. using namespace std;
  5. #pragma once
  6. #define N 624
  7. #define M 397
  8. #define NUM 100000
  9. #define MATRIX_A 0x9908b0df
  10. #define UPPER_MASK 0x80000000
  11. #define LOWER_MASK 0x7fffffff
  12. #define MTRand_Max 0xffffffff
  13. #define TEMPERING_MASK_B 0x9d2c5680
  14. #define TEMPERING_MASK_C 0xefc60000
  15. #define TEMPERING_SHIFT_U(ulMidValue) (ulMidValue >> 11)
  16. #define TEMPERING_SHIFT_S(ulMidValue) (ulMidValue << 7)
  17. #define TEMPERING_SHIFT_T(ulMidValue) (ulMidValue << 15)
  18. #define TEMPERING_SHIFT_L(ulMidValue) (ulMidValue >> 18)

  19. class cRandom
  20. {

  21. public:
  22.     bool RandomUniform(double *t_pdArray,unsigned long t_ulNumber,double t_dUp,double t_dDown);
  23.     bool RandomGaussion(double *t_pdArray,unsigned long t_ulNumber,double t_dMean,double t_dStD);
  24.     bool RandomCircle(double *t_pdXArray,double *t_pdYArray,unsigned long t_ulNumber,double t_dXcenter,double t_dYcenter,double t_dRadius);
  25.     bool RandomSequence(double *t_pdArray,unsigned long t_ulNumber);
  26.     cRandom()
  27.     {
  28.         wSeedFlag = 0;
  29.         bInitFlag = 0;
  30.     }
  31.     ~cRandom()
  32.     {
  33.         //cout << "Destructor called" << endl;
  34.     }
  35. private:
  36.     unsigned short wSeedFlag;
  37.     bool bInitFlag;
  38.     unsigned long ulaSeed[N];
  39.     void MTRandom (unsigned long *t_ulpRandom,unsigned long t_ulNumber);
  40. };
  41. #endif // CRANDOM_H

cRandom.cpp

  1. #include "cRandom.h"
  2. #include<ctime>
  3. #include <fstream>
  4. #include<cstdlib>
  5. #include<cmath>
  6. #include<iostream>
  7. #include<conio.h>
  8. #include<string>

  9. using std::ifstream;
  10. using std::ofstream;
  11. using std::cin;
  12. using std::cout;
  13. using std::endl;

  14. void cRandom::MTRandom(unsigned long *t_ulpRandom,unsigned long t_ulNumber)
  15. {
  16.     unsigned long ulMidValue;
  17.     unsigned short wTemp2,wMTNum = N,wPostValue;
  18.     unsigned long ulMag[2] =
  19.     {
  20.         0x0,MATRIX_A
  21.     };
  22.     if(bInitFlag==0)
  23.     {
  24.         unsigned long ulInitSeed=unsigned long(time(0));
  25.         ulaSeed[0]= ulInitSeed & 0xffffffffUL;
  26.         for (unsigned short wtemp1 = 1; wtemp1 < N; wtemp1++)
  27.         {
  28.             ulaSeed[wtemp1] = (1812433253UL * (ulaSeed[wtemp1-1] ^ (ulaSeed[wtemp1-1] >> 30)) + wtemp1);
  29.             ulaSeed[wtemp1] &= 0xffffffffUL;
  30.         }
  31.         bInitFlag = 1;
  32.     }
  33.     wPostValue = (t_ulNumber + wSeedFlag - 1) % N + 1;
  34.     for (unsigned long ulTemp = 0; ulTemp < t_ulNumber; ulTemp++)
  35.     {
  36.         if((wSeedFlag != 624) && (wSeedFlag != 0))
  37.         {
  38.             t_ulpRandom[ulTemp] = ulaSeed[wSeedFlag];
  39.             wSeedFlag ++;
  40.         }
  41.         else
  42.         {
  43.             if(wMTNum >= N)
  44.             {
  45.                 for (wTemp2 = 0; wTemp2 < N-M; wTemp2 ++)
  46.                 {
  47.                     ulMidValue = (ulaSeed[wTemp2] & UPPER_MASK) | (ulaSeed[wTemp2 + 1] & LOWER_MASK);
  48.                     ulaSeed[wTemp2] = ulaSeed[wTemp2 + M] ^ (ulMidValue >> 1)^ ulMag[ulMidValue & 0x1];
  49.                 }
  50.                 for (; wTemp2 < N-1; wTemp2++)
  51.                 {
  52.                     ulMidValue = (ulaSeed[wTemp2] & UPPER_MASK) | (ulaSeed[wTemp2 + 1] & LOWER_MASK);
  53.                     ulaSeed[wTemp2] = ulaSeed[wTemp2 + (M - N)] ^ (ulMidValue >> 1)^ ulMag[ulMidValue & 0x1];
  54.                 }
  55.                 ulMidValue = (ulaSeed[N - 1] & UPPER_MASK) | (ulaSeed[0] & LOWER_MASK);
  56.                 ulaSeed[N - 1] = ulaSeed[M - 1] ^ (ulMidValue >> 1) ^ ulMag[ulMidValue & 0x1];
  57.                 wMTNum = 0;
  58.             }
  59.             ulMidValue = ulaSeed[wMTNum++];
  60.             ulMidValue ^= TEMPERING_SHIFT_U(ulMidValue);
  61.             ulMidValue ^= TEMPERING_SHIFT_S(ulMidValue) & TEMPERING_MASK_B;
  62.             ulMidValue ^= TEMPERING_SHIFT_T(ulMidValue) & TEMPERING_MASK_C;
  63.             ulMidValue ^= TEMPERING_SHIFT_L(ulMidValue);
  64.             t_ulpRandom[ulTemp] = ulMidValue;
  65.         }
  66.     }
  67.     wSeedFlag = wPostValue;
  68. }
  69. bool cRandom::RandomUniform(double *t_pdArray,unsigned long t_ulNumber,double t_dUp,double t_dDown)
  70. {
  71.     bool bState;
  72.     double dInterval = (t_dUp - t_dDown) / MTRand_Max;
  73.     unsigned long *ulpNumber;
  74.     ulpNumber = new unsigned long[t_ulNumber];
  75.     memset(ulpNumber,0,sizeof(ulpNumber));
  76.     MTRandom(ulpNumber,t_ulNumber);
  77.     if(t_ulNumber >= 0)
  78.     {
  79.         for(unsigned long ulTemp=0; ulTemp<t_ulNumber; ulTemp ++)
  80.         {
  81.             t_pdArray[ulTemp] = double(ulpNumber[ulTemp]) * dInterval + t_dDown;
  82.         }
  83.         bState = true;
  84.     }
  85.     else
  86.     {
  87.         bState = false;
  88.     }
  89.     delete []ulpNumber;
  90.     return bState;
  91. }
  92. bool cRandom::RandomCircle(double *t_pdXArray,double *t_pdYArray,unsigned long t_ulNumber,double t_dXcenter,double t_dYcenter,double t_dRadius)
  93. {
  94.     bool bState;
  95.     unsigned long *ulpNumber;
  96.     ulpNumber=new unsigned long[t_ulNumber << 1];
  97.     memset(ulpNumber,0,t_ulNumber * sizeof(unsigned long) << 1);
  98.     MTRandom(ulpNumber,t_ulNumber << 1);
  99.     double dRadius = 0, dRandom1, dRandom2,dMiddle;
  100.     unsigned long ulTemp = 0;
  101.     dMiddle = (t_dRadius * 2) / MTRand_Max;//<<只试用于整型的数
  102.     if(t_ulNumber > 0)
  103.     {
  104.         for(unsigned long ultemp = 0; (ultemp != t_ulNumber - 1)&&(ulTemp != t_ulNumber); ultemp++)
  105.         {
  106.             dRandom1 = ulpNumber[(ultemp << 1)] * dMiddle - t_dRadius;//调用MT的次数太多了,进行修改
  107.             dRandom2 = ulpNumber[(ultemp << 1) + 1] * dMiddle - t_dRadius;//调用MT的次数太多了,进行修改
  108.             dRadius = sqrt(dRandom1 * dRandom1 + dRandom2 * dRandom2);
  109.             if (dRadius <= t_dRadius)
  110.             {
  111.                 t_pdXArray[ulTemp] = dRandom1 + t_dXcenter;
  112.                 t_pdYArray[ulTemp] = dRandom2 + t_dYcenter;
  113.                 ulTemp ++;
  114.             }
  115.             if(ultemp==t_ulNumber)
  116.             {
  117.                 ultemp=0;
  118.                 MTRandom(ulpNumber,t_ulNumber<<2);
  119.             }
  120.         }
  121.         bState = true;
  122.     }
  123.     else
  124.     {
  125.         bState = false;
  126.     }
  127.     delete []ulpNumber;
  128.     return bState;
  129. }
  130. bool cRandom::RandomGaussion(double *t_pdArray,unsigned long t_ulNumber,double t_dMean,double t_dStD)
  131. {
  132.     bool bState;
  133.     unsigned long ulTemp,ulNum;
  134.     double dRandomx,dRandomy,dRadius,dAngle;
  135.     unsigned long *ulpNumber;
  136.     ulNum = t_ulNumber + (t_ulNumber % 2);
  137.     ulpNumber = new unsigned long[ulNum];
  138.     memset(ulpNumber,0,ulNum*sizeof(unsigned long));
  139.     MTRandom(ulpNumber,ulNum);
  140.     ulNum = t_ulNumber >> 1;
  141.     if (t_dStD >= 0)
  142.     {
  143.         for(ulTemp = 0 ; ulTemp < ulNum ; ulTemp++)
  144.         {
  145.             dRandomx = (double)ulpNumber[ulTemp << 1] / MTRand_Max;
  146.             dRandomy = (double)ulpNumber[(ulTemp << 1) + 1] / MTRand_Max;
  147.             dRadius = (double)sqrt((-2) * log(dRandomx));
  148.             dAngle = 2 * 3.1415926 * dRandomy;
  149.             t_pdArray[ulTemp << 1] = (dRadius * cos(dAngle)) * t_dStD + t_dMean;
  150.             t_pdArray[(ulTemp << 1) + 1] = (dRadius * sin(dAngle)) * t_dStD + t_dMean;
  151.         }
  152.         if (t_ulNumber % 2 == 1)
  153.         {
  154.             dRandomx = (double)ulpNumber[ulTemp] / MTRand_Max;
  155.             dRandomy = (double)ulpNumber[ulTemp + 1] / MTRand_Max;
  156.             dRadius = (double)sqrt((-2) * log(dRandomx));
  157.             dAngle = 2 * 3.1415926 * dRandomy;
  158.             t_pdArray[ulTemp << 1] = (dRadius * cos(dAngle)) * t_dStD + t_dMean;
  159.         }
  160.         bState = true;
  161.     }
  162.     else
  163.     {
  164.         bState = false;
  165.     }
  166.     delete []ulpNumber;
  167.     return bState;
  168. }
  169. bool cRandom::RandomSequence(double *t_pdArray,unsigned long t_ulNumber)
  170. {
  171.     bool bState;
  172.     unsigned long *ulpNumber,ulMiddle,ulTemp,ulNum,ulIndex;
  173.     ulpNumber = new unsigned long[t_ulNumber * 18];
  174.     memset(ulpNumber,0,t_ulNumber * 18*sizeof(unsigned long));
  175.     MTRandom(ulpNumber,t_ulNumber * 18);
  176.     if(t_ulNumber>0)
  177.     {
  178.         for(ulNum=0; ulNum<18; ulNum++)
  179.         {
  180.             for(ulTemp=0; ulTemp<t_ulNumber; ulTemp++)
  181.             {
  182.                 ulIndex=ulpNumber[ulNum*18+ulTemp]%t_ulNumber;
  183.                 ulMiddle=t_pdArray[ulTemp];
  184.                 t_pdArray[ulTemp]=t_pdArray[ulIndex];
  185.                 t_pdArray[ulIndex]=ulMiddle;
  186.             }
  187.         }
  188.         bState=true;
  189.     }
  190.     else
  191.     {
  192.         bState = false;
  193.     }
  194.     delete []ulpNumber;
  195.     return bState;
  196. }

测试程序 main.cpp

  1. #include <iostream>
  2. #include "cRandom.h"
  3. #include <ctime>
  4. #include <fstream>
  5. #include <cstdlib>
  6. #include <cmath>
  7. #include <conio.h>
  8. #include <string.h>
  9. using std::ifstream;
  10. using std::ofstream;
  11. using std::cin;
  12. using std::cout;
  13. using std::endl;
  14. using namespace std;
  15. int main()
  16. {
  17.     cRandom cDistribute;
  18.     unsigned short chFlag;
  19.     unsigned long ulNumber, ulTemp;
  20.     double *pdArray, *pdXArray, *pdYArray;
  21.     bool bResult;
  22.     cout << "菜单选择" <<"\n"
  23.          << "1.均匀分布" <<"\n"
  24.          << "2.高斯分布" <<"\n"
  25.          << "3.二维均匀随机分布" <<"\n"
  26.          << "4.随机序列排序" <<"\n"
  27.          << "5.退出"<< endl;
  28.     while(1)
  29.     {
  30.         cin >> chFlag ;
  31.         if (chFlag == 1)
  32.         {
  33.             double dUp,dDown;
  34.             cout << "请输入产生均匀分布个数:" << endl;
  35.             cin >> ulNumber;
  36.             pdArray = new double[ulNumber];
  37.             memset(pdArray,0,ulNumber*sizeof(double));
  38.             cout << "请输入上限和下限:" << endl;
  39.             cin >> dUp >> dDown;
  40.             bResult = cDistribute.RandomUniform (pdArray, ulNumber,dUp,dDown);
  41.             if (bResult == true)
  42.             {
  43.                 cout << "均匀分布生成成功" << endl;
  44.             }
  45.             else
  46.             {
  47.                 cout << "均匀分布生成失败" << endl;
  48.                 return 0;
  49.             }
  50.             ofstream fFile("RandomUniform.txt");
  51.             for (ulTemp = 0; ulTemp < ulNumber; ulTemp ++)
  52.             {
  53.                 fFile << pdArray[ulTemp] << endl;
  54.             }
  55.             fFile.close();
  56.             fFile.clear();
  57.             delete []pdArray;
  58.         }
  59.         else if (chFlag == 2)
  60.         {
  61.             double dMean,dStD;
  62.             cout << "请输入产生高斯分布个数:" << endl;
  63.             cin >> ulNumber;
  64.             pdArray = new double[ulNumber];
  65.             memset(pdArray,0,ulNumber * sizeof(double));
  66.             cout << "请输入均值和方差" << endl;
  67.             cin >> dMean >> dStD;
  68.             bResult = cDistribute.RandomGaussion(pdArray,ulNumber,dMean,dStD);
  69.             if (bResult == true)
  70.             {
  71.                 cout << "高斯分布生成成功" << endl;
  72.             }
  73.             else
  74.             {
  75.                 cout << "高斯分布生成失败" << endl;
  76.                 return 0;
  77.             }
  78.             ofstream fFile("RandomUGaussion.txt");
  79.             for (ulTemp = 0; ulTemp < ulNumber; ulTemp ++)
  80.             {
  81.                 fFile << pdArray[ulTemp] << endl;
  82.             }
  83.             fFile.close();
  84.             fFile.clear();
  85.             delete []pdArray;
  86.         }
  87.         else if (chFlag == 3)
  88.         {
  89.             double dXCenter,dYCenter,dRadius;//the center's location
  90.             cout << "请输入产生圆上坐标的对数:" << endl;
  91.             cin >> ulNumber;
  92.             pdXArray = new double[ulNumber];
  93.             pdYArray = new double[ulNumber];
  94.             memset(pdXArray,0,ulNumber * sizeof(double));
  95.             memset(pdYArray,0,ulNumber * sizeof(double));
  96.             cout << "输入圆心的横纵坐标" << endl;
  97.             cin >> dXCenter >> dYCenter;
  98.             cout << "输入圆的半径" << endl;
  99.             cin >> dRadius;
  100.             bResult = cDistribute.RandomCircle(pdXArray,pdYArray,ulNumber,dXCenter,dYCenter,dRadius);
  101.             if (bResult == true)
  102.             {
  103.                 cout << "几何分布生成成功" << endl;
  104.             }
  105.             else
  106.             {
  107.                 cout << "几何分布生成失败" << endl;
  108.                 return 0;
  109.             }
  110.             ofstream fFile("RandomCircle.txt");
  111.             for (ulTemp = 0; ulTemp < ulNumber; ulTemp ++)
  112.             {
  113.                 fFile << pdXArray[ulTemp] << '\t' << pdYArray[ulTemp]<< endl;
  114.             }
  115.             fFile.close();
  116.             fFile.clear();
  117.             delete []pdXArray;
  118.             delete []pdYArray;
  119.         }
  120.         else if (chFlag == 4)
  121.         {
  122.             ofstream fFile("NumberList.txt",ios::out);
  123.             cout << "请输入随机数个数:" << endl;
  124.             cin >> ulNumber;
  125.             pdArray = new double[ulNumber];
  126.             memset(pdArray,0,ulNumber*sizeof(double));
  127.             cout << "请输入序列:" << endl;
  128.             for(ulTemp = 0; ulTemp < ulNumber; ulTemp++)
  129.             {
  130.                 cin >> pdArray[ulTemp];
  131.             }
  132.             bResult=cDistribute.RandomSequence(pdArray,ulNumber);
  133.             if (bResult == true)
  134.             {
  135.                 cout << "随机序列生成成功" << endl;
  136.             }
  137.             else
  138.             {
  139.                 cout << "随机序列生成失败" << endl;
  140.                 return 0;
  141.             }
  142.             for(ulTemp = 0; ulTemp < ulNumber; ulTemp++)
  143.             {
  144.                 fFile << pdArray[ulTemp] << endl;
  145.             }
  146.             fFile.close();
  147.             fFile.clear();
  148.             delete []pdArray;
  149.         }
  150.         else if (chFlag == 5)
  151.         {
  152.             return 0;
  153.         }
  154.         else
  155.         {
  156.             cout << "error!" << endl;
  157.         }
  158.     }
  159. }
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

已领礼包: 40个

财富等级: 招财进宝

发表于 2017-1-20 11:57:42 | 显示全部楼层
循环20次, 看看生成的随机数怎么样
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-5-23 19:12 , Processed in 0.241484 second(s), 30 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表