首页 > 代码库 > CSharp遗传算法求解背包问题

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 = http://www.mamicode.com/APP.Rd.Next() % 1000 + 50;"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();
        }
    }
}

  

CSharp遗传算法求解背包问题