随机重拍与抽样(random_shuffle,random_sample,random_sample_n)

//版本一:使用内部的随机数生成器 
template<class RandomAccessIterator> 
   void random_shuffle( 
      RandomAccessIterator _first,  
      RandomAccessIterator _last 
   )
{
  __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator);
  if (__first == __last) return;
  for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i)
    iter_swap(__i, __first + __random_number((__i - __first) + 1));
}
//版本二:是使用一个会产生随机数的仿函数
template<class RandomAccessIterator, class RandomNumberGenerator> 
   void random_shuffle( 
      RandomAccessIterator _first,  
      RandomAccessIterator _last,  
      RandomNumberGenerator& gen 
   )
{
    __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator);
  if (__first == __last) return;
  for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i)
    iter_swap(__i, __first + __rand((__i - __first) + 1));

}

  随机重排[first,last)中的数据,有N!中可能,N=last-first,此算法会产生一种均匀分布任何特定排列顺序被选中的几率为1/N!版本二是一种特别的function object,当被引数传进来,传递方式是by reference,而不是by value,因为RandomNumberGenerator的重要特点是具有局部状态,每次被调用时被改变。

  使用乱数时,能够明白设定乱数产生器的种子是非常重要的,如果这对程序重要,则使用第二个版本。

#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdio>
#include <ctime>
using namespace std;

class F
{
    public:
        ptrdiff_t operator()(ptrdiff_t max)
        {
            srand((unsigned)time(NULL));
            int _rand=static_cast<int>(rand()/static_cast<int>(RAND_MAX));
            return static_cast<ptrdiff_t>(_rand*max);
        }    
};
int main()
{
    vector<int> v{1,2,3,4,5,6};
    
    random_shuffle(v.begin(),v.end(),F());
    for_each(v.begin(),v.end(),[](int i)
    {
        cout<<i<<" ";
    });
    cout<<endl;
    return 0;
}

random_sample

template <class InputerIterator,class RandomAccessIterator>
RandomAccessIterator random_sample(InputerIterator first,InputIterator last,RandomAccessIterator ofirst,RandomAccessIterator olast);

template <class InputerIterator,class RandomAccessIterator>
RandomAccessIterator random_sample(InputerIterator first,InputIterator last,RandomAccessIterator ofirst,RandomAccessIterator olast,RandomNumberGenerator &rand);
  1. 随机的将[first,last)中的一个取样结果复制到[ofirst,olast)中,它会复制n个元素,n为min(last-first,olast-ofirst),Input range中的每个元素至多在Output range中出现一次,该结果以均匀方式选出
  2. 返回值为ofirst+n
  3. 对于N个元素,忽略元素顺序,欲选出n个元素,共有N!/(n!(N-n)!)中方法,本算法会产生均匀分布的结果,任何特定的元素被选出的几率为n/N,任何特定取样(不考虑元素顺序)几率为n!(N-n)!/N!
  4. 第一个版本用内部自定义的乱数产生器,第二个版本用自己定义的function object的乱数产生器
  5. Input range必须是Forward Iterator,Output range必须是RandomAccessIterator,所以Output range中元素的性对顺序不一定会与Input ragne中的顺序相同

random_sample_n

template <class InputerIterator,class OutputerIterator,class Distance>
OutputerIterator random_sample_n(InputerIterator first,InputIterator last,OutputerIterator out,Distance n);

template <class InputerIterator,class OutputerIterator,class Distance,class RandomNumberGenerator>
OutputerIterator random_sample_n(InputerIterator first,InputIterator last,OutputerIterator out,Distance n,RandomNumberGenerator &rand);
  1. 从[first,last)中随机的复制元素到[out,out+n)中,他将复制m个元素,此处m为min(last-first,n),Input range中的每个元素至多在Output range中出现一次,该结果以均匀方式选出
  2. 返回值为out+m
  3. Input range必须是Forward Iterator,Output range必须是 Output Iterator,所以会保证两个容器中的相对顺序相同

转载于:https://www.cnblogs.com/tianzeng/p/10386217.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值