예제 #1
0
        public EczaneNobetSonucModel Solve(EczaneNobetTekGrupDataModel data)
        {
            var model = Model(data);
            // Get a solver instance, change your solver
            var solver = new CplexSolver();

            try
            {
                // solve the model
                var solution = solver.Solve(model);
                //var cplexConfiguration = solver.Configuration;

                var modelStatus    = solution.ModelStatus;
                var solutionStatus = solution.Status;
                var modelName      = solution.ModelName;
                var bestBound      = solution.BestBound;

                //var confilicts = new ConflictingSet();
                //confilicts = solution.ConflictingSet;
                //ConstraintsUB = new IEnumerable<Constraint>();
                //ConstraintsUB = confilicts.ConstraintsUB;

                if (modelStatus != ModelStatus.Feasible)
                {
                    throw new Exception("Uygun çözüm bulunamadı!");
                }
                else
                {
                    // import the results back into the model
                    model.VariableCollections.ForEach(vc => vc.SetVariableValues(solution.VariableValues));
                    var objective = solution.ObjectiveValues.Single();
                    var sure      = solution.OverallWallTime;

                    Results = new EczaneNobetSonucModel
                    {
                        CozumSuresi    = sure,
                        ObjectiveValue = objective.Value,
                        ResultModel    = new List <EczaneNobetCozum>()
                    };

                    foreach (var r in data.EczaneNobetTarihAralik.Where(s => _x[s].Value == 1))
                    {
                        Results.ResultModel.Add(new EczaneNobetCozum()
                        {
                            TakvimId          = r.TakvimId,
                            EczaneNobetGrupId = r.EczaneNobetGrupId,
                            NobetGorevTipId   = r.NobetGorevTipId
                        });
                    }
                }
            }
            catch (Exception ex)
            {
                var mesaj = ex.Message;
                throw new Exception(mesaj);
            }
            return(Results);
        }
예제 #2
0
        private Model Model(EczaneNobetTekGrupDataModel data)
        {
            var model = new Model()
            {
                Name = "Eczane Nöbet Tekli Model"
            };

            #region Veriler
            var gunDegerler             = data.TarihAraligi.Select(s => s.NobetGunKuralId).Distinct().ToList();
            var diniBayramGunDegerleri  = data.TarihAraligi.Where(w => w.NobetGunKuralId == 8).Select(s => s.NobetGunKuralId).Distinct().ToList();
            var milliBayramGunDegerleri = data.TarihAraligi.Where(w => w.NobetGunKuralId == 9).Select(s => s.NobetGunKuralId).Distinct().ToList();
            var bayramGunDegerleri      = data.TarihAraligi.Where(w => w.NobetGunKuralId > 7).Select(s => s.NobetGunKuralId).Distinct().ToList();
            #endregion

            #region Karar Değişkenleri
            _x = new VariableCollection <EczaneNobetTarihAralik>(
                model,
                data.EczaneNobetTarihAralik,
                "_x", null,
                h => data.LowerBound,
                h => data.UpperBound,
                a => VariableType.Binary);
            #endregion

            #region Amaç Fonksiyonu
            var amac = new Objective(Expression.Sum((data.EczaneNobetTarihAralik
                                                     .Select(i => _x[i]))),
                                     "Sum of all item-values: ",
                                     ObjectiveSense.Minimize);
            model.AddObjective(amac);
            #endregion

            #region Kısıtlar

            #region Talep Kısıtları
            foreach (var nobetGrupGorevTip in data.NobetGrupGorevTipler)
            {
                foreach (var d in data.TarihAraligi)
                {
                    //nöbet gruplarının günlük nöbetçi sayısı
                    int talep = data.GerekliNobetSayisi;

                    var talepFarkli = data.NobetGrupTalepler
                                      .Where(s => s.NobetGrupGorevTipId == nobetGrupGorevTip.Id &&
                                             s.TakvimId == d.TakvimId)
                                      .Select(s => s.NobetciSayisi).SingleOrDefault();

                    if (talepFarkli > 0)
                    {
                        talep = talepFarkli;
                    }

                    model.AddConstraint(
                        Expression.Sum(data.EczaneNobetTarihAralik
                                       .Where(k => k.TakvimId == d.TakvimId)
                                       .Select(m => _x[m])) == talep,
                        $"her güne bir eczane atanmalı, {1}");
                }
            }
            #endregion

            #region Arz Kısıtları

            #region Peşpeşe Görev Yazılmasın
            foreach (var f in data.EczaneKumulatifHedefler)
            {
                foreach (var g in data.TarihAraligi.Take(data.TarihAraligi.Count() - data.PespeseNobet))
                {
                    //model.AddConstraint(
                    //  Expression.Sum(data.EczaneNobetTarihAralik
                    //                   .Where(e => e.EczaneNobetGrupId == f.EczaneNobetGrupId
                    //                               && e.NobetGorevTipId == f.NobetGorevTipId
                    //                               && (e.Gun >= g.Gun && e.Gun <= g.Gun + data.PespeseNobet)
                    //                         )
                    //                   .Select(m => _x[m])) <= 1,
                    //                   $"eczanelere peşpeşe nöbet yazılmasın, {f}");
                }
            }
            #endregion

            #region Her eczaneye yazılması gereken nöbetler Nöbet arzlarını(kapasitelerini-hedeflerini) ayarla

            foreach (var hedef in data.EczaneKumulatifHedefler)
            {
                #region Toplam

                model.AddConstraint(
                    Expression.Sum(data.EczaneNobetTarihAralik
                                   .Where(e => e.EczaneNobetGrupId == hedef.EczaneNobetGrupId &&
                                          e.NobetGorevTipId == hedef.NobetGorevTipId)
                                   .Select(m => _x[m])) <= hedef.Toplam,
                    $"her eczaneye bir ayda nöbet grubunun hedefi kadar nöbet yazılmalı, {hedef}");

                model.AddConstraint(
                    Expression.Sum(data.EczaneNobetTarihAralik
                                   .Where(e => e.EczaneNobetGrupId == hedef.EczaneNobetGrupId &&
                                          e.NobetGorevTipId == hedef.NobetGorevTipId)
                                   .Select(m => _x[m])) >= hedef.Toplam - 1,
                    $"her eczaneye bir ayda nöbet grubunun hedefi kadar nöbet yazılmalı, {hedef}");

                #endregion

                #region Bayram Toplamları

                if (bayramGunDegerleri.Count() > 0)
                {
                    var temp = hedef.ToplamBayram - 1;
                    if (temp < 0)
                    {
                        temp = 0;
                    }
                    model.AddConstraint(
                        Expression.Sum(data.EczaneNobetTarihAralik
                                       .Where(e => e.EczaneNobetGrupId == hedef.EczaneNobetGrupId &&
                                              e.NobetGunKuralId > 7)
                                       .Select(m => _x[m])) <= hedef.ToplamBayram,
                        $"her eczaneye bir ayda nöbet grubunun hedefi kadar toplam bayram nöbeti yazılmalı, {hedef}");

                    model.AddConstraint(
                        Expression.Sum(data.EczaneNobetTarihAralik
                                       .Where(e => e.EczaneNobetGrupId == hedef.EczaneNobetGrupId &&
                                              e.NobetGunKuralId > 7)
                                       .Select(m => _x[m])) >= temp,
                        $"her eczaneye bir ayda nöbet grubunun hedefi kadar toplam bayram nöbeti yazılmalı, {hedef}");
                }
                #endregion

                #region Diğer günler
                //gunDegerler: nöbet yazılacak tarih aralığındaki hafta ve bayram günleri
                foreach (var gunDeger in data.NobetGrupGunKurallar.Where(s => s.NobetGrupId == data.NobetGrup.Id).Select(s => s.NobetGunKuralId))
                {
                    //GetEczaneGunHedef2(out maxArz, out minArz, gunDeger, f.EczaneId);

                    GetEczaneGunHedef(hedef, out double maxArz, out double minArz, gunDeger);

                    model.AddConstraint(
                        Expression.Sum(data.EczaneNobetTarihAralik
                                       .Where(e => e.EczaneNobetGrupId == hedef.EczaneNobetGrupId &&
                                              e.NobetGunKuralId == gunDeger)
                                       .Select(m => _x[m])) <= maxArz,
                        $"her eczaneye bir ayda nöbet grubunun {gunDeger} hedefi kadar nöbet yazılmalı, {hedef}");

                    model.AddConstraint(
                        Expression.Sum(data.EczaneNobetTarihAralik
                                       .Where(e => e.EczaneNobetGrupId == hedef.EczaneNobetGrupId &&
                                              e.NobetGunKuralId == gunDeger)
                                       .Select(m => _x[m])) >= minArz,
                        $"her eczaneye bir ayda nöbet grubunun {gunDeger} hedefi kadar nöbet yazılmalı, {hedef}");
                }
                #endregion
            }
            #endregion

            #region İstek Karşılansın
            //foreach (var f in data.EczaneNobetIstekler)
            //{
            //    model.AddConstraint(
            //              Expression.Sum(data.EczaneNobetTarihAralik
            //                               .Where(e => e.EczaneId == f.EczaneId
            //                                        && e.NobetGrupId == f.NobetGrupId
            //                                        && e.TakvimId == f.TakvimId
            //                                        && e.NobetGrupId == data.NobetGrup.Id
            //                                     )
            //                               .Select(m => _x[m])) == 1,
            //                               $"istege nobet yaz, {f}");
            //}
            #endregion

            #region Mazerete Görev Yazılmasın
            foreach (var f in data.EczaneNobetMazeretListe)
            {
                model.AddConstraint(
                    Expression.Sum(data.EczaneNobetTarihAralik
                                   .Where(e => e.EczaneId == f.EczaneId &&
                                          e.NobetGrupId == f.NobetGrupId &&
                                          e.TakvimId == f.TakvimId &&
                                          e.NobetGrupId == data.NobetGrup.Id
                                          )
                                   .Select(m => _x[m])) == 0,
                    $"mazerete nobet yazma, {f}");
            }
            #endregion

            #region Bayram günlerinde en fazla 1 görev yazılsın.
            //eğer bayram günleri ardışık günlerden fazlaysa
            if (data.TarihAraligi.Where(w => w.NobetGunKuralId > 7).Count() > data.PespeseNobet)
            {
                foreach (var f in data.EczaneKumulatifHedefler)
                {
                    foreach (var g in data.TarihAraligi.Where(w => w.NobetGunKuralId > 7))
                    {
                        //model.AddConstraint(
                        //  Expression.Sum(data.EczaneNobetTarihAralik
                        //                   .Where(e => e.EczaneNobetGrupId == f.EczaneNobetGrupId
                        //                               && e.Gun == g.Gun
                        //                         )
                        //                   .Select(m => _x[m])) <= 1,
                        //                   $"bayram nöbeti sınırlama, {f}");
                    }
                }
            }
            #endregion
            #endregion
            #endregion
            return(model);
        }