// 选择用于交叉的个体,确保最差的个体不会进来 private static GiftTicketIndividual TournamentSelection(GiftTicketPopulation pop) { GiftTicketPopulation tournament = new GiftTicketPopulation(tournamentSize, false); for (int i = 0; i < tournamentSize; i++) { int randomId = (int)(new Random().NextDouble() * pop.Size()); tournament.SaveIndividual(i, pop.GetIndividual(randomId)); } GiftTicketIndividual fittest = tournament.GetFittest(); return(fittest); }
public GiftTicketIndividual GetFittest() { GiftTicketIndividual fittest = individuals[0]; // 取得适应度最高的个体作为种群的适应度 for (int i = 0; i < Size(); i++) { if (fittest.GetFitness() <= GetIndividual(i).GetFitness()) { fittest = GetIndividual(i); } } return(fittest); }
// 建立一个总群 public GiftTicketPopulation(int populationSize, bool initialise) { individuals = new GiftTicketIndividual[populationSize]; // 初始化种群 if (initialise) { // 建立每一个个体 for (int i = 0; i < Size(); i++) { GiftTicketIndividual newIndividual = new GiftTicketIndividual(); newIndividual.GenerateIndividual(GiftTicketAlgorithm.RetailDetails, GiftTicketAlgorithm.Tickets); SaveIndividual(i, newIndividual); } } }
// 计算某一个个体的适应度,最重要的地方 public static int GetFitness(GiftTicketIndividual individual) { int fitness = 0; // 个体和候选解比较,约接近候选集,适应度越高 for (int i = 0; i < individual.Size(); i++) {//所有优惠总和 fitness += individual.GetGene(i).DiscountMoney(); //截止日期越前越优先使用 if (individual.GetGene(i).Ticket != null) { TimeSpan ts = individual.GetGene(i).Ticket.ExpiredDate - DateTime.Now; //这个影响比较大,暂时不计算过期时间 // fitness -= ts.Days; } } return(fitness); }
// 进化一个种群 public static GiftTicketPopulation EvolvePopulation(GiftTicketPopulation pop) { GiftTicketPopulation newPopulation = new GiftTicketPopulation(pop.Size(), false); // 保留最优秀的个体 if (elitism) { newPopulation.SaveIndividual(0, pop.GetFittest()); } // 交叉种群 int elitismOffset; if (elitism) { elitismOffset = 1; } else { elitismOffset = 0; } // 交叉产生新的个体 for (int i = elitismOffset; i < pop.Size(); i++) { // Console.WriteLine("交叉产生新个体"); //确保不要把最差的个体选进来 GiftTicketIndividual indiv1 = TournamentSelection(pop); GiftTicketIndividual indiv2 = TournamentSelection(pop); GiftTicketIndividual newIndiv = Crossover(indiv1, indiv2); newPopulation.SaveIndividual(i, newIndiv); } // 变异 for (int i = elitismOffset; i < newPopulation.Size(); i++) { Mutate(newPopulation.GetIndividual(i)); } return(newPopulation); }
// 变异 private static void Mutate(GiftTicketIndividual indiv) { // Console.WriteLine("变异"); // Loop through genes for (int i = 0; i < indiv.Size(); i++) { if (new Random().NextDouble() <= mutationRate) { //从剩余的优惠券中,随机一个优惠券 GiftTicketMatch gene = indiv.GetGene(i); GiftTicket ticket = null; if (indiv.tickets.Count > 0) { Random random = new Random(GetRandomSeed()); int pickTicket = random.Next(0, indiv.tickets.Count); // int pickTicket = (int)(new Random().NextDouble() * indiv.tickets.Count); ticket = indiv.tickets[pickTicket]; indiv.SetMatch(i, gene, ticket); } } } }
// 交叉 private static GiftTicketIndividual Crossover(GiftTicketIndividual indiv1, GiftTicketIndividual indiv2) { // Console.WriteLine("交叉"); GiftTicketIndividual newSol = new GiftTicketIndividual(); newSol.RetailsOrg = GiftTicketAlgorithm.RetailDetails; newSol.TicketsOrg = GiftTicketAlgorithm.Tickets; // Loop through genes for (int i = 0; i < indiv1.Size(); i++) { // 以一定概率交叉,如果优惠券被占用了???那么交叉完了之后这个优惠券就变成空? if (new Random().NextDouble() <= uniformRate) { //检查优惠券是否被占用?如果被占用是否还有可以替换的优惠券使用?有就替换掉? newSol.SetGene(i, indiv1.GetGene(i)); } else { newSol.SetGene(i, indiv2.GetGene(i)); } } return(newSol); }
// Save individual public void SaveIndividual(int index, GiftTicketIndividual indiv) { individuals[index] = indiv; }