Exemplo n.º 1
0
        /// <summary>
        /// Получает точку на границе выпуклой оболочки, ближайшую к заданной точке, решая задачу квадратичного программирования
        /// </summary>
        /// <param name="realPoint">Точка, не принадлежащая к выпуклой оболочке</param>
        /// <returns></returns>
        private double[] NearestRealPoint(double[] realPoint, double[] weights, bool[] notUpper)
        {
            var faces  = _convexHull.Faces.ToList();
            int fCount = faces.Count();

            // Получаем свободный член уравнений поверхностей
            double[] facesD = faces.Select(face =>
            {
                return(face.Normal.Zip(face.Vertices[0].Position, (x, y) => x * y).Sum());
            }).ToArray();

            double[,] Q = new double[_realDimension, _realDimension];
            double[] d = new double[_realDimension];
            for (int i = 0; i < _realDimension; i++)
            {
                Q[i, i] = weights[i] * weights[i] * 2.0;
                d[i]    = weights[i] * weights[i] * (-2.0 * realPoint[i]);
            }

            bool hasUpperBound = notUpper.Any(x => x);
            int  constrCount   = hasUpperBound ? fCount + _realDimension : fCount;

            double[,] A = new double[constrCount, _realDimension];
            double[] b = new double[constrCount];
            for (int i = 0; i < fCount; i++)
            {
                b[i] = -facesD[i];
                for (int j = 0; j < _realDimension; j++)
                {
                    A[i, j] = -faces[i].Normal[j];
                }
            }
            if (hasUpperBound)
            {
                for (int i = fCount; i < fCount + _realDimension; i++)
                {
                    int dim = i - fCount;
                    b[i]      = notUpper[dim] ? -realPoint[dim] : -_realMax[dim] * 0.1;
                    A[i, dim] = -1.0;
                }
            }

            return(AlgorithmHelper.SolveQP(Q, d, A, b, 0));
        }
        public double[] GetNearestPumpsPoit(double[] Gpumps, RepairMathModel repair, double[] pumpsPriority = null)
        {
            CheckRepair(repair);
            CheckPumps(Gpumps);
            if (pumpsPriority == null)
            {
                pumpsPriority = pumpSign.Select(x => 1.0).ToArray();
            }
            else
            {
                if (pumpsPriority.Count() != PumpsCount)
                {
                    throw new Exception();
                }
                if (pumpsPriority.Any(x => x < 0))
                {
                    throw new Exception();
                }
            }

            var system = GetSystemOfInequalities(repair);

            double[,] A = system.Item1.ToMatrix().Multiply(-1.0);
            double[] b = system.Item2.Multiply(-1.0);

            double[,] Q = new double[PumpsCount, PumpsCount];
            double[] d = new double[PumpsCount];

            for (int i = 0; i < PumpsCount; i++)
            {
                Q[i, i] = 2.0 * pumpsPriority[i] * pumpsPriority[i];
                d[i]    = pumpsPriority[i] * pumpsPriority[i] * -2.0 * Gpumps[i];
            }

            return(AlgorithmHelper.SolveQP(Q, d, A, b, 0));
        }