/// <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)); }