示例#1
0
        public void ClearEvents()
        {
            //Формирование всех дат и доступных нарядов в них
            var dates = ПериодГрафика.Select(date => new ДатаГрафика
            {
                Date  = date,
                Смены =
                    Наряды.Where(nar => !nar.Усиление || Усиления.Contains(date))
                    .Where(nar => nar.Дни == WeekDays.Все ||
                           (nar.Дни == WeekDays.Выходные && Праздники.Contains(date)) ||
                           (nar.Дни == WeekDays.Будние && !Праздники.Contains(date)))
                    .ToDictionary <Наряд, Наряд, Подразделение>(nar => nar, nar => null)
            }).ToList();

            //Заполнение заблокированных нарядов
            foreach (var date in dates)
            {
                var find = ДатыГрафика.FirstOrDefault(gr => gr.Date == date.Date);
                if (find == null)
                {
                    continue;
                }
                foreach (var nar in find.Блокировки)
                {
                    date.Блокировки.Add(nar);
                    if (!find.Смены.ContainsKey(nar))
                    {
                        continue;
                    }
                    if (nar.Усиление && !Усиления.Contains(date.Date))
                    {
                        continue;
                    }
                    if (Подразделения.Contains(find.Смены[nar]))
                    {
                        date.Смены[nar] = find.Смены[nar];
                    }
                }
            }

            //Перезапись старого графика новым
            //ДатыГрафика = new ObservableCollection<ДатаГрафика>(dates);
            ДатыГрафика.Clear();
            foreach (var date in dates)
            {
                ДатыГрафика.Add(date);
            }
            ПересчитатьПодразделения();
        }
示例#2
0
        /// <summary>
        ///     Раскидывание подразделений по разным дням
        ///     Чтобы в один день не было в наряде несколько человек с одного подразделения
        /// </summary>
        public void  аскидать()
        {
            //Счётчик сделаных замен
            var count = 0;

            do
            {
                count = 0;
                var collisions = new Dictionary <ДатаГрафика, Dictionary <Наряд, Подразделение> >();

                //Ищем повторы в днях
                foreach (var day in ДатыГрафика)
                {
                    //Берём все заполненные незаблокированные наряды
                    var nars = day.Смены.Where(pair => pair.Value != null && !day.Блокировки.Contains(pair.Key)).ToList();
                    //Сортируем по имени подразделения, чтобы легко найти дубликаты
                    nars.Sort((p1, p2) => String.Compare(p1.Value.Название, p2.Value.Название, StringComparison.Ordinal));
                    var last = new KeyValuePair <Наряд, Подразделение>();
                    foreach (var nar in nars)
                    {
                        //Если два подряд одинаковые
                        if (nar.Value == last.Value && last.Value != null)
                        {
                            if (!collisions.ContainsKey(day))
                            {
                                collisions[day] = new Dictionary <Наряд, Подразделение>();
                            }
                            //Добавляем в словарь повторов
                            collisions[day][last.Key] = last.Value;
                            collisions[day][nar.Key]  = nar.Value;
                        }
                        last = nar;
                    }
                }


                //Пробегаем по повторам
                foreach (var collision in collisions)
                {
                    //Выделяем подобные дни
                    var days = ДатыГрафика.Where(day => day.Holyday == collision.Key.Holyday).ToList();
                    //Выделяем подразделения с повторами
                    foreach (var district in collision.Value.Select(vp => vp.Value).Distinct().ToList())
                    {
                        var finded = false;
                        //Выделяем наряды в которые в этот день идёт конкретное подразделение
                        var naryads = collision.Value.Where(vp => vp.Value == district).Select(vp => vp.Key).ToList();
                        //Выделяем дни в которые данное подразделение ещё не стоит в наряде
                        foreach (var vday in days.Where(d => !d.Смены.ContainsValue(district)).ToList())
                        {
                            //Проверяем каждый день до первой замены
                            if (finded)
                            {
                                break;
                            }
                            foreach (var nar in naryads)
                            {
                                //Ищем наряд в который уже идёт какое-нибудь подразделение
                                var podob = vday.Смены.Where(vp => vp.Value != null
                                                             //Наряд не заблокирован
                                                             && !vday.Блокировки.Contains(vp.Key)
                                                             //Такой же длительности
                                                             && vp.Key.Длительность == nar.Длительность
                                                             //И подразделение которое в него идёт не идёт в выбранный день
                                                             && !collision.Key.Смены.ContainsValue(vp.Value)
                                                             //И подразделение которое в него идёт может пойти в выбранный наряд
                                                             && vp.Value.Наряды.Contains(nar)).ToList();

                                if (podob.Count <= 0)
                                {
                                    continue;
                                }
                                finded = true;
                                count++;
                                //Меняем наряды местами
                                collision.Key.Смены[nar] = podob[0].Value;
                                vday.Смены[podob[0].Key] = district;
                                break;
                            }
                        }
                    }
                }
            } while (count > 0); //Пока есть что заменять
        }
示例#3
0
        public void GenerateEvents()
        {
            List <ДатаГрафика> best    = null;
            double             bestres = 0;

            for (int i = 0; i < 1000; i++)
            {
                ClearEvents();
                var rand = new Random();

                //Формирование конкретных нарядов на выходные
                var holypairs = new List <KeyValuePair <ДатаГрафика, Наряд> >();
                foreach (var day in ДатыГрафика)
                {
                    var day1 = day;
                    foreach (var smen in day.Смены
                             .Where(pair => !day1.Блокировки.Contains(pair.Key) && pair.Value == null && day1.Holyday)
                             .Select(pair => pair.Key))
                    {
                        holypairs.Insert(rand.Next(holypairs.Count), (new KeyValuePair <ДатаГрафика, Наряд>(day, smen)));
                    }
                }

                //Сортировка нарядов по длительности в порядке убывания
                holypairs.Sort((pair, valuePair) => valuePair.Value.Длительность.CompareTo(pair.Value.Длительность));

                аспределитьНаряды(holypairs);

                //Формирование конкретных нарядов
                var pairs = new List <KeyValuePair <ДатаГрафика, Наряд> >();
                foreach (var day in ДатыГрафика)
                {
                    var day1 = day;
                    foreach (var smen in day.Смены
                             .Where(pair => !day1.Блокировки.Contains(pair.Key) && pair.Value == null)
                             .Select(pair => pair.Key))
                    {
                        pairs.Insert(rand.Next(pairs.Count), (new KeyValuePair <ДатаГрафика, Наряд>(day, smen)));
                    }
                }

                //Сортировка нарядов по длительности в порядке убывания
                pairs.Sort((pair, valuePair) => valuePair.Value.Длительность.CompareTo(pair.Value.Длительность));

                аспределитьНаряды(pairs);

                //Выборка лучшего случая
                if (best == null)
                {
                    best = ДатыГрафика.ToList();

                    if (Подразделения.Count == 0)
                    {
                        break;
                    }
                    bestres = Math.Abs(Подразделения.Max(dist => dist.ОтклонениеЗагруженности)) +
                              Math.Abs(Подразделения.Min(dist => dist.ОтклонениеЗагруженности));
                }
                else
                {
                    var res = Math.Abs(Подразделения.Max(dist => dist.ОтклонениеЗагруженности)) +
                              Math.Abs(Подразделения.Min(dist => dist.ОтклонениеЗагруженности));
                    if (res < bestres)
                    {
                        best.Clear();
                        best.AddRange(ДатыГрафика);
                        ПересчитатьПодразделения();
                        bestres = res;
                    }
                }
            }
            //ДатыГрафика = best;
            ДатыГрафика.Clear();
            foreach (var date in best)
            {
                ДатыГрафика.Add(date);
            }
            аскидать();
        }