【机器学习】【遗传算法】【项目实战】药品分拣的优化策略【附Python源码】
仅供学习、参考使用
一、遗传算法简介
遗传算法(Genetic Algorithm, GA)是机器学习领域中常见的一类算法,其基本思想可以用下述流程图简要表示:
(图参考论文:Optimization of Worker Scheduling at Logistics
Depots Using GeneticAlgorithms and Simulated
Annealing)
一种常见的遗传算法变例是有偏随机密匙遗传算法 (BRKGA: Biased Random Key Genetic Algorithm) ,参考论文:A BIASED RANDOM-KEY GENETIC ALGORITHM WITH VARIABLE MUTANTS TO
SOLVE A VEHICLE ROUTING PROBLEM,算法流程大致如下:
(图参考博客:Pymoo学习 (11):有偏随机密匙遗传算法 (BRKGA: Biased Random Key Genetic Algorithm) 的使用)
二、项目源码(待进一步完善)
1、导入相关库
import csv
import random
import numpy as np
import pandas as pd
from datetime import datetime
import matplotlib.pyplot as plt
2、药品统计
# 统计zone_id=2110的药品
def screen_goods_id(tote_data, zone):zone_goods_id_lists = []for i in range(len(tote_data)):zone_id = tote_data['区段ID'][i]goods_id = tote_data['产品编号'][i]if zone_id == zone:zone_goods_id_lists.append(goods_id)zone_goods_id_lists = list(set(zone_goods_id_lists))return zone_goods_id_lists
3、货位统计
# 统计zone_id=2110的货位
def generate_locations():index_id_0 = [2173, 2174, 2175, 2176, 2177, 2178, 2179, 2180, 2181]index_id_1 = [1, 2, 3, 4, 5, 6, 7, 8]index_id_2 = [21, 22, 23, 24, 25, 31, 32, 33, 34, 35, 41, 42, 43, 44, 45]location_id_data = [f"{aa:04d}{bb:02d}{cc:02d}1" for aa in index_id_0 for bb in index_id_1 for cc in index_id_2]return location_id_data
4、缺失货位统计
# 统计zone_id=2110的缺失货位
def del_locations():index_id_0 = [217408, 217507, 217708, 217807, 218008, 218107]index_id_1 = [22, 23, 24, 25, 32, 33, 34, 35, 42, 43, 44, 45]del_loc_data = [f"{aa:06d}{bb:02d}1" for aa in index_id_0 for bb in index_id_1]return del_loc_data
5、生成可使用货位
# 去除缺失货位,生成最终的可使用货位
def screen_location_id():location_id_data = generate_locations()del_loc_data = del_locations()location_id_lists = [loc_id for loc_id in location_id_data if loc_id not in del_loc_data]return location_id_lists
6、个体(单个基因型)生成
# 生成一个个体
def pop_one_combined(list_1, list_2): # list1的长度不能大于list2goods_ids_copy = list_1[:]location_ids_copy = list_2[:]combined_list = []for _ in range(len(list_1)):element = random.choice(location_ids_copy)location_ids_copy.remove(element)combined_list.append(element)return combined_list
生成测试:大小为6的一维数组,生成50个个体(种群类似):
list1 = [1, 2, 3, 4, 5, 6]
list2 = [1, 2, 3, 4, 5, 6]# 个体生成测试(批量生成)for i in range(50):print(pop_one_combined(list1, list2))
7、种群(基因池)生成
# 生成种群
def generate_pop_list(POP_SIZE, zone_goods_id_data, zone_location_id_data):pop_list = []for _ in range(POP_SIZE):pop_individuality = pop_one_combined(zone_goods_id_data, zone_location_id_data)pop_list.append(pop_individuality)return pop_list
生成测试:
# 种群生成测试(样本量50)
print(generate_pop_list(50, list1, list2))
8、劳累值(特征系数)计算公式
# 拣选劳累值计算公式
def pick_distance_formula(location_id, shelves_num):if location_id[-2] == '4': # 第4层(最高层)distance = 10 * (int(location_id[0:4]) - 2173) + (shelves_num - 1) * 10 + int(location_id[-3]) + 3else: # 第1~3层distance = 10 * (int(location_id[0:4]) - 2173) + (shelves_num - 1) * 10 + int(location_id[-3])return distance
9、一组数据的劳累值计算
# 拣选劳累值计算(一组)
def pick_distance_value(location_id):distance = 0shelves_num = int(location_id[4:6])group_1 = [1, 3, 5, 7]group_2 = [2, 4, 6, 8]if shelves_num in group_1:shelves_num = shelves_num // 2 + 1elif shelves_num in group_2:shelves_num = shelves_num // 2distance = pick_distance_formula(location_id, shelves_num)return distance
10、选择优势个体进入下一代
# 选择优胜个体
def select(pop_list, CROSS_RATE, POP_SIZE):index = int(CROSS_RATE * POP_SIZE) # 一轮筛选后的样本数量return pop_list[0:index] # 返回前xxx个优胜个体
11、遗传变异机制
# 遗传变异
def mutation(MUTA_RATE, child, zone_goods_id_data, zone_location_id_data):if np.random.rand() < MUTA_RATE:mutation_list = [loc_id for loc_id in zone_location_id_data if loc_id not in child]num = np.random.randint(1, int(len(zone_goods_id_data) * MUTA_RATE))for _ in range(num):index = np.random.randint(0, len(zone_goods_id_data))mutation_list.append(child[index])loc_id = random.choice(mutation_list)child[index] = loc_idreturn child
12、子代中0值的替换
# (子代)0值的替换
def obx_count_run(child, parent):for parent_elemental in parent:if parent_elemental not in child:for i in range(len(child)):if child[i] == 0:child[i] = parent_elementalbreakreturn child
13、基于顺序的交叉方式(Order-Based Crossover, OBX)
# 遗传交叉(交叉算子:基于顺序的交叉(Order-Based Crossover,OBX))
def crossmuta(pop_list, POP_SIZE, MUTA_RATE, zone_goods_id_data, zone_location_id_data):pop_new = []for i in range(len(pop_list)):pop_new.append(pop_list[i][1:])while len(pop_new) < POP_SIZE:parent_1 = random.choice(pop_list)[1:]parent_2 = random.choice(pop_list)[1:]while parent_1 == parent_2:parent_2 = random.choice(pop_list)[1:]child_1 = [0 for _ in range(len(zone_goods_id_data))]child_2 = [0 for _ in range(len(zone_goods_id_data))]for j in range(len(zone_goods_id_data)):genetic_whether = np.random.choice([0, 1])if genetic_whether == 1:child_1[j] = parent_1[j]child_2[j] = parent_2[j]if (child_1 == parent_1) or (child_2 == parent_2):continuechild_1 = obx_count_run(child_1, parent_2)child_1 = mutation(MUTA_RATE, child_1, zone_goods_id_data, zone_location_id_data)child_2 = obx_count_run(child_2, parent_1)child_2 = mutation(MUTA_RATE, child_2, zone_goods_id_data, zone_location_id_data)pop_new.append(child_1)pop_new.append(child_2)return pop_new
14、损失曲线图绘制
# 每轮总拣选劳累值绘制曲线图
def loss_chart(data):y_values = datax_values = list(range(len(y_values)))plt.plot(x_values, y_values)plt.title("zone_2110_pick_distance_loss")plt.xlabel("Iterations") # 迭代次数plt.ylabel("zone_2110_pick_distance") # 距离plt.grid()plt.savefig('./JS_zone_2110_pick_distance_loss.png')plt.show()
15、结果合成
# 最终结果合成
def goods_location_data_consolidation(zone_goods_id_data, zone_goods_location_id_data):goods_location_data = []for i in range(len(zone_goods_id_data)):goods_location_data.append([zone_goods_id_data[i], zone_goods_location_id_data[i]])return goods_location_data
主函数及运行:
def main():list1 = [1, 2, 3, 4, 5, 6]list2 = [1, 2, 3, 4, 5, 6]# 个体生成测试(批量生成)for i in range(50):print(pop_one_combined(list1, list2))# 种群生成测试(样本量50)print(generate_pop_list(50, list1, list2))print("Genetic algorithm run start")print(f"start_time --> {datetime.now()}")zone_2110_pick_distance = []tote_goods_data_2403 = pd.read_csv('./tote_goods_data_2024_03.csv') # 读取数据集POP_SIZE = 20 # 种群大小CROSS_RATE = 0.9 # 交叉率MUTA_RATE = 0.05 # 变异率Iterations = 10 # 迭代次数zone_2110_goods_id_lists = screen_goods_id(tote_goods_data_2403, 2110)zone_2110_location_id_lists = screen_location_id()POP = generate_pop_list(POP_SIZE, zone_2110_goods_id_lists, zone_2110_location_id_lists)for i in range(Iterations):POP = getfitness(POP, 2110, tote_goods_data_2403, zone_2110_goods_id_lists)POP = select(POP, CROSS_RATE, POP_SIZE)zone_2110_pick_distance.append(POP[0][0])POP = crossmuta(POP, POP_SIZE, MUTA_RATE, zone_2110_goods_id_lists, zone_2110_location_id_lists)loss_chart(zone_2110_pick_distance)Updated_goods_location_data = goods_location_data_consolidation(zone_2110_goods_id_lists, POP[0])with open('./zone_2110_goods_location_data.csv', 'w', newline='') as csvfile:writer = csv.writer(csvfile)writer.writerow(['goods_id', 'location_id'])for row in Updated_goods_location_data:writer.writerow(row)print(f"end_time --> {datetime.now()}")print("Genetic algorithm run end")if __name__ == "__main__":main()
三、算法测试
1、pop_size=20, iterations=10
cross_rate=0.5, muta_rate=0.05:
交叉率不变,增加变异率到0.1:
交叉率不变,增加变异率到0.2:
变异率不变,增加交叉率到0.9:
2、在另一个数据集上进行测试
采用初始参数设定:
交叉率提高至0.9:
四、算法优化
GA(遗传)算法优化可行性分析
一、优化算法核心步骤参数
GA(Genetic Algorithm,遗传算法)的主要流程可以用下图进行简要描述:
在初始化阶段,需要确定imax(最大迭代次数)的值用于主循环的迭代。除这个值外,在算法的“交叉”步骤中,需要确定交叉方法(常用的交叉方法包括单点交叉、两点交叉、多点交叉、部分匹配交叉、均匀交叉、顺序交叉、基于位置的交叉、基于顺序的交叉、循环交叉、子路径交换交叉等),并指定参数cross_rate(交叉率)的值;在“变异”步骤中,需要指定参数muta_rate(变异率)的值;在“适应度计算”步骤中,需要自定义适应度(fitness)计算公式。故而可以进行优化的参数包括:
(1)最大迭代次数;
(2)交叉方法;(待验证)
(3)交叉率;
(4)变异率;(结论:提高变异率可以显著提高损失函数的收敛速度)
(5)适应度计算公式(涉及到按比例缩放的问题)。可能的策略:使用二次或者高次函数?如何提高损失函数的收敛速度?
二、采用GA的常见变式
上述流程图为GA的最基本的形式(基础GA),常见的优化变式包括:
(1)GA+SA——遗传算法结合模拟退火(Simulated Annealing)算法;
见论文:《Optimization of Worker Scheduling at Logistics
Depots Using Genetic Algorithms and Simulated
Annealing》
(2)AQDE(Adaptive Quantum Differential Evolution)算法(适应性量子差分进化算法);
见论文:《Z. Sun, Z. Tian, X. Xie, Z. Sun, X. Zhang, and G. Gong, “An metacognitive based logistics human resource modeling and optimal
scheduling,”》
(3)BRKGA(Biased Random-Key Genetic Algorithm)算法(有偏随机密钥遗传算法);
见论文:《A Biased Random-Key Genetic Algorithm With Variable Mutants To Solve a Vehicle Routing Problem》
三、结合深度学习或者强化学习
todo
四、其他可行方法
其他可行方法主要包括:
(1)向量化(vectorization);
(2)多线程(multithreading);
(3)并行计算(multiprocessing);
(4)带缓存的多级计算(cached computation)。
并行计算方面,可以使用Python中的joblib库:
相关文章:
【机器学习】【遗传算法】【项目实战】药品分拣的优化策略【附Python源码】
仅供学习、参考使用 一、遗传算法简介 遗传算法(Genetic Algorithm, GA)是机器学习领域中常见的一类算法,其基本思想可以用下述流程图简要表示: (图参考论文:Optimization of Worker Scheduling at Logi…...
电子电气架构 ---车载安全防火墙
我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都是你的不对。非必要不费力证明自己,无利益不试图说服别人,是精神上的节…...
解决selenium加载网页过慢影响程序运行时间的问题
在用selenium爬取动态加载网页时,发现网页内容都全部加载完了,但是页面还在转圈,并且获取页面内容的代码也没有执行,后面了解到selenium元素操作等方法是需要等待页面所有元素完全加载完成后才开始执行的,所以在页面未…...
何为云防护?有何作用
云防护又称云防御。随着Internet互联网络带宽的增加和多种DDOS 黑客工具的不断发布,云计算越演越热,DDOS拒绝服务攻击的实施越来越容易,DDOS攻击事件正在成上升趋势。出于商业竞争、打击报复和网络敲诈等多种因素,导致很多IDC 托管…...
2024050402-重学 Java 设计模式《实战责任链模式》
重学 Java 设计模式:实战责任链模式「模拟618电商大促期间,项目上线流程多级负责人审批场景」 一、前言 场地和场景的重要性 射击🏹需要去靶场学习、滑雪🏂需要去雪场体验、开车🚗需要能上路实践,而编程…...
centos7安装字体
1.安装命令 yum install fontconfig #字体库命令 yum install mkfontscale #更新字体命令2.安装字体(注意权限问题) 进入目录 /usr/share/fonts ,该目录是 centos7 字体库的默认安装目录。在该目录下创建一个文件夹 ekp (名字…...
Llama模型家族之使用 ReFT技术对 Llama-3 进行微调(三)为 ReFT 微调准备模型及数据集
LlaMA 3 系列博客 基于 LlaMA 3 LangGraph 在windows本地部署大模型 (一) 基于 LlaMA 3 LangGraph 在windows本地部署大模型 (二) 基于 LlaMA 3 LangGraph 在windows本地部署大模型 (三) 基于 LlaMA…...
学习Canvas过程中2D的方法、注释及感悟一(通俗易懂)
1.了解Canvas: Canvas是前端一个很重要的知识点,<canvas>标签用于创建画布绘制图形,通过JavaScript进行操作。它为开发者提供一个动态绘制图形的区域,用于创建图标、游戏动画、图像处理等。 对于能够熟练使用Canvas的开发者…...
《TCP/IP网络编程》(第十三章)多种I/O函数(2)
使用readv和writev函数可以提高数据通信的效率,它们的功能可以概括为**“对数据进行整合传输及发送”**。 即使用writev函数可以将分散在多个缓冲中的数据一并发送,使用readv函数可以由多个缓冲分别接受,所以适当使用他们可以减少I/O函数的调…...
Java集合汇总
Java中的集合框架是Java语言的核心部分,提供了强大的数据结构来存储和操作对象集合。集合框架位于java.util包中,主要可以分为两大类:Collection(单列集合)和Map(双列集合)。下面是对它们的总结…...
度小满金融大模型的应用创新
XuanYuan/README.md at main Duxiaoman-DI/XuanYuan GitHub...
Android WebView上传文件/自定义弹窗技术,附件的解决方案
安卓内核开发 其实是Android的webview默认是不支持<input type"file"/>文件上传的。现在的前端页面需要处理的是: 权限 文件路径AndroidManifest.xml <uses-permission android:name"android.permission.WRITE_EXTERNAL_STORAGE"/&g…...
selenium 输入框、按钮,输入点击,获取元素属性等简单例子
元素操作 nput框 输入send_keys, input框 清除clear(), 按钮 点击click() 按钮 提交submit() 获取元素 tag_name、 class属性值、 坐标尺寸 """ input框 输入1次,再追加输入一次, 清除, 再重新输入&…...
结构体构造函数
【知识点:结构体构造函数】下面两段代码等价。 (1)结构体构造函数写法 struct LinkNode {int data;LinkNode* next;LinkNode(int x):data(x),next(NULL) {} }; LinkNode* Lnew LinkNode(123); (2)非结构体构造函数写…...
基于单片机的电子万年历设计
摘要: 本设计以 AT89C51 单片机为主控器,使用 DS1302 时钟芯片、DS18B20 温度芯片、LCD1602 显示模块,利用Proteus 仿真软件和 Keil 编译软件进行了基于单片机的电子万年历仿真,设计的万年历可以在液晶上显示时间,同时还具有时间校准、温度显示等功能。 关键词 :单片机…...
大厂真实面试题(一)
滴滴大数据sql 取出累计值与1000差值最小的记录 1.题目 已知有表t_cost_detail包含id和money两列,id为自增,请累加计算money值,并求出累加值与1000差值最小的记录。 2.分析 本题主要是想找到累加值域1000差距最小的记录,也就是我们要对上述按照id进行排序并且累加,并…...
Docker搭建ELKF日志分析系统
Docker搭建ELKF日志分析系统 文章目录 Docker搭建ELKF日志分析系统资源列表基础环境一、系统环境准备1.1、创建所需的映射目录1.2、修改系统参数1.3、单击创建elk-kgc网络桥接 二、基于Dockerfile构建Elasticsearch镜像2.1、创建Elasticsearch工作目录2.2、上传资源到指定工作路…...
把系统引导做到U盘,实现插上U盘才能开机
前言 有个小伙伴提出了这样一个问题:能不能把U盘制作成电脑开机的钥匙? 小白稍微思考了一下,便做了这样一个回复:可以。 至于为什么要思考一下,这样会显得我有认真思考他提出的问题。 Windows7或以上系统均支持UEF…...
【计算机网络基础知识】
首先举一个生活化的例子,当你和朋友打电话时,你可能会使用三次握手和四次挥手的过程进行类比: 三次握手(Three-Way Handshake): 你打电话给朋友:你首先拨打你朋友的电话号码并等待他接听。这就…...
个股场外期权个人如何参与买卖?
个股场外期权作为一种金融衍生品,为个人投资者提供了多样化的投资选择和风险管理工具。想要参与个股场外期权的买卖,以下是一些关键步骤和考虑因素。 文章来源/:财智财经 第一步:选择合适的金融机构 首先,个人投资者需…...
程序猿大战Python——pycharm软件的使用
基础配置 目标:了解PyCharm软件的基础配置处理。 修改背景颜色: Appearance -> Theme 修改字体大小: 搜索font -> Font 例如,一起完成背景、字体大小的修改。 总结: (1)如果要对PyChar…...
Unity Standard shader 修改(增加本地坐标裁剪)
本想随便找一个裁剪的shader,可无奈的是没找到一个shader符合要求,美术制作的场景都是用的都标准的着色器他们不在乎你的功能逻辑需求,他们只关心场景的表现,那又找不到和unity标准着色器表现一样的shader 1.通过贴图的透明通道做…...
【数据结构】排序——插入排序,选择排序
前言 本篇博客我们正式开启数据结构中的排序,说到排序,我们能联想到我之前在C语言博客中的冒泡排序,它是排序中的一种,但实现效率太慢,这篇博客我们介绍两种新排序,并好好深入理解排序 💓 个人主…...
2024.6.9刷题记录
目录 一、1103. 分糖果 II 1.模拟 2.数学 二、312. 戳气球 1.递归-记忆化搜索 2.区间dp 三、2. 两数相加 1.迭代 2.递归-新建节点 3.递归-原节点 四、4. 寻找两个正序数组的中位数 1.堆 2.双指针二分 五、5. 最长回文子串 1.动态规划 2.中心扩展算法 六、6. Z…...
Matlab|遗传粒子群-混沌粒子群-基本粒子群
目录 1 主要内容 2 部分代码 3 效果图 4 下载链接 1 主要内容 很多同学在发文章时候最犯愁的就是创新点创新点创新点(重要的事情说三遍),对于采用智能算法的模型,可以采用算法改进的方式来达到提高整个文章创新水平的目的&…...
31|HTTP3:甩掉TCP、TLS 的包袱,构建高效网络
前面两篇文章我们分析了HTTP/1和HTTP/2,在HTTP/2出现之前,开发者需要采取很多变通的方式来解决HTTP/1所存在的问题,不过HTTP/2在2018年就开始得到了大规模的应用,HTTP/1中存在的一大堆缺陷都得到了解决。 HTTP/2的一个核心特性是…...
2 程序的灵魂—算法-2.2 简单算法举例-【例 2.3】
【例 2.3】判定 2000 — 2500 年中的每一年是否闰年,将结果输出。 润年的条件: 1. 能被 4 整除,但不能被 100 整除的年份; 2. 能被 100 整除,又能被 400 整除的年份; 设 y 为被检测的年份,则算法可表示如下…...
Python中的上下文管理器(contextlib)模块
Python中的contextlib模块提供了一些用于创建和管理上下文管理器(context managers)的工具。上下文管理器是实现了__enter__()和__exit__()方法的对象,它们通常用于确保在代码块执行前后执行某些操作,比如资源获取与释放、设置和重…...
C语言:定义和使用结构体变量
定义和使用结构体变量 介绍基础用法1.定义结构体2. 声明结构体变量3. 初始化和访问结构体成员4. 使用指针访问结构体成员5. 使用结构体数组 高级用法6. 嵌套结构体7. 匿名结构体8. 结构体和动态内存分配9. 结构体作为函数参数按值传递按引用传递 介绍 在C语言中,结…...
Vue3学习第二天记录
Vue3学习第二天记录 背景说明截图记录一个简单的JS文件Vue3的watch()函数Vue3的toRef()/toRefs()函数前端数据类型的分类前端写一个对外暴露的函数前端的...语法Vue3中watch()函数的总结Vue3中watchEffect()函数Vue3中watch()函数的坑Vue3中computed()函数 背景 最近在学习尚硅…...
豫icp郑州网站建设/百度地图关键词排名优化
网络的核心设备并不在应用层上起作用,而仅在较底层起作用,特别是在网络层及下面的层次起作用;特别是在网络层及下面层次起作用。这种基本设计,即将应用层软件限制在端系统的方法,促进了大量的网络应用程序的迅速研发和…...
禁止指定ip访问网站/开一个网站需要多少钱
LinuxShell col命令 Linux col命令用于过滤控制字符。 在许多UNIX说明文件里,都有RLF控制字符。当我们运用shell特殊字符">“和”>>",把说明文件的内容输出成纯文本文件时,控制字符会变成乱码,col指令则能有…...
为了爱我可以做任何事俄剧网站/官网seo
一套完整的WordPress模板应至少具有如下文件: style.css : CSS(样式表)文件index.php : 主页模板archive.php : Archive/Category模板404.php : Not Found 错误页模板comments.php : 留言/回复模板footer.php : Footer模板header.php : Header模板sidebar.php : 侧栏…...
网站做子页面怎么做的/搜索引擎营销方法有哪些
在下笔写SQL系列文章时,我突然有点懵,因为从某种意义上来说SQL是我熟悉的陌生人。熟悉是因为我和SQL很早就已相遇,回首整个过程,我们经历过浅浅的相知,长长的相忘于江湖,紧接着又是短暂的重逢,然…...
建行app官方下载/网站seo好学吗
CWinApp* acedGetAcadWinApp()返回指向AutoCAD应用程序类实例的指针 CDocument* acedGetAcadDoc()返回指向AutoCAD文件类实例的指针 CView* acedGetAcadDwgView()返回指向视图类的指针(AutoCAD的绘图区) CMDIFrameWnd* acedGetAcadFrame()返回一个多文…...
广汉做网站/seo搜狗排名点击
assertNotContains()函数是PHPUnit中的内置函数,用于断言没有值的数组。如果数组不包含所提供的值,则该断言将返回true;否则返回false;如果为true,则断言了已通过测试的用例,否则测试用例失败了。用法&…...