public DescretOptTask(DataPlavka _task, DescrModel _model, int _numOfIntervals, int _degree, int _shift, double _eps)
 {
     task = _task;
     model = _model;
     numOfIntervals = _numOfIntervals;
         degree = _degree;
         shift = _shift;
         eps = _eps;
 }
        public CondOptModel(RegressionModel regr, DescrModel descr, double[] _y, double _epsg, double _epsi, int _iter)
        {
            regModel = regr;
            desModel = descr;
            epsg = _epsg;
            epsx = _epsi;
            epsi = _epsi;
            iter = _iter;
            yModel = new double[regModel.y.Count];

            technology = new Technology(regr.x, regr.y, descr.id, regr.id, _y);
        }
        private void getBoundsBtn_Click(object sender, RoutedEventArgs e)
        {
            if (task == null)
            {
                Log.Text = "Данные не загружены";
                return;
            }

            xBoundsData.Clear();
            xDescrGrid.ItemsSource = null;
            modelDescret = task.GetPlavkaBounds();
            foreach (Conditions c in modelDescret.xBounds)
                xBoundsData.Add(new itemGrid(c.descr, c.lower, c.upper));
            xDescrGrid.ItemsSource = xBoundsData;
            Log.Text = "Границы загружены";

            xOptDescrGrid.ItemsSource = null;
            xOptDescrGrid.ItemsSource = modelDescret.xBounds;

            SetModelInfoDescret();
        }
        private void descrBoundsBtn_Click(object sender, RoutedEventArgs e)
        {
            if (task.data == null)
            {
                Log.Text = "Данные не загружены";
                return;
            }
            if (yBoundsData.Count == 0)
            {
                Log.Text = "Не выбран стандарт на марку";
                return;
            }
            modelDescret = new DescrModel(task.x, task.y, Convert.ToDouble(alphaTextBox.Text), Convert.ToDouble(betaTextBox.Text));
            modelDescret.SetBounds(xBoundsData, yBoundsData); //берем границы из табличек
            task.CorrectBoundsY(modelDescret); //если верхняя не определена - берем максимум по выборке
            //List<string[]> results;
            DescretOptTask descrOptimizeBackground = new DescretOptTask(task, modelDescret, Convert.ToInt32(numIntervalsTextBox.Text),
                Convert.ToInt32(degreeTextBox.Text), Convert.ToInt32(shiftTextBox.Text), Convert.ToDouble(epsTextBox.Text));

            backgroundWorker.RunWorkerAsync(descrOptimizeBackground);
            Log.Text = "Начато построение дискретной модели . . . ";
                 //передаем ссыль на модель, в функции все меняется

            getBoundsBtn.IsEnabled = false;
            descrBoundsBtn.IsEnabled = false;
        }
 public CondOptModel(RegressionModel regr, DescrModel descr, Technology tech, double _epsg, double _epsi, int _iter, double[] _xCur)
 {
     regModel = regr;
     desModel = descr;
     epsg = _epsg;
     epsx = _epsi;
     epsi = _epsi;
     iter = _iter;
     yModel = new double[regModel.y.Count];
     technology = tech;
     technology.baseTechnologyID = tech.id;
     technology.id = -1;
     xDone = _xCur;
     for (int i = 0; i < xDone.Length; i++)
         if (xDone[i] == -1)
         {
             numDone = i;
             break;
         }
 }
 //если не задана верхняя граница - берем максимум из выборки
 public void CorrectBoundsY(DescrModel model)
 {
     double upper;
     for (int i = 0; i < x.Count; i++) //границы для Х
         if (model.xBounds[i].upper == 0)
         {
             upper = data[0, y.Count + i]; // Convert.ToDouble(plavka.Rows[0].ItemArray[y.Count + i]);
             for (int j = 1; j < data.GetLength(0); j++) //0 вверху 2 строки
                 if (data[j, y.Count + i] > upper) upper = data[j, y.Count + i];
             model.xBounds[i].upper = upper;
         }
     for (int i = 0; i < y.Count; i++) //границы для Y
     {
         if (model.yBounds[i].upper == 0)
         {
             upper = data[0, i]; // Convert.ToDouble(plavka.Rows[0].ItemArray[i]);
             for (int j = 1; j < data.GetLength(0); j++) //0 вверху 2 строки
                 if (data[j, i] > upper) upper = data[j, i];
             model.yBounds[i].upper = upper;
         }
     }
 }
        public double StartBoundsOptimize(int numIntervals, DescrModel model, int degree, int boundsShift, double eps, 
            System.ComponentModel.BackgroundWorker backgroundWorker)
        {
            int[] intervals = new int[numIntervals];
            for(int i=0; i<numIntervals; i++) intervals[i] = i; // берем все нулевые интервалы
            int[][] vars = new int[x.Count][];
            for (int i = 0; i < x.Count; i++) vars[i] = intervals;
            var cross = new CartesianProduct<int>(vars);
            IEnumerable<int[]> intervalVars = cross.Get();

            double maxCriteria = -1000000;
            List<Conditions> bestBounds = new List<Conditions>();
            foreach (int[] variant in intervalVars) //выбор начального подпространства
            {
                List<Conditions> bounds = model.IntervalsBounds(numIntervals, variant);
                 double res = OneIntervalCriteria(bounds, model);

                if (res > maxCriteria) //здесь оцениваем интервал, просто сравниваем критерий
                {
                    backgroundWorker.ReportProgress(1);
                    maxCriteria = res;
                    bestBounds.Clear();
                    for (int i = 0; i < bounds.Count; i++) bestBounds.Add(new Conditions(bounds[i]));
                }
            }
            //поехали двигать границы
            backgroundWorker.ReportProgress(2);
            DescrModel modelMaxBounds = GetPlavkaBounds();
            bool gettingGlobalBetter = true;
            while (gettingGlobalBetter)
            {
                backgroundWorker.ReportProgress(3);
                gettingGlobalBetter = false;
                for (int i = 0; i < x.Count; i++) //для каждого параметра смотрим
                {
                    bool gettingBetter = true; //пока изменяются границы хотя бы одного интервала - пересматриваем заново
                    while (gettingBetter) //повторяем пока сдвиги границ дают результат
                    {
                        gettingBetter = false;//пока изменяются границы внутри интервала - пересматриваем заново
                        //double size = bestBounds[i].upper - bestBounds[i].lower;
                        List<Conditions> newBestBounds = new List<Conditions>();

                        for (int v = 0; v < 4; v++)
                            for (int j = 0; j < degree + 1; j++)
                            {
                                List<Conditions> newBounds = new List<Conditions>();
                                foreach (Conditions c in bestBounds) newBounds.Add(new Conditions(c));
                                if (v == 0) //увеличиваем интервал верхней границы
                                    newBounds[i].upper += Math.Abs(modelMaxBounds.xBounds[i].upper - bestBounds[i].upper) / Math.Pow(boundsShift, i);
                                if (v == 1) //уменьшаем интервал
                                    newBounds[i].upper -= ( bestBounds[i].upper - bestBounds[i].lower) / Math.Pow(boundsShift, i + 1); //уменьшаем интервал
                                if (v == 2) //увеличиваем интервал нижней границы
                                    newBounds[i].lower += Math.Abs(modelMaxBounds.xBounds[i].lower - bestBounds[i].lower) / Math.Pow(boundsShift, i);
                                if (v == 3) //уменьшаем интервал
                                    newBounds[i].lower -= (bestBounds[i].upper - bestBounds[i].lower) / Math.Pow(boundsShift, i + 1);
                                double res = OneIntervalCriteria(newBounds, model);
                                if (backgroundWorker.WorkerReportsProgress) backgroundWorker.ReportProgress(1);
                                if (res > maxCriteria) //здесь оцениваем интервал, просто сравниваем критерий
                                {
                                    backgroundWorker.ReportProgress(1);
                                    gettingBetter = true;
                                    if( (Math.Abs(res) - Math.Abs(maxCriteria)) > eps) gettingGlobalBetter = true;
                                    maxCriteria = res;
                                    newBestBounds.Clear();
                                    for (int w = 0; w < newBounds.Count; w++) newBestBounds.Add(new Conditions(newBounds[w])); //новые улучшенные границы
                                }
                            }
                        if (gettingBetter)
                        {
                            bestBounds.Clear();
                            for (int w = 0; w < newBestBounds.Count; w++) bestBounds.Add(new Conditions(newBestBounds[w]));
                        }
                    }
                }
            }
            double beforeCriteria = OneIntervalCriteria(model.xBounds, model);
            model.criteria = maxCriteria;
            model.SetBounds(bestBounds);

            return beforeCriteria;
        }
 public double OneIntervalCriteria(List<Conditions> bounds, DescrModel model)
 {
     int Tplus = 0, Splus = 0, TSplus = 0;
     for (int i = 0; i < data.GetLength(0); i++)
     {
         bool flagOk = false;
         for (int q = 0; q < y.Count; q++)
             if (!(data[i, q] >= model.yBounds[q].lower && data[i, q] <= model.yBounds[q].upper)) break;//не попыл - выходим сразу
             else if (q == y.Count - 1)
             {
                 flagOk = true;
                 Splus++;
             }
         for (int q = 0; q < x.Count; q++)
             if (!(data[i, q + y.Count] >= bounds[q].lower && data[i, q + y.Count] <= bounds[q].upper)) break;
             else if (q == x.Count - 1)
             {
                 Tplus++;
                 if (flagOk) TSplus++;
             }
     }
     if (Tplus > 0 && Splus > 0)
         return model.CalcCriteria(data.GetLength(0), Tplus, Splus, TSplus);
     else return -1000;
 }
 public DescrModel GetPlavkaBounds()
 {
     DescrModel model = new DescrModel(x, y, 0, 0);
     double lower, upper;
     for (int i = 0; i < x.Count; i++) //границы для Х
     {
         lower = data[0, y.Count + i];// Convert.ToDouble(plavka.Rows[0].ItemArray[y.Count + i]);
         upper = data[0, y.Count + i]; // Convert.ToDouble(plavka.Rows[0].ItemArray[y.Count + i]);
         for (int j = 1; j < data.GetLength(0); j++) //0 вверху 2 строки
         {
             if (data[j, y.Count + i] < lower) lower = data[j, y.Count + i];
             if (data[j, y.Count + i] > upper) upper = data[j, y.Count + i];
         }
         model.xBounds.Add(new Conditions(lower, upper, xAll[x[i]].description));
     }
     for (int i = 0; i < y.Count; i++) //границы для Y
     {
         lower = data[0, i]; //Convert.ToDouble(plavka.Rows[0].ItemArray[i]);
         upper = data[0, i]; // Convert.ToDouble(plavka.Rows[0].ItemArray[i]);
         for (int j = 1; j <data.GetLength(0); j++) //0 вверху 2 строки
         {
             if (data[j, i] < lower) lower = data[j, i];
             if (data[j, i] > upper) upper = data[j, i];
         }
         model.yBounds.Add(new Conditions(lower, upper, yAll[y[i]].description));
     }
     model.criteria = 0;
     return model;
 }