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();
        }
    }
}

  

时间: 2024-10-21 18:16:27

CSharp遗传算法求解背包问题的相关文章

基于遗传算法求解TSP问题(Java界面)

近期为做展示,改写了一个遗传算法求TSP的Java界面版,思路代码和 http://blog.csdn.net/wangqiuyun/article/details/12838903 这篇文章思路是一样的,追加了Java用Graphics画点及画线做路径展示,展示部分做得比較粗糙,须要的拿走,效果图例如以下. 下载地址:http://download.csdn.net/detail/wangqiuyun/7406201 另C#界面版:http://blog.csdn.net/wangqiuyun

利用回溯法求解背包问题

最近看完了利用回溯法求八皇后问题,最后成功求解到92种解法,然后在看利用贪心求解背包问题,突然想到其实也可以利用回溯法求解背包问题,本质上回溯法是一个穷举的方式在求. 回溯法求解出的结果肯定是正确的,这也可以验证自己所写的贪心算法的正确性. 问题描诉: 设定Wmax为最大重量,W[](0~n-1)为编号0~n-1的货物重量,V[](0~n-1)为其价值,x[]为其中解, 在wn=ΣXi*Wi<Wmax的条件下,求Vmax=ΣXi*Vi. 代码如下: //全局变量最大价值int maxvalue=

贪心法求解背包问题

#include<stdio.h> struct A{ double w; double v; double xingjiabi; }a[100],p; void QuickSort(A a[],int numsize) { int i=0,j=numsize-1; A p=a[0]; if(numsize>1) { while(i<j) { for(;j>i;j--) if(a[j].xingjiabi<p.xingjiabi) { a[i]=a[j]; break;

遗传算法求解TSP问题

遗传算法是一种启发式搜索,属于进化算法的一种.它最初是人们根据自然界对物种的自然选择和遗传规律而设计的.它模拟自然界物种的自然选择.遗传和变异等,对一个种群的基因进行改良. 遗传算法需要设置交叉概率.变异概率和迭代次数等参数,且算法的收敛性受其参数设置影响较大. 遗传算法中把每一个候选解看做是一个个体,个体组成的集合看作是一个种群.遗传算法通过对每个解进行二进制编码把每个解转化为0-1字符串,其中每一个位叫做一个基因.不同基因的组合构成的个体的表现型也不同.它从一个初始种群开始,经过N次迭代最终

遗传算法求解最优值

1.遗传算法介绍 遗传算法,模拟进化论的自然选择和生物进化构成的计算模型,一种不断选择优良个体的算法.谈到遗传,想想自然界动物遗传是怎么来的,自然主要过程包括染色体的选择,交叉,变异,这些操作后,保证了以后的个基本上是最优的,那么以后再继续迭代这样下去,就可以一直最优了. 2.解决的问题 遗传算法能解决的问题很多了,但是遗传算法主要还是解决优化类问题,尤其是那种不能直接解出来的很复杂的问题,而实际情况通常也是这样的. 本部分主要为了了解遗传算法的应用,选择一个复杂的二维函数来进行遗传算法优化,函

遗传算法求解TSP源码及解析

1.算法效果 图 1?1算法效果1 图 1?2算法效果2 2.原理说明 TSP问题是指假设有一个旅行商人要拜访n个城市,他必须选择所要走的路径,路径的限制是每个城市只能拜访一次,而且最后要回到原来出发的城市.路径的选择目标是要求得的路径路程为所有路径之中的最小值.本文使用遗传算法解决att30问题,即30个城市的旅行商问题. 旅行商问题是一个经典的组合优化问题.一个经典的旅行商问题可以描述为:一个商品推销员要去若干个城市推销商品,该推销员从一个城市出发,需要经过所有城市后,回到出发地.应如何选择

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

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

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

上篇初识遗传算法讲述了遗传算法的基本思想,这篇博客就用遗传算法求解方程. 具体的如下: 求解方程 -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

0/1背包问题的动态规划法求解 —— Java 实现

0/1背包问题的动态规划法求解,前人之述备矣,这里所做的工作,不过是自己根据理解实现了一遍,主要目的还是锻炼思维和编程能力,同时,也是为了增进对动态规划法机制的理解和掌握. 值得提及的一个问题是,在用 JAVA 实现时, 是按算法模型建模,还是用对象模型建模呢? 如果用算法模型,那么 背包的值.重量就直接存入二个数组里:如果用对象模型,则要对背包以及背包问题进行对象建模.思来想去,还是采用了对象模型,尽管心里感觉算法模型似乎更好一些.有时确实就是这样,对象模型虽然现在很主流,但也不是万能的,采用