Beispiel #1
0
 // Check if crossover points are good
 private bool GoodCrossover(int split_1_F, int split_1_M, int split_2_F, int split_2_M, EAPath Son, EAPath Daughter, bool blnTwoCommonNodes)
 {
     if (blnTwoCommonNodes)
     {
         if (ValidCrossover(split_1_F, Son, 2)               // First crossover point for Son
             && ValidCrossover(split_1_F, Son, 1)            // First crossover point for Son
             && ValidCrossover(split_1_M, Daughter, 2)       // First crossover point for Daughter
             && ValidCrossover(split_1_M, Daughter, 1)       // First crossover point for Daughter
             && ValidCrossover(split_1_F + split_2_M - split_1_M, Son, 2)        // Second crossover point for Son
             && ValidCrossover(split_1_F + split_2_M - split_1_M, Son, 1)        // Second crossover point for Son
             && ValidCrossover(split_1_M + split_2_F - split_1_F, Daughter, 2)   // Second crossover point for Daughter
             && ValidCrossover(split_1_M + split_2_F - split_1_F, Daughter, 1))  // Second crossover point for Daughter
         {
             // Both crossover points are good
             return true;
         }
         else
         {
             // Some crossover point is bad
             return false;
         }
     }
     else
     {
         if (ValidCrossover(split_1_F, Son, 2)           // First crossover point for Son
             && ValidCrossover(split_1_F, Son, 1)        // First crossover point for Son
             && ValidCrossover(split_1_M, Daughter, 2)   // First crossover point for Daughter
             && ValidCrossover(split_1_M, Daughter, 1))  // First crossover point for Daughter
         {
             // First crossover is good
             return true;
         }
         else
         {
             // First crossover is bad
             return false;
         }
     }
 }
Beispiel #2
0
        // Algorithm specific implementation of the path planning
        protected override void DoPathPlanning()
        {
            // Disabled hiararchical decision making in EA. Since EA should have plenty of time.
            //if (HiararchicalSearch())
            //{
            //    return;
            //}

            DateTime startTime2 = DateTime.Now;
            // Generate initial population
            CurGeneration = CreatePopulation();
            DateTime stopTime2 = DateTime.Now;
            TimeSpan duration2 = stopTime2 - startTime2;
            double RunTime2 = duration2.TotalSeconds;
            if (ProjectConstants.DebugMode)
            {
                curRequest.SetLog("CreatePopulation took " + RunTime2 + " seconds.\n");
            }

            // Sort based on CDF. Best at the end.
            CurGeneration.Sort();
            //// Debug
            //CheckPathValidity(CurGeneration, "After CreatePopulation()");

            // Remaining population size (e.g. 100-3=97)
            PRemain = ProjectConstants.EA_Population - ProjectConstants.EA_BestToKeep;

            // What's the best we have so far?
            CDF = CurGeneration[CurGeneration.Count - 1].CDF;
            Path = new List<Point>();
            Path.AddRange(CurGeneration[CurGeneration.Count - 1].Path);

            // Prepare lists to store improvements
            List<double> Improvement = new List<double>();
            Improvement.Add(0);
            List<double> RememberCDF = new List<double>();
            RememberCDF.Add(CurGeneration[CurGeneration.Count - 1].CDF);

            startTime2 = DateTime.Now;
            // Iterate until converge or until certain number of iterations
            int count = 1;
            double epsilon = 1;
            while (epsilon > 0 && count < ProjectConstants.EA_Maximum_Run)
            {
                // If we already have the path, then no need to continue
                if (Math.Abs(CDF - Efficiency_UB) < 0.001)
                {
                    break;
                }

                // Create a new generation

                // 0. Keep the best three to mid generation
                // (First three in new generation are the best three from last generation)
                NewGeneration = CurGeneration.GetRange(PRemain, ProjectConstants.EA_BestToKeep);
                //// Debug
                //CheckPathValidity(NewGeneration, "After Newgeneration keep best");

                // 1. Select based on replace rate
                SelectPopulation();
                //// Debug
                //CheckPathValidity(NewGeneration, "After SelectPopulation()");

                // 2. Crossover based on crossover rate
                Crossover();
                //// Debug
                //CheckPathValidity(NewGeneration, "After Crossover()");

                // 3. Add best to keep to end of list and don't mutate those
                for (int i = 0; i < ProjectConstants.EA_BestToKeep; i++)
                {
                    EAPath eap = new EAPath();
                    eap.CDF = NewGeneration[i].CDF;
                    eap.DirPath.AddRange(NewGeneration[i].DirPath);
                    eap.Path.AddRange(NewGeneration[i].Path);
                    NewGeneration.Add(eap);
                }
                //// Debug
                //CheckPathValidity(NewGeneration, "After add best 3 to end");

                // 4. Mutate based on mutate rate
                Mutate();
                //// Debug
                //CheckPathValidity(NewGeneration, "After Mutate()");

                // 5. Evaluate
                EvaluateFitness();
                NewGeneration.Sort();
                //// Debug
                //CheckPathValidity(NewGeneration, "After EvaluateFitness()");

                // 6. Update
                CurGeneration.Clear();
                CurGeneration.AddRange(NewGeneration.GetRange(NewGeneration.Count - ProjectConstants.EA_Population, ProjectConstants.EA_Population));
                //// Debug
                //CheckPathValidity(CurGeneration, "After generating new CurGeneration");

                // 7. Remember best and record improvement
                RememberCDF.Add(CurGeneration[ProjectConstants.EA_Population - 1].CDF);
                Improvement.Add(CurGeneration[ProjectConstants.EA_Population - 1].CDF - CDF);
                CDF = CurGeneration[ProjectConstants.EA_Population - 1].CDF;
                Path = new List<Point>();
                Path.AddRange(CurGeneration[ProjectConstants.EA_Population - 1].Path);
                //// Debug
                //CheckPathValidity(NewGeneration, "After remember best and record improvement");

                if (Improvement.Count < ProjectConstants.EA_Minimum_Run)
                {
                    epsilon = 1;
                }
                else
                {
                    epsilon = 0;
                    for (int i = 0; i < ProjectConstants.EA_Epsilon_Run; i++)
                    {
                        epsilon += Improvement[Improvement.Count - 1 - i];
                    }
                    epsilon = epsilon / ProjectConstants.EA_Epsilon_Run;
                }
                //// Debug
                //CheckPathValidity(NewGeneration, "After computing epsilon");

                // 7. Increase counter
                count++;
            }

            // Evolution completed...
            Path = new List<Point>();
            Path.AddRange(CurGeneration[CurGeneration.Count - 1].Path);

            // Report how many iterations
            if (ProjectConstants.DebugMode)
            {
                curRequest.SetLog("Algorithm ran " + count.ToString() + " iterations.\n");
            }

            // Record EA time
            stopTime2 = DateTime.Now;
            duration2 = stopTime2 - startTime2;
            RunTime2 = duration2.TotalSeconds;

            if (ProjectConstants.DebugMode)
            {
                curRequest.SetLog("EA took " + RunTime2 + " seconds.\n");

                // Print out improvement log
                curRequest.SetLog("Improvement: \n");
                for (int i = 0; i < Improvement.Count; i++)
                {
                    curRequest.SetLog(Improvement[i].ToString() + " ");
                }
                curRequest.SetLog("\n");
            }

            // Cleaning up
            Improvement.Clear();
            Improvement = null;
        }
Beispiel #3
0
        // Function to actually generate seeds of various algorithms
        private bool GenerateSeeds(List<EAPath> AllPaths, PathPlanningRequest newRequest, AlgPathPlanning myAlg, int count)
        {
            for (int i = 0; i < count; i++)
            {
                switch (newRequest.AlgToUse)
                {
                    case AlgType.CC:
                        myAlg = new AlgCC(newRequest, mDist, mDiff, Efficiency_UB);
                        break;
                    case AlgType.LHCGWCONV:
                        myAlg = new AlgGlobalWarming(newRequest, ModeCount, mDist, mDiff, Efficiency_UB);
                        break;
                    case AlgType.LHCGWPF:
                        myAlg = new AlgGlobalWarming(newRequest, ModeCount, mDist, mDiff, Efficiency_UB);
                        break;
                    case AlgType.LHCRandom:
                        myAlg = new AlgLHCRandom(newRequest, mDist, mDiff, Efficiency_UB);
                        break;
                    case AlgType.Random:
                        myAlg = new AlgRandom(newRequest, mDist, mDiff, Efficiency_UB);
                        break;
                    case AlgType.TopTwoH:
                        myAlg = new AlgTopTwo(newRequest, ModeCount, mModes, mDist, mDiff, Efficiency_UB);
                        break;
                    case AlgType.TopNH:
                        myAlg = new AlgTopTwo(newRequest, ModeCount, mModes, mDist, mDiff, Efficiency_UB);
                        break;
                    default:
                        break;
                }

                DateTime startTime2 = DateTime.Now;
                myAlg.PlanPath();
                DateTime stopTime2 = DateTime.Now;
                TimeSpan duration2 = stopTime2 - startTime2;
                double RunTime2 = duration2.TotalSeconds;
                if (ProjectConstants.DebugMode)
                {
                    curRequest.SetLog("Algorithm " + newRequest.AlgToUse + " took " + RunTime2 + " seconds.\n");
                }

                EAPath eap = new EAPath();
                eap.CDF = myAlg.GetCDF();
                eap.Path.AddRange(myAlg.GetPath());
                myAlg = null;

                // Add EAPath to population
                AllPaths.Add(eap);

                // If we already have the best path, then no need to continue
                CDF = eap.CDF;
                Path = eap.Path;
                if (Math.Abs(CDF - Efficiency_UB) < 0.001)
                {
                    return true;
                }
            }
            return false;
        }
Beispiel #4
0
 // Dobule Point Crossover
 private void DoublePointCrossover(int split_1_F, int split_1_M, List<Point> Father, List<Point> Mother, int split_2_F, int split_2_M, EAPath Son, EAPath Daughter)
 {
     Son.Path.AddRange(Father.GetRange(0, split_1_F));
     Son.Path.AddRange(Mother.GetRange(split_1_M, split_2_M - split_1_M));
     Son.Path.AddRange(Father.GetRange(split_2_F, Father.Count() - split_2_F));
     Daughter.Path.AddRange(Mother.GetRange(0, split_1_M));
     Daughter.Path.AddRange(Father.GetRange(split_1_F, split_2_F - split_1_F));
     Daughter.Path.AddRange(Mother.GetRange(split_2_M, Mother.Count() - split_2_M));
 }
Beispiel #5
0
        // Crossover based on replacement rate
        private void Crossover()
        {
            // Generate remaining quota of the population by crossover (Divide by 2 because I am generating 2 children each time)
            for (int k = 0; k < Convert.ToInt16(ProjectConstants.EA_ReplacementRate * ProjectConstants.EA_Population / 2); k++)
            {
                // Find father and good mother
                int split_1_F, split_1_M;
                List<Point> Father, Mother;
                if (!FindFatherMother(out split_1_F, out split_1_M, out Father, out Mother))
                {
                    // Cleaning up
                    Father = null;
                    Mother = null;
                    // Did not find a good Mother
                    k--;
                    continue;
                }

                // Found a good mother that has the node
                // See if father and mother have second common node
                // And perform crossover
                int split_2_F = -1;
                int split_2_M = -1;
                EAPath Son = new EAPath();
                EAPath Daughter = new EAPath();
                bool blnTwoCommonNodes = FindSecondCommonNode(split_1_F, split_1_M, Father, Mother, ref split_2_F, ref split_2_M);
                if (blnTwoCommonNodes)
                {
                    DoublePointCrossover(split_1_F, split_1_M, Father, Mother, split_2_F, split_2_M, Son, Daughter);
                }
                else
                {
                    SinglePointCrossover(split_1_F, split_1_M, Father, Mother, Son, Daughter);
                }

                // Make sure there's no flying backward for non-copter
                if (curRequest.VehicleType != UAVType.Copter)
                {
                    bool blnGoodCrossover = GoodCrossover(split_1_F, split_1_M, split_2_F, split_2_M, Son, Daughter, blnTwoCommonNodes);
                    if (!blnGoodCrossover)
                    {
                        // Cleaning up
                        Father = null;
                        Mother = null;
                        Son = null;
                        Daughter = null;
                        // Try again
                        k--;
                        continue;
                    }
                }

                // Make sure they still fly all the way.
                // Now both children are valid paths, let's truncate or extend so they all have length T+1;
                // After crossover, if Son or Daughter becomes too long, truncate
                EAPath ShorterPath = new EAPath();
                EAPath LongerPath = new EAPath();
                TruncateLongerPath(Son, Daughter, ref ShorterPath, ref LongerPath);
                if (LongerPath.Path.Count == 0)
                {
                    // Both Son and Daughter have right length. Move on!
                    NewGeneration.Add(Son);
                    NewGeneration.Add(Daughter);
                    continue;
                }

                // After crossover, if Son or Daughter becomes too short,
                // probablistically randomly pick another path and crossover again.
                // This time only keep the longer one and then truncate.
                EAPath OldLongerPath = LongerPath;
                int index1 = -1;
                Father = ShorterPath.Path;
                if (!FindMother(index1, Father, out split_1_F, out split_1_M, out Mother))
                {
                    // Cleaning up
                    Father = null;
                    Mother = null;
                    // Did not find a good Mother
                    k--;
                    continue;
                }
                // Found a good mother that has the node
                Son = new EAPath();
                Daughter = new EAPath();
                SinglePointCrossover(split_1_F, split_1_M, Father, Mother, Son, Daughter);
                bool blnSonLonger = TruncateLongerPath(Son, Daughter, ref ShorterPath, ref LongerPath);
                EAPath NewLongerPath = LongerPath;

                // Make sure there's no flying backward for non-copter
                if (curRequest.VehicleType != UAVType.Copter)
                {
                    // Only worry about LongerPath
                    if (!blnSonLonger)
                    {
                        split_1_F = split_1_M;
                        Son = Daughter;
                    }
                    bool blnGoodCrossover = GoodCrossover(split_1_F, split_1_F, 0, 0, Son, Son, false);
                    if (!blnGoodCrossover)
                    {
                        // Cleaning up
                        Father = null;
                        Mother = null;
                        Son = null;
                        Daughter = null;
                        LongerPath = null;
                        ShorterPath = null;
                        OldLongerPath = null;
                        NewLongerPath = null;
                        // Try again
                        k--;
                        continue;
                    }
                }

                // Add new paths to new generation
                NewGeneration.Add(OldLongerPath);
                NewGeneration.Add(NewLongerPath);

                // Cleaning up
                Father = null;
                Mother = null;
                Son = null;
                Daughter = null;
                LongerPath = null;
                ShorterPath = null;
                OldLongerPath = null;
                NewLongerPath = null;
            }
        }
Beispiel #6
0
 // Simply create n copies to save time.
 private static void CreateEAPathCopies(List<EAPath> AllPaths, int n)
 {
     for (int i = 0; i < n; i++)
     {
         // Create new EAPath
         EAPath eap = new EAPath();
         eap.CDF = AllPaths[AllPaths.Count - 1].CDF;
         eap.Path.AddRange(AllPaths[AllPaths.Count - 1].Path);
         // Add EAPath to population
         AllPaths.Add(eap);
     }
 }
Beispiel #7
0
 // Check if the crossover is valid for non-copter (no flying backwards)
 private bool ValidCrossover(int split_point, EAPath Son, int i)
 {
     if (split_point != -1 && Son.Path.Count - 1 > split_point && split_point > 1)
     {
         if (!ValidMove(Son.Path[split_point - i], Son.Path[split_point - i + 1], Son.Path[split_point - i + 2]))
         {
             return false;
         }
     }
     return true;
 }
Beispiel #8
0
 // Truncate longer path and identify who is who
 private bool TruncateLongerPath(EAPath Son, EAPath Daughter, ref EAPath ShorterPath, ref EAPath LongerPath)
 {
     if (Son.Path.Count > curRequest.T + 1)
     {
         Son.Path.RemoveRange(curRequest.T + 1, Son.Path.Count - (curRequest.T + 1));
         LongerPath = Son;
         ShorterPath = Daughter;
         return true;
     }
     if (Daughter.Path.Count > curRequest.T + 1)
     {
         Daughter.Path.RemoveRange(curRequest.T + 1, Daughter.Path.Count - (curRequest.T + 1));
         LongerPath = Daughter;
         ShorterPath = Son;
         return false;
     }
     return true;
 }