public (DihtomiaRectangle first, DihtomiaRectangle second) SplitByMaxSide(GraphicSettings settings = null) { int splitDimension = GetMaxSide().dimension; List <double> firstUp = new List <double>(upperCorner); firstUp[splitDimension] = (lowerCorner[splitDimension] / 2 + upperCorner[splitDimension] / 2); DihtomiaRectangle first = new DihtomiaRectangle(new List <double>(lowerCorner), firstUp, settings); List <double> secondLow = new List <double>(lowerCorner); secondLow[splitDimension] = (lowerCorner[splitDimension] / 2 + upperCorner[splitDimension] / 2); DihtomiaRectangle second = new DihtomiaRectangle(secondLow, new List <double>(upperCorner), settings); return(first, second); }
public static (double FunctionMinimum, int counter, int optimal, List <double> optimalPoint) Solve(OptimizingFunction function, LipzitsFunction lipzits, double precision, double epsilon, List <double> lowerBound, List <double> upperBound, RuleD rule, GraphicSettings settings = null) { double lipConst = lipzits(epsilon); LinkedList <DihtomiaRectangle> rectangles = new LinkedList <DihtomiaRectangle>(); DihtomiaRectangle first = new DihtomiaRectangle(lowerBound, upperBound, settings); first.EvalQ(function, lipConst); rectangles.AddFirst(first); int counter = 1; int optimal = counter; List <double> optimalPoint; double currentMin = Math.Min(function(lowerBound), function(first.center)); if (function(lowerBound) < function(first.center)) { optimalPoint = new List <double>(lowerBound); } else { optimalPoint = new List <double>(first.center); } if (first.Q >= currentMin - epsilon) { return(currentMin, counter, optimal, optimalPoint); } while (rectangles.Count != 0) { var current = GetRectangle(rectangles, rule); var newRects = current.SplitByMaxSide(settings); newRects.first.EvalQ(function, lipConst); newRects.second.EvalQ(function, lipConst); double funcInFirst = function(newRects.first.center); double funcInSecond = function(newRects.second.center); if (currentMin < Math.Min(funcInFirst, funcInSecond)) { if (newRects.first.Q < (currentMin - epsilon) && newRects.first.GetMaxSide().max >= (2d * precision / lipConst)) { rectangles.AddFirst(newRects.first); } if (newRects.second.Q < (currentMin - epsilon) && newRects.second.GetMaxSide().max >= (2d * precision / lipConst)) { rectangles.AddFirst(newRects.second); } } else { if (funcInFirst < funcInSecond) { currentMin = funcInFirst; rectangles.AddFirst(newRects.first); optimalPoint = new List <double>(newRects.first.center); } else { currentMin = funcInSecond; rectangles.AddFirst(newRects.second); optimalPoint = new List <double>(newRects.second.center); } rectangles.RemoveWorse(currentMin, epsilon); optimal = counter; } counter++; } GC.Collect(); return(currentMin, counter, optimal, optimalPoint); }