rand(m)模拟rand(K)

问题:给定一个长度N的key-value对序列,序列中的key没有重复,value赋值为正整数,例如长度为4的序列:[1:3, 2:1, 3:9, 4:6]。另外给定一个随机数生成函数rand(m)可以等概率的生成0~m-1中的任何一个整数。

  1. 请实现一个随机生成Key的函数,生成每个key的概率正比于这个key对应的value值。

          方法:首先将列表中的value加起来,比如是K;问题转化为如何利用rand(m)去模拟rand(K)的新问题,因为获得rand(K)之后便可以使用划分子区间的方法实现题目要求;

          当K<=m的时候,可以设计rand(K) 为:

          a = rand (m);
          while(a>=K)
          {
               a=rand (m);
          }
          return a;

          当K>m && K <m*m,则构造一个rand(m*m),具体构造方法是rand(m)*m + rand (m),再利用rand(m*m) 去构造rand(K),方法也是取子区间;

     比如该题目例子中K=1+2+3+4=10,假设m=4,那么K>4&&K<16, 先用rand(4)*4+rand(4)构造出了rand(16)。然后用rand(16)构造rand(10),并且使得key值与生成key的概率成正比,那么我们可以令rand(16)=0时,输出1;rand(16)=1、2时,输出2;rand(16)=3,4,5时,输出3;rand(16)=6,7,8,9时,输出4;rand(16)=10~15时,抛弃;
          设计rand(K)为:    

 a=rand(4)*4+rand(4);

 while(a>=K)

 {
         a=rand(4)*4+rand(4);
 }

switch(a):

{

         case 0:return 1;break;

         case 1:

         case 2:return 2;break;

         case 3:

         case 4:
 
         case 5:return 3;break;

         case 6:

         case 7:

         case 8:

         case 9:return 4;break;

}

          当K>m*m的时候,类似利用rand(m*m)去构建rand(m*m*m*m),再利用取子区间的方法;不再赘述

posted @ 2016-09-30 09:36  beaglebone  阅读(591)  评论(0编辑  收藏  举报