Футбол на плюсе, ч.2: практическая

от автора

Несмотря на некоторый скепсис, по поводу первой части материала, как и обещал, публикую результаты, и то как они были получены.
В основном манипуляции производились с данными, хранимыми в Excell, таблицы которого сформированы по 3НФ, поэтому в некоторых местах кода вместо индексов используются данные из ячеек. Итак согласно алгоритму необходимо получить коэффициент клуба и климатическую характеристику города, в котором этот клуб принимает соперников = команда: {климат, рейтинг} — это и есть основная цель. Поехали.

1 этап:

Уполномоченный человек или Система случайным образом выбирают число N в рамках количества представителей команд участниц – от 1 до 16, упорядоченных согласно алфавиту. Выбранный участник приглашается для вычисления веса-рейтинга случайной команды.

            TeamSequence = new List<int>();             for (int i = 0; i < teams.Length; i++)             {                 int team_ambassor = generator.Next(1000, 1000000)%teams.Length;                  while (TeamSequence.Contains(team_ambassor))                 team_ambassor = generator.Next(1000, 1000000)%teams.Length;                  TeamSequence.Add(team_ambassor);              }             foreach (int i in TeamSequence) textBox1.Text += "Приглашается прдставитель команды: " + teams[i] + "\r\n"; 

Для представителя уже сформированы данные по участникам соревнований, которые конечно же он не видит, также как и название команды, для которой производится расчет:
image

2 Этап

Т.к. у меня не было возможности пригласить кого-либо из экспертов, расстановку оценок по параметрам сделал случайной, а для того чтобы приблизить к реальности провел эту процедуру 8 раз ровно по количеству оцениваемых показателей.

            double[,] rate = new double[16,8];             int team=new int();             DataTable table = new DataTable();             List<int> Marklist = new List<int>();             string strConn = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"Excel 12.0 Xml;HDR=YES;IMEX=1;TypeGuessRows=0;ImportMixedTypes=Text\"", "C:\\team.xlsx");             using (OleDbConnection dbConnection = new OleDbConnection(strConn))             {                 using (OleDbDataAdapter dbAdapter = new OleDbDataAdapter("SELECT * FROM [Лист3$]", dbConnection))                 dbAdapter.Fill(table);                 for (int j = 0; j < 8; j++)                 {                     team = 0;                     foreach (DataRow dr in table.Rows)                     {                         for (int i = 9; i < 17; i++)                         {                             int mark = 1 + generator.Next(10000, 10000000)%8;                             while (Marklist.Contains(mark))                                 mark = 1 + generator.Next(10000, 10000000)%8;                             Marklist.Add(mark);                             rate[team, i - 9] += Convert.ToInt32(dr.ItemArray[i])*mark;                         }                         team++;                         Marklist.Clear();                     }                 }                 dbConnection.Close();             } 

Хранение данных в xlsx файлах достаточно удобное, т.к. некоторые тривиальные арифметические действия можно проводить сразу внутри таблиц с данными.
Выполнив случайную оценку показателей, были получены объективные характеристики участников соревнований.
image
Результаты получились вполне логичными.
Напомню, что оптимизация производится по минимальному критерию, т.е. меньше=лучше.

3 Этап

Остается к коэффициенту клуба, добавить климатическую характеристику города. Эти характеристики были получены для каждого месяца, в в рамках которых проводится турнир: июль-декабрь, март-май. Данные достаточно громоздкие и приводить их не вижу смысла.
Подсчитаем итоговые характеристики:

           double[,] rate = new double[12,9];             int team=new int();             DataTable table = new DataTable();             List<int> Marklist = new List<int>();             string strConn = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"Excel 12.0 Xml;HDR=YES;IMEX=1;TypeGuessRows=0;ImportMixedTypes=Text\"", "C:\\team.xlsx");             using (OleDbConnection dbConnection = new OleDbConnection(strConn))             {                 //здесь данные о климате, 12 городов, 9 месяцев                 using (OleDbDataAdapter dbAdapter = new OleDbDataAdapter("SELECT * FROM [Лист5$]", dbConnection))                 dbAdapter.Fill(table);                 team = 0;                 foreach (DataRow dr in table.Rows)                 {                     {                         rate[Convert.ToInt32(dr.ItemArray[0]) - 1, team%9] = Convert.ToDouble(dr.ItemArray[6]);                         team++;                     }                 }                 dbConnection.Close();             }             table = new DataTable();             double[,] team_rate = new double[16,9];             team = 0;             using (OleDbConnection dbConnection = new OleDbConnection(strConn))             {                  //здесь данные о командах = 16 шт.                 using (OleDbDataAdapter dbAdapter = new OleDbDataAdapter("SELECT * FROM [Лист6$]", dbConnection))                 dbAdapter.Fill(table);                 foreach (DataRow dr in table.Rows)                 {                     for (int i = 0; i < 9; i++)                     {                         team_rate[team%16, i] = rate[Convert.ToInt32(dr.ItemArray[0]) - 1, i]*                                                 Convert.ToDouble(dr.ItemArray[1]);                     }                     team++;                                      }                 dbConnection.Close();             }             StreamWriter sw = new StreamWriter("teams_koeff.txt");             for (int i = 0; i <16; i++)             {                 sw.WriteLine(Convert.ToString(teams[i]));                 for (int j = 0; j < 9; j++)                 {                     sw.Write(Convert.ToString(month[j]+"\t"));                     sw.Write(team_rate[i, j]+"\t");                 }                 sw.WriteLine();             }             sw.Close(); 

Готово. Немного преобразования и получится следующая таблица:
image
Как видно, у Кубани и Краснодара рейтинги разные, хотя они из одного города, аналогичная ситуация у московских клубов. На основе этой информации можно оптимизировать процедуру жеребьевки. Конечно же, разные форс-мажоры, игры в еврокубках, сборные, рекомендации полиции и т.п., необходимо будет учитывать вручную, но общий каркас сетки уже будет сформирован.
Для примера сравним опубликованный календарь и нашу таблицу:
image image
Если не учитывать 2 московские пары, то примерно 50% «качетсва». Однако в некоторых парах, коэффициент отличается на порядок!!! Кто-то может сказать, что в принципе «все нормально», но определенно можно было бы сформировать календарь так, чтобы (по 1 таблице) Терек сыграл с Томью, а Краснодар с Рубином. Как ни крути в Сибири в ноябре прохладно и бегать и уж тем более смотреть на трибуне.
Спасибо! Как всегда рад Вашим комментариям.

ссылка на оригинал статьи http://habrahabr.ru/post/185130/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *