示例#1
0
        private void OptimizeRoutes()
        {
            var itn  = 0;
            var mask = (byte)rng.Next();

            CreateGeneration();

            while (true)
            {
                progress(itn + 1);

                // 1. Objective function calculation
                Generations.ForEach(element =>
                {
                    element.ObjectiveFunctionValue = CalculateObjectiveFunction(element.Elements);
                    reporting.NextPopulation(element);
                });

                // Report this
                reporting.NextIteration();

                // 2. Check stop condition
                if (itn + 1 >= IterationCount)
                {
                    goto finish;
                }

                // 3. Selection
                var selected = Generations
                               .Select((element, index) => new { element, groupId = rng.Next(0, (int)Math.Floor(Generations.Count * 0.3d)) })
                               .GroupBy(x => x.groupId)
                               .Select(x => x.Aggregate((i1, i2) => i1.element.ObjectiveFunctionValue > i2.element.ObjectiveFunctionValue ? i1 : i2))
                               .Select(x => x.element)
                               .ToList();

                // 4. Pairing
                var pairs = new List <Population[]>();
                while (pairs.Count < Generations.Count / 2)
                {
                    var idx1 = rng.Next(0, selected.Count);
                    var idx2 = rng.Next(0, selected.Count);
                    while (idx1 != idx2)
                    {
                        idx2 = rng.Next(0, selected.Count);
                    }

                    var first  = selected[idx1];
                    var second = selected[idx2];
                    pairs.Add(new Population[] { first, second });
                }

                // 5. Crossing
                var newGeneration = new List <Population>();
                foreach (var pair in pairs)
                {
                    var first     = pair[0].Elements;
                    var second    = pair[1].Elements;
                    var newFirst  = new Population();
                    var newSecond = new Population();

                    for (int i = 0; i < first.Count(); i++)
                    {
                        var firstElement    = first[i];
                        var secondElement   = second[i];
                        var newFirstElement = new PopulationElement()
                        {
                            Plane = firstElement.Plane,
                        };
                        var newSecondElement = new PopulationElement()
                        {
                            Plane = secondElement.Plane,
                        };

                        byte cnt = 1;
                        for (int j = 0; j < firstElement.Route.Count(); j++)
                        {
                            var newFirstRouteItem  = (mask & cnt) > 1 ? firstElement.Route[j] : secondElement.Route[j];
                            var newSecondRouteItem = (mask & cnt) == 0 ? firstElement.Route[j] : secondElement.Route[j];
                            newFirstElement.Route.Add(newFirstRouteItem);
                            newSecondElement.Route.Add(newSecondRouteItem);
                            cnt <<= 1;
                        }

                        newFirst.Elements.Add(newFirstElement);
                        newSecond.Elements.Add(newSecondElement);
                    }

                    newGeneration.Add(newFirst);
                    newGeneration.Add(newSecond);
                }

                // 6. Mutation
                newGeneration.SelectMany(x => x.Elements).ForEach(x =>
                {
                    if (RngMutation())
                    {
                        var swap1 = rng.Next(0, x.Route.Count());
                        var swap2 = swap1;
                        while (swap1 == swap2)
                        {
                            swap2 = rng.Next(0, x.Route.Count());
                        }

                        x.Route.Swap(swap1, swap2);
                    }
                });

                // 7. Replace population
                if (newGeneration.Count == 0)
                {
                    newGeneration.AddRange(selected);
                }

                Generations = newGeneration;

                if (Generations.Count == 1)
                {
                    goto finish;
                }
                else if (Generations.Count == 0)
                {
                    throw new Exception("Generations count has reached 0");
                }

                itn++;
            }

finish:
            var final = Generations.OrderByDescending(x => x.ObjectiveFunctionValue).FirstOrDefault();

            CalculateObjectiveFunction(final.Elements);
            reporting.FinalSolution(final);
            reporting.NextPopulation(final);
        }