当前位置: 首页 > article >正文

别再死记硬背遗传算法了!用Python实战POX/JBX交叉,搞定流水车间调度

用Python实战遗传算法POX/JBX交叉算子解决流水车间调度问题每次看到遗传算法的理论推导都头大论文里的数学公式让人望而生畏今天我们就用Python代码手把手带你实现POX和JBX这两种经典交叉算子解决实际的流水车间调度问题。告别枯燥的理论直接动手写出能运行的代码1. 环境准备与问题建模在开始编码之前我们需要明确流水车间调度问题的具体定义。假设我们有n个工件需要在m台机器上加工每个工件包含m道工序每台机器上一道且所有工件的加工顺序相同这就是流水的含义。我们的目标是找到一个工序排列使得所有工件完成加工的总时间makespan最短。首先安装必要的Python库pip install deap matplotlib numpyDEAP是一个强大的进化计算框架我们将用它来实现遗传算法。让我们先定义问题的基本结构from deap import base, creator, tools import numpy as np import random # 定义问题参数 num_jobs 3 # 工件数量 num_machines 3 # 机器数量 processing_times [ [2, 3, 1], # 工件1在各机器上的加工时间 [4, 1, 3], # 工件2 [2, 2, 2] # 工件3 ] # 创建适应度类和个体类 creator.create(FitnessMin, base.Fitness, weights(-1.0,)) creator.create(Individual, list, fitnesscreator.FitnessMin)2. 基于工序的编码实现遗传算法的第一步是确定如何编码解决方案。对于流水车间调度问题基于工序的编码(Operation-based Representation)是最常用的方法之一。在这种编码中每个基因代表一个工序每个工件的编号会出现m次m是机器数第k次出现的工件编号代表该工件的第k道工序让我们实现这个编码的初始化和评估函数def init_individual(icls, num_jobs, num_machines): # 创建个体每个工件出现num_machines次 individual [j for j in range(num_jobs) for _ in range(num_machines)] random.shuffle(individual) return icls(individual) def evaluate(individual, processing_times, num_machines): # 解码染色体并计算makespan job_steps {j: 0 for j in range(len(processing_times))} machine_times [0] * num_machines job_times [0] * len(processing_times) for op in individual: job op step job_steps[job] machine step # 假设工序顺序对应机器顺序 time processing_times[job][machine] start_time max(job_times[job], machine_times[machine]) end_time start_time time job_times[job] end_time machine_times[machine] end_time job_steps[job] 1 return max(machine_times),3. POX交叉算子实现POX(Precedence Operation Crossover)是一种保留工序优先关系的交叉算子特别适合流水车间调度问题。它的核心思想是随机将工件集划分为两个非空子集J1和J2从父代1复制J1中工件的所有工序到子代1保持位置不变从父代2复制J2中工件的工序到子代1保持顺序不变下面是Python实现def pox_crossover(ind1, ind2, num_jobs): size len(ind1) jobs list(range(num_jobs)) random.shuffle(jobs) split_point random.randint(1, num_jobs-1) J1 set(jobs[:split_point]) J2 set(jobs[split_point:]) # 创建子代 child1 [None]*size child2 [None]*size # 步骤1复制J1中的工序保持位置 for i in range(size): if ind1[i] in J1: child1[i] ind1[i] if ind2[i] in J1: child2[i] ind2[i] # 步骤2填充J2中的工序保持顺序 fill_J2_operations(child1, ind2, J2) fill_J2_operations(child2, ind1, J2) return child1, child2 def fill_J2_operations(child, parent, J2): # 辅助函数填充J2中的工序 parent_ops [op for op in parent if op in J2] ptr 0 for i in range(len(child)): if child[i] is None: child[i] parent_ops[ptr] ptr 14. JBX交叉算子实现JBX(Job-based Crossover)是另一种常用的交叉算子与POX类似但有细微差别随机划分工件集为两个非空子集J1和J2从父代1复制J1中工件的所有工序到子代1保持位置不变从父代2复制J2中工件的所有工序到子代1保持位置不变实现代码如下def jbx_crossover(ind1, ind2, num_jobs): size len(ind1) jobs list(range(num_jobs)) random.shuffle(jobs) split_point random.randint(1, num_jobs-1) J1 set(jobs[:split_point]) J2 set(jobs[split_point:]) child1 [None]*size child2 [None]*size # 填充J1中的工序 for i in range(size): if ind1[i] in J1: child1[i] ind1[i] if ind2[i] in J1: child2[i] ind2[i] # 填充J2中的工序 for i in range(size): if ind2[i] in J2: child1[i] ind2[i] if ind1[i] in J2: child2[i] ind1[i] return child1, child25. 完整遗传算法实现与结果可视化现在我们可以组装完整的遗传算法流程并比较POX和JBX的表现def run_ga(crossover_func, cx_prob0.7, mut_prob0.2, pop_size50, ngen100): toolbox base.Toolbox() num_jobs len(processing_times) num_machines len(processing_times[0]) # 注册遗传算子 toolbox.register(individual, init_individual, creator.Individual, num_jobs, num_machines) toolbox.register(population, tools.initRepeat, list, toolbox.individual) toolbox.register(evaluate, evaluate, processing_timesprocessing_times, num_machinesnum_machines) toolbox.register(mate, crossover_func, num_jobsnum_jobs) toolbox.register(mutate, tools.mutShuffleIndexes, indpb0.05) toolbox.register(select, tools.selTournament, tournsize3) # 初始化种群 pop toolbox.population(npop_size) hof tools.HallOfFame(1) stats tools.Statistics(lambda ind: ind.fitness.values) stats.register(avg, np.mean) stats.register(min, np.min) # 运行算法 pop, log algorithms.eaSimple(pop, toolbox, cxpbcx_prob, mutpbmut_prob, ngenngen, statsstats, halloffamehof, verboseTrue) return hof[0], log # 运行POX和JBX的比较 best_pox, log_pox run_ga(pox_crossover) best_jbx, log_jbx run_ga(jbx_crossover)为了直观比较结果我们可以绘制甘特图import matplotlib.pyplot as plt import matplotlib.patches as patches def plot_gantt(individual, processing_times): num_jobs len(processing_times) num_machines len(processing_times[0]) fig, ax plt.subplots(figsize(10, 5)) colors plt.cm.tab10.colors job_steps {j: 0 for j in range(num_jobs)} machine_times [0] * num_machines job_times [0] * num_jobs for op in individual: job op step job_steps[job] machine step time processing_times[job][machine] start_time max(job_times[job], machine_times[machine]) end_time start_time time # 绘制矩形块 rect patches.Rectangle( (start_time, machine-0.4), time, 0.8, linewidth1, edgecolorblack, facecolorcolors[job % 10], labelfJob {job1} ) ax.add_patch(rect) # 添加文本标签 ax.text(start_time time/2, machine, fJ{job1}, hacenter, vacenter, colorwhite) job_times[job] end_time machine_times[machine] end_time job_steps[job] 1 ax.set_xlabel(Time) ax.set_ylabel(Machine) ax.set_yticks(range(num_machines)) ax.set_yticklabels([fMachine {i1} for i in range(num_machines)]) ax.set_title(Gantt Chart for Job Shop Schedule) ax.grid(True, whichboth, linestyle--, linewidth0.5) # 处理图例 handles, labels ax.get_legend_handles_labels() by_label dict(zip(labels, handles)) ax.legend(by_label.values(), by_label.keys()) plt.tight_layout() plt.show() # 绘制最佳解的甘特图 print(POX best makespan:, evaluate(best_pox, processing_times, num_machines)[0]) plot_gantt(best_pox, processing_times) print(JBX best makespan:, evaluate(best_jbx, processing_times, num_machines)[0]) plot_gantt(best_jbx, processing_times)6. 性能对比与参数调优在实际应用中我们需要考虑多种因素来优化算法性能关键参数对比表参数推荐范围影响说明种群大小50-200越大探索能力越强但计算成本增加交叉概率0.6-0.9控制新个体产生的速度变异概率0.01-0.2保持种群多样性防止早熟收敛迭代次数50-500问题复杂度越高需要越多迭代POX vs JBX 特点对比POX优势更好地保留工序间的优先关系在复杂约束条件下表现更稳定适合工序间有强依赖的场景JBX优势实现更简单计算开销略低在简单问题上收敛速度可能更快适合各工件相对独立的问题调优建议对于大规模问题(50个工件)可以采用分层遗传算法结合局部搜索策略使用并行计算加速评估当陷入局部最优时尝试增加变异概率引入自适应变异算子定期注入随机个体# 自适应参数调整示例 def adaptive_ga(): toolbox base.Toolbox() # ...初始化代码同上... # 自适应参数 cx_prob 0.7 mut_prob 0.1 for gen in range(100): # 动态调整参数 if gen 20 and stats[-1][min] stats[-2][min]: mut_prob min(0.3, mut_prob * 1.2) # 选择下一代 offspring toolbox.select(pop, len(pop)) offspring list(map(toolbox.clone, offspring)) # 交叉 for child1, child2 in zip(offspring[::2], offspring[1::2]): if random.random() cx_prob: toolbox.mate(child1, child2) del child1.fitness.values del child2.fitness.values # 变异 for mutant in offspring: if random.random() mut_prob: toolbox.mutate(mutant) del mutant.fitness.values # 评估 invalid_ind [ind for ind in offspring if not ind.fitness.valid] fitnesses toolbox.map(toolbox.evaluate, invalid_ind) for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values fit pop[:] offspring7. 常见问题与调试技巧在实际实现过程中可能会遇到以下典型问题问题1算法过早收敛症状种群多样性迅速降低所有个体变得相似解决方案增加变异概率使用更大的种群引入小生境技术(niching)定期注入随机个体问题2计算结果不稳定症状每次运行结果差异很大解决方案增加迭代次数使用精英保留策略检查随机数种子是否固定尝试不同的选择算子(如锦标赛选择)问题3解码后调度不可行症状甘特图显示工序顺序违反约束解决方案验证编码解码逻辑检查交叉算子是否保持可行性添加约束处理机制实用调试技巧可视化中间结果# 在评估函数中添加调试输出 def evaluate(individual, processing_times, num_machines, debugFalse): if debug: print(Evaluating:, individual) # ...其余代码不变...记录进化过程# 在算法循环中记录更多信息 history [] for gen in range(100): # ...算法逻辑... history.append({ generation: gen, best_fitness: min(ind.fitness.values[0] for ind in pop), avg_fitness: sum(ind.fitness.values[0] for ind in pop)/len(pop), diversity: len(set(tuple(ind) for ind in pop))/len(pop) })交叉算子验证# 测试交叉算子 p1 [0,0,1,1,2,2] p2 [1,1,0,0,2,2] c1, c2 pox_crossover(p1.copy(), p2.copy(), 3) print(fPOX: {p1} {p2} - {c1}, {c2})性能分析# 使用cProfile分析性能瓶颈 import cProfile cProfile.run(run_ga(pox_crossover), sortcumtime)

相关文章:

别再死记硬背遗传算法了!用Python实战POX/JBX交叉,搞定流水车间调度

用Python实战遗传算法:POX/JBX交叉算子解决流水车间调度问题 每次看到遗传算法的理论推导都头大?论文里的数学公式让人望而生畏?今天我们就用Python代码,手把手带你实现POX和JBX这两种经典交叉算子,解决实际的流水车间…...

企业财务数字化转型:从RPA到AI Agent的落地路径

在企业数字化转型中,财务一直是最优先落地的场景之一。原因很现实:流程标准、数据集中、效果可量化。但也正因为“好做”,很多企业对财务自动化的理解,长期停留在一个比较初级的阶段,随着AI能力的引入,财务…...

乳腺癌生存预测模型开发与实践指南

1. 乳腺癌患者生存概率模型开发指南在临床医学研究中,预测患者生存概率一直是肿瘤学领域的核心课题。乳腺癌作为全球女性最常见的恶性肿瘤,其生存率预测对治疗方案选择、预后评估和医疗资源分配都具有重要意义。本文将系统介绍如何构建一个科学可靠的乳腺…...

从ZBrush高模到游戏引擎:3dMax UV展开全流程避坑指南(含Headus UVLayout实战)

从ZBrush高模到游戏引擎:3dMax UV展开全流程避坑指南(含Headus UVLayout实战) 在次世代游戏角色与道具制作中,UV展开往往是决定贴图质量的关键环节。当艺术家们花费数十小时在ZBrush中雕琢出高精度模型后,如何将这些细…...

别再傻傻重编译了!Vivado 2023.2 与 ModelSim 10.7c 联合仿真报错 vsim-19 的快速定位与修复

从根源解决Vivado与ModelSim联合仿真中的vsim-19报错 遇到vsim-19报错时,很多工程师的第一反应是重新编译整个库——这就像发现电脑卡顿就立刻重装系统一样,虽然可能解决问题,但效率极低。本文将带你深入理解Vivado与ModelSim联合仿真的工作机…...

WarcraftHelper终极指南:让魔兽争霸3在Win10/Win11上完美运行的完整方案

WarcraftHelper终极指南:让魔兽争霸3在Win10/Win11上完美运行的完整方案 【免费下载链接】WarcraftHelper Warcraft III Helper , support 1.20e, 1.24e, 1.26a, 1.27a, 1.27b 项目地址: https://gitcode.com/gh_mirrors/wa/WarcraftHelper 还在为魔兽争霸3在…...

别再死记硬背Apriori了!用Python手把手带你跑通超市购物篮分析(附完整代码和数据集)

从超市购物篮到商业洞察:Python实战Apriori算法全流程解析 走进任何一家现代超市,货架上的商品摆放绝非随意为之。当你在购买啤酒时顺手拿了一袋薯片,或是选购婴儿奶粉时带上了尿不湿,这些看似偶然的消费行为背后,隐藏…...

Qwen3-4B-Instruct部署案例:混合精度推理(AMP)开启与吞吐量提升实测

Qwen3-4B-Instruct部署案例:混合精度推理(AMP)开启与吞吐量提升实测 1. 模型概述 Qwen3-4B-Instruct-2507是Qwen3系列的端侧/轻量旗舰模型,专为高效推理和实际应用场景优化。该模型原生支持256K token(约50万字&…...

python代码:基于DDPG(深度确定性梯度策略)算法的售电公司竞价策略研究

python代码:基于DDPG(深度确定性梯度策略)算法的售电公司竞价策略研究 关键词:DDPG 算法 深度强化学习 电力市场 发电商 竞价 说明文档:完美复现英文文档,可找我看文档 主要内容: 代码主要…...

SCons构建MDK工程翻车实录:从‘No module named building’到完美运行的踩坑全指南

SCons构建MDK工程实战:从报错排查到工程定制的完整指南 第一次接触SCons构建MDK工程时,那种从满屏红色报错到最终看到"Build Complete"的成就感,至今记忆犹新。作为替代传统IDE手动配置的自动化方案,SCons确实能显著提升…...

Jetson Nano新手必看:jtop命令报错‘jetson_stats.service not active’的完整解决流程

Jetson Nano新手必看:jtop命令报错‘jetson_stats.service not active’的完整解决流程 刚拿到Jetson Nano的开发者,往往迫不及待想体验这款强大边缘计算设备的性能监控功能。作为官方推荐的系统监控工具,jtop以其直观的界面和丰富的参数展示…...

避坑指南:GD32F470的SPI FIFO与DMA刷屏时,为何屏幕会闪烁或花屏?

GD32F470 SPI DMA刷屏异常全解析:从FIFO机制到数据对齐的深度避坑指南 当你在GD32F470上实现SPI DMA刷屏时,是否遇到过屏幕闪烁、花屏或数据错位的诡异现象?这背后往往隐藏着SPI FIFO机制、DMA传输边界、数据宽度匹配等关键技术细节。本文将带…...

Windows服务器修改默认远程端口3389

修改默认远程访问端口(如Windows的RDP,默认端口3389 )可以增强系统安全性,通过避免自动化攻击和恶意扫描针对常用端口的攻击,从而保护服务器或服务免受未授权访问的风险服务器系统:Windows Server 2022 修改…...

【windows命令-网络命令、系统管理命令】

windows命令-网络命令、系统管理命令一、网络命令二、系统管理命令三、其他一、网络命令 1.ipconfig:查看本机IP信息(ipconfig /all:完整信息(MAC、DNS、DHCP等)、ipconfig /release:释放当前IP、ipconfig…...

回顾AQATrack模型遇到的问题

1.环境 (1)如果只是pytorch的版本是CPU,直接在这个环境里面去修改那个版本改为GPU就可以了,不用整个环境去打包,打包环境进行迁移的灵感💡来源于deepseek的离谱建议 具体操作步骤: 确认 CUDA …...

2026年怎么从培训学员反馈辨真假?这3个判断标准很实用

"做HR快6年,年年牵头做内部培训,每次收完学员反馈,我都头疼——哪是真满意哪是随便应付交差?以前踩过好多坑,白瞎培训预算不说,改方案也改不到点子上。今天把我摸出来的3个判断标准放这,看…...

记录生活&学习Day15深度强化学习第十六集:Advantage Actor-Critic(A2C)

生活我让Y把我拉黑了,我们应该结束了,心里好难受,觉得很可惜,不知道怎么办...五一我想去找L但是她已经拒绝我三次了,那就不去了吧...我现在不知道怎么办了,什么也做不下去。...

5款主流SaaS建站平台实测横评:兜客互动凭借全链路服务与高性价比,成为中小企业数字化入门首选

# 中小企业如何选对数字化“第一站”?一场关乎效率与成本的关键抉择在数字经济加速渗透的今天,一个官网、一个小程序、一场微信营销活动,已成为中小企业触达客户的基本配置。然而面对市面上琳琅满目的SaaS建站平台,功能重叠、价格…...

5分钟搭建专属OCR服务:cv_resnet18_ocr-detection部署与使用详解

5分钟搭建专属OCR服务:cv_resnet18_ocr-detection部署与使用详解 1. 为什么选择cv_resnet18_ocr-detection 在日常工作和生活中,我们经常需要从图片中提取文字信息。无论是处理发票、识别证件,还是分析商品包装,传统的手动录入方…...

Weka机器学习实战:鸢尾花分类完整教程

1. 使用Weka完成多类别分类项目的完整指南Weka作为一款开源的机器学习工作台,以其直观的图形界面和丰富的算法库,成为了许多数据科学初学者的首选工具。今天我将通过经典的鸢尾花分类案例,带大家走完一个完整的机器学习项目流程 - 从数据加载…...

别再死记硬背了!一张图看懂DDR到DDR4内存的演变史(附关键参数对比)

从DDR到DDR4:内存技术的进化图谱与设计哲学 在计算机硬件发展的长河中,内存技术的迭代如同一部微缩的科技史诗。从2000年DDR标准的诞生到如今DDR4的普及,每一次升级都不仅仅是数字的跃进,更是工程智慧的结晶。对于硬件爱好者、嵌入…...

BitNet b1.58-2B-4T-gguf部署教程:SELinux严格模式下服务权限配置指南

BitNet b1.58-2B-4T-gguf部署教程:SELinux严格模式下服务权限配置指南 1. 项目概述 BitNet b1.58-2B-4T-gguf是一款极致高效的1.58-bit量化开源大模型,采用独特的权重三值化技术(-1, 0, 1),平均仅需1.58 bit存储每个…...

长芯微LDC2654完全P2P替代LTC2654,是一款具有±4LSB(最大值)INL、10ppm/℃内部温度系数的16位4通道DAC

概述 LDC2654是一款具有4LSB(最大值)INL、10ppm/℃(最大值)内部温度系数的16位4通道DAC。LDC2654具有内置的高性能、轨至轨输出缓冲器,并保证具有单调性。LDC2654具有一个2.5V的全标度输出和集成基准,并采用4.5V至5.5V的单电源工作。每个DAC也可以采用一…...

C 盘突然爆满?一次彻底排查与迁移实战:从仅剩 12GB 到释放到 46GB

前言很多人都有一个误区: “软件安装到了 D 盘,C 盘就不会继续变大。”我之前也是这么认为的。 结果实际使用一段时间后,C 盘空间还是一路被吃掉,最后只剩下 12GB 左右,已经开始明显影响系统流畅度和开发环境使用。这次…...

爆火的“养马”是什么?Hermes Agent 全面解析+一键部署实操

前言:最近AI圈“养马”热潮席卷而来,不少开发者调侃“从养虾到养马,AI智能体迭代太快”。这里的“马”并非奢侈品爱马仕,而是美国Nous Research团队研发的开源AI智能体——Hermes Agent,“养马”就是搭建、调试并使用这…...

逆向知乎x-zse-96时,我踩过的那些‘环境检测’坑:从Canvas到Window原型链

逆向知乎x-zse-96时,我踩过的那些‘环境检测’坑:从Canvas到Window原型链 在JS逆向工程领域,知乎的x-zse-96参数加密一直以其复杂的环境检测机制闻名。许多开发者在成功提取核心加密逻辑后,往往会在Node.js环境中遭遇各种难以调试…...

去哪个嵌入式培训机构学习比较好

在郑州嵌入式培训领域,结合课程体系、师资实力、实战项目、就业保障四大核心维度,整理出2026年优质机构参考榜,以下是详细对比,供嵌入式学习者参考(数据真实可查,无夸大)。1. 参考依据&#xf…...

【5G Modem】从协议栈到天线阵列:揭秘5G Modem的完整架构与协同设计

1. 5G Modem的架构全景图 当你用手机刷视频、打游戏时,背后有个"隐形交通指挥官"在默默工作——它就是5G Modem。这个比硬币还小的芯片,内部却像一座精密的现代城市:协议栈是交通法规,基带处理器是调度中心,…...

x86-64数据传送指令精解

仅用于个人复习计算机基础,一、核心概览这份文档的核心是讲解如何在不同位置(寄存器、内存)之间移动数据,以及移动时如何处理数据的大小和符号问题。关键在于理解 “数据大小” 和 “符号扩展/零扩展” 这两个概念。二、通用数据传…...

在线数据库建模工具dbdiagram.io - 学习

在线数据库建模工具dbdiagram.io - 创建ER图 工具在线网址:https://dbdiagram.io/home 说明文档网址:https://dbml.dbdiagram.io/docs/ 创建ER图: 1、打开在线网址:https://dbdiagram.io/home,点下图红色的创建图表 。…...