Advertisement
kiraventom

Untitled

May 15th, 2021
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.39 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Runtime.CompilerServices;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. using Microsoft.EntityFrameworkCore.ChangeTracking.Internal;
  8. using Microsoft.EntityFrameworkCore.Query.Internal;
  9. using MoreLinq;
  10.  
  11. namespace Model
  12. {
  13. public static class BoxMethodSolver
  14. {
  15. public static Solution Solve(Input input)
  16. {
  17. var func = new Func<double, double, double>((t1, t2) =>
  18. input.Alpha *
  19. (t1 - input.Beta * input.DeltaP1) *
  20. Math.Cos(input.Gamma * input.DeltaP2 * Math.Sqrt(t1*t1 + t2*t2)));
  21. Point[] lastValues = new Point[20];
  22. for (int i = 0; i < 20; i++)
  23. {
  24. Point point = null;
  25. while (point is null)
  26. {
  27. point = GetMinimumValue(input, func);
  28. }
  29.  
  30. lastValues[i] = point;
  31. }
  32.  
  33. var bestPoint = lastValues.MinBy(p => p.Value).First();
  34. return new Solution { S = bestPoint.Value, T1 = bestPoint.X, T2 = bestPoint.Y, C = bestPoint.Value * 10 };
  35. }
  36.  
  37. private static Point GetMinimumValue(Input inputs, Func<double, double, double> func)
  38. {
  39. var random = new Random();
  40. Point finalPoint;
  41. int triesCount = 0;
  42.  
  43. var points = GetPoints(inputs.T1Min, inputs.T2Min, inputs.T1Max, inputs.T2Max, func, inputs);
  44.  
  45. while (true)
  46. {
  47. if (triesCount++ > 1000)
  48. {
  49. return null;
  50. }
  51.  
  52. points = points.OrderBy(point => point.Value).ToList();
  53. double sumX = points.Sum(point => point.X) - points[3].X;
  54. double sumY = points.Sum(point => point.Y) - points[3].Y;
  55. double Cx = sumX / 3;
  56. double Cy = sumY / 3;
  57.  
  58. double B = 0.25 * ((Math.Abs(Cx - points[3].X) + Math.Abs(Cx - points[0].X)) +
  59. (Math.Abs(Cy - points[3].Y) + Math.Abs(Cy - points[0].Y)));
  60. if (inputs.Acc > B)
  61. {
  62. finalPoint = points[0];
  63. break;
  64. }
  65.  
  66. double x0 = 2.3 * Cx - 1.3 * points[3].X;
  67. double y0 = 2.3 * Cy - 1.3 * points[3].Y;
  68.  
  69. if (x0 > inputs.T1Max)
  70. x0 = inputs.T1Max - inputs.Acc;
  71. if (x0 < inputs.T1Min)
  72. x0 = inputs.T1Min + inputs.Acc;
  73. if (y0 > inputs.T2Max)
  74. y0 = inputs.T2Max - inputs.Acc;
  75. if (y0 < inputs.T2Min)
  76. y0 = inputs.T2Min + inputs.Acc;
  77.  
  78. Point newPoint = new Point(x0, y0, func, inputs);
  79. if (!newPoint.IsCorrect)
  80. newPoint.ChangePointToCorrect(Cx, Cy, inputs);
  81.  
  82. if (newPoint.Value <= 0)
  83. continue;
  84.  
  85. if (newPoint.Value > points[3].Value)
  86. newPoint.MoveToGood(points[0], points[3].Value, inputs);
  87. points[3] = newPoint;
  88. }
  89.  
  90. return finalPoint;
  91. }
  92.  
  93. private static List<Point> GetPoints(double minX, double minY, double maxX, double maxY, Func<double, double, double> func, Input input)
  94. {
  95. var random = new Random();
  96. while (true)
  97. {
  98. var points = new List<Point>();
  99. for (int i = 0; i < 4; i++)
  100. {
  101. double x = minX + random.NextDouble() * (maxX - minX);
  102. double y = minY + random.NextDouble() * (maxY - minY);
  103. points.Add(new Point(x, y, func, input));
  104. }
  105.  
  106. var correctPoints = new List<Point>();
  107. var notCorrectPoints = new List<Point>();
  108.  
  109. foreach (Point point in points)
  110. {
  111. if (point.IsCorrect)
  112. correctPoints.Add(point);
  113. else
  114. notCorrectPoints.Add(point);
  115. }
  116.  
  117. if (correctPoints.Count != 0)
  118. {
  119. foreach (Point point in notCorrectPoints)
  120. {
  121. point.ChangePointToCorrect(correctPoints, input);
  122. correctPoints.Add(point);
  123. }
  124.  
  125. if (correctPoints.Any(p => p.Value <= 0))
  126. {
  127. continue;
  128. }
  129. return correctPoints;
  130. }
  131. }
  132. }
  133. }
  134.  
  135. internal class Point
  136. {
  137. public double X { get; private set; }
  138. public double Y { get; private set; }
  139. public double Value { get; private set; }
  140. public bool IsCorrect { get; private set; }
  141.  
  142. private readonly Func<double, double, double> Func;
  143.  
  144. public Point(double x, double y, Func<double, double, double> func, Input input)
  145. {
  146. X = x;
  147. Y = y;
  148. Value = func(x, y);
  149. IsCorrect = CheckCorrect(x, y, input);
  150. Func = func;
  151. }
  152.  
  153. public bool ChangePointToCorrect(List<Point> correctPoints, Input input)
  154. {
  155. double x = X;
  156. double y = Y;
  157. double sumX = correctPoints.Sum(point => point.X);
  158. double sumY = correctPoints.Sum(point => point.Y);
  159.  
  160. int correctTriesCount = 0;
  161. while (!CheckCorrect(x, y, input))
  162. {
  163. if (correctTriesCount++ > 100)
  164. {
  165. break;
  166. }
  167.  
  168. x = 0.5 * (x + (sumX / correctPoints.Count));
  169. y = 0.5 * (y + (sumY / correctPoints.Count));
  170. }
  171.  
  172. X = x;
  173. Y = y;
  174. Value = Func(x, y);
  175. IsCorrect = true;
  176. return true;
  177. }
  178.  
  179. public void ChangePointToCorrect(double Cx, double Cy, Input input)
  180. {
  181. double x = X;
  182. double y = Y;
  183.  
  184. int triesCount = 0;
  185. while (!CheckCorrect(x, y, input))
  186. {
  187. if (triesCount++ > 100)
  188. {
  189. return;
  190. }
  191. x = 0.5 * (x + Cx);
  192. y = 0.5 * (y + Cy);
  193. }
  194.  
  195. X = x;
  196. Y = y;
  197. Value = Func(x, y);
  198. IsCorrect = true;
  199. }
  200.  
  201. private bool CheckCorrect(double x, double y, Input input)
  202. {
  203. return x + y <= input.T1T2Sum && Value > 0 ;
  204. }
  205.  
  206. public void MoveToGood(Point goodPoint, double badValue, Input input )
  207. {
  208. double x = X;
  209. double y = Y;
  210. double value = Value;
  211.  
  212. while (value > badValue)
  213. {
  214. x = 0.5 * (x + goodPoint.X);
  215. y = 0.5 * (y + goodPoint.Y);
  216. value = Func(x, y);
  217. }
  218.  
  219. X = x;
  220. Y = y;
  221. Value = value;
  222. IsCorrect = CheckCorrect(x, y, input);
  223. }
  224. }
  225. }
  226.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement