遗传算法的简单实现

参考资料

遗传算法--背包问题

感觉文中的代码有些许问题,按照自己的理解进行了修改,水平有限,有错欢迎指出。
1.在对fitness进行排序是,原文是是一个假排序,没有真的排序下来,
2,为选择的保留进行遗传的是将fitness最好的一般保留下来进行交叉遗传。
3.货物的信息,初始的基因我都保持了不变。

另外,感觉第一代的数据比较的时候还是有点问题,就是第一代去比较fitness的时候,总感觉有问题,因为有的时候,输出的是比第一代小的。(极少数)

代码

# -*- coding: utf-8 -*-
# @Time    :    2021/7/29 9:29
# @Author  :    LuoCheng
# @FileName:    背包修改.py 
# @Software:    PyCharm
"""
===============================================
文档功能说明:
链接:https://zerosyf.github.io/2018/10/10/%E9%81%97%E4%BC%A0%E7%AE%97%E6%B3%95-%E8%83%8C%E5%8C%85%E9%97%AE%E9%A2%98/
将背包问题转化成初始基因、初始质量价值不变的问题
===============================================
"""
import random
import pandas as pd

PACK_MAX_CAP = 1000
MAX_GENERATION = 100


def getRand():
    intnum = random.randint(0, 65535)
    return intnum


def getRand_float():
    floatnum = random.uniform(0, 1)
    return floatnum


class Good:
    def __init__(self, weight, value):
        # self.weight = weight
        self.value = value


class Entity:
    def __init__(self, goods_num):
        """
        :param goods_num: 货物的数量,也是特征的维度
        """
        self.fitness = 0
        # self.sum_weight = 0
        self.generation_id = 0
        self.gene = []
        self.initgene(goods_num)

    def initgene(self, goods_num):
        """每个个体:初始化基因,全部为 0"""
        for i in range(goods_num):
            self.gene.append(0)


class GeneAlgorithm:
    def __init__(self, grnum, cr, vr, gonum):
        self.group_num = grnum
        self.goods_num = gonum
        self.cross_rate = cr
        self.varia_rate = vr
        self.best_entity = None
        self.group = []  # 群体
        self.goods = []  # 物品
        self.initgoods()

    def get_totalfitness(self, group):
        sum = 0.0
        for i in range(len(group)):
            sum += group[i].fitness
        return sum

    def print_opt(self):
        print("最优解所在代数" + str(self.best_entity.generation_id) + "\n")
        # print("总重量" + str(self.best_entity.sum_weight) + "\n")
        print("总价值" + str(self.best_entity.fitness) + "\n")
        print("装入情况为:\n")
        for i in range(len(self.best_entity.gene)):
            print(self.best_entity.gene[i])

    def initgoods(self):
        good_info = pd.read_excel('.\背包货物信息.xlsx', sheet_name='goodinfo')
        print("物品集合信息:")
        for i in range(self.goods_num):
            self.goods.append(good_info['value'][i])
            print("物品号:" + str(i) + "价值:" + str(self.goods[i].value))

    def initgroup(self):
        self.best_entity = Entity(self.goods_num)
        for i in range(self.group_num):
            ent = Entity(self.goods_num)  # 每次初始化一个个体
            genes_info = pd.read_excel('./基因序列.xlsx')
            for i in range(self.group_num):
                ent = Entity(self.goods_num)
                ent.gene = list(genes_info.iloc[i])
                self.group.append(ent)
            # 初始化后加入种群;

    def cal_fitness(self):
        for i in range(len(self.group)):
            ent = self.group[i]
            # wei = 0;
            val = 0
            for j in range(len(ent.gene)):
                if ent.gene[j] == 1:
                    # wei += self.goods[j].weight
                    val += self.goods[j].value
            # if wei > PACK_MAX_CAP:
            #     ent.fitness = 0
            #     continue
            ent.fitness = val
            # ent.sum_weight = wei

    def recordoptimalentity(self, gid):
        sorted(self.group, key=lambda entity: entity.fitness)  # 通过fitness排序;
        ent = self.group[len(self.group) - 1]
        if ent.fitness > self.best_entity.fitness:
            self.best_entity = ent
            self.best_entity.generation_id = gid
        print("遗传代数" + str(gid) + " 总价值:" + str(ent.fitness) + "\n")

    def select(self):
        new_group = []
        selected_rate = []
        sorted(self.group, key=lambda entity: entity.fitness)
        group_num = len(self.group)
        sum_fitness = self.get_totalfitness(self.group)
        selected_rate.append(self.group[0].fitness / sum_fitness)
        for i in range(1, group_num):
            selected_rate.append(selected_rate[i - 1] + self.group[i].fitness / sum_fitness)
            # 构造轮盘;
        left_group_num = group_num * 0.5
        for i in range(int(left_group_num)):
            rand_rate = getRand_float()
            for idx in range(len(selected_rate)):
                if rand_rate <= selected_rate[idx]:
                    new_group.append(self.group[idx])
                    break;
        # 更新群体
        self.group.clear()
        self.group = new_group

    def Willcross(self):
        return (getRand_float() <= self.cross_rate)

    def cross(self):
        group_num = len(self.group)
        for i in range(0, (group_num - 1), 2):
            father = self.group[i]
            mother = self.group[i + 1]
            for j in range(len(father.gene)):
                if self.Willcross():
                    temp = father.gene[j]
                    father.gene[j] = mother.gene[j]
                    mother.gene[j] = temp
            self.group.append(father)
            self.group.append(mother)

    def Willvaria(self):
        return (getRand_float() <= self.varia_rate)

    def varia(self):
        group_num = len(self.group)
        for i in range(group_num):
            if self.Willvaria():
                ent = self.group[i]
                for j in range(len(ent.gene)):
                    if self.Willvaria():
                        if ent.gene[j] == 1:
                            ent.gene[j] == 0
                        else:
                            ent.gene[j] == 1

    def run(self):
        self.initgroup()
        for i in range(MAX_GENERATION):
            self.cal_fitness()
            self.recordoptimalentity(i)
            self.select()
            self.cross()
            if i % 5 == 0 & i != 0:
                self.varia()


if __name__ == '__main__':
    ga = GeneAlgorithm(20, 0.8, 0.5, 40)
    ga.run()
    ga.print_opt()

数据信息

货物信息

weight value
142 66
79 106
22 12
126 40
26 75
63 0
144 71
54 36
6 88
35 4
31 134
105 79
89 64
148 132
144 19
57 64
53 137
67 103
35 144
101 19
99 147
85 78
35 108
3 134
4 91
35 103
134 145
146 85
49 146
41 16
41 80
54 3
115 30
3 64
20 122
132 148
36 148
108 87
43 14
22 80

基因片段信息

gene_0 gene_1 gene_2 gene_3 gene_4 gene_5 gene_6 gene_7 gene_8 gene_9 gene_10 gene_11 gene_12 gene_13 gene_14 gene_15 gene_16 gene_17 gene_18 gene_19 gene_20 gene_21 gene_22 gene_23 gene_24 gene_25 gene_26 gene_27 gene_28 gene_29 gene_30 gene_31 gene_32 gene_33 gene_34 gene_35 gene_36 gene_37 gene_38 gene_39
0 0 0 0 0 0 1 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 1 0 0 0 0 0 1 0
0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 1 0 0 1 0 0 0 0 0 0 1 0 1 0 0 1 0 0
1 0 1 0 0 0 1 0 0 1 0 0 0 1 0 0 0 0 1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 1
0 0 0 0 0 1 0 0 0 1 0 0 0 1 1 1 0 1 0 1 0 0 0 0 0 1 0 1 0 0 0 1 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 0 0 1 0 0 1 0 0 0 0 1 0 1 0 0 0 0 0 0 1 1 0 0 0 0 1 0 0 0 1 0 0
0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 0 1 0 1 1 0 0 0 0 1 0 0 0 0 0 0 0 1 1 1 1 0 0 1 1
1 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 0 1 0 1 0
0 0 1 0 0 0 1 0 0 0 0 0 0 1 0 0 1 0 0 0 0 1 0 0 1 0 1 0 1 0 0 0 0 1 0 0 0 1 0 0
0 1 1 1 0 0 1 0 1 0 1 0 0 0 0 0 1 1 0 0 0 0 0 0 0 1 1 1 0 0 1 0 0 0 1 0 0 0 0 0
1 1 0 0 0 0 1 0 0 1 1 0 0 0 1 0 1 0 1 0 0 1 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0
1 1 0 0 0 0 1 1 0 0 1 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 1 0 1 0 0 1 0 0 0 0 0 0 0 1
0 1 0 0 1 1 0 0 0 0 1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0
1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0
0 1 0 0 1 0 0 0 0 0 0 0 0 1 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 1 0 0 1 0 0 1 1 1 0 0 0 0 1 1 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1
1 0 1 0 0 0 0 0 1 0 0 0 0 1 1 0 0 1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0 1 0 1 0 1 0 1 1 0 1 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 0 1 0 0 0 0 1 0 0 1 0 0 1 0 0 0 0 1 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0
1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 1
0 1 1 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 1 0 0 0 0
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,402评论 6 499
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,377评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,483评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,165评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,176评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,146评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,032评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,896评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,311评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,536评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,696评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,413评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,008评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,815评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,698评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,592评论 2 353

推荐阅读更多精彩内容