private static int ChoiseOfStop(Stop stopStart, int j_region) // входные параметры - остановка отправления и регион назначения { double shance = rand.NextDouble(); // шанс выбрать остановку случайно // вероятность выбора любой остановки if (shance < probability_of_arbitrary_choise) // если случайное число будет меньше вероятности произвольного выбора остановки, то задаётся случайная остановка назначения из списка остановок { return((int)(shance * listStop.Count) + 1); } // вероятность выбора остановки в заданном районе else { double zzz = rand.NextDouble(); // случайное число // вероятность выбора остановки без пересадки if (zzz <= probability_without_jump) // если случайное число не превышает вероятность выбора остановки без пересадки, то... { List <Stop> list_stop_region = stopStart.StopWoTransfer.Where(x => x.District == listDist[j_region].NameDistrict).ToList(); // задаётся лист остановок района назначения //если нет остановки в выбранном районе - задаётся случайная остановка if (list_stop_region.Count == 0) { return((int)rand.Next(stopStart.StopWoTransfer.Count) + 1); } // формирование классов для каждой остановки List <int> list_group = new List <int>(); // лист классов остановок foreach (Stop stop in list_stop_region) // для каждой остановки из листа остановок района назначения { for (int i_a = 0; i_a < attractive.GetLength(0); i_a++) { if (stop.Attraction <= attractive[i_a, 0]) // сравнение: попадает ли привлекательность остановки в какую-либо одну из пяти интервалов привлекательности { list_group.Add(i_a); break; } } } // выбирается номер класса остановок var list_group_dist = list_group.Distinct().ToList(); int count_group = list_group_dist.Count(); double uuu = rand.NextDouble(); double border = 0; int i_group = 0; for (int i = 0; i < list_group_dist.Count; i++) { border += attractive[list_group_dist[i], 1]; if (uuu <= border) { i_group = list_group_dist[i];// номер класса, куда поедет пассажир break; } } // генерируется остановка из выбранного класса int count_stop_group = list_group.Where(x => x == i_group).Count(); int number_of_stop = (int)(count_stop_group * rand.NextDouble()); int n_of_stop = 0; for (int i = 0; i < list_group.Count; i++) { if (list_group[i] == i_group) { if (n_of_stop == number_of_stop) { return(i); // возвращается номер остановки назначения } n_of_stop++; } } } // вероятность выбора остановки с одной пересадкой else { List <Stop> list_stop_region = stopStart.StopWithTransfer.Where(x => x.District == listDist[j_region].NameDistrict).ToList(); //если нет остановки в выбранном районе - задаётся случайная остановка if (list_stop_region.Count == 0) { return((int)rand.Next(stopStart.StopWithTransfer.Count) + 1); } // формирование классов для каждой остановки List <int> list_group = new List <int>(); // лист классов остановок foreach (Stop stop in list_stop_region) // для каждой остановки из листа остановок района назначения { for (int i_a = 0; i_a < attractive.GetLength(0); i_a++) { if (stop.Attraction <= attractive[i_a, 0]) // сравнение: попадает ли привлекательность остановки в какую-либо одну из пяти интервалов привлекательности { list_group.Add(i_a); break; } } } // выбирается номер класса остановок var list_group_dist = list_group.Distinct().ToList(); int count_group = list_group_dist.Count(); double uuu = rand.NextDouble(); double border = 0; int i_group = 0; for (int i = 0; i < list_group_dist.Count; i++) { border += attractive[list_group_dist[i], 1]; if (uuu <= border) { i_group = list_group_dist[i];// номер класса, куда поедет пассажир break; } } // генерируется остановка из выбранного класса int count_stop_group = list_group.Where(x => x == i_group).Count(); int number_of_stop = (int)(count_stop_group * rand.NextDouble()); int n_of_stop = 0; for (int i = 0; i < list_group.Count; i++) { if (list_group[i] == i_group) { if (n_of_stop == number_of_stop) { return(i); // возвращается номер остановки назначения } n_of_stop++; } } } } return(-2); // если ошибка }
static double[,] attractive; // Вероятность выбора остановок прибытия public static void LoadFromExcel() { // создание списка для класса Stop listStop = new List <Stop>(); // создание списка для класса District listDist = new List <District>(); // Подгрузка файла с исходными данными FileInfo file = new FileInfo("данные\\Source_data.xlsx"); using (ExcelPackage package = new ExcelPackage(file)) { int code; // код i-го района int route; //Сохранение листа "Население" в переменную ExcelWorksheet population = package.Workbook.Worksheets["Население"]; int x = 10; // вспомогательная переменная //загрузка списка районов do //начало цикла { code = population.Cells[x, 1].GetValue <int>(); //запись кода района с листа "Население", где х - строка, 1 - столбец, в которых находится нужная ячейка string nameDist = population.Cells[x, 2].GetValue <string>(); //запись названия района с листа "Население" int countWork = population.Cells[x, 4].GetValue <int>() + population.Cells[x, 5].GetValue <int>(); //запись количества жителей первой категории данного района с листа "Население" int countPens = population.Cells[x, 3].GetValue <int>() + population.Cells[x, 6].GetValue <int>(); //запись количества жителей второй категории данного района с листа "Население" // запись данных о районе в класс District if (code != 0) //если переменная code получила код района { listDist.Add( new District { CodeDistrict = code, NameDistrict = nameDist, CountWork = countWork, CountPens = countPens } ); } x++; // переход к следующей строке в Excel }while (code != 0); // цикл выполняется до тех пор, пока не дойдёт до пустой ячейки //загрузка доли пассажиров общественного транспорта, предпочитающего общественный транспорт probability_use_pub_trans = population.Cells["D3"].GetValue <double>(); //загрузка доли пассажиров общественного транспорта, предпочитающего маршрутки probability_use_taxi = population.Cells["D4"].GetValue <double>(); //загрузка количества поездок работников и молодежи за день count_work_trip = population.Cells["H3"].GetValue <double>(); //загрузка количества поездок школьников и пенсионеров за день count_pens_trip = population.Cells["H4"].GetValue <double>(); //загрузка вероятности выбора остановки без пересадки probability_of_arbitrary_choise = population.Cells["L6"].GetValue <double>(); //загрузка вероятности произвольного выбора остановки probability_without_jump = population.Cells["H6"].GetValue <double>(); //загрузка вероятности выбора остановок прибытия attractive = new double[5, 2]; for (int i = 0; i < attractive.GetLength(0); i++) { for (int j = 0; j < attractive.GetLength(1); j++) { attractive[i, j] = population.Cells[3 + i, 14 + j].GetValue <double>(); } } //Сохранение листа "Маршруты" в переменную ExcelWorksheet routes = package.Workbook.Worksheets["Маршруты"]; x = 2; //загрузка списка остановок do { code = routes.Cells[x, 1].GetValue <int>(); // запись кода остановки с листа "Маршруты" string nameStop = routes.Cells[x, 2].GetValue <string>(); // запись названия остановки с листа "Маршруты" string district = routes.Cells[x, 3].GetValue <string>(); // запись названия района, в котором находится остановка с листа "Маршруты" int countPass = routes.Cells[x, 4].GetValue <int>(); // запись количества пассажиров, приходящих на остановку, с листа "Маршруты" int attraction = routes.Cells[x, 5].GetValue <int>(); // запись привлекательности остановки с листа "Маршруты" List <int> listRoutes = new List <int>(); // создание списка маршрутов, проходящих через конкретную остановку int countRoutes = routes.Cells[x, 6].GetValue <int>(); // запись количества маршрутов, проходящих через конкретную остановку //заполнение списка маршрутов для каждой остановки for (int i = 0; i < countRoutes; i++) { route = routes.Cells[x, i + 7].GetValue <int>(); listRoutes.Add(route); } // запись данных об остановке в класс Stop if (code != 0) { Stop stop = new Stop { CodeStop = code, NameStop = nameStop, District = district, CountPass = countPass, Attraction = attraction, ListOfRoutes = listRoutes }; listStop.Add(stop); //Запись в класс District списка остановок для каждого района District d = listDist.Find(xx => xx.NameDistrict == district); //нахождение остановок, у которых название района совпадает с названием конкретного района d.ListStop.Add(stop); } x++; }while (code != 0); //загрузка долей жителей зоны остановок for (int i_stop = 0; i_stop < listStop.Count(); i_stop++) { for (int i_region = 0; i_region < COUNT_DISTRICT; i_region++) { // просчитываем и записываем доли жителей зоны остановки в класс Stop if (listStop[i_stop].District == listDist[i_region].NameDistrict) //нахождение остановок, у которых название района совпадает с названием конкретного района { double part_area = (double)listStop[i_stop].CountPass / (double)listDist[i_region].CountPass; //количество пассажиров, приходящих на остановку, делится на общее количество жителей района listStop[i_stop].PercentageSitizen = part_area; } } } mornWork = new double[COUNT_DISTRICT, COUNT_DISTRICT]; // матрица доли рабочих и молодёжи утром mornPens = new double[COUNT_DISTRICT, COUNT_DISTRICT]; // матрица доли пенсионеров и школьников утром dayTime = new double[COUNT_DISTRICT, COUNT_DISTRICT]; // матрица доли людей в обеденное время evenWork = new double[COUNT_DISTRICT, COUNT_DISTRICT]; // матрица доли рабочих и молодёжи вечером evenPens = new double[COUNT_DISTRICT, COUNT_DISTRICT]; // матрица доли пенсионеров и школьников вечером timeDist = new double[COUNT_DISTRICT, COUNT_HOUR]; // матрица доли пассажиров, отъезжающих от остановки, в зависимости от времени прибытия ballWork = new double[COUNT_DISTRICT, COUNT_HOUR]; // матрица количества рабочих и молодёжи, находящихся в районе по часам ballPens = new double[COUNT_DISTRICT, COUNT_HOUR]; // матрица количества пенсионеров и школьников, находящихся в районе по часам //загрузка прочих матриц for (int i = 0; i < COUNT_DISTRICT; i++) { for (int j = 0; j < COUNT_DISTRICT; j++) { mornWork[i, j] = population.Cells[i + 25, j + 3].GetValue <double>(); // матрица доли рабочих и молодёжи утром mornPens[i, j] = population.Cells[i + 37, j + 3].GetValue <double>(); // матрица доли пенсионеров и школьников утром dayTime[i, j] = population.Cells[i + 49, j + 3].GetValue <double>(); // матрица доли людей в обеденное время evenWork[i, j] = population.Cells[i + 61, j + 3].GetValue <double>(); // матрица доли рабочих и молодёжи вечером evenPens[i, j] = population.Cells[i + 61, j + 15].GetValue <double>(); // матрица доли пенсионеров и школьников вечером } } //загрузка матрицы распределения по времени for (int i = 0; i < COUNT_DISTRICT; i++) { for (int j = 0; j < COUNT_HOUR; j++) { timeDist[i, j] = population.Cells[i + 73, j + 3].GetValue <double>(); // матрица доли пассажиров, отъезжающих от остановки, в зависимости от времени прибытия } } } }