private void PerformKMeans() { stationList.Clear(); int numStations = int.Parse(toolStripComboBoxStations.SelectedItem.ToString()); KMeansResults <OHCAEvent> stations = KMeans.Cluster <OHCAEvent>(eventList.ToArray(), numStations, 100); double[][] results = stations.Means.Clone() as double[][]; for (int j = 0; j < numStations; j++) { stationList.Add(new Station(results[j][0], results[j][1], 1)); } /* * Find the best number of stations for the given budget * * int budget = int.Parse(toolStripComboBoxBudget.SelectedItem.ToString()); * double maxSurvivalRate = 0.0; * * for (int i = 1; i <= budget / (Utils.DRONE_PRICE + Utils.STATION_PRICE); i++) * { * KMeansResults<OHCAEvent> stations = KMeans.Cluster<OHCAEvent>(eventList.ToArray(), i, 100); * List<Station> tempStationList = new List<Station>(); * double[][] results = stations.Means.Clone() as double[][]; * int numStations = results.Length; * int numDrones = (budget - Utils.STATION_PRICE * numStations) / Utils.DRONE_PRICE; * int fewer = numDrones / numStations; * int remainder = numDrones % numStations; * for (int j = 0; j < numStations; j++) * { * tempStationList.Add(new Station(results[j][0], results[j][1], fewer + (j < remainder ? 1 : 0))); * } * * Simulator tempSimulator = new Simulator(); * tempSimulator.Simulate(tempStationList, eventGrid); * double survivalRate = tempSimulator.GetExpectedSurvivalRate(); * * if (survivalRate > maxSurvivalRate) * { * maxSurvivalRate = survivalRate; * stationList.Clear(); * * foreach(Station s in tempStationList) * { * stationList.Add(s); * } * } * } */ placedStations = true; }
public List <RubisStation> Calculate(List <OHCAEvent> eventList, int budget) { List <RubisStation> prevStationList = new List <RubisStation>(); List <RubisStation> nextStationList; double epsilonTemp = 0.1; double alpha = 0.995; double bestSurvivalRate = 0.0; int tempBudget; int maxStations = (int)(budget / (Utils.STATION_PRICE + Utils.DRONE_PRICE)); //for (int stations = 1; stations <= maxStations; stations++) int stations = 16; tempBudget = budget; // Step 1. Finds initial stations with a drone using K-Means tempBudget = tempBudget - (stations * (Utils.STATION_PRICE + Utils.DRONE_PRICE)); KMeansResults <OHCAEvent> kMeansStations = KMeans.Cluster <OHCAEvent>(eventList.ToArray(), stations, Utils.KMEANS_ITERATION_COUNT); prevStationList.Clear(); foreach (double[] d in kMeansStations.Means) { prevStationList.Add(new RubisStation(d[0], d[1], 2)); } // Step 2. Assigns remaining drones to busy stations /*int remainingDrones = (int)(tempBudget / Utils.DRONE_PRICE); * while (remainingDrones > 0) * { * int mostBusyStationIndex = getIndexOfMostBusyStation(prevStationList); * prevStationList[mostBusyStationIndex].droneList.Add(new Drone(prevStationList[mostBusyStationIndex].stationID)); * remainingDrones--; * } */ // Step 4. Simulated Annealing double currentTemp = 100.0; int iteration = 0; double prevSurvivalRate = GetOverallSurvivalRate(ref prevStationList); double delta = 0.0; double nextSurvivalRate = 0.0; while (currentTemp > epsilonTemp) { iteration++; // Near search using local optimization nextStationList = MoveOneStepToBestDirection(prevStationList, prevSurvivalRate); nextSurvivalRate = GetOverallSurvivalRate(ref nextStationList); delta = nextSurvivalRate - prevSurvivalRate; if (delta > 0) { CloneList(nextStationList, prevStationList); prevSurvivalRate = nextSurvivalRate; } else { // Even if worst, choose it randomly according to the current temperature double probility = new Random().NextDouble(); if (probility < Math.Exp(-delta / currentTemp)) { // Far search using random placement nextStationList = FindRandomStationPlacement(prevStationList, 0); CloneList(nextStationList, prevStationList); prevSurvivalRate = GetOverallSurvivalRate(ref prevStationList); if (prevSurvivalRate < bestSurvivalRate * 0.9) //double r = new Random().NextDouble(); //if (r < 0.1) { /* * kMeansStations = KMeans.Cluster<OHCAEvent>(eventList.ToArray(), stations, new Random().Next(50, 100)); * foreach (double[] d in kMeansStations.Means) * { * prevStationList.Add(new RubisStation(d[0], d[1], 2)); * }*/ Random rand = new Random(); bool okay = false; while (!okay) { int pos = rand.Next(0, 990000); kMeansStations = KMeans.Cluster <OHCAEvent>(simulator.GetSimulatedEvents().GetRange(pos, 10000).ToArray(), stations, Utils.KMEANS_ITERATION_COUNT); okay = true; foreach (double[] d in kMeansStations.Means) { if (d[0] == 0.0 || d[1] == 0.0) { okay = false; break; } } } prevStationList.Clear(); foreach (double[] d in kMeansStations.Means) { prevStationList.Add(new RubisStation(d[0], d[1], 2)); } /* * remainingDrones = (int)(tempBudget / Utils.DRONE_PRICE); * while (remainingDrones > 0) * { * int mostBusyStationIndex = getIndexOfMostBusyStation(prevStationList); * prevStationList[mostBusyStationIndex].droneList.Add(new Drone(prevStationList[mostBusyStationIndex].stationID)); * remainingDrones--; * } */ prevSurvivalRate = GetOverallSurvivalRate(ref prevStationList); } } } // Keep the best solution if (prevSurvivalRate > bestSurvivalRate) { CloneList(prevStationList, stationList); bestSurvivalRate = prevSurvivalRate; } // Cool-down currentTemp *= alpha; Console.WriteLine("[" + iteration + "] Stations = " + stations + ", Temp.: " + String.Format("{0:0.000000000000}", currentTemp) + "℃ " + "Best = " + String.Format("{0:0.000000}", (bestSurvivalRate * 100)) + "% " + "Current = " + String.Format("{0:0.000000}", (prevSurvivalRate * 100)) + "%"); } return(stationList); }