Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Runtime.CompilerServices;
- using System.Text;
- using System.Threading.Tasks;
- using Microsoft.EntityFrameworkCore.ChangeTracking.Internal;
- using Microsoft.EntityFrameworkCore.Query.Internal;
- using MoreLinq;
- namespace Model
- {
- public static class BoxMethodSolver
- {
- public static Solution Solve(Input input)
- {
- var func = new Func<double, double, double>((t1, t2) =>
- input.Alpha *
- (t1 - input.Beta * input.DeltaP1) *
- Math.Cos(input.Gamma * input.DeltaP2 * Math.Sqrt(t1*t1 + t2*t2)));
- Point[] lastValues = new Point[20];
- for (int i = 0; i < 20; i++)
- {
- Point point = null;
- while (point is null)
- {
- point = GetMinimumValue(input, func);
- }
- lastValues[i] = point;
- }
- var bestPoint = lastValues.MinBy(p => p.Value).First();
- return new Solution { S = bestPoint.Value, T1 = bestPoint.X, T2 = bestPoint.Y, C = bestPoint.Value * 10 };
- }
- private static Point GetMinimumValue(Input inputs, Func<double, double, double> func)
- {
- var random = new Random();
- Point finalPoint;
- int triesCount = 0;
- var points = GetPoints(inputs.T1Min, inputs.T2Min, inputs.T1Max, inputs.T2Max, func, inputs);
- while (true)
- {
- if (triesCount++ > 1000)
- {
- return null;
- }
- points = points.OrderBy(point => point.Value).ToList();
- double sumX = points.Sum(point => point.X) - points[3].X;
- double sumY = points.Sum(point => point.Y) - points[3].Y;
- double Cx = sumX / 3;
- double Cy = sumY / 3;
- double B = 0.25 * ((Math.Abs(Cx - points[3].X) + Math.Abs(Cx - points[0].X)) +
- (Math.Abs(Cy - points[3].Y) + Math.Abs(Cy - points[0].Y)));
- if (inputs.Acc > B)
- {
- finalPoint = points[0];
- break;
- }
- double x0 = 2.3 * Cx - 1.3 * points[3].X;
- double y0 = 2.3 * Cy - 1.3 * points[3].Y;
- if (x0 > inputs.T1Max)
- x0 = inputs.T1Max - inputs.Acc;
- if (x0 < inputs.T1Min)
- x0 = inputs.T1Min + inputs.Acc;
- if (y0 > inputs.T2Max)
- y0 = inputs.T2Max - inputs.Acc;
- if (y0 < inputs.T2Min)
- y0 = inputs.T2Min + inputs.Acc;
- Point newPoint = new Point(x0, y0, func, inputs);
- if (!newPoint.IsCorrect)
- newPoint.ChangePointToCorrect(Cx, Cy, inputs);
- if (newPoint.Value <= 0)
- continue;
- if (newPoint.Value > points[3].Value)
- newPoint.MoveToGood(points[0], points[3].Value, inputs);
- points[3] = newPoint;
- }
- return finalPoint;
- }
- private static List<Point> GetPoints(double minX, double minY, double maxX, double maxY, Func<double, double, double> func, Input input)
- {
- var random = new Random();
- while (true)
- {
- var points = new List<Point>();
- for (int i = 0; i < 4; i++)
- {
- double x = minX + random.NextDouble() * (maxX - minX);
- double y = minY + random.NextDouble() * (maxY - minY);
- points.Add(new Point(x, y, func, input));
- }
- var correctPoints = new List<Point>();
- var notCorrectPoints = new List<Point>();
- foreach (Point point in points)
- {
- if (point.IsCorrect)
- correctPoints.Add(point);
- else
- notCorrectPoints.Add(point);
- }
- if (correctPoints.Count != 0)
- {
- foreach (Point point in notCorrectPoints)
- {
- point.ChangePointToCorrect(correctPoints, input);
- correctPoints.Add(point);
- }
- if (correctPoints.Any(p => p.Value <= 0))
- {
- continue;
- }
- return correctPoints;
- }
- }
- }
- }
- internal class Point
- {
- public double X { get; private set; }
- public double Y { get; private set; }
- public double Value { get; private set; }
- public bool IsCorrect { get; private set; }
- private readonly Func<double, double, double> Func;
- public Point(double x, double y, Func<double, double, double> func, Input input)
- {
- X = x;
- Y = y;
- Value = func(x, y);
- IsCorrect = CheckCorrect(x, y, input);
- Func = func;
- }
- public bool ChangePointToCorrect(List<Point> correctPoints, Input input)
- {
- double x = X;
- double y = Y;
- double sumX = correctPoints.Sum(point => point.X);
- double sumY = correctPoints.Sum(point => point.Y);
- int correctTriesCount = 0;
- while (!CheckCorrect(x, y, input))
- {
- if (correctTriesCount++ > 100)
- {
- break;
- }
- x = 0.5 * (x + (sumX / correctPoints.Count));
- y = 0.5 * (y + (sumY / correctPoints.Count));
- }
- X = x;
- Y = y;
- Value = Func(x, y);
- IsCorrect = true;
- return true;
- }
- public void ChangePointToCorrect(double Cx, double Cy, Input input)
- {
- double x = X;
- double y = Y;
- int triesCount = 0;
- while (!CheckCorrect(x, y, input))
- {
- if (triesCount++ > 100)
- {
- return;
- }
- x = 0.5 * (x + Cx);
- y = 0.5 * (y + Cy);
- }
- X = x;
- Y = y;
- Value = Func(x, y);
- IsCorrect = true;
- }
- private bool CheckCorrect(double x, double y, Input input)
- {
- return x + y <= input.T1T2Sum && Value > 0 ;
- }
- public void MoveToGood(Point goodPoint, double badValue, Input input )
- {
- double x = X;
- double y = Y;
- double value = Value;
- while (value > badValue)
- {
- x = 0.5 * (x + goodPoint.X);
- y = 0.5 * (y + goodPoint.Y);
- value = Func(x, y);
- }
- X = x;
- Y = y;
- Value = value;
- IsCorrect = CheckCorrect(x, y, input);
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement