zoukankan      html  css  js  c++  java
  • 云顶之弈阵容助手-基于遗传算法

      概述

      本人云顶新手,好多年不玩LOL了,被朋友安利云顶之弈,玩了两天觉得有点意思。但是这个游戏阵容可搭配太多了,如果不是天天研究这个游戏的,很难吃鸡。所以我就心血来潮想写个阵容助手(python),给定几个你想玩的英雄,基于遗传算法向玩家推荐阵容。目前适配9.19版本,不过后面有新阵容出现的话,改起来也方便。增加铲子功能,不过只能增加一个(增加两个的话计算量大,不够实时性)

      爬取相关网站内容获取英雄信息

      这一步是可以自己输入的,但是作为一个倔强的程序员,显然不能做这种事(手动狗头)

      一开始选的是lol官网…搞半天都搞不出来(技术不够,泪目)

      后来发现还是多玩好爬一点

      结果如下

      另外还保存了英雄的昵称与其对应的id,方便输入(有时候真想不起来英雄的真名啊)

      阵容搭配与得分

      建立一个列表,记录各种阵容搭配,需要人口数目,记录铲子能增加的羁绊

      计算英雄阵容与所需金币总数

      def teamtype(hero_ids, heros_info):

      '''

      查看阵容,金币

      '''

      team = {}

      gold = 0

      for hero_id in hero_ids:

      gold += heros_info['gold'][hero_id]

      for job in heros_info['info'][hero_id]:

      if job in team:

      team[job] += 1

      else:

      team[job] = 1

      return team, gold

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      计算得分时候,不考虑羁绊效果不平衡的情况(我也玩得少…不大了解)

      另外,默认组成人口越多,羁绊效果增加得越多(采用平方得分函数)

      def calculateTeamScore(team, show= 0, shovel= False):

      '''

      计算队伍得分(铲子)

      羁绊得分规则:按达成羁绊人数得分,不考虑羁绊效果不平衡

      '''

      max_score = 0

      if shovel:

      #计算铲子

      change = 'null'

      team_out = {}

      for j in shovel_add:

      #如果队伍里没有相关职业,跳过(铲子没有单独羁绊)

      if j not in team.keys():

      continue

      team_copy = copy.deepcopy(team)

      team_copy[j] +=1

      score = calc(team= team_copy, show= 0)

      change = change if score <= max_score else j

      team_out = team_out if score <= max_score else copy.deepcopy(team_copy)

      max_score = max_score if score <= max_score else score

      calc(team= team_out, show= show)

      return max_score, change

      else:

      max_score = calc(team= team, show= show)

      return max_score, None

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      27

      28

      遗传算法设计

      编码的话,就是用的实数编码

      得分函数选择是上面的阵容得分+所需金币数(越贵的英雄越强)

      选择策略是得分最高的个体直接复制到下一代,得分最低的9个个体直接全部重抽

      上代码:

      def GA(team_pnum, selected_ids, heros_info, heros_info_short,gens = 100, sample = 50, alpha = 0.5, shovel= False):

      '''

      team_pnum:你想组成多少人队伍

      selected_ids:列表,已经选定哪些英雄

      heros_info:英雄信息

      heros_info_short:英雄名称缩写信息

      gens:最大繁殖多少代

      sample:每代繁衍个体数

      alpha:金钱影响程度(值越大,越偏向便宜的英雄)

      '''

      selected_ids = getHeroid(selected_ids,heros_info_short= heros_info_short)

      hero_info_cp = copy.deepcopy(heros_info)

      k = len(selected_ids)

      n = team_pnum - k

      hero_couldchose = hero_info_cp['hero_id']

      for idxs in selected_ids:

      hero_couldchose.pop(hero_couldchose.index(idxs))

      #生成第一代

      scores = {

      'chosed_ids':[],

      'score':[]

      }

      for i in range(sample):

      hero_thisGenCouldChose = copy.deepcopy(hero_couldchose)

      random.shuffle(hero_thisGenCouldChose)

      teamChoesd = selected_ids + hero_thisGenCouldChose[:n]

      team, gold = teamtype(teamChoesd, hero_info_cp)

      score,change = calculateTeamScore(team,shovel= shovel)

      # print('<================================>')

      score = score * 10 - gold * alpha if score > 0 else 0

      scores['chosed_ids'].append(teamChoesd)

      scores['score'].append(score)

      #开始繁衍

      maxscores = []

      for gen in range(gens):

      scores_thisgen = {

      'chosed_ids':[],

      'score':[]

      }

      #最优的个体直接保存

      score_max_idx = scores['score'].index(max(scores['score']))

      scores_thisgen['chosed_ids'].append(scores['chosed_ids'][score_max_idx])

      scores_thisgen['score'].append(scores['score'][score_max_idx])

      #最差个体的直接重置掉(重复9次)

      for i in range(9):

      #重排、重选序号

      random.shuffle(hero_thisGenCouldChose)

      teamChoesd= selected_ids + hero_thisGenCouldChose[:n]

      #重新赋值

      score_min_idx = scores['score'].index(min(scores['score']))

      scores['chosed_ids'][score_min_idx] = teamChoesd

      scores_thisgen['chosed_ids'].append(teamChoesd)

      #计算得分

      team, gold = teamtype(teamChoesd, hero_info_cp)

      score,change = calculateTeamScore(team, shovel= shovel)

      score = score * 10 - gold * alpha if score > 0 else 0

      scores['score'][score_min_idx] = score

      scores_thisgen['score'].append(score)

      #计算累积概率

      p = [0]

      totalScores = sum(scores['score'])

      for i in range(2,sample):

      p.append(p[-1] + scores['score'][i]/totalScores)

      #根据轮盘赌法生成新一代个体

      for i in range(sample):

      #有莫名bug找不到双亲,所以先赋值,如果后面找到了会被覆盖

      Dad = scores['chosed_ids'][0]

      Mom = scores['chosed_ids'][-1]

      #选父体

      rnd = random.random()

      for theone in range(len(p)):

      if p[theone] > rnd:

      Dad = scores['chosed_ids'][theone - 1]

      break

      else:

      continue

      #选母体

      rnd = random.random()

      for theone in range(len(p)):

      if p[theone] > rnd:

      Mom = scores['chosed_ids'][theone - 1]

      break

      else:

      continue

      #求并集

      dadmon = list(set(Dad[k:]) | set(Mom[k:]))

      random.shuffle(dadmon)

      baby = selected_ids + dadmon[:n]

      #求得分

      team, gold = teamtype(baby, hero_info_cp)

      score,change = calculateTeamScore(team, shovel= shovel)

      score = score * 10 - gold * alpha if score > 0 else 0

      scores_thisgen['chosed_ids'].append(baby)

      scores_thisgen['score'].append(score)

      maxscores.append(max(scores_thisgen['score']))

      #保存这代信息

      scores = copy.deepcopy(scores_thisgen)

      #取出最佳个体

      besTeam = scores['chosed_ids'][scores['score'].index(max(scores['score']))]

      return besTeam, maxscores  郑州男科医院:http://www.63556355.com/郑州看男科哪家好:http://www.63556355.com/郑州割包皮多少钱:http://www.63556355.com/

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      27

      28

      29

      30

      31

      32

      33

      34

      35

      36

      37

      38

      39

      40

      41

      42

      43

      44

      45

      46

      47

      48

      49

      50

      51

      52

      53

      54

      55

      56

      57

      58

      59

      60

      61

      62

      63

      64

      65

      66

      67

      68

      69

      70

      71

      72

      73

      74

      75

      76

      77

      78

      79

      80

      81

      82

      83

      84

      85

      86

      87

      88

      89

      90

      91

      92

      93

      94

      95

      96

      97

      98

      99

      100

      101

      102

      103

      104

      105

      106

      107

      108

      109

      110

      111

      112

      113

      运行结果

      效果还不错,大概几秒钟就能运行出结果,不影响游戏进度

      同时为不熟悉python的小伙伴做了个双击直接运行版本

      双击,cmd里根据提示输入参数即可

      (至少需要安装pandas库,命令:pip install pandas)

      ————————————————

  • 相关阅读:
    20191211 HNOI2017 模拟赛 问题A
    20191211 HNOI2017模拟赛 C题
    BZOJ 3681 Arietta
    netcore3.1中的Json操作
    netcore2.2出现的新特性HealthCheck
    MVC为什么要使用TagHelper?
    psql备份csv文件
    DataAnnotations的使用及细节处理
    记录一次mac安装node遇到的错误
    记录一次netcore3.0 code first使用迁移命令报错问题
  • 原文地址:https://www.cnblogs.com/sushine1/p/11654236.html
Copyright © 2011-2022 走看看