`

我该怎样shuffle呢

阅读更多

        在STL的Algorithm中有着这样的一种算法:mutating algorithm,这一类算法的主要作用是改变Sequence Container中元素的顺序。而改变元素顺序的方法有好几个,如将元素反序(reverse),将元素位置循环旋转(rotate)等,而最吸引我的就是能够产生随机序列的方法了(random_shuffle)。
        于是,我写了一段代码是试验一下这个方法:

#include <iostream>
#include 
<algorithm>
#include 
<iterator>
#include 
<vector>

using namespace std;

void main()
{
  vector
<int> v1(10);
  
for(int j = 0; j < v1.size(); ++j)
    v1[ j ] 
= j;
  ostream_iterator
<int> iter(cout, " ");
  copy(v1.begin(), v1.end(), iter);
  cout 
<< " ";
  random_shuffle(v1.begin(), v1.end());
  copy(v1.begin(), v1.end(), iter);
  cout 
<< " ";
}


        当我第一次执行的时候,哇,果然次序挺乱的哦。结果如下:

0 1 2 3 4 5 6 7 8 9
4 3 0 2 6 7 8 9 5 1

        然后我满心欢喜的将程序再执行了一遍,咦,怎么那么像原来的序列呢?我反复运行了几次,结果让我很沮丧,因为产生的随机序列是一样的。为什么会这样呢?只能深入到random_shuffle方法里面去瞧瞧了,于是我又开始debug之旅。
        在STL中的random-shuffle函数的实现是这样的:

template<class _RI> 
inline 
void random_shuffle(_RI _F, _RI _L)
{
  
if (_F != _L)
  _Random_shuffle(_F, _L, _Dist_type(_F)); 
}


template
<class _RI, class _Pd> 
inline 
void _Random_shuffle(_RI _F, _RI _L, _Pd *)
{
  
const int _RBITS = 15;
  
const int _RMAX = (1U << _RBITS) - 1;
  _RI _X 
= _F;
  
for (_Pd _D = 1++_X != _L; ++_D)
  
{
    unsigned 
long _Rm = _RMAX;
    unsigned 
long _Rn = rand() & _RMAX;
    
for (; _Rm < _D && _Rm != ~0UL;
     _Rm 
= _Rm << _RBITS | _RMAX)
     _Rn 
= _Rn << _RBITS | _RMAX;
     iter_swap(_X, _F 
+ _Pd(_Rn % _D)); 
  }

}


        在random_shuffle的两个参数的版本中,我们可以发现这样的一个函数:_Dist_type(_F)。而在iterator类中,我看到了这样的代码:

template<class _Ty> 
inline ptrdiff_t 
*_Dist_type(const _Ty *)
{return ((ptrdiff_t *)0); }

        在STDDEF.H文件中,我也找到ptrdiff的定义:typedef int ptrdiff_t。那么这个函数到底做了什么呢?不就是返回了一个 int *吗?而且值为00000000。更要命的是,传递进去之后,也没有地方使用啊,整个函数就在for循环出出现了_Pd,那么在这样的一段代码中,_Pd起到了怎样的作用呢?我觉得一点用处都没有。接下来的代码,由于在运行的时候,都没有改变通过srand改变随机数种子的话,得到的_Rn是恒定的,所以每次运行的结果都一样就不难理解了。现在我是知道了为什么得到的随机序列是一样的了,可是这个函数为什么要设计成这样呢?我能想到的就是为了随机序列能够被追溯吧。
    为了能够让每次运行的结果都不一样,于是我重写了这个函数:

template <typename T> 
inline 
void shuffle(T first, T last)
{
  
const int _RBITS = 15;
  
const int _RMAX = (1U << _RBITS) - 1;
  T temp 
= first;
  srand((unsigned)time(NULL));
  
for (int i = 1++temp != last; ++i)
  

    unsigned 
long _Rm = _RMAX;
    unsigned 
long _Rn = rand() & _RMAX;
    
for (; _Rm < i && _Rm != ~0UL;_Rm = _Rm << _RBITS | _RMAX)
       _Rn 
= _Rn << _RBITS | _RMAX;
    iter_swap(temp, first 
+ int(_Rn % i)); 
  }

}

        其实也没有改变什么,只是增加srand函数去改变随机种子并且去掉了对_Dist_type函数的调用而已。当我写到这里,突然间想到了是否可以不重写方法呢?只要在调用random_shuffle函数之前调用srand方法不就行了吗?试了一下,果然成功了。哇,太笨了。What a shame!
        说实在的,我对那个_Pd还是有点云里雾里的,还恳请各位大侠指点一二了。

分享到:
评论

相关推荐

    怎样让你的Win7桌面主题壁纸更酷更炫

    "Shuffle"=dword:00000000 "LastTickLow"=dword:00000000 "LastTickHigh"=dword:00000000 "AnimationDuration"=dword:00002328 ``` 保存该文件为`cool.reg`。 2. **导入注册表**:双击刚刚保存的`cool.reg`...

    ### 文章标题: 【自然语言处理】基于ChatGPT的REFORMER框架:提升Text-to-SQL模型的数据合成与增强系统设计

    内容概要:本文介绍了REFORMER,一个由ChatGPT驱动的数据合成框架,旨在解决Text-to-SQL模型因训练数据不足而导致的泛化能力差的问题。REFORMER通过“检索-编辑”方法,利用ChatGPT生成新的(问题,SQL查询)对,无需额外训练。该框架还引入了问题-查询-问题循环一致性验证,确保生成数据的质量。此外,REFORMER探索了两种数据增强技术:带模式信息的直接改写和使用构造SQL查询描述的改写。实验结果表明,REFORMER在多个评估指标上均优于之前的增强方法。 适合人群:对自然语言处理和SQL查询生成感兴趣的科研人员、工程师,尤其是从事Text-to-SQL模型开发和优化的专业人士。 使用场景及目标:①生成更多样化和高质量的(问题,SQL查询)对以增强Text-to-SQL模型的训练数据;②通过ChatGPT生成新的SQL查询和问题改写,提升模型的泛化能力和适应新领域的能力;③验证生成数据的一致性和质量,确保其符合预期。 阅读建议:本文不仅展示了REFORMER的技术细节和实验结果,还讨论了其局限性和未来研究方向。读者应重点关注框架的设计思路、实验设置和结果分析,以理解ChatGPT在数据增强中的应用潜力。同时,建议结合实际应用场景,思考如何利用REFORMER提升现有Text-to-SQL系统的性能。

    20220319-1.pdf

    20220319-1.pdf

    电磁兼容仿真:电磁敏感性分析.zip

    电磁领域系列仿真模拟教程,每个包10几个教程,从基础到精通,案例多多。

    ### 软考高项项目管理领域核心知识点与备考策略:涵盖综合知识、案例分析与论文写作

    内容概要:本文详细介绍了软考高项(高级信息系统项目管理师)的备考策略、考试内容及应试技巧。首先,文章强调了二八法则的应用,即80%的时间精力应放在项目管理领域的核心知识点上,如五大过程组、十大知识域等,20%的时间放在IT知识和组织级项目管理上。备考分为三个阶段:基础阶段通过精读教材、绘制思维导图夯实基础;强化阶段通过真题训练、案例分析提升实战能力;冲刺阶段通过论文押题、模拟考试做好最后准备。文章还特别指出,计算题和论文写作是考试的重点和难点,需重点练习。此外,针对不同地区的考生,提供了差异化的备考建议,如一线城市侧重新技术应用,中西部地区关注乡村振兴信息化等。最后,文章提醒考生关注机考模拟系统的开放时间和准考证打印时间,确保顺利参加考试。 适合人群:准备参加软考高项考试的考生,特别是有一定项目管理基础并希望系统复习、提高应试能力的考生。 使用场景及目标:①帮助考生高效利用有限时间,集中精力复习核心知识点;②通过模拟练习和真题训练,提升计算题和论文写作的能力;③结合实际案例,掌握项目管理全流程知识,提高考试通过率。 其他说明:备考过程中,考生应结合自身实际情况,灵活调整学习计划。同时,充分利用各种学习资源,如精讲课视频、直播课、历年真题等,不断巩固和深化对知识点的理解。考试改革后,机考成为主流,考生需提前熟悉机考系统,确保考试时能够熟练操作。

    多功能医用护理床(sw20可编辑+cad+说明书)_三维3D设计图纸.zip

    多功能医用护理床(sw20可编辑+cad+说明书)_三维3D设计图纸.zip

    西门子S7-200 Smart与台达DT330温控器基于Modbus RTU的485通讯实现及调试技巧

    内容概要:本文详细介绍了西门子S7-200 Smart PLC与台达DT330温控器通过RS485接口进行Modbus RTU通讯的方法。首先,文中阐述了双方设备的通讯参数设置,确保波特率、校验位等参数的一致性。接着,展示了PLC端的轮询控制逻辑,采用定时器和状态机来管理读写操作,避免数据冲突。对于具体的读写操作,提供了详细的寄存器地址映射规则以及数据类型的转换方法,解决了台达温控器特有的寄存器地址偏移问题。此外,还分享了一些实用的调试技巧,如使用串口助手抓包验证通讯效果,以及针对常见错误码的解决方案。最后,在触摸屏方面,利用昆仑通态MCGS组态软件实现了温度数据显示和设定的功能。 适合人群:从事工业自动化领域的工程师和技术人员,特别是那些需要进行PLC与温控器通讯集成工作的人员。 使用场景及目标:适用于需要将西门子S7-200 Smart PLC与台达DT330温控器进行通讯连接并实现温度监控的应用场合。主要目的是掌握正确的通讯配置步骤,理解Modbus RTU协议的具体应用,提高系统的可靠性和稳定性。 其他说明:文中提到的所有代码均已经过实际测试,并附带详细的注释,便于读者理解和学习。同时强调了硬件连接的重要性,给出了接线建议,帮助初学者少走弯路。

    基于Simulink的四永磁同步电机偏差耦合同步控制仿真建模与优化

    内容概要:本文详细介绍了利用Simulink构建四台永磁同步电机(PMSM)偏差耦合同步控制系统的方法及其优化策略。首先阐述了多电机同步控制在工业自动化中的重要性和应用场景,如AGV小车底盘驱动、传送带协同等。接着深入探讨了偏差耦合控制的具体实现方式,包括环形耦合结构的设计、耦合补偿算法以及PID参数调整方法。文中特别强调了耦合系数的选择对于系统稳定性的影响,并提供了具体的MATLAB函数用于计算各电机之间的耦合补偿量。此外,还讨论了如何通过动态权重分配算法来增强相邻电机间的耦合关系,从而提高同步速度。同时,针对可能出现的问题提出了预防措施,如避免使用微分环节、设置合理的摩擦系数和采样周期等。最后分享了一些实践经验,例如采用在线参数辨识技术和低通滤波器以应对负载突变等情况。 适用人群:从事工业自动化领域的工程师和技术人员,尤其是那些对多电机同步控制感兴趣的读者。 使用场景及目标:适用于需要精确控制多个电机同步运行的场合,如生产线上多轴协调动作、机器人关节控制等。主要目的是确保各个电机能够按照预定的速度平稳地协同工作,减少由于不同步造成的故障风险。 其他说明:文章不仅提供了理论指导,还包括了许多实用的操作技巧和注意事项,有助于读者更好地理解和掌握这一复杂的控制技术。

    2011春土木工程施工习题集(1).pdf

    2011春土木工程施工习题集(1).pdf

    信捷XD5 PLC与欧姆龙E5CC温控器基于Modbus RTU的双设定温度控制系统实现

    内容概要:本文详细介绍了信捷XD5 PLC与欧姆龙E5CC温控器之间的通讯实现及其双设定温度控制功能。首先,文中阐述了硬件连接的具体步骤,包括PLC、温控器和触摸屏的选择与连接方式。接着,详细解释了参数设置的关键点,确保两者能够正确通信。然后,展示了主程序的轮询机制以及温度读取、设定值写入和输出控制的具体代码实现。针对可能出现的问题,提供了详细的避坑指南和技术细节,如温度值转换、通讯超时处理等。最后,强调了系统的稳定性和可靠性,并给出了实际应用中的经验和建议。 适合人群:从事工业自动化领域的工程师和技术人员,尤其是对PLC与温控器通讯感兴趣的读者。 使用场景及目标:适用于需要实现PLC与温控器之间高效、稳定的通讯控制的工业自动化项目。目标是帮助工程师快速掌握信捷XD5 PLC与欧姆龙E5CC温控器的通讯配置和双设定温度控制的实现方法。 其他说明:文中提供的代码和配置建议已经过实际项目的验证,具有较高的实用价值。对于初学者来说,可以作为入门级的学习资料;对于有一定经验的技术人员,则可以作为参考和优化现有系统的依据。

    (整理)2 全 四川大学 土木工程经济练习题 四川大学锦城学院 肖栋天 0303COLLEGE TWO XIA.doc

    (整理)2 全 四川大学 土木工程经济练习题 四川大学锦城学院 肖栋天 0303COLLEGE TWO XIA.doc

    电大自我鉴定土木工程.doc

    电大自我鉴定土木工程.doc

    粉料搅拌器sw18_三维3D设计图纸.zip

    粉料搅拌器sw18_三维3D设计图纸.zip

    00300118347_ad5d7425.pdf

    00300118347_ad5d7425.pdf

    【嵌入式开发】STM32F103C8T6最小系统板硬件组成与开发环境搭建指南:快速上手嵌入式项目开发

    内容概要:文章详细介绍了 STM32F103C8T6 最小系统板,包括其组成、硬件连接方式、开发环境搭建步骤以及一个简单的 LED 闪烁示例代码。STM32F103C8T6 是一款基于 ARM Cortex-M3 内核的 32 位微控制器,具有高性能、低功耗和丰富的外设资源。最小系统板由主处理器、电源电路、时钟电路、复位与调试接口和 I/O 引脚组成。硬件连接方面,支持多种供电方式和调试接口。开发环境可以使用 STM32CubeIDE、Keil MDK-ARM 或 Arduino IDE 搭建。; 适合人群:对嵌入式开发有兴趣的学习者和初学者,尤其是希望了解 STM32 系列微控制器的开发者。; 使用场景及目标:① 学习 STM32F103C8T6 最小系统板的基本组成和硬件连接;② 搭建适合 STM32F103C8T6 的开发环境,如 STM32CubeIDE 或 Keil MDK-ARM;③ 实现简单的嵌入式项目,如 LED 闪烁示例。; 其他说明:此指南提供了详细的步骤和示例代码,帮助用户快速上手 STM32F103C8T6 最小系统板的开发。建议在实际操作中仔细阅读每一步骤,并参考提供的代码示例进行实践。

    公共安全视频图像信息系统管理条例.docx

    公共安全视频图像信息系统管理条例.docx

    回转工作台sw20_三维3D设计图纸_三维3D设计图纸.zip

    回转工作台sw20_三维3D设计图纸_三维3D设计图纸.zip

    清晰结构的三螺杆泵sw16可编辑_三维3D设计图纸_三维3D设计图纸.zip

    清晰结构的三螺杆泵sw16可编辑_三维3D设计图纸_三维3D设计图纸.zip

    汽轮机低压缸sw22可编辑_三维3D设计图纸_三维3D设计图纸.zip

    汽轮机低压缸sw22可编辑_三维3D设计图纸_三维3D设计图纸.zip

    电磁场仿真:磁热耦合仿真.zip

    电磁领域系列仿真模拟教程,每个包10几个教程,从基础到精通,案例多多。

Global site tag (gtag.js) - Google Analytics