zoukankan      html  css  js  c++  java
  • 利用遗传学算法求解工作分配问题

    问题:现在有10份工作。有300名工人被分配参与这10份工作,每份工作需要30人。每人参与不同的工作都有个评价值,代表该人参与该工作的损耗值,损耗值的范围在0-9。问:如何分配这300人工作,使得总的损耗值最低。

    本问题的基础数据: 工人选择工作损耗表数据.rar

    这是一个典型的工作分配问题。当然,利用匈牙利算法能求出该问题的最优解

    今天,本文介绍利用遗传学算法来求解该工作分配问题

    下面先介绍些名词解释:

    先给工人编个号,工人001-工人300

    再给工作编个号,工作01-工作10

    个体实例:一个实际的分配方案被称为个体实例。例如:工人001-工人030参与工作01、工人031-工人060参与工作02、……、工人271-工人300参与工作10。这就是一个个体实例。当然,个体实例的总的可能数非常多,要遍历每个个体实例并找到最优解几乎不可能。

    实例权重:每个个体实例代表一个实际分配方案,那么该方案的所有工人的损耗值的总和——总的损耗值,就是该个体实例实例权重。求解最优解就是找到实例权重最小的那个个体实例

    基因:每个个体实例中,每一位工人选择参与的工作,称为该个体实例的一个基因。很显然,每个个体实例有300个基因,每个基因有10个选择可能。基因间有相互约束的作用(每份工作有且只有30人选择,不能多也不能少)。给基因编个号,基因001-基因300

    繁衍:两个个体实例生成一个新的个体实例的过程称为繁衍。两个个体实例称为父代,新个体实例称为子代。子代,从基因001开始,随机从两个父代的基因001中选择一个,依次类推,直到基因300为止。这样随机选择300个基因后,会产生一个新的问题——基因冲突,即某些工作会有超过30人,而某些工作会不足30人。再利用平衡算法进行实例内部的基因调整,使得每份工作有且只有30人。这样的子代才是符合问题的个体实例。

    变异:一个个体实例生成一个新的个体实例的过程称为变异。一个个体实例称为父代,新个体实例称为子代。父代中随机选取N对基因,对换这N对基因,生成子代(例如:选择基因033和基因254,分别代表工人033和工人254的选择,交换他们的选择,这样不会产生基因冲突的问题)。

    种群:若干个个体实例组成一个种群。遗传学算法的核心就是构建一个种群种群里个体实例数要合适。不能太少,太少了求解最优解的可能性降低;不能太多,虽然能提高求解最优解的可能性,但是也会大大增加求解的时间消耗。

    迭代种群进化的过程称为迭代。过程如下:先在种群中选取部分个体实例,通过繁衍生成若干子代;再在种群中选取部分个体实例,通过变异生成若干子代。这样子代归入到种群中,种群中的数量就增加了,再对种群中的个体实例按照实例权重进行选择,淘汰掉部分个体实例,以维持种群中的个体实例数量(像不像大自然的自然选择,优胜劣汰?)。本问题中,按照实例权重进行排序,保留实例权重小的个体实例,淘汰掉实例权重大的个体实例

    下面介绍如何用遗传学算法求解本问题

    构建种群

    先构造一个含有2000个个体实例的种群

    每个个体实例的创建过程如下:先随机产生一个工人序列,然后按照工人序列,每位工人都选择当前对他来说损耗最小的工作(最好是选择损耗为0的工作,但假如该工作已经满员了,就选择损耗为1的工作,依次类推)。很显然,最后一位工人只有一种选择。这样生成的个体实例的实例权重大约在85-140之间

    进行迭代

    每次迭代,随机选择父代繁衍出1000个子代,变异出100个子代。这样父代和子代加在一起一共3100个(2000+1000+100),然后对这3100个个体实例按照实例权重进行排序,保留权重最低的2000个个体实例,1100个个体实例被淘汰掉,保留种群中2000个个体实例的数量稳定

    之前提过,在繁衍的生成的子代可能会有基因冲突(某些工作会有超过30人,而某些工作会不足30人),需要通过平衡算法进行实例内部的基因调整,使得每份工作有且只有30人。下面介绍该平衡算法

    1、 找到超过30人的工作,假设超过K人。若找不到,说明已经平衡,退出算法

    2、 找到所有低于30人的工作,记工作集W

    3、 在步骤1中的每一位工人,计算出在工作集W中所有工作的损耗值的最小值,并记录对应的工作编号

    4、 对步骤1中的所有工人按照步骤3中的最小值进行排序,取最小的前K人,分配到其所对应的工作中。这样保证步骤1中的工作就只有30人了

    5、 重复步骤1

    通过上面的迭代过程,进行若干次迭代,在迭代结束后,在种群中找到实例权重最小的个体实例就是该问题的最优解

    那么,如何判断出已经得到最优解,来终止迭代过程呢?有两种方法

    一是,指定迭代次数,例如迭代1000次。

    这个由于没有理论支撑,并不知道1000次能迭代到什么地步,故不合适。

    二是,每次迭代后,都计算一下新的子代在种群中的数目。若连续若干次迭代(例如10次)新的子代在种群中的数目为0,那么迭代结束(说明迭代已经不能产生新的个体实例了)

    本文中,用的就是这个,下面把迭代过程贴一下

    迭代过程:迭代过程.rar

    最优解:最优解.rar

    后记

    遗传学算法能不能找到最优解?这个不一定的,看迭代的数据收敛性了,但是能收敛到一个局部最优解(接近最优解或者就是最优解)。目前,通过几次的求解过程,所得到的最优解是55,假如有人算出更优解,欢迎交流

    通过查看迭代数据,发现,迭代结束的时候,种群中的个体实例的权重都是55,也就是全部个体实例都一样了。

    作者:万仓一黍
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    elform 校验
    深入理解ES6系列
    【数据结构&算法】10串基础&KMP算法源码
    【数据结构&算法】13赫夫曼树&赫夫曼编码
    【RTOS】FreeRTOS中的任务堆栈溢出检测机制
    【数据结构&算法】11树基础&二叉树遍历
    【环境】解决linux与windows之间的复制粘贴
    【数据结构&算法】09队列概念&参考源码
    【网络基础】内网IP与外网IP
    【数据结构&算法】12线索二叉树
  • 原文地址:https://www.cnblogs.com/grenet/p/15054631.html
Copyright © 2011-2022 走看看