首页 > HFSS > HFSS教程 > 基于遗传算法的HFSS和C#联合仿真(二)程序实现

基于遗传算法的HFSS和C#联合仿真(二)程序实现

录入:edatop.com    点击:

基于遗传算法的HFSS和C#联合仿真(二)

说明:上一篇博客介绍了C#和HFSS联合仿真的方法,这一篇主要介绍实现方法。

初始设置:

		static int Population_size = 12;             //种群规模
		static int child_size = 6;                   //子种群规模
		static int best_size = 2;                    //精英个体
		static int val = 21;                         //染色体个数21
		static int vaw = 16;                         //染色体维数16
		static int Chromosome_length = val * vaw;    //染色体网格数
		static double rate_crossover = 0.9;          //交叉率
		static double rate_mutation = 0.1;           //变异率
		static int iteration_num = 70;               //迭代次数   
		static ChooseType chooseType = ChooseType.Roulette;//选择方法,Bubble,冒泡; Roulette,轮盘赌;
		static double rate_roulette=0.6;			 //轮盘选择率

种群规模:每次参与演化的个体数量
子种群规模:每次演化后迭代进入下一次的个体数量
精英个体:种群中适应度最高的个体,进入下次演化,加快收敛
染色体条数和维数:基因组的大小,对应微带天线的大小
交叉率:基因组产生交叉的概率
变异率:基因组产生变异的概率
选择方法:在种群中选择进入下次演化的个体的方法
轮盘选择率:提高精英个体在轮盘选择中存活的概率

主要方法

		public MainWindow()
		{
			InitializeComponent();
			//初始化种群
			Init();
			//迭代次数累计器
			int i = 0;
			//适应度
			double cost = 0;
			List<double> cost_list = new List<double>();
			while (i <iteration_num || cost < 780)
			{
				i++;
				//重新计算fit值			
				UpdateFitValue();				
				//适应度排序
				ChooseChromosome();
				//选择方法,轮盘赌
				UpdateNext();
				//交叉得到新个体
				CrossOperate();
				//变异操作
				VariationOperate();
				//插入新的种群,保留子种群
				Initchild()
				//记录适应度值
				cost = chromosomes[0].fitValue;
				cost_list.Add(cost);
			}
			//打印结果
			double maxfit = chromosomes[0].fitValue;			
			Console.WriteLine("最大值为: " + maxfit);
			Print();
			//控制台打印适应度值
			foreach (double cs in cost_list)
				Console.WriteLine("cost:"+cs);
			Console.ReadLine();
		}

定义个体类

包含个体的编码,适应值,选择概率和累计概率

		class chromosome
		{
			// 对染色体进行编码;
			public int[] bits = new int[val * vaw];
			// 适应值;
			public double fitValue;
			// 选择概率;
			public double fitValuePercent;
			// 累积概率;
			public double probability;
		}

选择方法

采用改进的轮盘选择方法,提高适应度高的个体的存活概率,减小选择误差

     private void UpdateNext()
        {
            // 获取总的fit;
            double totalFitValue = 0;
            for (int i = best_size ; i < chromosomes.Count; i++)
            {
                //适应度为负数的取0;
                if (chromosomes[i].fitValue <= 0)
                {
                    totalFitValue += 0;
                }
                else
                {
                    totalFitValue += chromosomes[i].fitValue;
                }
            }
            //算出每个的fit percent;
            for (int i = best_size ; i < chromosomes.Count; i++)
            {
                if (chromosomes[i].fitValue <= 0)
                {
                    chromosomes[i].fitValuePercent = 0;
                }
                else
                {
                    chromosomes[i].fitValuePercent = chromosomes[i].fitValue / totalFitValue;
                }
            }
            //计算累积概率;
            //第一个的累计概率就是自己的概率;
            chromosomes[best_size].probability = chromosomes[best_size].fitValuePercent;
            for (int i = best_size +1; i < chromosomes.Count; i++)
            {
                // 上一个的累计概率加上自己的概率,得到自己的累计概率;
                chromosomes[i].probability = chromosomes[i - 1].probability + chromosomes[i].fitValuePercent;
            }
            //轮盘赌选择方法
            for (int i = best_size ; i < chromosomes.Count; i++)
            {
				//产生随机的选择概率
				string uuid2 = Guid.NewGuid().ToString("N");
				char []c_array = uuid2.ToArray();
				Random random = new Random(c_array [i%30]*best_size+i*i+c_array [best_size%30]*i);
				double rand = (random.Next(1, 10000)/10000.00000)*rate_roulette;
                if (rand <= chromosomes[best_size].probability)
                {
					break;
                }
                else
                {
                    for (int j = best_size ; j < chromosomes.Count - 1; j++)
                    {
                        if (chromosomes[j].probability < rand && rand <= chromosomes[j + 1].probability)
                        {
							int[] bits_aa = new int[val * vaw];
							int[] bits_bb = new int[val * vaw];
							bits_aa = chromosomes[j + 1].bits ;
							bits_bb = chromosomes[best_size].bits ;
							chromosomes[best_size].bits  =bits_aa;
							chromosomes[j + 1].bits = bits_bb;
							break;
                        }
                    }
                }
            }
        }

交叉方法

采用改进的均匀交叉方法,同一纬度上的基因片段进行交叉,且交叉概率和交叉位置不定

 private void CrossOperate()
        {
			for (int k = 0; k < child_size /2; k++)
			{
				for (int j = 0; j < val; j++)
					{
						//每一维度产生不同的交叉机率
						string uuid_c = Guid.NewGuid().ToString("N");
						char[] c_ac = uuid_c.ToArray();
						int seed_c =c_ac[j % 31] + c_ac[12]+j+j*j+c_ac[j % 31]*c_ac[j % 31]*c_ac[k % 31];
						Random random_c = new Random(seed_c);
						double rate_rand = random_c.Next(1, 10000) / 10000.00000;
						int seed_j =c_ac[k % 31] + c_ac[23]+k+j*k+c_ac[k % 31]*c_ac[k % 31]*c_ac[k % 31];
						//每一维度产生不同的交叉位置
						Random random_j = new Random(seed_j);
						int rand_j = random_j.Next(3, vaw-2);
						int a = child_size -1-k;
						int b = child_size -1-k;
						//如果大于交叉概率就进行交叉操作
						if (rate_rand <= rate_crossover)
						{
							for (int i = 0; i < rand_j; i++)
							{
								int bit_a = 0;
								bit_a= chromosomes[b].bits[j * vaw + i];
								chromosomes[a].bits[j * vaw + i] =bit_a;
							}
							for (int i = rand_j; i < vaw; i++)
							{
								int bit_b = 0;
								bit_b = chromosomes[(b+1)%(child_size /2)].bits[j * vaw + i];
								chromosomes[a].bits[j * vaw + i] = bit_b;
							}	
						}
					}
			}
        }

变异方法

采用均匀变异的方法,对每一维度上不定位置进行随机变异

        private void VariationOperate()
        {
			for (int k =1; k < Population_size; k++)
			{
				for (int j = 0; j < val; j++)
				{
					//每一维度上的变异概率
					string uuid_d = Guid.NewGuid().ToString("N");
					char[] c_ad = uuid_d.ToArray();
					int seed_d =c_ad[j % 31] + c_ad[16]*k+k*j+c_ad[j % 31]*c_ad[j % 21]*c_ad[j % 11];
					Random random_d= new Random(seed_d);
					double rate_rand_d = random_d.Next(1, 10000)/10000.00000;
					if (rate_rand_d < rate_mutation)
					{
						string uuid_e = Guid.NewGuid().ToString("N");
						char[] c_ae = uuid_e.ToArray();
						int seed_e =c_ae[j % 21] + c_ae[12]*k+k*j+c_ae[j % 31]*c_ae[k % 21]*c_ae[j % 31];
						Random random_e= new Random(seed_e);
						//每一维度上基因变异的位置
						int col = random_e.Next(1, vaw);
						// 0变为1,1变为0;
						if (chromosomes[k].bits[j * vaw + col] == 0)
						{
							chromosomes[k].bits[j * vaw + col] = 1;
						}
						else
						{
							chromosomes[k].bits[j * vaw + col] = 0;
						}
					}
				}
			}
        }

获取适应度

将hfss仿真得到的驻波转换为cost值,其中,在范围内达到要求的值记为0,将范围内超出要求的驻波值乘2,将频带范围内的值相加记为总的cost值。

        private double  GetFitValue(int []x)
        {
			//目标函数,将cost变为正值,方便计算
			return (hfss_runandgetdata(x));		
        }

HFSS 学习培训课程套装,专家讲解,视频教学,帮助您全面系统地学习掌握HFSS

上一篇:基于遗传算法的HFSS和C#联合仿真(一)算法简介
下一篇:HFSS仿真软件完成微带天线设计

HFSS视频培训课程推荐详情>>
HFSS教程推荐

  网站地图