public DefenseSwarm()
 {
     lBestDefense     = new Defense();
     defenseParticles = new DefenseParticle[Program.NumParticles];
     for (int defenseParticleIdx = 0; defenseParticleIdx < Program.NumParticles; ++defenseParticleIdx)
     {
         defenseParticles[defenseParticleIdx] = new DefenseParticle();
         //penalize initial errors since we aren't doing triple checking of new gBests
         defenseParticles[defenseParticleIdx].error = defenseParticles[defenseParticleIdx].pBestError *= 1.5;
         if (defenseParticles[defenseParticleIdx].error < lBestError)
         {
             lBestError = defenseParticles[defenseParticleIdx].error;
             lBestDefense.CopyDefense(defenseParticles[defenseParticleIdx].defense);
         }
     }
 }
Exemple #2
0
        ///<summary>
        /// Create and run a Fleet MSO that attempts to find the optimum fleet composition to raid this defense
        ///</summary>

        static Defense Solve()
        {
            Random rand = new Random(0);

            DefenseSwarm[] defenseSwarms = new DefenseSwarm[NumSwarms];
            for (int i = 0; i < NumSwarms; i++)
            {
                defenseSwarms[i] = new DefenseSwarm();
            }
            Defense gBestDefense = new Defense();
            double  gBestError   = double.MaxValue;

            for (int i = 0; i < NumSwarms; ++i)
            {
                if (defenseSwarms[i].lBestError < gBestError)
                {
                    gBestError = defenseSwarms[i].lBestError;
                    gBestDefense.CopyDefense(defenseSwarms[i].lBestDefense);
                }
            }


            var gBestList = new List <(int, double)>
            {
                (-1, gBestError)
            };


            int epoch = 0;

            while (epoch < MaxEpochsOuter)
            {
                ++epoch;

                if (epoch < MaxEpochsOuter)
                {
                    Console.WriteLine("Outer Epoch " + epoch + ", gBestError " + gBestError.ToString("F1"));
                }

                for (int i = 0; i < NumSwarms; ++i) // each swarm
                {
                    // Shuffle(sequence, rand); // move particles in random sequence
                    for (int j = 0; j < NumParticles; ++j) // each particle
                    {
                        //Death
                        double p1 = rand.NextDouble();
                        if (defenseSwarms[i].defenseParticles[j].consecutiveNonImproves * p1 > 20)
                        {
                            defenseSwarms[i].defenseParticles[j] = new DefenseParticle();                 // new random position
                            if (defenseSwarms[i].defenseParticles[j].error < defenseSwarms[i].lBestError) // new swarm best by luck?
                            {
                                defenseSwarms[i].lBestError = defenseSwarms[i].defenseParticles[j].error;
                                defenseSwarms[i].lBestDefense.CopyDefense(defenseSwarms[i].defenseParticles[j].defense);
                                if (defenseSwarms[i].defenseParticles[j].error < gBestError) // if a new swarm best, maybe also a new global best?
                                {
                                    //must repeat defense evaluation to avoid outlier skewing results
                                    double result1 = defenseSwarms[i].defenseParticles[j].error;
                                    double result2 = defenseSwarms[i].defenseParticles[j].EvaluateDefense();
                                    double result3 = defenseSwarms[i].defenseParticles[j].EvaluateDefense();
                                    double maxResult = new[] { result1, result2, result3 }.Max();
                                    if (maxResult < gBestError)
                                    {
                                        gBestError = maxResult;
                                        gBestDefense.CopyDefense(defenseSwarms[i].defenseParticles[j].defense);
                                    }
                                }
                            }
                        }

                        //Immigration
                        double p2 = rand.NextDouble();
                        if (p2 < ProbImmigrate)
                        {
                            int             otherSwarm    = rand.Next(0, NumSwarms);
                            int             otherParticle = rand.Next(0, NumParticles);
                            DefenseParticle tmp           = defenseSwarms[i].defenseParticles[j];
                            defenseSwarms[i].defenseParticles[j] = defenseSwarms[otherSwarm].defenseParticles[otherParticle];
                            defenseSwarms[otherSwarm].defenseParticles[otherParticle] = tmp;

                            if (defenseSwarms[i].defenseParticles[j].pBestError < defenseSwarms[otherSwarm].lBestError) // new (other) swarm best?
                            {
                                defenseSwarms[otherSwarm].lBestError = defenseSwarms[i].defenseParticles[j].pBestError;
                                defenseSwarms[otherSwarm].lBestDefense.CopyDefense(defenseSwarms[i].defenseParticles[j].defense);
                            }
                            if (defenseSwarms[otherSwarm].defenseParticles[otherParticle].pBestError < defenseSwarms[i].lBestError) // new (curr) swarm best?
                            {
                                defenseSwarms[i].lBestError = defenseSwarms[otherSwarm].defenseParticles[otherParticle].pBestError;
                                defenseSwarms[i].lBestDefense.CopyDefense(defenseSwarms[otherSwarm].defenseParticles[otherParticle].defense);
                            }
                            // not possible for a new global best
                        }

                        for (int k = 0; k < DefenseDims; ++k) // update velocity. each x position component
                        {
                            double r1 = rand.NextDouble();
                            double r2 = rand.NextDouble();
                            double r3 = rand.NextDouble();

                            defenseSwarms[i].defenseParticles[j].velocity[k]
                                = (
                                      (Inertia * defenseSwarms[i].defenseParticles[j].velocity[k])
                                      + (GravityLocal * r1 * (defenseSwarms[i].defenseParticles[j].pBestDefense.DefenseCounts[k]
                                                              - defenseSwarms[i].defenseParticles[j].defense.DefenseCounts[k])
                                         )
                                      + (GravitySwarm * r2 * (defenseSwarms[i].lBestDefense.DefenseCounts[k]
                                                              - defenseSwarms[i].defenseParticles[j].defense.DefenseCounts[k])
                                         )
                                      + (GravityGlobal * r3 * (gBestDefense.DefenseCounts[k]
                                                               - defenseSwarms[i].defenseParticles[j].defense.DefenseCounts[k])
                                         )
                                      );

                            //constrain velocities
                            //if (defenseSwarms[i].defenseParticles[j].velocity[k] < minX)
                            //    defenseSwarms[i].defenseParticles[j].velocity[k] = minX;
                            //else if (defenseSwarms[i].defenseParticles[j].velocity[k] > maxX)
                            //    defenseSwarms[i].defenseParticles[j].velocity[k] = maxX;
                        }

                        for (int k = 0; k < DefenseDims; ++k) // update position
                        {
                            defenseSwarms[i].defenseParticles[j].defense.DefenseCounts[k] += (int)defenseSwarms[i].defenseParticles[j].velocity[k];
                            // constrain all xi
                            if (defenseSwarms[i].defenseParticles[j].defense.DefenseCounts[k] < 0 ||
                                defenseSwarms[i].defenseParticles[j].defense.DefenseCounts[k] > DefenseUnitsMaximums[k])
                            {
                                defenseSwarms[i].defenseParticles[j].defense.DefenseCounts[k] = (int)(rand.NextDouble() * DefenseUnitsMaximums[k]);
                            }
                        }

                        // update error
                        defenseSwarms[i].defenseParticles[j].EvaluateDefense();

                        // check if new best error for this particle
                        if (defenseSwarms[i].defenseParticles[j].error < defenseSwarms[i].defenseParticles[j].pBestError)
                        {
                            defenseSwarms[i].defenseParticles[j].pBestError = defenseSwarms[i].defenseParticles[j].error;
                            defenseSwarms[i].defenseParticles[j].pBestDefense.CopyDefense(defenseSwarms[i].defenseParticles[j].defense);

                            if (defenseSwarms[i].defenseParticles[j].error < defenseSwarms[i].lBestError) // new swarm best?
                            {
                                defenseSwarms[i].lBestError = defenseSwarms[i].defenseParticles[j].error;
                                defenseSwarms[i].lBestDefense.CopyDefense(defenseSwarms[i].defenseParticles[j].defense);

                                if (defenseSwarms[i].defenseParticles[j].error < gBestError) // new global best?
                                {
                                    //must repeat defense evaluation to avoid outlier skewing results
                                    double result1 = defenseSwarms[i].defenseParticles[j].error;
                                    double result2 = defenseSwarms[i].defenseParticles[j].EvaluateDefense();
                                    double result3 = defenseSwarms[i].defenseParticles[j].EvaluateDefense();
                                    double maxResult = new[] { result1, result2, result3 }.Max();
                                    if (maxResult < gBestError)
                                    {
                                        gBestError = maxResult;
                                        gBestDefense.CopyDefense(defenseSwarms[i].defenseParticles[j].defense);
                                        gBestList.Add((epoch, gBestError));
                                    }
                                }
                            }
                        }
                    } // each particle
                }     // each swarm
            }         // while
            string defenseStr = String.Join(", ", gBestDefense.DefenseCounts);

            Console.WriteLine("\n****Best defense found: " + defenseStr + " ****");
            var pm = new PlotModel {
                Title = "DefenseMSO", PlotAreaBorderThickness = new OxyThickness(0)
            };
            var categoryAxis = new OxyPlot.Axes.CategoryAxis {
                AxislineStyle = LineStyle.Solid, TickStyle = TickStyle.None
            };
            var value = new List <DataPoint>();

            for (int i = 0; i < gBestList.Count; i++)
            {
                value.Add(new DataPoint(gBestList[i].Item1, gBestList[i].Item2));
            }


            pm.Axes.Add
            (
                new OxyPlot.Axes.LinearAxis
            {
                Position      = AxisPosition.Left,
                Minimum       = -Math.Abs(gBestList[0].Item2),
                Maximum       = 1.05 * Math.Abs(gBestList[gBestList.Count - 1].Item2),
                MajorStep     = Math.Abs(gBestList[0].Item2 / 10),
                MinorStep     = Math.Abs(gBestList[0].Item2 / 50),
                AxislineStyle = LineStyle.Solid,
                TickStyle     = TickStyle.Crossing,
                StringFormat  = "0,0"
            }
            );

            pm.Axes.Add
            (
                new OxyPlot.Axes.LinearAxis
            {
                Position      = AxisPosition.Bottom,
                Minimum       = -1,
                Maximum       = MaxEpochsOuter,
                MajorStep     = Program.MaxEpochsInner / 5,
                MinorStep     = Program.MaxEpochsInner / 20,
                AxislineStyle = LineStyle.Solid,
                TickStyle     = TickStyle.Outside
            }
            );


            pm.Series.Add
            (
                new OxyPlot.Series.ScatterSeries
            {
                ItemsSource  = value,
                MarkerType   = MarkerType.Circle,
                MarkerSize   = 3.0,
                MarkerFill   = OxyColors.White,
                MarkerStroke = OxyColors.Black,
                DataFieldX   = "X",
                DataFieldY   = "Y"
            }
            );

            Stream stream = File.Create("C:\\Users\\admin\\source\\repos\\SpeedSimML\\SpeedSimML\\defenseplot.pdf");
            var    pdf    = new PdfExporter();

            PdfExporter.Export(pm, stream, 400.0, 400);


            return(gBestDefense);
        }