public static void correctDeltas() { for (int i = 0; i < airplanes.Count; i++) { if ((currentTime.AddMinutes(120 - modulationStep) <= airplanes[i].applicationTime) && ((currentTime.AddHours(2) > airplanes[i].applicationTime))) { if (airplanes[i].delta > 0) { runways[airplanes[i].runwayNumber].erase_plane(airplanes[i].applicationTime); arrival_queue.Add(airplanes[i]); } } else if ((airplanes[i].applicationTime.AddMinutes(airplanes[i].delta) == currentTime) && (airplanes[i].delta < 0)) { runways[airplanes[i].runwayNumber].erase_plane(airplanes[i].applicationTime); if (arrival_queue.Count == 0) { arrival_queue.Add(airplanes[i]); } else { int index = 0; while (arrival_queue[index].delta < 0) { index++; if (index == arrival_queue.Count) { break; } } arrival_queue.Insert(index, airplanes[i]); } } } // на полосах останутся только те, у кого нет задержек или о чьих задержках еще неизвестно // все, чего-то ожидающие, стоят в очереди. Прилетевшие раньше стоят в этой очереди первыми // в порядке появления, то есть выходит очередь с приоритетами // теперь мы будем идти по всей очереди, пытаясь впихнуть // сначала смотрим все досрочно прилетевшие и если сейчас их applicationTime то сажаем их как по расписанию // далее смотрим уже всю очередь по порядку, пытаясь впихнуть из них того, кто влезет, но самый длинный из возможных if (arrival_queue.Count != 0) { // сажаем самолеты из очереди, которые дождались до того, что наступил их интервал по расписанию for (int i = 0; i < arrival_queue.Count; i++) { if (arrival_queue[i].delta <= 0) // !!!!!! { if (currentTime == arrival_queue[i].applicationTime) { Airplane airplane = new Airplane(arrival_queue[i].applicationTime, arrival_queue[i].flight, arrival_queue[i].companyName, arrival_queue[i].isArriving, arrival_queue[i].timeIntervals, arrival_queue[i].runwayNumber); runways[arrival_queue[i].runwayNumber].addAirplane(airplane.applicationTime, airplane); arrival_queue.RemoveAt(i); i--; } } else { break; } } } if (arrival_queue.Count != 0) { // сажаем все самолеты из очереди, которые можем foreach (KeyValuePair <int, Runway> runway in runways) { List <KeyValuePair <DateTime, DateTime> > empties = runway.Value.get_empties(); if (empties.Count != 0) { foreach (KeyValuePair <DateTime, DateTime> interval in empties) { int adding_index = -1; for (int i = 0; i < arrival_queue.Count; i++) { if ((arrival_queue[i].applicationTime.AddMinutes(arrival_queue[i].delta) >= interval.Key) && (arrival_queue[i].applicationTime.AddMinutes(arrival_queue[i].delta + arrival_queue[i].getRequiredTimeInterval()) <= interval.Value)) { adding_index = i; } } if (adding_index != -1) { Airplane airplane = new Airplane(arrival_queue[adding_index].applicationTime.AddMinutes(arrival_queue[adding_index].delta), arrival_queue[adding_index].flight, arrival_queue[adding_index].companyName, arrival_queue[adding_index].isArriving, arrival_queue[adding_index].timeIntervals, runway.Key); runway.Value.addAirplane(airplane.applicationTime, airplane); arrival_queue.RemoveAt(adding_index); } } } } } // теперь надо проследить за увеличением дельт // у всех, кто находится в очереди, дельта увеличивается на то, насколько его время отправки с учетом дельты отличается от текущего времени //for (int i = 0; i < arrival_queue.Count; i++) //{ // arrival_queue[i].delta += modulationStep; //(int)currentTime.Subtract(arrival_queue[i].applicationTime).TotalMinutes; // airplanes[find_airplane_index(arrival_queue[i].flight)].delta = arrival_queue[i].delta; //} }
public static void generateSchedule() { // выдает только заведомо выполнимое расписание // важными являются только время подачи заявки, тип самолета и уникальный номер рейса // сначала выберем количество самолетов того типа, что занимает полосу дольше всех List <Airplane> ranges = new List <Airplane>(); DateTime time = currentTime; foreach (durations d in timeDurations) { Airplane plane1 = new Airplane(time, Convert.ToString(ranges.Count()), "", true, d); if (ranges.Count() == 0) { ranges.Add(plane1); } else { int j = 0; while ((ranges[j].isLonger(plane1)) && (j < ranges.Count())) { j++; } ranges.Insert(j, plane1); } Airplane plane2 = new Airplane(time, Convert.ToString(ranges.Count()), "", false, d); int i = 0; while (ranges[i].isLonger(plane2)) { i++; } ranges.Insert(i, plane2); } // теперь имеем отсортированный по убыванию список, содержащий все различные варианты самолетов int free_time = runwaysAmount * 24 * 60; // 24 часа List <Airplane> rand_airplanes = new List <Airplane>(); foreach (Airplane plane in ranges) { int max_frequency = free_time / plane.getRequiredTimeInterval(); int amount = rnd.Next(0, max_frequency); // рандомно решаем, сколько самолетов такого типа будет free_time -= amount * plane.getRequiredTimeInterval(); while (amount > 0) { rand_airplanes.Add(plane); amount--; } } // нашли набор самолетов, с которыми возможно составить рабочее расписание // теперь надо растолкать их по полосам List <Runway> ways = new List <Runway>(); // имеющиеся полосы for (int i = 0; i < runwaysAmount; i++) { ways.Add(new Runway()); } for (int i = 0; i < rand_airplanes.Count(); i++) { DateTime begin = new DateTime(1, 1, 1, currentTime.Hour, currentTime.Minute, 0, 0); DateTime next_day = new DateTime(1, 1, 2, currentTime.Hour, currentTime.Minute, 0, 0); DateTime end; // рандомно ищем временной интервал [begin; end) для данного самолета внутри тех 24 часов, на которых моделируем do { int mins = (rnd.Next(0, 60 * 24 / GenerateDelay.integral_step)) * GenerateDelay.integral_step; // домножаем на шаг, который есть минимальная единица измерения времени в программе (5 минут) if (mins != 0) { begin = new DateTime(1, 1, 1, currentTime.Hour, currentTime.Minute, 0, 0); begin = begin.AddMinutes(mins); } end = begin.AddMinutes(rand_airplanes[i].getRequiredTimeInterval()); } while (end >= next_day); // с end до begin находится нужный временной интервал для rand_airplanes for (int j = 0; j < runwaysAmount; j++) { if (ways[j].airplanesUse.Count == 0) { ways[j].airplanesUse.Add(rand_airplanes[i]); rand_airplanes[i].applicationTime = begin; rand_airplanes[i].runwayNumber = j + 1; airplanes.Add(rand_airplanes[i]); break; } if (ways[j].is_free(begin, end)) { ways[j].airplanesUse.Add(rand_airplanes[i]); rand_airplanes[i].applicationTime = begin; rand_airplanes[i].runwayNumber = j + 1; airplanes.Add(rand_airplanes[i]); break; } if (j == runwaysAmount - 1) { begin = begin.AddMinutes(modulationStep); end = end.AddMinutes(modulationStep); j = 0; if (end >= next_day) { break; } } } } using (StreamWriter wr = new StreamWriter(scheduleFilename)) { foreach (Airplane airplane in airplanes) { string status = "DEPARTURE"; if (airplane.isArriving) { status = "ARRIVAL"; } wr.WriteLine("{0};{1};{2};{3};{4}", airplane.applicationTime.ToShortTimeString(), airplane.flight, airplane.companyName, airplane.type, status); } } }
public void addAirplane(DateTime time, Airplane airplane) { // добавить самолет на полосу с указанием времени заявки this.airplanesUse.Add(time, airplane); }