{"id":15716354,"url":"https://github.com/shuai-xie/genetic-algorithm","last_synced_at":"2025-04-06T11:07:58.905Z","repository":{"id":41452584,"uuid":"89571778","full_name":"Shuai-Xie/genetic-algorithm","owner":"Shuai-Xie","description":"遗传算法 - Matlab","archived":false,"fork":false,"pushed_at":"2017-08-05T18:20:10.000Z","size":9,"stargazers_count":440,"open_issues_count":1,"forks_count":142,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-04-06T11:07:52.886Z","etag":null,"topics":["genetic-algorithm","matlab"],"latest_commit_sha":null,"homepage":"http://www.jianshu.com/p/8a965c04c787#","language":"Matlab","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Shuai-Xie.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-04-27T07:57:42.000Z","updated_at":"2025-04-06T05:46:11.000Z","dependencies_parsed_at":"2022-08-25T13:31:18.674Z","dependency_job_id":null,"html_url":"https://github.com/Shuai-Xie/genetic-algorithm","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Shuai-Xie%2Fgenetic-algorithm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Shuai-Xie%2Fgenetic-algorithm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Shuai-Xie%2Fgenetic-algorithm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Shuai-Xie%2Fgenetic-algorithm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Shuai-Xie","download_url":"https://codeload.github.com/Shuai-Xie/genetic-algorithm/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247471518,"owners_count":20944158,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["genetic-algorithm","matlab"],"created_at":"2024-10-03T21:45:14.310Z","updated_at":"2025-04-06T11:07:58.885Z","avatar_url":"https://github.com/Shuai-Xie.png","language":"Matlab","funding_links":[],"categories":[],"sub_categories":[],"readme":"## [遗传算法 - 简书](http://www.jianshu.com/p/8a965c04c787#)\n\n遗传算法的理论是根据达尔文进化论而设计出来的算法: 人类是朝着好的方向（最优解）进化，进化过程中，会自动选择优良基因，淘汰劣等基因。\n\n[**遗传算法**](https://zh.wikipedia.org/wiki/%E9%81%97%E4%BC%A0%E7%AE%97%E6%B3%95)（英语：genetic algorithm (GA) ）是计算数学中用于解决最佳化的搜索算法，是[进化算法](https://zh.wikipedia.org/wiki/%E8%BF%9B%E5%8C%96%E7%AE%97%E6%B3%95)的一种。进化算法最初是借鉴了[进化生物学](https://zh.wikipedia.org/wiki/%E8%BF%9B%E5%8C%96%E7%94%9F%E7%89%A9%E5%AD%A6)中的一些现象而发展起来的，这些现象包括**遗传、突变、自然选择、杂交**等。\n\n\n[搜索算法](http://baike.baidu.com/item/%E6%90%9C%E7%B4%A2%E7%AE%97%E6%B3%95)的共同特征为：\n1. 首先组成一组候选解\n1. 依据某些适应性条件测算这些候选解的[适应度](http://baike.baidu.com/item/%E9%80%82%E5%BA%94%E5%BA%A6)\n1. 根据[适应度](http://baike.baidu.com/item/%E9%80%82%E5%BA%94%E5%BA%A6)保留某些候选解，放弃其他候选解\n1. 对保留的候选解进行某些操作，生成新的候选解\n\n\n![遗传算法流程](http://upload-images.jianshu.io/upload_images/1877813-4b08f7f282e0e277.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)\n\n\n**遗传算法的一般步骤**\n1. **my_fitness函数** 评估每条染色体所对应个体的适应度\n2. 升序排列适应度评估值，选出 **前 parent_number 个** 个体作为 **待选 parent 种群**（适应度函数的值越小越好）\n3. 从 **待选 parent 种群** 中随机选择 2 个个体作为父方和母方。\n4. 抽取父母双方的染色体，进行交叉，产生 2 个子代。（交叉概率）\n5. 对子代（**parent + 生成的 child**）的染色体进行变异。（变异概率）\n6. 重复3,4,5步骤，直到新种群（**parent_number + child_number**）的产生。\n\n循环以上步骤直至找到满意的解。\n\n**名词解释**\n- 交叉概率：两个个体进行交配的概率。例如，交配概率为0.8，则80%的“夫妻”会生育后代。\n- 变异概率：所有的基因中发生变异的占总体的比例。\n\n\n## GA函数\n```matlab\nfunction [best_fitness, elite, generation, last_generation] = my_ga( ...\n    number_of_variables, ...    % 求解问题的参数个数\n    fitness_function, ...       % 自定义适应度函数名\n    population_size, ...        % 种群规模（每一代个体数目）\n    parent_number, ...          % 每一代中保持不变的数目（除了变异）\n    mutation_rate, ...          % 变异概率\n    maximal_generation, ...     % 最大演化代数\n    minimal_cost ...            % 最小目标值（函数值越小，则适应度越高）\n)\n\n% 累加概率\n% 假设 parent_number = 10\n% 分子 parent_number:-1:1 用于生成一个数列\n% 分母 sum(parent_number:-1:1) 是一个求和结果（一个数）\n%\n% 分子 10     9     8     7     6     5     4     3     2     1\n% 分母 55\n% 相除 0.1818    0.1636    0.1455    0.1273    0.1091    0.0909    0.0727    0.0545    0.0364    0.0182\n% 累加 0.1818    0.3455    0.4909    0.6182    0.7273    0.8182    0.8909    0.9455    0.9818    1.0000\n%\n% 运算结果可以看出\n% 累加概率函数是一个从0到1增长得越来越慢的函数\n% 因为后面加的概率越来越小（数列是降虚排列的）\ncumulative_probabilities = cumsum((parent_number:-1:1) / sum(parent_number:-1:1)); % 1个长度为parent_number的数列\n\n% 最佳适应度\n% 每一代的最佳适应度都先初始化为1\nbest_fitness = ones(maximal_generation, 1);\n\n% 精英\n% 每一代的精英的参数值都先初始化为0\nelite = zeros(maximal_generation, number_of_variables);\n\n% 子女数量\n% 种群数量 - 父母数量（父母即每一代中不发生改变的个体）\nchild_number = population_size - parent_number; % 每一代子女的数目\n\n% 初始化种群\n% population_size 对应矩阵的行，每一行表示1个个体，行数=个体数（种群数量）\n% number_of_variables 对应矩阵的列，列数=参数个数（个体特征由这些参数表示）\npopulation = rand(population_size, number_of_variables);\n\nlast_generation = 0; % 记录跳出循环时的代数\n\n\n% 后面的代码都在for循环中\nfor generation = 1 : maximal_generation % 演化循环开始\n    \n    % feval把数据带入到一个定义好的函数句柄中计算\n    % 把population矩阵带入fitness_function函数计算\n    cost = feval(fitness_function, population); % 计算所有个体的适应度（population_size*1的矩阵）\n\n    % index记录排序后每个值原来的行数\n    [cost, index] = sort(cost); % 将适应度函数值从小到大排序\n\n    % index(1:parent_number) \n    % 前parent_number个cost较小的个体在种群population中的行数\n    % 选出这部分(parent_number个)个体作为父母，其实parent_number对应交叉概率\n    population = population(index(1:parent_number), :); % 先保留一部分较优的个体\n    % 可以看出population矩阵是不断变化的\n\n    % cost在经过前面的sort排序后，矩阵已经改变为升序的\n    % cost(1)即为本代的最佳适应度\n    best_fitness(generation) = cost(1); % 记录本代的最佳适应度\n\n    % population矩阵第一行为本代的精英个体\n    elite(generation, :) = population(1, :); % 记录本代的最优解（精英）\n\n    % 若本代的最优解已足够好，则停止演化\n    if best_fitness(generation) \u003c minimal_cost; \n        last_generation = generation;\n        break; \n    end\n    \n    % 交叉变异产生新的种群\n\n    % 染色体交叉开始\n    for child = 1:2:child_number % 步长为2是因为每一次交叉会产生2个孩子\n        \n        % cumulative_probabilities长度为parent_number\n        % 从中随机选择2个父母出来  (child+parent_number)%parent_number\n        mother = find(cumulative_probabilities \u003e rand, 1); % 选择一个较优秀的母亲\n        father = find(cumulative_probabilities \u003e rand, 1); % 选择一个较优秀的父亲\n        \n        % ceil（天花板）向上取整\n        % rand 生成一个随机数\n        % 即随机选择了一列，这一列的值交换\n        crossover_point = ceil(rand*number_of_variables); % 随机地确定一个染色体交叉点\n        \n        % 假如crossover_point=3, number_of_variables=5\n        % mask1 = 1     1     1     0     0\n        % mask2 = 0     0     0     1     1\n        mask1 = [ones(1, crossover_point), zeros(1, number_of_variables - crossover_point)];\n        mask2 = not(mask1);\n        \n        % 获取分开的4段染色体\n        % 注意是 .*\n        mother_1 = mask1 .* population(mother, :); % 母亲染色体的前部分\n        mother_2 = mask2 .* population(mother, :); % 母亲染色体的后部分\n        \n        father_1 = mask1 .* population(father, :); % 父亲染色体的前部分\n        father_2 = mask2 .* population(father, :); % 父亲染色体的后部分\n        \n        % 得到下一代\n        population(parent_number + child, :) = mother_1 + father_2; % 一个孩子\n        population(parent_number+child+1, :) = mother_2 + father_1; % 另一个孩子\n        \n    end % 染色体交叉结束\n    \n    \n    % 染色体变异开始\n    \n    % 变异种群\n    mutation_population = population(2:population_size, :); % 精英不参与变异，所以从2开始\n    \n    number_of_elements = (population_size - 1) * number_of_variables; % 全部基因数目\n    number_of_mutations = ceil(number_of_elements * mutation_rate); % 变异的基因数目（基因总数*变异率）\n    \n    % rand(1, number_of_mutations) 生成number_of_mutations个随机数(范围0-1)组成的矩阵(1*number_of_mutations)\n    % 数乘后，矩阵每个元素表示发生改变的基因的位置（元素在矩阵中的一维坐标）\n    mutation_points = ceil(number_of_elements * rand(1, number_of_mutations)); % 确定要变异的基因\n    \n    % 被选中的基因都被一个随机数替代，完成变异\n    mutation_population(mutation_points) = rand(1, number_of_mutations); % 对选中的基因进行变异操作\n    \n    population(2:population_size, :) = mutation_population; % 发生变异之后的种群\n    \n    % 染色体变异结束\n   \nend % 演化循环结束\n```\n## 适应度函数\n适应度函数由解决的问题决定。\n举一个平方和的例子。\n\n![简单的平方和问题](http://upload-images.jianshu.io/upload_images/1877813-e51446138a407db0.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)\n\n求函数的最小值，其中每个变量的取值区间都是 [-1, +1]。\n问题的最优解：每个 x_i 都等于0。\n\n```matlab\nfunction y = my_fitness(population)\n% population是随机数[0,1]矩阵，下面的操作改变范围为[-1,1]\npopulation = 2 * (population - 0.5); \ny = sum(population.^2, 2); % 行的平方和\n```\n\n## 测试\n```matlab\nclear; \nclose all;\n\n% 调用 my_ga 进行计算\n% 求解问题的参数个数         10\n% 自定义适应度函数名         my_fitness\n% 种群规模                  100\n% 每一代中保持不变的数目     50 (即交叉率0.5)\n% 变异概率                  0.1 (1/10的个体发生变异)\n% 最大演化代数              10000 10000代\n% 最小目标值                1.0e-6 个体适应度函数值 \u003c 0.000001结束\n[best_fitness, elite, generation, last_generation] = my_ga(10, 'my_fitness', 100, 50, 0.1, 10000, 1.0e-6);\n\n\n% 输出后10行\n% disp(best_fitness(9990:10000,:));\n% disp(elite(9990:10000,:))\n% 这样是不合适的，因为GA常常在中间就跳出循环了\n\n% 这样才是合适的输出\ndisp(last_generation); \ni_begin = last_generation - 9;\ndisp(best_fitness(i_begin:last_generation,:));\n% 将elite值转化为问题范围内\nmy_elite = elite(i_begin:last_generation,:);\nmy_elite = 2 * (my_elite - 0.5);\ndisp(my_elite);\n\n% 最佳适应度的演化情况\nfigure\nloglog(1:generation, best_fitness(1:generation), 'linewidth',2)\nxlabel('Generation','fontsize',15);\nylabel('Best Fitness','fontsize',15);\nset(gca,'fontsize',15,'ticklength',get(gca,'ticklength')*2);\n\n% 最优解的演化情况\nfigure\nsemilogx(1 : generation, 2 * elite(1 : generation, :) - 1)\nxlabel('Generation','fontsize',15);\nylabel('Best Solution','fontsize',15);\nset(gca,'fontsize',15,'ticklength',get(gca,'ticklength')*2);\n```\n## 输出\n注意：这些值都是不确定的。\n```matlab\n\u003e\u003e test_ga\n        2035 // last_generation 跳出循环\n\n   // best_fitness 后10行\n   0.268244559363828\n   0.268244559363828\n   0.268244559363828\n   0.268244559363828\n   0.268244559363828\n   0.268244559363828\n   0.268244559363828\n   0.268244559363828\n   0.268244559363828\n   0.063540829423325\n\n  // elite 后10行，最后一行为想要的解\n  Columns 1 through 7\n\n  -0.000383439136218  -0.000401508032900   0.000097444596325   0.000337256996077  -0.000064973174152   0.000120384223563   0.000117039829849\n  -0.000383439136218  -0.000401508032900   0.000097444596325   0.000337256996077  -0.000064973174152   0.000120384223563   0.000117039829849\n  -0.000383439136218  -0.000401508032900   0.000097444596325   0.000337256996077  -0.000064973174152   0.000120384223563   0.000117039829849\n  -0.000383439136218  -0.000401508032900   0.000097444596325   0.000337256996077  -0.000064973174152   0.000120384223563   0.000117039829849\n  -0.000383439136218  -0.000401508032900   0.000097444596325   0.000337256996077  -0.000064973174152   0.000120384223563   0.000117039829849\n  -0.000383439136218  -0.000401508032900   0.000097444596325   0.000337256996077  -0.000064973174152   0.000120384223563   0.000117039829849\n  -0.000383439136218  -0.000401508032900   0.000097444596325   0.000337256996077  -0.000064973174152   0.000120384223563   0.000117039829849\n  -0.000383439136218  -0.000401508032900   0.000097444596325   0.000337256996077  -0.000064973174152   0.000120384223563   0.000117039829849\n  -0.000383439136218  -0.000401508032900   0.000097444596325   0.000337256996077  -0.000064973174152   0.000120384223563   0.000117039829849\n  -0.000383439136218  -0.000401508032900   0.000097444596325   0.000337256996077  -0.000064973174152   0.000120384223563   0.000117039829849\n\n  Columns 8 through 10\n\n  -0.000362645135942  -0.001433818552852   0.000176675571817\n  -0.000362645135942  -0.001433818552852   0.000176675571817\n  -0.000362645135942  -0.001433818552852   0.000176675571817\n  -0.000362645135942  -0.001433818552852   0.000176675571817\n  -0.000362645135942  -0.001433818552852   0.000176675571817\n  -0.000362645135942  -0.001433818552852   0.000176675571817\n  -0.000362645135942  -0.001433818552852   0.000176675571817\n  -0.000362645135942  -0.001433818552852   0.000176675571817\n  -0.000362645135942  -0.001433818552852   0.000176675571817\n  -0.000362645135942  -0.000093799483467   0.000176675571817\n```\n\n## 趋势图\n\n最佳适应度函数的值\n\n![Best_Fitness - Generation](http://upload-images.jianshu.io/upload_images/1877813-93767bded3307b2d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)\n\nelite 的变化趋势，10条折线 -\u003e 10个变量\n\n![Best_Solution - Generation](http://upload-images.jianshu.io/upload_images/1877813-78593e09815a718b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)\n\n## 文章参考\n[科学网 - 一个用matlab实现的50行的遗传算法程序](http://blog.sciencenet.cn/blog-3102863-1029280.html)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshuai-xie%2Fgenetic-algorithm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshuai-xie%2Fgenetic-algorithm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshuai-xie%2Fgenetic-algorithm/lists"}