按照指定的权重求随机数

原文:http://fatelei.github.io/2015/09/08/

按照指定的权重求随机数

描述:通常取随机数,取到每个数字的概率都是一样,比如取 n 次,取到某个数的概率都是 1/n。现在情况发生了变化,要随机取的数,每个数字都被设置了一个权值(weight),比如:

上面这个图表的含义是:进行随机取数,取到 1 的概率是 1/5,取到 2 概率是 2/5,取到 3 的概率是 2/5。现在要求你使用代码完成这个按照不同权值进行取值的过程。

一开始想到方法是:

使用一个数组 value ,数组的下标对应于这个权重的范围,下标对应的值就是要求的值,比如还是上面这个例子,比如在 1 < x <= 3这个区间范围内,然后对整个区间长度求随机值,rand(1, 5) 会得到一个下标值,然后根据这个下标值去获取想要的值。这个解法的问题是,如果某个值的权值很大,那么需要一个很大的数组,这样会非常非常消耗内存,显然不是一个很好的解决方法。不过当时也没有想到更好的方法。

晚上回来想了想,有没有可以优化的方向

123
p(x = 1) = 1/5  (x <= 1)p(x = 2) = 2/5  (1 < x <= 3)p(x = 3) = 2/5  (3 < x <= 5)

转换成累积概率:

123
cp(x = 1) = 1/5 (x <= 1)cp(x = 2) = 3/5 (1 < x <= 3)cp(x = 3) = 1 (3 < x <= 5)

有上面这个映射关键,在 0 - 1 随机取一个数 x,如果 x <= cp[i] ,i 就是所要求的结果:

Python 实现

1234567
import random

def random_by_weight(values, cp):    for v, w in zip(values, cp):        rand = random.randint(0, 1)        if  rand <= w:             return v

选自:http://blog.csdn.net/v_july_v/article/details/6132775

3.1、选择算子

遗传算法使用选择运算对个体进行优胜劣汰操作。

适应度高的个体被遗传到下一代群体中的概率大;适应度低的个体,被遗传到下一代群体中的概率小。

选择操作的任务就是从父代群体中选取一些个体,遗传到下一代群体。

基本遗传算法(SGA)中选择算子采用轮盘赌选择方法。

Ok,下面就来看下这个轮盘赌的例子,这个例子通俗易懂,对理解选择算子帮助很大。

轮盘赌选择方法
轮盘赌选择又称比例选择算子,其基本思想是:
各个个体被选中的概率与其适应度函数值大小成正比。

设群体大小为N,个体xi 的适应度为 f(xi),则个体xi的选择概率为:

轮盘赌选择法可用如下过程模拟来实现:
(1)在[0, 1]内产生一个均匀分布的随机数r。
(2)若r≤q1,则染色体x1被选中。
(3)若qk-1<r≤qk(2≤k≤N), 则染色体xk被选中。 
其中的qi称为染色体xi (i=1, 2, …, n)的积累概率, 其计算公式为:

积累概率实例:

轮盘赌选择方法的实现步骤:
(1)计算群体中所有个体的适应度值;
(2)计算每个个体的选择概率;
(3)计算积累概率;
(4)采用模拟赌盘操作(即生成0到1之间的随机数与每个个体遗传到下一代群体的概率进行匹配)
来确定各个个体是否遗传到下一代群体中。

例如,有染色体
s1= 13 (01101)
s2= 24 (11000) 
s3= 8   (01000)
s4= 19 (10011)

假定适应度为f(s)=s^2 ,则
f (s1) = f(13) = 13^2 = 169
f (s2) = f(24) = 24^2 = 576
f (s3) = f(8) = 8^2 = 64
f (s4) = f(19) = 19^2 = 361

染色体的选择概率为:

染色体的累计概率为:

根据上面的式子,可得到:

例如设从区间[0, 1]中产生4个随机数:

r1 = 0.450126,    r2 = 0.110347

r3 = 0.572496,    r4 = 0.98503

时间: 2024-10-25 06:00:13

按照指定的权重求随机数的相关文章

生成指定范围的一组随机数并求平均值

Math.random()是令系统随机选取大于等于 0.0 且小于 1.0 的伪随机 double 值,是Java语言常用代码. 随机数生成20~90之间的数值,并求平均数: public class Random01 { public static void main(String[] args) { int len = 5; int sum = 0; int[] arr = new int[len]; for (int i = 0; i < len; i++) { arr[i] = (int

指定范围内生成随机数

随机数生成20~70之间的数值: public class Random { public static void main(String[] args) { java.util.Random r = new java.util.Random(); for (int i = 0; i < 10; i++) { System.out.print(" " + (r.nextInt(70) + 20)); } } } 运行结果如下图: 指定范围内生成随机数,布布扣,bubuko.com

求随机数,按后三位排序

编写程序实现以下功能:    //随机产生20个正整数存入数组a中,且每个数均在1000-9999之间(包含1000和9999).对数组进行排序,要求按每个数的后三位的大小进 行升序排列,然后取出满足此条件的前10个数放入数组b中,如果后三位的数值相等,则按原先的数值进行降序排列.最后输出数组b的内容 #import <Foundation/Foundation.h>int value(int x){ //如何求出5609 的后三位数    int y = x /1000;    int c

js中Math.random()生成指定范围数值的随机数

http://www.111cn.net/wy/js-ajax/57062.htm Math.random() 这个方法相信大家都知道,是用来生成随机数的.不过一般的参考手册时却没有说明如何用这个方法来生成指定范围内的随机数.这次我就来详细的介绍一下Math.random(),以及如何用它来生成制定范围内的随机数.w3school的random()教程定义和用法 random() 方法可返回介于 0 ~ 1 之间的一个随机数.语法 Math.random() 返回值 0.0 ~ 1.0 之间的一

SQL Server生成指定范围内的随机数

在开发中很多时候,我们都会遇到这种需要生成一个指定范围随机数的情况.而且在很多语言中比如Java.C#.SQl等,都会有一个函数生成一个类似于0.234273983423789的随机小数,而所有的随机数都是通过这个最基本的随机数(0.234273983423789)变化过来的. 下面我说一下生成指定范围随机数的思路,比如我要生成一个100-999范围内的随机数,我就要保证我写的生成随机数的表达式所生成的值,最大是999,最小是100.还有就是要明白一个数学里的小道理,0.99去乘一个数字所得的结

[Python]基于权重的随机数2种实现方式

问题: 例如我们要选从不同省份选取一个号码,每个省份的权重不一样,直接选随机数肯定是不行的了,就需要一个模型来解决这个问题. 简化成下面的问题: 字典的key代表是省份,value代表的是权重,我们现在需要一个函数,每次基于权重选择一个省份出来 {"A":2, "B":2, "C":4, "D":10, "E": 20} 解决: 这是能想到和能看到的最多的版本,不知道还没有更高效好用的算法. #!/usr/

使用python已知平均数求随机数

问题描述:产生40个数,范围是363-429之间,平均值为402 思路: 1 产生一个随机数 2 使用平均数求和随机数求出第二个数,生成20组 3 将排序打乱 # -*- coding: cp936 -*- import random import string ###################产生随机整数################### ###################第一个数随机产生,第二个使用平均数求出################### #count 数字的个数 #a

题目一:编写一个可以 获取任意指定范围内的随机数

分析: 键盘录入数据来指定范围:[start,end] String start =sc.next(); String end=sc.next(); 实现代码: public static int getRoundomNum(int start, int end){ //(int)(Math.random()*100)+1 ;//[1,100]   ---(1) //(int) (Math.random()*end)+start;//[start,end+start-1]  --(2) //由式

shell生成指定范围内的随机数

#!/bin/bash read -p "请输入起始数:" min read -p "请输入终止数:" max if [ $min -gt $max ] then echo "起始数大于终止数!" else echo -n "随机数:" ;expr $(date +%N) % $[$max - $min + 1] + $min #日期函数生成随机数向最大值和最小值的差加1后取余得到一个随机数,然后加上最小值保证能取到的最小值和