static void Main(string[] args) { Console.WriteLine("Using Multi-Swarm Optimization to find optimum anti-Raid defense"); //set up SpeedSim // SpeedSimInterface.Init(); SpeedSimInterface.SetSystemsApart(20); SpeedSimInterface.SetTechs(15, 15, 13, 17, 17, 17, 12, 12, 12); //Calculate cost of defense units in Metal Equivalent Value terms DefenseUnitsTotalCosts[0] = (int)CostRL.Zip(ResourceValueRatios, (CostRL, ResourceValueRatios) => CostRL * ResourceValueRatios).Sum(); DefenseUnitsTotalCosts[1] = (int)CostLL.Zip(ResourceValueRatios, (CostLL, ResourceValueRatios) => CostLL * ResourceValueRatios).Sum(); DefenseUnitsTotalCosts[2] = (int)CostHL.Zip(ResourceValueRatios, (CostHL, ResourceValueRatios) => CostHL * ResourceValueRatios).Sum(); DefenseUnitsTotalCosts[3] = (int)CostGC.Zip(ResourceValueRatios, (CostGC, ResourceValueRatios) => CostGC * ResourceValueRatios).Sum(); DefenseUnitsTotalCosts[4] = (int)CostIC.Zip(ResourceValueRatios, (CostIC, ResourceValueRatios) => CostIC * ResourceValueRatios).Sum(); DefenseUnitsTotalCosts[5] = (int)CostPT.Zip(ResourceValueRatios, (CostPT, ResourceValueRatios) => CostPT * ResourceValueRatios).Sum(); //set maximum number of each type of defense unit for (int defenseIdx = 0; defenseIdx < DefenseDims; ++defenseIdx) { DefenseUnitsMaximums[defenseIdx] = (int)(DefenseValue / (ulong)DefenseUnitsTotalCosts[defenseIdx]); } //Calculate cost of ship units in Metal Equivalent Value terms FleetUnitsTotalCosts[0] = (int)DataSC.Zip(ResourceValueRatiosFleet, (DataSC, ResourceValueRatiosFleet) => DataSC * ResourceValueRatiosFleet).Sum(); FleetUnitsTotalCosts[1] = (int)DataLC.Zip(ResourceValueRatiosFleet, (DataLC, ResourceValueRatiosFleet) => DataLC * ResourceValueRatiosFleet).Sum(); FleetUnitsTotalCosts[2] = (int)DataLF.Zip(ResourceValueRatiosFleet, (DataLF, ResourceValueRatiosFleet) => DataLF * ResourceValueRatiosFleet).Sum(); FleetUnitsTotalCosts[3] = (int)DataHF.Zip(ResourceValueRatiosFleet, (DataHF, ResourceValueRatiosFleet) => DataHF * ResourceValueRatiosFleet).Sum(); FleetUnitsTotalCosts[4] = (int)DataC.Zip(ResourceValueRatiosFleet, (DataC, ResourceValueRatiosFleet) => DataC * ResourceValueRatiosFleet).Sum(); FleetUnitsTotalCosts[5] = (int)DataBS.Zip(ResourceValueRatiosFleet, (DataBS, ResourceValueRatiosFleet) => DataBS * ResourceValueRatiosFleet).Sum(); FleetUnitsTotalCosts[6] = (int)DataB.Zip(ResourceValueRatiosFleet, (DataB, ResourceValueRatiosFleet) => DataB * ResourceValueRatiosFleet).Sum(); FleetUnitsTotalCosts[7] = (int)DataD.Zip(ResourceValueRatiosFleet, (DataD, ResourceValueRatiosFleet) => DataD * ResourceValueRatiosFleet).Sum(); FleetUnitsTotalCosts[8] = (int)DataBC.Zip(ResourceValueRatiosFleet, (DataBC, ResourceValueRatiosFleet) => DataBC * ResourceValueRatiosFleet).Sum(); Array.Copy(FleetUnitsTotalCosts, 0, UnitTotalCosts, 0, 6); UnitTotalCosts[6] = (int)(10000 * 1 + 20000 * 1.66667 + 10000 * 2.5); UnitTotalCosts[7] = (int)(10000 * 1 + 6000 * 1.66667 + 2000 * 2.5); UnitTotalCosts[8] = (int)(0 * 1 + 1000 * 1.66667 + 0 * 2.5); UnitTotalCosts[9] = FleetUnitsTotalCosts[6]; UnitTotalCosts[10] = (int)(0 * 1 + 2000 * 1.66667 + 500 * 2.5); UnitTotalCosts[11] = FleetUnitsTotalCosts[7]; UnitTotalCosts[12] = (int)(5000000 * 1 + 4000000 * 1.66667 + 1000000 * 2.5); UnitTotalCosts[13] = FleetUnitsTotalCosts[8]; Array.Copy(DefenseUnitsTotalCosts, 0, UnitTotalCosts, 14, 6); UnitTotalCosts[20] = (int)(10000 * 1 + 10000 * 1.66667 + 0 * 2.5); UnitTotalCosts[21] = (int)(50000 * 1 + 50000 * 1.66667 + 0 * 2.5); Defense bestDefense = Solve(); Console.WriteLine("\nDone"); Console.WriteLine("\nBest solution found: "); ShowVector(bestDefense.DefenseCounts, true); Console.WriteLine("\nEnd multi-swarm optimization demo\n"); }
//Measures the fleet error (should change term, since we are now maximizing error(profit)) public double EvaluateFleet(int numTrials = 1) { SpeedSimInterface.Reset(); //This was not working, was unable to find a solution, currently these values are hardcoded into speedsimlib.dll //SpeedSimInterface.SetLoot(new int[] { 8767680, 2598864, 1507632 }); SpeedSimInterface.SetSystemsApart(20); //convert the fleet ship counts from the 9-element array of viable ships to the 14-element array needed by SpeedSimLib List <int> fleetList = fleet.ShipCounts.ToList(); //insert Deathstar slot fleetList.Insert(8, 0); //insert Solar Sat slot fleetList.Insert(7, 0); //insert colony ship, recycler, and probe slots fleetList.InsertRange(6, new int[] { 0, 0, 0 }); //convert the defense unit counts to the 21-element array needed by SpeedSim List <int> defList = targetDefense.DefenseCounts.ToList(); //add the 14 ship slots defList.InsertRange(0, new int[14]); defList[1] = 200; defList[10] = 400; defList.Add(1); //Small shield dome defList.Add(1); //Large shield dome SpeedSimInterface.SetFleetInt(fleetList.ToArray(), defList.ToArray()); SpeedSimInterface.SetTechs(15, 15, 13, 17, 17, 17, 14, 14, 14); SpeedSimInterface.Simulate(numTrials); //calculate fleet profits profits = 0; //subtract losses profits -= (SpeedSimInterface.GetAttackMetalLoss() * Program.ResourceValueRatios[0]); profits -= (SpeedSimInterface.GetAttackCrystalLoss() * Program.ResourceValueRatios[1]); profits -= (SpeedSimInterface.GetAttackDeuteriumLoss() * Program.ResourceValueRatios[2]); //subtract fuel profits -= (SpeedSimInterface.GetFuelConsumption() * Program.ResourceValueRatios[2]); //add loot (must multiply by odds of winning) double loot = (SpeedSimInterface.GetLootMetal() * Program.ResourceValueRatios[0]); loot += (SpeedSimInterface.GetLootCrystal() * Program.ResourceValueRatios[1]); loot += (SpeedSimInterface.GetLootDeuterium() * Program.ResourceValueRatios[2]); float winPercentage = SpeedSimInterface.GetAttackWinPercent(); profits += (loot * winPercentage); //add df profits += (SpeedSimInterface.GetDebrisMetal() * Program.ResourceValueRatios[0]); profits += (SpeedSimInterface.GetDebrisCrystal() * Program.ResourceValueRatios[1]); profits += (SpeedSimInterface.GetDebrisDeuterium() * Program.ResourceValueRatios[2]); //divide by flight time to get profits per hour long flightTime = SpeedSimInterface.GetFlightTime(); double flightHours = flightTime / 3600.0; profits = (profits / flightHours); return(profits); }