zoukankan      html  css  js  c++  java
  • CSharp遗传算法求解背包问题

     断断续续写了四天,感觉背包问题是最适合了解遗传算法的问题模型

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace Bag
    {
    
    
        /// <summary>
        /// 背包类
        /// </summary>
        public class Bag
        {
            public int Size { get; }
            public Bag(int Size)
            {
                this.Size = Size;
            }
        }
        /// <summary>
        /// 货物类
        /// </summary>
        public class Goods
        {
            public int Weight { set; get; }
            public int Value { set; get; }
            /// <summary>
            /// 这里随机生成货物属性
            /// </summary>
            public Goods()
            {
                this.Weight = APP.Rd.Next() % 200 + 10;
                this.Value = APP.Rd.Next() % 1000 + 50;
            }
        }
        /// <summary>
        /// 测试结果,编号,总重与总价
        /// </summary>
        public class Total
        {
            public int Index { set; get; }
            public long TotalWeight { set; get; }
            public long TotalValue { get; set; }
            public Total(int Index, long TotalWeight, long TotalValue)
            {
                this.Index = Index;
                this.TotalWeight = TotalWeight;
                this.TotalValue = TotalValue;
            }
        }
    
    
    
    
        public class Chromosome
        {
            private bool[] _GeneList = new bool[APP.GoodsNumber];
            public bool[] GeneList
            {
                get
                {
                    return this._GeneList;
                }
            }
            public Chromosome()
            {
                for (int i = 0; i < APP.GoodsNumber; ++i)
                {
                    this._GeneList[i] = ((APP.Rd.Next() % 2) == 0);
                }
            }
            public Chromosome(Chromosome Father, Chromosome Mother)
            {
                int CutPoint = (APP.Rd.Next() % (APP.GoodsNumber - 1)) + 1;
                Array.Copy(Father._GeneList, 0, this._GeneList, 0, CutPoint);
                Array.Copy(Mother._GeneList, CutPoint, this._GeneList, CutPoint, APP.GoodsNumber - CutPoint);
                if ((APP.Rd.Next() % APP.Mutation) == 0)
                {
                    var MutationIndexList = APP.RandomSelect(APP.MutationNumber);
                    foreach (var Index in MutationIndexList)
                    {
                        this._GeneList[Index] = !this._GeneList[Index];
                    }
                }
            }
        }
    
    
    
    
        public class Population
        {
            private Chromosome[] _ChromosomeList = new Chromosome[APP.PopulationSize];
            public Chromosome[] ChromosomeList
            {
                get
                {
                    return this._ChromosomeList;
                }
            }
    
            private Total Test(int Index, Chromosome pChromosome, Goods[] pGoodsList)
            {
                long WeightSum = 0;
                long ValueSum = 0;
                int i = 0;
                foreach (var BValue in pChromosome.GeneList)
                {
                    if (BValue)
                    {
                        WeightSum += pGoodsList[i].Weight;
                        ValueSum += pGoodsList[i].Value;
                    }
                    ++i;
                }
                return new Total(Index, WeightSum, ValueSum);
            }
    
    
    
            public Population()
            {
                for (int i = 0; i < APP.PopulationSize; ++i)
                {
                    this._ChromosomeList[i] = new Chromosome();
                }
            }
    
    
            /// <summary>
            /// 随机选取一个繁殖对象
            /// </summary>
            /// <returns></returns>
            public int Select()
            {
                for (int i = 0; i < APP.PopulationSize; ++i)
                {
                    if (APP.Rd.Next() % 2 == 0)
                    {
                        return i;
                    }
                }
                return APP.PopulationSize - 1;
            }
            /// <summary>
            /// 随机选取两个不同的繁殖对象
            /// </summary>
            /// <param name="Index1"></param>
            /// <param name="Index2"></param>
            public void SelectDouble(out int Index1, out int Index2)
            {
                int I1 = -1, I2 = -1;
                while (I1 == I2)
                {
                    I1 = Select();
                    I2 = Select();
                }
                Index1 = I1;
                Index2 = I2;
            }
    
            /// <summary>
            /// 总群演化方法
            /// </summary>
            /// <param name="pBag">背包</param>
            /// <param name="pGoodsList">商品清单</param>
            /// <returns></returns>
            public Total[] Evolution(Bag pBag, Goods[] pGoodsList)
            {
                Total[] TotalList = new Total[this.ChromosomeList.Count()];
                for (int i = 0; i < this.ChromosomeList.Count(); ++i)
                {
                    TotalList[i] = Test(i, this.ChromosomeList[i], pGoodsList);
                }
                var OkList = TotalList.Where(p => p.TotalWeight <= pBag.Size).OrderByDescending(p => p.TotalValue);
                var OutList = TotalList.Where(p => p.TotalWeight > pBag.Size).OrderByDescending(p =>
                {
                    double BaseA = (double)p.TotalValue / p.TotalWeight;
                    double BaseB = ((double)pBag.Size * pBag.Size) / ((double)p.TotalWeight * p.TotalWeight);
                    return BaseA * BaseB;
                });
    
                var NewList = OkList.Concat(OutList).ToArray();
                var SubChromosomeList = new Chromosome[APP.PopulationSize];
    
                int FatherIndex;
                int MotherIndex;
                SelectDouble(out FatherIndex, out MotherIndex);
                var Father = this.ChromosomeList[NewList[FatherIndex].Index];
                var Mother = this.ChromosomeList[NewList[MotherIndex].Index];
    
                for (int i = 0; i < SubChromosomeList.Count(); ++i)
                {
                    if (i % 2 == 0)
                    {
                        SubChromosomeList[i] = new Chromosome(Father, Mother);
                    }
                    else
                    {
                        SubChromosomeList[i] = new Chromosome(Mother, Father);
                        SelectDouble(out FatherIndex, out MotherIndex);
                        Father = this.ChromosomeList[TotalList[FatherIndex].Index];
                        Mother = this.ChromosomeList[TotalList[MotherIndex].Index];
                    }
                }
    
                this._ChromosomeList = SubChromosomeList;
    
                return NewList;
            }
        }
    
    
        public class APP
        {
            //伪随机数产生器
            public static Random Rd = new Random();
            //货物个数,对应染色体基因长度
            public static int GoodsNumber = 200;
            //突变比率倒数
            public static int Mutation = 10;
            //突变基因数量
            public static int MutationNumber = 2;
            //种群大小
            public static int PopulationSize = 1000;
    
            /// <summary>
            /// 从列表之中随机选取一定数量的元素
            /// </summary>
            /// <typeparam name="T">类型</typeparam>
            /// <param name="pList">源列表</param>
            /// <param name="pLen">随机选取的元素列表长度</param>
            /// <returns></returns>
            public static List<T> GetRandomList<T>(IEnumerable<T> pList, int pLen)
            {
                if (pLen > pList.Count())
                {
                    pLen = pList.Count();
                }
                List<T> TmpList = pList.ToList<T>();
                List<T> DstList = new List<T>();
                for (int i = 0; i < pLen && TmpList.Count() > 1; ++i)
                {
                    int Index = APP.Rd.Next() % TmpList.Count();
                    DstList.Add(TmpList[Index]);
                    TmpList.RemoveAt(Index);
                }
                return DstList;
            }
            /// <summary>
            /// 随机选取一定数量的Index序列
            /// </summary>
            /// <param name="Num">数量</param>
            /// <returns></returns>
            public static List<int> RandomSelect(int Num)
            {
                int[] NumList = new int[APP.GoodsNumber];
                for (int i = 0; i < APP.GoodsNumber; ++i)
                {
                    NumList[i] = i;
                }
                return GetRandomList<int>(NumList, Num);
            }
    
            public APP()
            {
                #region 初始化背包与货物列表
                Bag MyBag = new Bag(10000);
                Goods[] GoodsList = new Goods[APP.GoodsNumber];
                for (int i = 0; i < GoodsList.Count(); ++i)
                {
                    GoodsList[i] = new Goods();
                }
                #endregion
    
                #region 创建总群与进行演化
                Population iPopulation = new Population();
                Total MaxTotal = null;
                while (true)
                {
                    var Fst = iPopulation.Evolution(MyBag, GoodsList).First();
                    if (MaxTotal == null)
                    {
                        MaxTotal = Fst;
                    }
                    else
                    {
                        if (Fst.TotalValue > MaxTotal.TotalValue)
                        {
                            MaxTotal = Fst;
                        }
                    }
                    //这里没有保存染色体,仅仅是取出当前总群的最优结果显示
                    Console.WriteLine("Value: " + MaxTotal.TotalValue + "  Weight: " + MaxTotal.TotalWeight);
                }
                #endregion
            }
        }
    
    
    
        public class Program
        {
            static void Main(string[] args)
            {
                APP App = new APP();
            }
        }
    }
    

      

  • 相关阅读:
    javascript计算两个时间差
    angular 倒计时15 minute的方法封装
    一个页面多个倒计时的封装
    网站倒计时
    angularjs定时任务的设置与清除
    浏览器Event Loop 是个什么鬼
    一个图片测试的小网站:dummyimage.com
    在vscode 一行的末尾按下tab键 快速生成代码 很爽
    VSCODE 快捷键
    weex 在iOS 平台上的整合
  • 原文地址:https://www.cnblogs.com/jimaojin/p/7015591.html
Copyright © 2011-2022 走看看