遗传算法的简单应用-求解方程

上篇初识遗传算法讲述了遗传算法的基本思想,这篇博客就用遗传算法求解方程。

具体的如下:

求解方程 -x^3+7*x+13=0 在[3,4]区间的解,解精确到0.001,交叉概率0.7

变异概率0.01,迭代次数为100,字符编码长度为10(二进制编码)

首先简单的分析一下:

1、编码与解码

题目要求的是采用二进制的编码方式来实现,既然已经编码了,自然就需要解码,给定的10

位二进制编码表示的区间范围就是0~1023,题目的区间是[3,4]很自然的就能想到10位二进

制编码中的0表示是就是[3,4]中的3,1023表示的就是[3,4]中的4,所以,每个二进制对应的

十进制就是((10位二进制对应的十进制数/1023)+3),这个就是解码后的在区间[3,4]中的具体值。

2、适应度函数

这里取的适应度函数是方程绝对值的倒数,即f=1/(|-x^3+7*x+13|)

3、选择算子

确定选择比例,采用轮盘赌算法。

        /// <summary>
        /// 模拟轮盘赌选择算法
        /// 思路:1.求适应度的总和;2.计算每个个体适应度所占的比例(除第一个之外,其他的都是叠加);
        /// 3.在0~1产生随机数,这个随机数所在的区间,就是要选择的个体
        /// </summary>
        /// <returns>选择出来的优秀个体</returns>
        static List<int> RWS(List<double> list)
        {
            List<int> select = new List<int>();
            List<double> p = new List<double>();
            double sum = list.Sum()/*适应度之和*/, temp = 0/*临时变量*/;
            foreach (var item in list)
            {
                temp += (item / sum);//叠加
                p.Add(temp);//概率
            }
            int i, j;
            for (i = 0; i < p.Count; i++)
            {
                temp = rd.NextDouble();//0~1的随机数
                for (j = 0; j < p.Count; j++)
                {
                    if (j == 0 && temp < p[0])
                    {
                        select.Add(0);
                    }
                    else if (temp < p[j] && temp >= p[j - 1])
                    {
                        select.Add(j);
                    }
                }
            }
            return select;
        }    

4、交配算子

随机产生交配位,交换两个染色体的部分基因。

        /// <summary>
        /// 交叉过程个体的变化(字符的替换)
        /// </summary>
        /// <param name="dic">参加交叉的两个个体</param>
        /// <param name="geti1">个体1</param>
        /// <param name="geti2">个体2</param>
        /// <returns></returns>
        static List<string> Crossover_Replace(Dictionary<int, int> dic, string geti1, string geti2)
        {
            int index; double p;
            List<string> tmp_group = new List<string>();//存放交叉过后的个体
            foreach (var item in dic)
            {
                p = rd.NextDouble();
                if (p <= crossover_probability)//概率小于0.7进行交叉
                {
                    index = rd.Next(0, 8);
                    geti1 = group[item.Key];//要交叉的两个个体
                    geti2 = group[item.Value];
                    //交叉的实现
                    tmp_group.Add(geti1.Insert(geti1.Length, geti2.Substring(index)).Remove(index, str_length - index));
                    tmp_group.Add(geti2.Insert(geti2.Length, geti1.Substring(index)).Remove(index, str_length - index));
                }
                else
                {
                    tmp_group.Add(group[item.Key]);
                    tmp_group.Add(group[item.Value]);
                }
            }
            return tmp_group;
        }

5、变异算子

变换染色体基因的值,即0-1,1-0的变换。

        /// <summary>
        /// 变异过程个体的变化(0->1,1->0)
        /// 思路:1.将个体的编码转化成字符;2.为每个字符产生一个0~1的随机数,判断是否要进行变异操作
        /// 3.要变异则将0->1,1->0
        /// </summary>
        /// <param name="str">个体(二进制编码)</param>
        /// <param name="result">变异后的结果</param>
        /// <param name="probability">变异概率</param>
        /// <returns></returns>
        static string Mutation_Replace(string str, string result, double probability)
        {
            char[] chrArray = str.ToCharArray();
            for (int i = 0; i < chrArray.Count(); i++)
            {
                //小于概率,替换字符
                if (rd.NextDouble() <= probability)
                {
                    if (chrArray[i] == ‘0‘)
                    {
                        chrArray[i] = ‘1‘;
                    }
                    else if (chrArray[i] == ‘1‘)
                    {
                        chrArray[i] = ‘0‘;
                    }
                }
            }
            //将字符拼接成字符串
            foreach (char ch in chrArray)
            {
                result += ch;
            }
            return result;
        }

其中的方法,实现不唯一,时间比较敢,也没有作一定的优化,只是为了熟悉算法而写的。

希望能帮到初学者,也欢迎各位提出修改意见。

完整代码可在这下载

https://github.com/hwqdt/Catcher.Equation

时间: 2024-10-07 11:35:33

遗传算法的简单应用-求解方程的相关文章

牛顿法求解方程

目的:求解方程{\displaystyle f(x)=0}的根

C++ 二分法求解方程的解

二分法是一种求解方程近似根的方法.对于一个函数 f(x)f(x),使用二分法求 f(x)f(x) 近似解的时候,我们先设定一个迭代区间(在这个题目上,我们之后给出了的两个初值决定的区间 [-20,20][?20,20]),区间两端自变量 xx 的值对应的 f(x)f(x) 值是异号的,之后我们会计算出两端 xx 的中点位置 x'x′ 所对应的 f(x')f(x′) ,然后更新我们的迭代区间,确保对应的迭代区间的两端 xx 的值对应的 f(x)f(x) 值还会是异号的. 重复这个过程直到我们某一次

用弦截法求解方程的根

//弦截法求解方程的根 //要求:输入左右两个端点x值 //结果:在一定精度范围内求解出方程的根 //难点:1)推导出x处的横坐标的求解公式 2)迭代掉原来的左端点或者右端点 #include "pch.h" #include <iostream> #include <cmath> #include <iomanip> using namespace std; double f(double x); double xpoint(double x1,

Leetcode 640.求解方程

求解方程 求解一个给定的方程,将x以字符串"x=#value"的形式返回.该方程仅包含'+',' - '操作,变量 x 和其对应系数. 如果方程没有解,请返回"No solution". 如果方程有无限解,则返回"Infinite solutions". 如果方程中只有一个解,要保证返回值 x 是一个整数. 示例 1: 输入: "x+5-3+x=6+x-2" 输出: "x=2" 示例 2: 输入: &quo

遗传算法的简单应用-巡回旅行商(TSP)问题的求解

上篇我们用遗传算法求解了方程,其中用到的编码方式是二进制的编码,实现起来相对简单很多, 就连交配和变异等操作也是比较简单,但是对于TSP问题,就稍微复杂一点,需要有一定的策略, 才能较好的实现. 这次的TSP问题的题目是: 随机产生10~30个城市,每个城市之间的距离也是随机产生,距离的范围是[1,50],求最优的路径 ========================================================== 下面就是具体的求解,由于我的策略是基于知网上的<一种改进的遗

高斯消元法求解方程

#include<iostream> #include<math.h> #include<vector> #include<bits/stdc++.h> using namespace std; typedef vector<double> vec; typedef vector<vec> mat; const double EPS=1E-8; //求解Ax=b,其中A是方针 //当方程组无解或者有无穷多解时,返回一个长度为0的数组

遗传算法的应用(求解迷宫问题)

遗传算法(Genetic Algorithm): 是模拟达尔文生物进化论的自然选择和遗传学机理的生物进化过程的计算模型,是一种通过模拟自然进化过程搜索最优解的方法. 遗传算法是从代表问题可能潜在的解集的一个种群(population)开始的,而一个种群则由经过基因(gene)编码的一定数目的个体(individual)组成. 每个个体实际上是染色体(chromosome)带有特征的实体. 染色体作为遗传物质的主要载体,即多个基因的集合,其内部表现(即基因型)是某种基因组合,它决定了个体的形状的外

数据拟合求解方程参数

首先引入三件套和scipy import numpy as np import pandas as pd import matplotlib.pyplot as plt from scipy.optimize import curve_fit 拿到实验数据,通过pandas读取为DataFrame data = pd.read_csv("W-900K.csv") data.head() .dataframe tbody tr th:only-of-type { vertical-ali

求解方程A5+B5+C5+D5+E5=F5

方程A5+B5+C5+D5+E5=F5刚好有一个满足0<A≤B≤C≤D≤E≤F≤75的整数解.请编写一个求出该解的程序: 1 using System; 2 3 namespace ReverseTheExponentiation 4 { 5 class Program 6 { 7 static void Main(string[] args) 8 { 9 Program P = new Program(); 10 P.ReverseTheExponentiation(); 11 } 12 13