只能用最简单的命令行模式,不要有ui等元素,遗传算法实现函数优化求函数的最大值:
max f (x , x ) = x 2 + x2
x1 Î{0,1, 2, 3, 4, 5, 6, 7}
x2 Î{0,1, 2, 3, 4, 5, 6, 7}
该回答引用ChatGPT
以下是用C#实现遗传算法求函数f(x1,x2)的最大值的代码:
using System;
using System.Collections.Generic;
namespace GeneticAlgorithm
{
class Program
{
static Random random = new Random();
static int populationSize = 50;
static int maxGeneration = 100;
static double mutationProbability = 0.01;
static double crossoverProbability = 0.8;
static int geneLength = 3;
static int variableRange = 8;
static void Main(string[] args)
{
List<Chromosome> population = InitializePopulation();
for (int i = 0; i < maxGeneration; i++)
{
population = EvolvePopulation(population);
Console.WriteLine("Generation {0}, Best Fitness: {1}", i+1, population[0].Fitness);
}
Console.WriteLine("Best Solution: x1={0}, x2={1}, f(x1,x2)={2}",
population[0].GetGene(0), population[0].GetGene(1), FitnessFunction(population[0]));
}
static List<Chromosome> InitializePopulation()
{
List<Chromosome> population = new List<Chromosome>();
for (int i = 0; i < populationSize; i++)
{
Chromosome chromosome = new Chromosome(geneLength * 2);
for (int j = 0; j < geneLength * 2; j++)
{
chromosome.SetGene(j, random.Next(variableRange));
}
population.Add(chromosome);
}
return population;
}
static List<Chromosome> EvolvePopulation(List<Chromosome> population)
{
List<Chromosome> newPopulation = new List<Chromosome>();
population.Sort();
for (int i = 0; i < populationSize; i++)
{
if (i < populationSize * crossoverProbability)
{
Chromosome parent1 = RouletteSelection(population);
Chromosome parent2 = RouletteSelection(population);
Chromosome child = Crossover(parent1, parent2);
Mutate(child);
newPopulation.Add(child);
}
else
{
newPopulation.Add(GenerateRandomChromosome());
}
}
return newPopulation;
}
static Chromosome RouletteSelection(List<Chromosome> population)
{
double totalFitness = 0;
foreach (Chromosome chromosome in population)
{
totalFitness += chromosome.Fitness;
}
double rouletteWheelPosition = random.NextDouble() * totalFitness;
double spinWheel = 0;
foreach (Chromosome chromosome in population)
{
spinWheel += chromosome.Fitness;
if (spinWheel >= rouletteWheelPosition)
{
return chromosome;
}
}
return population[population.Count - 1];
}
static Chromosome Crossover(Chromosome parent1, Chromosome parent2)
{
Chromosome child = new Chromosome(geneLength * 2);
int crossoverPoint = random.Next(geneLength * 2);
for (int i = 0; i < geneLength * 2; i++)
{
if (i < crossoverPoint)
{
child.SetGene(i, parent1.GetGene(i));
}
else
{
child.SetGene(i, parent2.GetGene(i));
}
}
return child;
}
static void Mutate(Chromosome chromosome)
{
for (int i = 0; i < geneLength * 2; i++)
{
if (random.NextDouble() < mutationProbability)
{
chromosome.SetGene(i, random.Next(variableRange));
}
}
}
static Chromosome GenerateRandomChromosome()
{
Chromosome chromosome = new Chromosome(geneLength * 2);
for (int i = 0; i < geneLength * 2; i++)
{
chromosome.SetGene(i, random.Next(variableRange));
}
return chromosome;
}
static double FitnessFunction(Chromosome chromosome)
{
double x1 = chromosome.GetGene(0) * 1.0 / (variableRange - 1);
double x2 = chromosome.GetGene(1) * 1.0 / (variableRange - 1);
return x1 * x1 + x2 * x2;
}
}
class Chromosome : IComparable<Chromosome>
{
private int[] genes;
public double Fitness { get; private set; }
public Chromosome(int geneLength)
{
genes = new int[geneLength];
}
public void SetGene(int index, int value)
{
genes[index] = value;
}
public int GetGene(int index)
{
return genes[index];
}
public void CalculateFitness()
{
Fitness = 1 / FitnessFunction();
}
private double FitnessFunction()
{
double x1 = genes[0] * 1.0 / (Program.variableRange - 1);
double x2 = genes[1] * 1.0 / (Program.variableRange - 1);
return x1 * x1 + x2 * x2;
}
public int CompareTo(Chromosome other)
{
return other.Fitness.CompareTo(Fitness);
}
}
}
“Devil组”引证GPT后的撰写:
using System;
using System.Linq;
class Program
{
static int populationSize = 50;
static int numGenerations = 100;
static double mutationRate = 0.05;
static double crossoverRate = 0.9;
static Random random = new Random();
static void Main(string[] args)
{
// Initialize population
int[][] population = new int[populationSize][];
for (int i = 0; i < populationSize; i++)
{
population[i] = new int[] { random.Next(0, 8), random.Next(0, 8) };
}
// Run genetic algorithm
for (int generation = 0; generation < numGenerations; generation++)
{
// Evaluate fitness
double[] fitnessValues = new double[populationSize];
for (int i = 0; i < populationSize; i++)
{
int[] chromosome = population[i];
double x1 = chromosome[0];
double x2 = chromosome[1];
double fitness = x1 * x1 + x2 * x2;
fitnessValues[i] = fitness;
}
// Select parents
int[][] parents = new int[populationSize][];
for (int i = 0; i < populationSize; i++)
{
int parentIndex1 = RouletteWheelSelection(fitnessValues);
int parentIndex2 = RouletteWheelSelection(fitnessValues);
parents[i] = population[parentIndex1];
}
// Crossover
int[][] offspring = new int[populationSize][];
for (int i = 0; i < populationSize; i += 2)
{
if (random.NextDouble() < crossoverRate)
{
int[] parent1 = parents[i];
int[] parent2 = parents[i + 1];
int crossoverPoint = random.Next(0, 2);
offspring[i] = new int[] { parent1[0], parent2[1] };
offspring[i + 1] = new int[] { parent2[0], parent1[1] };
}
else
{
offspring[i] = parents[i];
offspring[i + 1] = parents[i + 1];
}
}
// Mutation
for (int i = 0; i < populationSize; i++)
{
if (random.NextDouble() < mutationRate)
{
int[] chromosome = offspring[i];
int geneToMutate = random.Next(0, 2);
chromosome[geneToMutate] = random.Next(0, 8);
}
}
// Replace population
population = offspring;
}
// Print best solution
double bestFitness = double.MaxValue;
int[] bestChromosome = null;
for (int i = 0; i < populationSize; i++)
{
int[] chromosome = population[i];
double x1 = chromosome[0];
double x2 = chromosome[1];
double fitness = x1 * x1 + x2 * x2;
if (fitness < bestFitness)
{
bestFitness = fitness;
bestChromosome = chromosome;
}
}
Console.WriteLine("Best solution: x1={0}, x2={1}, fitness={2}", bestChromosome[0], bestChromosome[1], bestFitness);
}
static int RouletteWheelSelection(double[] fitnessValues)
{
double fitnessSum = fitnessValues.Sum();
double randomValue = random.NextDouble() * fitnessSum;
double currentSum = 0;
for (int i = 0; i < fitnessValues.Length; i++)
{
currentSum += fitnessValues[i];
if (currentSum >= randomValue)
{
return i;
}
}
return fitnessValues.Length - 1;
}
}
在这个示例代码中,我们定义了一些常量和变量来实现遗传算法。populationSize表示每一代中个体数量,numGenerations表示需要运行的代数,mutationRate和crossoverRate表示遗传算法的两个参数。我们首先初始化了一个种群,种群中的每一个个体由两个基因组成,这两个基因都是来自于{0,1,2,3,4,5,6,7}之中的整数。接下来,我们通过对每个个体进行适应度函数的计算,得出每个个体的适应度,然后选择优秀的个体作为父母进行交叉和变异,最后得到下一代种群。我们重复这个过程直到达到预定的代数,然后输出最优解。在本例中,我们将适应度函数定义为f(x1,x2)=x1^2+x2^2,目标是最大化适应度函数值。我们采用轮盘赌算法作为选择父母的方法,这是一种常见的遗传算法选择算子。
参考GPT和自己的思路,下面是一个简单的C#命令行程序,使用遗传算法来求解给定函数的最大值:
using System;
namespace GeneticAlgorithmDemo
{
class Program
{
static Random random = new Random();
static void Main(string[] args)
{
int populationSize = 100;
int chromosomeLength = 2;
int maxGenerations = 100;
double mutationProbability = 0.1;
double crossoverProbability = 0.8;
int[][] population = InitializePopulation(populationSize, chromosomeLength);
int[][] newPopulation = new int[populationSize][];
double[] fitnessValues = new double[populationSize];
for (int generation = 1; generation <= maxGenerations; generation++)
{
double totalFitness = EvaluatePopulation(population, fitnessValues);
Console.WriteLine("Generation {0}: Best fitness = {1}", generation, fitnessValues.Max());
for (int i = 0; i < populationSize; i++)
{
int[] parent1 = SelectParent(population, fitnessValues, totalFitness);
int[] parent2 = SelectParent(population, fitnessValues, totalFitness);
int[] child = Crossover(parent1, parent2, crossoverProbability);
Mutate(child, mutationProbability);
newPopulation[i] = child;
}
population = newPopulation;
newPopulation = new int[populationSize][];
}
double bestFitness = fitnessValues.Max();
int[] bestChromosome = population[Array.IndexOf(fitnessValues, bestFitness)];
Console.WriteLine("Best solution: x1 = {0}, x2 = {1}, f(x1, x2) = {2}", bestChromosome[0], bestChromosome[1], bestFitness);
Console.ReadKey();
}
static int[][] InitializePopulation(int populationSize, int chromosomeLength)
{
int[][] population = new int[populationSize][];
for (int i = 0; i < populationSize; i++)
{
int[] chromosome = new int[chromosomeLength];
chromosome[0] = random.Next(0, 8);
chromosome[1] = random.Next(0, 8);
population[i] = chromosome;
}
return population;
}
static double EvaluateFitness(int[] chromosome)
{
double x1 = chromosome[0];
double x2 = chromosome[1];
return x1 * x1 + x2 * x2;
}
static double EvaluatePopulation(int[][] population, double[] fitnessValues)
{
double totalFitness = 0;
for (int i = 0; i < population.Length; i++)
{
double fitness = EvaluateFitness(population[i]);
fitnessValues[i] = fitness;
totalFitness += fitness;
}
return totalFitness;
}
static int[] SelectParent(int[][] population, double[] fitnessValues, double totalFitness)
{
double rand = random.NextDouble() * totalFitness;
int index = 0;
while (rand > 0)
{
rand -= fitnessValues[index];
index++;
}
index--;
return population[index];
}
static int[] Crossover(int[] parent1, int[] parent2, double crossoverProbability)
{
int[] child = new int[parent1.Length];
for (int i = 0; i < parent1.Length; i++)
{
if (random.NextDouble() < crossoverProbability)
{
child[i] = parent1[i];
}
else
{
child[i] =parent2[i];
}
}
return child;
}
这是一个基于遗传算法的交叉操作,根据传入的两个父代个体(parent1和parent2)和交叉概率(crossoverProbability),生成一个子代个体(child)。
具体实现时,对于每一个基因位上的值,以概率crossoverProbability选择parent1中对应的基因值,否则选择parent2中对应的基因值。
需要继续完成的部分是生成的child数组中剩下的基因位的赋值操作。可以根据具体情况来确定剩下基因位的赋值策略,例如:
随机选择parent1或parent2中的基因值;
保留parent1或parent2的对应基因值;
交替选择parent1和parent2的对应基因值等。
下面是一个完整的基于遗传算法的函数最大值优化求解示例,你可以参考一下实现细节:
using System;
namespace GeneticAlgorithm
{
class Program
{
static Random random = new Random();
static void Main(string[] args)
{
// 遗传算法参数设置
int populationSize = 100; // 种群规模
int chromosomeLength = 2; // 染色体长度,即变量个数
int maxGeneration = 100; // 最大迭代次数
double crossoverProbability = 0.8; // 交叉概率
double mutationProbability = 0.1; // 变异概率
int elitismCount = 1; // 精英保留数量
// 初始化种群
int[][] population = new int[populationSize][];
for (int i = 0; i < populationSize; i++)
{
population[i] = new int[chromosomeLength];
for (int j = 0; j < chromosomeLength; j++)
{
population[i][j] = random.Next(8); // 变量取值范围为{0,1,2,3,4,5,6,7}
}
}
// 迭代更新种群
for (int g = 0; g < maxGeneration; g++)
{
// 计算种群适应度
double[] fitnessValues = CalculateFitnessValues(population);
// 选择操作
int[][] selectedPopulation = Selection(population, fitnessValues);
// 交叉操作
int[][] crossoverPopulation = Crossover(selectedPopulation, crossoverProbability);
// 变异操作
int[][] mutationPopulation = Mutation(crossoverPopulation, mutationProbability);
// 精英保留
int[][] elitismPopulation = Elitism(population, elitismCount);
// 新一代种群
population = MergePopulation(mutationPopulation, elitismPopulation);
}
// 最终种群适应度
double[] finalFitnessValues = CalculateFitnessValues(population);
// 最优个体
int[] bestIndividual = GetBestIndividual(population, finalFitnessValues);
// 输出结果
Console.WriteLine($"最优个体:x1={bestIndividual[0]}, x2={bestIndividual[1]}, f(x1,x2)={FitnessFunction(bestIndividual[0], bestIndividual[1])}");
Console.WriteLine($"最优解:{FitnessFunction(bestIndividual[0], bestIndividual[1])}");
}
static void Main(string[] args)
{
// 种群大小
int populationSize = 50;
// 迭代次数
int maxGeneration = 200;
// 交叉概率
double crossoverProbability = 0.8;
// 变异概率
double mutationProbability = 0.1;
// 初始化种群
int[][] population = InitializePopulation(populationSize);
// 逐代迭代
for (int generation = 0; generation < maxGeneration; generation++)
{
// 选择
int[][] selectedPopulation = SelectPopulation(population);
// 交叉
for (int i = 0; i < selectedPopulation.Length; i += 2)
{
Crossover(selectedPopulation[i], selectedPopulation[i + 1], crossoverProbability);
}
// 变异
MutatePopulation(selectedPopulation, mutationProbability);
// 合并种群
int[][] combinedPopulation = CombinePopulation(population, selectedPopulation);
// 计算适应度
double[] fitnessValues = CalculateFitnessValues(combinedPopulation);
// 选择新一代种群
population = SelectNewPopulation(combinedPopulation, fitnessValues);
}
// 输出结果
OutputResult(population);
}
}
}
遗传算法是一种基于生物进化过程的优化算法,它模拟了自然选择、交叉和变异等过程,通过不断迭代得到最优解。
using System;
using System.Collections.Generic;
namespace GeneticAlgorithm
{
class Program
{
static void Main(string[] args)
{
const int populationSize = 10; // 种群大小
const int maxGeneration = 100; // 最大迭代次数
const double crossoverProbability = 0.8; // 交叉概率
const double mutationProbability = 0.05; // 变异概率
// 初始化种群
var population = new List<(int x1, int x2)>();
var random = new Random();
for (int i = 0; i < populationSize; i++)
{
var x1 = random.Next(0, 8);
var x2 = random.Next(0, 8);
population.Add((x1, x2));
}
// 迭代
for (int generation = 0; generation < maxGeneration; generation++)
{
// 计算适应度
var fitness = new List<double>();
foreach (var individual in population)
{
var f = individual.x1 * individual.x1 + individual.x2 * individual.x2;
fitness.Add(f);
}
// 选择父代
var parents = new List<(int x1, int x2)>();
for (int i = 0; i < populationSize / 2; i++)
{
var index1 = RouletteSelection(fitness);
var index2 = RouletteSelection(fitness);
var parent1 = population[index1];
var parent2 = population[index2];
parents.Add(parent1);
parents.Add(parent2);
}
// 交叉
var offspring = new List<(int x1, int x2)>();
for (int i = 0; i < populationSize / 2; i++)
{
var parent1 = parents[i * 2];
var parent2 = parents[i * 2 + 1];
if (random.NextDouble() < crossoverProbability)
{
var child1 = (parent1.x1, parent2.x2);
var child2 = (parent2.x1, parent1.x2);
offspring.Add(child1);
offspring.Add(child2);
}
else
{
offspring.Add(parent1);
offspring.Add(parent2);
}
}
// 变异
for (int i = 0; i < populationSize; i++)
{
if (random.NextDouble() < mutationProbability)
{
var child = offspring[i];
var newx1 = random.Next(0, 8);
var newx2 = random.Next(0, 8);
offspring[i] = (newx1, newx2);
}
}
// 更新种群
var newPopulation = new List<(int x1, int x2)>();
for (int i = 0; i < populationSize; i++)
{
var individual = offspring[i];
newPopulation.Add(individual);
}
population = newPopulation;
}
// 计算最优解
var bestFitness = double.MinValue;
var bestIndividual = (0, 0);
foreach (var individual in population)
{
var f = individual.x1 * individual.x1 + individual.x2 * individual.x2;
if (f > bestFitness)
{
bestFitness = f;
bestIndividual = individual;
}
}
// 输出结果
Console.WriteLine($"最优解为 f({bestIndividual.x1}, {bestIndividual.x2}) = {bestFitness}");
}
static int RouletteSelection(List<double> fitness)
{
var totalFitness = 0.0;
foreach (var f in fitness)
{
totalFitness += f;
}
var rouletteValue = new Random().NextDouble() * totalFitness;
var accumulatedFitness = 0.0;
for (int i = 0; i < fitness.Count; i++)
{
accumulatedFitness += fitness[i];
if (accumulatedFitness >= rouletteValue)
{
return i;
}
}
return fitness.Count - 1; // 如果没找到,返回最后一个
}
}
}
用什么语言写的
参考chatGPT的回答内容,以下是使用遗传算法实现函数优化求最大值的C#代码示例:
using System;
class Program {
static Random random = new Random();
static int populationSize = 50;
static int chromosomeLength = 14;
static double mutationRate = 0.1;
static double crossoverRate = 0.9;
static int elitismCount = 2;
static void Main(string[] args) {
// 初始化种群
int[][] population = InitializePopulation(populationSize, chromosomeLength);
// 进入遗传算法循环
while (true) {
// 计算适应度
double[] fitnessValues = CalculateFitnessValues(population);
// 选择父代
int[][] parents = SelectParents(population, fitnessValues);
// 交叉产生子代
int[][] offspring = Crossover(parents);
// 变异
Mutate(offspring);
// 合并父代和子代种群
int[][] combinedPopulation = CombinePopulations(population, offspring);
// 选择下一代种群
population = SelectNextGeneration(combinedPopulation);
// 计算当前种群中最优的染色体
int[] bestChromosome = GetBestChromosome(population);
// 输出结果
Console.WriteLine("当前最优解为:f({0}, {1}) = {2}", DecodeChromosome(bestChromosome)[0], DecodeChromosome(bestChromosome)[1], CalculateFitness(bestChromosome));
}
}
// 初始化种群
static int[][] InitializePopulation(int size, int length) {
int[][] population = new int[size][];
for (int i = 0; i < size; i++) {
population[i] = new int[length];
for (int j = 0; j < length; j++) {
population[i][j] = random.Next(2);
}
}
return population;
}
// 计算适应度
static double[] CalculateFitnessValues(int[][] population) {
double[] fitnessValues = new double[population.Length];
for (int i = 0; i < population.Length; i++) {
fitnessValues[i] = CalculateFitness(population[i]);
}
return fitnessValues;
}
// 计算染色体的适应度
static double CalculateFitness(int[] chromosome) {
int[] decoded = DecodeChromosome(chromosome);
double x1 = decoded[0] * 7.0 / 127.0;
double x2 = decoded[1] * 7.0 / 127.0;
return x1 * x1 + x2 * x2;
}
// 将染色体解码成二进制数对应的十进制数
static int[] DecodeChromosome(int[] chromosome) {
int[] decoded = new int[2];
decoded[0] = chromosome[0] * 64 + chromosome[1] * 32 + chromosome[2] * 16 + chromosome[3] * 8 + chromosome[4] * 4 + chromosome[5] * 2 + chromosome[6];
decoded[1] = chromosome[7] * 64 + chromosome[8] * 32 + chromosome[9] * 16 + chromosome[10] * 8 + chromosome[11] * 4 + chromosome[12] * 2
+ chromosome[13];
return decoded;
}
// 选择父代
static int[][] SelectParents(int[][] population, double[] fitnessValues) {
int[][] parents = new int[2][];
// 精英选择:选取当前种群中适应度最高的染色体作为父代
int[] elite = GetElite(population, fitnessValues, elitismCount);
parents[0] = elite[0];
parents[1] = elite[1];
// 锦标赛选择:从种群中随机选取两个染色体,比较它们的适应度,适应度高的染色体被选为父代
for (int i = elitismCount; i < 2; i++) {
int index1 = random.Next(population.Length);
int index2 = random.Next(population.Length);
if (fitnessValues[index1] > fitnessValues[index2]) {
parents[i] = population[index1];
} else {
parents[i] = population[index2];
}
}
return parents;
}
// 获取当前种群中适应度最高的染色体
static int[] GetBestChromosome(int[][] population) {
int[] bestChromosome = population[0];
double bestFitnessValue = CalculateFitness(bestChromosome);
for (int i = 1; i < population.Length; i++) {
double fitnessValue = CalculateFitness(population[i]);
if (fitnessValue > bestFitnessValue) {
bestChromosome = population[i];
bestFitnessValue = fitnessValue;
}
}
return bestChromosome;
}
// 获取当前种群中适应度最高的 elitismCount 个染色体
static int[][] GetElite(int[][] population, double[] fitnessValues, int count) {
int[][] elite = new int[count][];
Array.Copy(population, elite, count);
for (int i = 0; i < count - 1; i++) {
int maxIndex = i;
for (int j = i + 1; j < population.Length; j++) {
if (fitnessValues[j] > fitnessValues[maxIndex]) {
maxIndex = j;
}
}
if (maxIndex != i) {
int[] tempChromosome = elite[i];
elite[i] = elite[maxIndex];
elite[maxIndex] = tempChromosome;
}
}
return elite;
}
// 交叉产生子代
static int[][] Crossover(int[][] parents) {
int[][] offspring = new int[2][];
// 一点交叉:从随机位置开始,将两个父代染色体分别交叉组成两个子代染色体
if (random.NextDouble() < crossoverRate) {
int crossoverPoint = random.Next(1, chromosomeLength - 1);
offspring[0] = new int[chromosomeLength];
offspring[1] = new int[chromosomeLength];
for (int i = 0; i < crossoverPoint; i++) {
offspring[0][i] = parents[0][i];
offspring[1][i] = parents[1][i];
}
for (int i = crossoverPoint; i < chromosomeLength; i++) {
offspring[0][i] = parents[1][i];
offspring[1][i] = parents[0][i];
}
}
// 如果没有交叉,则直接将父代复制到子代中
else {
offspring[0] = new int[chromosomeLength];
offspring[1] = new int[chromosomeLength];
for (int i = 0; i < chromosomeLength; i++) {
offspring[0][i] = parents[0][i];
offspring[1][i] = parents[1][i];
}
}
return offspring;
}
// 变异产生新个体
static int[] Mutate(int[] chromosome) {
int[] mutatedChromosome = new int[chromosomeLength];
// 随机选取染色体上的一个基因进行变异
for (int i = 0; i < chromosomeLength; i++) {
if (random.NextDouble() < mutationRate) {
mutatedChromosome[i] = random.Next(0, geneRange);
} else {
mutatedChromosome[i] = chromosome[i];
}
}
return mutatedChromosome;
}
这段代码实现了一个简单的遗传算法来优化函数 f(x1, x2) = x1^2 + x2^2,其中 x1 和 x2 分别来自集合 {0, 1, 2, 3, 4, 5, 6, 7}。算法通过迭代进化过程来逐步优化染色体的适应度,从而达到求解 f 函数最大值的目标。
以下答案由GPT-3.5大模型与博主波罗歌共同编写:
在命令行模式下,可以使用纯C#语言来实现遗传算法求解函数最大值的问题。具体实现如下:
定义编码方式:由于函数只有两个自变量,可以使用二进制编码方式,每个自变量使用3位二进制数表示,共占用6位。由于每个自变量取值的范围是[0,7],因此可以把二进制数转换为十进制,得到每个自变量的数值。
初始化种群:随机生成一定数量的个体,每个个体由两个自变量组成。个体的自变量使用步骤1中定义的编码方式表示。
适应度函数:计算每个个体的适应度值,即将个体的自变量带入函数计算得到的结果。
选择操作:使用基于轮盘赌的选择算法对种群进行选择操作,根据每个个体的适应度值确定被选中的概率。
交叉操作:对被选中的个体进行交叉操作,使用单点交叉算法。
变异操作:对交叉后的个体进行变异操作,使用位变异算法。
终止条件:设定一个终止迭代次数或者达到了预设的最优解。
输出结果:输出种群中的最优解,即具有最大适应度值的个体。
下面是完整的C#代码实现:
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
const int POP_SIZE = 50;//种群数量
const int DNA_SIZE = 6;//每个个体包含的基因数量
const int MAX_GENERATION = 1000;//最大迭代次数
const double CROSSOVER_RATE = 0.8;//交叉概率
const double MUTATION_RATE = 0.03;//变异概率
static Random random = new Random();
static List<double> population = new List<double>();
static List<double> fitness = new List<double>();
static void Main()
{
InitPopulation();
for (int i = 0; i < MAX_GENERATION; i++)
{
Selection();
Crossover();
Mutation();
Console.WriteLine($"Generation:{i},Best Solution:{population[0]}");
if (fitness[0] == 2)
{
break;//找到最优解,退出迭代
}
}
Console.WriteLine($"Best Solution:{population[0]}");
}
static void InitPopulation()
{
for (int i = 0; i < POP_SIZE; i++)
{
double chromosome = 0;
for (int j = 0; j < DNA_SIZE; j++)
{
chromosome += random.NextDouble() * Math.Pow(2, j * 3);//生成0~7的随机数并转化为二进制
}
population.Add(chromosome);
}
UpdateFitness();
}
static void UpdateFitness()
{
fitness.Clear();
foreach (var chromosome in population)
{
double f = Evaluate(chromosome);//计算适应度值
fitness.Add(f);
}
}
static double Evaluate(double chromosome)
{
double x1 = Convert.ToInt32(chromosome % Math.Pow(2, 3));
double x2 = Convert.ToInt32(chromosome / Math.Pow(2, 3));
double f = Math.Pow(x1, 2) + Math.Pow(x2, 2);
return f;
}
static void Selection()
{
double totalFitness = fitness.Sum();
List<double> probability = new List<double>();
double sum = 0;
foreach (var f in fitness)
{
double p = f / totalFitness;//计算每个个体被选中的概率
sum += p;
probability.Add(sum);
}
List<double> newPopulation = new List<double>();
newPopulation.Add(population[0]);//精英保留
while (newPopulation.Count < POP_SIZE)
{
double dice = random.NextDouble();
for (int i = 0; i < probability.Count; i++)
{
if (dice <= probability[i])
{
newPopulation.Add(population[i]);
break;
}
}
}
population = newPopulation;
UpdateFitness();
}
static void Crossover()
{
for (int i = 1; i < POP_SIZE; i += 2)
{
if (random.NextDouble() < CROSSOVER_RATE)
{
int crossoverPoint = random.Next(DNA_SIZE);//随机选择交叉点
double parent1 = population[i - 1];
double parent2 = population[i];
double offspring1 = ((parent1 >> (crossoverPoint * 3)) << (crossoverPoint * 3)) + (parent2 & ((1 << (crossoverPoint * 3)) - 1));
double offspring2 = ((parent2 >> (crossoverPoint * 3)) << (crossoverPoint * 3)) + (parent1 & ((1 << (crossoverPoint * 3)) - 1));
population[i - 1] = offspring1;
population[i] = offspring2;
}
}
UpdateFitness();
}
static void Mutation()
{
for (int i = 1; i < POP_SIZE; i++)
{
double chromosome = population[i];
for (int j = 0; j < DNA_SIZE * 3; j++)
{
if (random.NextDouble() < MUTATION_RATE)
{
chromosome ^= (long)1 << j;//进行位变异
}
}
population[i] = chromosome;
}
UpdateFitness();
}
}
在执行以上代码后,程序会输出每一代中最优解的数值以及最终求得的最优解,即函数的最大值。
如果我的回答解决了您的问题,请采纳!
可以参考一下C#写的代码:
```c#
using System;
using System.Linq;
class Program
{
static int populationSize = 50;
static int numGenerations = 100;
static double mutationRate = 0.05;
static double crossoverRate = 0.9;
static Random random = new Random();
static void Main(string[] args)
{
// Initialize population
int[][] population = new int[populationSize][];
for (int i = 0; i < populationSize; i++)
{
population[i] = new int[] { random.Next(0, 8), random.Next(0, 8) };
}
// Run genetic algorithm
for (int generation = 0; generation < numGenerations; generation++)
{
// Evaluate fitness
double[] fitnessValues = new double[populationSize];
for (int i = 0; i < populationSize; i++)
{
int[] chromosome = population[i];
double x1 = chromosome[0];
double x2 = chromosome[1];
double fitness = x1 * x1 + x2 * x2;
fitnessValues[i] = fitness;
}
// Select parents
int[][] parents = new int[populationSize][];
for (int i = 0; i < populationSize; i++)
{
int parentIndex1 = RouletteWheelSelection(fitnessValues);
int parentIndex2 = RouletteWheelSelection(fitnessValues);
parents[i] = population[parentIndex1];
}
// Crossover
int[][] offspring = new int[populationSize][];
for (int i = 0; i < populationSize; i += 2)
{
if (random.NextDouble() < crossoverRate)
{
int[] parent1 = parents[i];
int[] parent2 = parents[i + 1];
int crossoverPoint = random.Next(0, 2);
offspring[i] = new int[] { parent1[0], parent2[1] };
offspring[i + 1] = new int[] { parent2[0], parent1[1] };
}
else
{
offspring[i] = parents[i];
offspring[i + 1] = parents[i + 1];
}
}
// Mutation
for (int i = 0; i < populationSize; i++)
{
if (random.NextDouble() < mutationRate)
{
int[] chromosome = offspring[i];
int geneToMutate = random.Next(0, 2);
chromosome[geneToMutate] = random.Next(0, 8);
}
}
// Replace population
population = offspring;
}
// Print best solution
double bestFitness = double.MaxValue;
int[] bestChromosome = null;
for (int i = 0; i < populationSize; i++)
{
int[] chromosome = population[i];
double x1 = chromosome[0];
double x2 = chromosome[1];
double fitness = x1 * x1 + x2 * x2;
if (fitness < bestFitness)
{
bestFitness = fitness;
bestChromosome = chromosome;
}
}
Console.WriteLine("Best solution: x1={0}, x2={1}, fitness={2}", bestChromosome[0], bestChromosome[1], bestFitness);
}
static int RouletteWheelSelection(double[] fitnessValues)
{
double fitnessSum = fitnessValues.Sum();
double randomValue = random.NextDouble() * fitnessSum;
double currentSum = 0;
for (int i = 0; i < fitnessValues.Length; i++)
{
currentSum += fitnessValues[i];
if (currentSum >= randomValue)
{
return i;
}
}
return fitnessValues.Length - 1;
}
}
```
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static readonly int POPULATION_SIZE = 50;
static readonly int GENERATION_COUNT = 200;
static readonly double MUTATION_RATE = 0.01;
static readonly Random random = new Random();
static void Main(string[] args)
{
List<Chromosome> population = InitializePopulation(POPULATION_SIZE);
for (int i = 0; i < GENERATION_COUNT; i++)
{
List<Chromosome> newPopulation = new List<Chromosome>();
while (newPopulation.Count < POPULATION_SIZE)
{
Chromosome parent1 = SelectParent(population);
Chromosome parent2 = SelectParent(population);
Chromosome child = Crossover(parent1, parent2);
if (random.NextDouble() < MUTATION_RATE)
{
child.Mutate();
}
newPopulation.Add(child);
}
population = newPopulation;
}
Chromosome bestChromosome = population.OrderByDescending(c => c.Fitness()).First();
Console.WriteLine($"x1 = {bestChromosome.Genes[0]}, x2 = {bestChromosome.Genes[1]}, f(x1,x2) = {bestChromosome.Fitness()}");
}
static List<Chromosome> InitializePopulation(int size)
{
List<Chromosome> population = new List<Chromosome>();
for (int i = 0; i < size; i++)
{
int x1 = random.Next(8);
int x2 = random.Next(8);
population.Add(new Chromosome(new int[] { x1, x2 }));
}
return population;
}
static Chromosome SelectParent(List<Chromosome> population)
{
// Tournament selection
int tournamentSize = 5;
List<Chromosome> candidates = new List<Chromosome>();
for (int i = 0; i < tournamentSize; i++)
{
int index = random.Next(population.Count);
candidates.Add(population[index]);
}
return candidates.OrderByDescending(c => c.Fitness()).First();
}
static Chromosome Crossover(Chromosome parent1, Chromosome parent2)
{
// Single-point crossover
int crossoverPoint = random.Next(parent1.Genes.Length);
int[] genes = new int[parent1.Genes.Length];
for (int i = 0; i < crossoverPoint; i++)
{
genes[i] = parent1.Genes[i];
}
for (int i = crossoverPoint; i < parent2.Genes.Length; i++)
{
genes[i] = parent2.Genes[i];
}
return new Chromosome(genes);
}
}
class Chromosome
{
public int[] Genes { get; private set; }
public Chromosome(int[] genes)
{
Genes = genes;
}
public double Fitness()
{
int x1 = Genes[0];
int x2 = Genes[1];
return x1 * x1 + x2 * x2;
}
public void Mutate()
{
// Random mutation
int index = Program.random.Next(Genes.Length);
Genes[index] = Program.random.Next(8);
}
}