使用Python实现轮盘赌选择法Roulette Wheel Selection Method in Python

2023-12-08 04:04

本文主要是介绍使用Python实现轮盘赌选择法Roulette Wheel Selection Method in Python,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、引言

        最近在手写遗传算法,想尝试解决一些优化问题。然而,在编码的过程中,自己发现了很多都不懂的问题。比如,交叉的操作,有单点交叉、两点交叉和多点交叉,具体选哪一种会更好呢?未知。还有交叉的概率,以及变异的概率,取多少才算合理呢?未知。最后就是轮盘赌选择法,在实现的时候,也有一点小疑惑,就是:通过Python的random没办法直接使用choice、choices或sample进行选择。所以,只好通过手动的方式写一个了。

二、轮盘赌选择法/Roulette Wheel Selection Method

        轮盘赌选择法,即Roulette Wheel Selection Method,又称为Fitness Proportionate Selection Method。常用于遗传算法染色体的选择。从选择的个数来看,如果只是一个,那么很好实现。但如果是从多个选择之中选择一个,那么就稍微复杂一些了。

        想象有一个轮盘,现在我们将它分割成m个部分,而这里的m代表我们总体中染色体的个数。每条染色体在轮盘上占有的区域面积将根据适应度分数成比例表达出来。例如m=4,而各条染色体的适应度分数分别为28、23、12、34。那么,轮盘的形状如下:

        假设有一个固定的指针固定在圆盘周长上的某一点,轮盘开始旋转,那么当旋转停止时,就能够确定指针停留在哪个区域,并根据此区域能够选择出一个染色体。例如,

        这样,第一个染色体便被选了出来,而且它被选中的概率是35%(34/(28+23+12+34))。此时如果要选出第二个染色体,就拥有两种实现方式了:

        ①轮盘中不删除chromosome4,如果通过旋转随机停下选出来的还是chromosome4,就重新选择,直到选出一个染色体不是chromosome4为止。

        ②轮盘中删除chromosome4,然后按照下面的轮盘进行选择:

        显然,在第二种实现方法中,各染色体被选中的概率已经发生了变化。而且,第一种实现方法存在一个比较明显的缺点,就是:有可能一直都选择同一个染色体,尽管选择的尝试越久、概率越低,这导致选择的效率下降。第一种实现方式还有一个缺点是,选择到两个不同的染色体的概率是不可计算的,因为轮盘选择的结果拥有无数个(例如,每次旋转都被选中相同的chromosome4,导致一个死循环并不断做轮盘选择);而第二种的概率是可以被计算,因为每种选择的结果确定(例如,chromosome4-chromosome1、chromosome4-chromosome2或chromosome4-chromosome3)。

        因此,这里推荐使用第二种实现方式实现轮盘赌选择法。

三、基于Python的实现方式

        编程思想很简单,大概如下。生成一个[0,total_fitness)的随机数R

        如果R≤28,则选择chromosome1;

        如果28<R≤28+23,则选择chromosome2;

        如果28+23<R≤28+23+12,则选择chromosome3;

        如果28+23+12<R≤28+23+12+34,则选择chromosome4。

        当需要选择第二个染色体时,就从list中进行删除,当然fitness所对应的list也需要进行删除。

        实现方式为:

import copy
import random# function: achieve the roulette wheel selection method
# population_list: the list of optional chromosomes
# fitness_list: the corresponding fitness of chromosomes
# num_selection: the number of chromosome selection
def rw_selection(chromosome_list, fitness_list, num_selection):# copy a duplicate of the populationcp_chromosome_list = copy.deepcopy(chromosome_list)cp_fitness_list = copy.deepcopy(fitness_list)# define a list for save the selected chromosomesselected_chromosome_list = []# select m chromosomes from cp_chromosome_listfor _ in range(num_selection):# calculate the current sum of chromosome fitnesstotal_fitness = sum(cp_fitness_list)# judge which chromosome is selectedrandom_value = random.uniform(0, total_fitness)cumulative_fitness = 0for i, chromosome in enumerate(cp_chromosome_list):cumulative_fitness += cp_fitness_list[i]if cumulative_fitness >= random_value:# select a chromosomeselected_chromosome_list.append(chromosome)# remove the corresponding chromosome and fitnesscp_chromosome_list.pop(i)cp_fitness_list.pop(i)break# return the selection resultreturn selected_chromosome_list# enter of the program
if __name__ == '__main__':p = ['chromosome1', 'chromosome2', 'chromosome3', 'chromosome4']f = [28, 23, 12, 34]m = 2for _ in range(10):selected_p = rw_selection(p, f, m)print(selected_p)

四、运行结果和讨论

['chromosome3', 'chromosome4']
['chromosome1', 'chromosome2']
['chromosome2', 'chromosome1']
['chromosome3', 'chromosome1']
['chromosome1', 'chromosome2']
['chromosome1', 'chromosome3']
['chromosome4', 'chromosome1']
['chromosome4', 'chromosome2']
['chromosome3', 'chromosome4']
['chromosome4', 'chromosome1']

Process finished with exit code 0

        从运行的结果来看,chromosome4和chromosome1被优先选择的概率较高,因为chromosome4被选择的次数为5/20,而chromosome1被选择的次数为7/20。另外,chromosome2被选择的次数为4/20,chromosome3被选择的次数为4/20。基本上符合fitness的分布,但由于试验次数太少,chromosome4被选择的次数要少于chromosome1。

五、总结

        其实感觉这篇博客的意义不是很大,但是怕自己以后还遇到这个小问题,所以,还是记录一下比较好。如果博客中出现一些问题,还请广大网友批评指正。

六、参考资料

        1. 遗传算法

        2. Fitness Proportionate Selection

        3. what is roulette wheel selection

这篇关于使用Python实现轮盘赌选择法Roulette Wheel Selection Method in Python的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/468476

相关文章

Java中的Cursor使用详解

《Java中的Cursor使用详解》本文介绍了Java中的Cursor接口及其在大数据集处理中的优势,包括逐行读取、分页处理、流控制、动态改变查询、并发控制和减少网络流量等,感兴趣的朋友一起看看吧... 最近看代码,有一段代码涉及到Cursor,感觉写法挺有意思的。注意是Cursor,而不是Consumer

Vue ElementUI中Upload组件批量上传的实现代码

《VueElementUI中Upload组件批量上传的实现代码》ElementUI中Upload组件批量上传通过获取upload组件的DOM、文件、上传地址和数据,封装uploadFiles方法,使... ElementUI中Upload组件如何批量上传首先就是upload组件 <el-upl

前端知识点之Javascript选择输入框confirm用法

《前端知识点之Javascript选择输入框confirm用法》:本文主要介绍JavaScript中的confirm方法的基本用法、功能特点、注意事项及常见用途,文中通过代码介绍的非常详细,对大家... 目录1. 基本用法2. 功能特点①阻塞行为:confirm 对话框会阻塞脚本的执行,直到用户作出选择。②

Node.js net模块的使用示例

《Node.jsnet模块的使用示例》本文主要介绍了Node.jsnet模块的使用示例,net模块支持TCP通信,处理TCP连接和数据传输,具有一定的参考价值,感兴趣的可以了解一下... 目录简介引入 net 模块核心概念TCP (传输控制协议)Socket服务器TCP 服务器创建基本服务器服务器配置选项服

Docker部署Jenkins持续集成(CI)工具的实现

《Docker部署Jenkins持续集成(CI)工具的实现》Jenkins是一个流行的开源自动化工具,广泛应用于持续集成(CI)和持续交付(CD)的环境中,本文介绍了使用Docker部署Jenkins... 目录前言一、准备工作二、设置变量和目录结构三、配置 docker 权限和网络四、启动 Jenkins

Python3脚本实现Excel与TXT的智能转换

《Python3脚本实现Excel与TXT的智能转换》在数据处理的日常工作中,我们经常需要将Excel中的结构化数据转换为其他格式,本文将使用Python3实现Excel与TXT的智能转换,需要的可以... 目录场景应用:为什么需要这种转换技术解析:代码实现详解核心代码展示改进点说明实战演练:从Excel到

Python中常用的四种取整方式分享

《Python中常用的四种取整方式分享》在数据处理和数值计算中,取整操作是非常常见的需求,Python提供了多种取整方式,本文为大家整理了四种常用的方法,希望对大家有所帮助... 目录引言向零取整(Truncate)向下取整(Floor)向上取整(Ceil)四舍五入(Round)四种取整方式的对比综合示例应

python 3.8 的anaconda下载方法

《python3.8的anaconda下载方法》本文详细介绍了如何下载和安装带有Python3.8的Anaconda发行版,包括Anaconda简介、下载步骤、安装指南以及验证安装结果,此外,还介... 目录python3.8 版本的 Anaconda 下载与安装指南一、Anaconda 简介二、下载 An

如何使用CSS3实现波浪式图片墙

《如何使用CSS3实现波浪式图片墙》:本文主要介绍了如何使用CSS3的transform属性和动画技巧实现波浪式图片墙,通过设置图片的垂直偏移量,并使用动画使其周期性地改变位置,可以创建出动态且具有波浪效果的图片墙,同时,还强调了响应式设计的重要性,以确保图片墙在不同设备上都能良好显示,详细内容请阅读本文,希望能对你有所帮助...

Python自动化处理手机验证码

《Python自动化处理手机验证码》手机验证码是一种常见的身份验证手段,广泛应用于用户注册、登录、交易确认等场景,下面我们来看看如何使用Python自动化处理手机验证码吧... 目录一、获取手机验证码1.1 通过短信接收验证码1.2 使用第三方短信接收服务1.3 使用ADB读取手机短信1.4 通过API获取