public ManualSolverForm(ProblemSpec problem) { Model = new ManualSolverModel(problem); var copy = new ToolStripMenuItem("Reflect copy", null, (sender, args) => ChangeModel(Model.StartOperation(PendingOperationType.ReflectCopy))); copy.ShortcutKeys = Keys.Q | Keys.Control; var move = new ToolStripMenuItem("Reflect move", null, (sender, args) => ChangeModel(Model.StartOperation(PendingOperationType.ReflectMove))); move.ShortcutKeys = Keys.W | Keys.Control; var cancel = new ToolStripMenuItem("Cancel", null, (sender, args) => ChangeModel(Model.CancelPendingOperation())); var undo = new ToolStripMenuItem("Undo", null, (sender, args) => Undo()); undo.ShortcutKeys = Keys.Z | Keys.Control; var redo = new ToolStripMenuItem("Redo", null, (sender, args) => Redo()); redo.ShortcutKeys = Keys.Z | Keys.Control | Keys.Shift; var border = new ToolStripMenuItem("MarkAsBorder", null, (sender, args) => ChangeModel(Model.MarkAsBorder())); var noborder = new ToolStripMenuItem("MarkAsNOTBorder", null, (sender, args) => ChangeModel(Model.MarkAsNoBorder())); var solve = new ToolStripMenuItem("Solve", null, SolveClick); var selectAll = new ToolStripMenuItem("Select All", null, (sender, args) => ChangeModel(Model.SelectAll())); selectAll.ShortcutKeys = Keys.A | Keys.Control; var menu = new ToolStrip(selectAll, copy, move, cancel, undo, redo, border, noborder, solve); WindowState = FormWindowState.Maximized; this.Controls.Add(menu); }
public static List <Polygon> GetRealPolygons(ProblemSpec problem) { var segments = GetRealSegments(problem); segments.AddRange(segments.ToArray().Select(Reverse)); Dictionary <Vector, List <Segment> > outerSegments = segments.GroupBy(segment => segment.Start).ToDictionary(group => group.Key, group => group.ToList()); HashSet <Tuple <Vector, Vector> > usedSegments = new HashSet <Tuple <Vector, Vector> >(); List <Polygon> polygons = new List <Polygon>(); var holePolygons = problem.Polygons.Select(polygon => new HashSet <Vector>(polygon.Vertices)).ToList(); foreach (var segment in segments) { if (usedSegments.Contains(Tuple.Create(segment.Start, segment.End))) { continue; } var points = GeneratePolygon(segment, outerSegments, usedSegments).ToArray(); polygons.Add(new Polygon(points)); } foreach (var holePolygon in holePolygons) { var polygon = polygons.LastOrDefault(p => ArePointsPolygon(p.Vertices, holePolygon)); if (polygon != null) { polygons.Remove(polygon); } } return(polygons); }
public ManualSolverModel(ProblemSpec problem) { Problem = problem; Segments = problem.Segments.Select(s => new SegmentModel(s, GetUsualColor(s))).ToImmutableArray(); SelectedSegmentIndices = ImmutableList <int> .Empty; Shift = -problem.MinXY(); }
private static void Solve(ProblemSpec problemSpec) { var originalities = new[] { 0.5 }; var mutex = new object(); var solutionFoundEvent = new ManualResetEvent(false); var threads = originalities .Select(coeff => { var thread = new Thread(() => { try { var solution = SolutionPacker.Pack(new ConstructorSolver(problemSpec).Work()); if (solution == null || solution.Size() > 5000 || !solution.AreFacetsValid()) { return; } double ps; lock (mutex) { Console.WriteLine(" posting... "); ps = ProblemsSender.Post(solution, problemSpec.id); Console.Write($" perfect score: {ps}"); } if (ps == 1.0) { solutionFoundEvent.Set(); } } catch (Exception e) { if (e is ThreadAbortException) { return; } Console.WriteLine($"Exception in ProjectionSolverRunner: {e}"); } }) { IsBackground = true }; thread.Start(); return(thread); }) .ToArray(); solutionFoundEvent.WaitOne(TimeSpan.FromSeconds(10)); foreach (var t in threads) { if (t.IsAlive) { t.Abort(); t.Join(); } } }
private static double EstimateDifficulty(ProblemSpec problem) { var ratSegments = problem.Segments.Where(s => Arithmetic.IsSquare(s.QuadratOfLength)).ToList(); double ratSegCount = ratSegments.Count; double smallSegCount = problem.Segments.Count(s => s.IrrationalLength < 1d / 8); double blackPoints = problem.Points.Count(p => !ratSegments.Any(s => s.IsEndpoint(p))); return(ratSegCount / 10 + smallSegCount / 3 + blackPoints); }
private ProblemSpec CreatProblemSpec(List <SegmentModel> polygon) { var ss = polygon.Select(s => s.Segment).ToArray(); var ps = ss.SelectMany(s => new[] { s.Start, s.End }).Distinct().ToArray(); var convexHull = new Polygon(ps).GetConvexBoundary(); var convexProblem = new ProblemSpec(new Polygon[] { convexHull, }, ss); return(convexProblem); }
public ManualSolverModel(ProblemSpec problem, Vector shift, ImmutableArray <SegmentModel> segments, int?highlightedSegmentIndex, ImmutableList <int> selectedSegmentIndices, PendingOperationType pendingOperation, ImmutableList <Segment> mirrors) { Problem = problem; Shift = shift; Segments = segments; HighlightedSegmentIndex = highlightedSegmentIndex; SelectedSegmentIndices = selectedSegmentIndices; PendingOperation = pendingOperation; this.mirrors = mirrors; }
private static SolutionSpec TrySolve(ProblemSpec problem) { if (problem.Polygons.Length > 1 || !problem.Polygons.Single().IsConvex() || problem.Polygons.Single().GetSignedSquare() < 0) { return(null); } var problemPolygon = problem.Polygons[0]; return(ConvexPolygonSolver.TrySolveInBestShot(problem, problemPolygon.GetConvexBoundary())); }
public IEnumerable <SolutionSpec> SolveConvex() { var polygon = SelectedSegmentIndices.Select(i => Segments[i]).ToList(); ProblemSpec problem = CreatProblemSpec(polygon); var solution = TrySolve(problem); if (solution == null) { return(Enumerable.Empty <SolutionSpec>()); } return(GetAllMirrorCombinatons(solution, mirrors)); }
static void DrawPathGraph(int task) { var fname = string.Format("...\\..\\..\\problems\\{0:D3}.spec.txt", task); var spec = ProblemSpec.Parse(File.ReadAllText(fname)); var r = Pathfinder.BuildGraph(spec); var lens = r.Edges.Select(z => z.Data.length).OrderBy(z => z).ToList(); var matrix = new PathStat[r.NodesCount, r.NodesCount]; foreach (var e in Pathfinder.FindAllPathes(r, 1, 0.7)) { var i = e.FirstEdge.From.NodeNumber; var j = e.LastEdge.To.NodeNumber; if (matrix[i, j] == null) { matrix[i, j] = new PathStat(); } matrix[i, j].pathes.Add(e); } var gr = new Graph <PathStat, NodeInfo>(r.NodesCount); for (int i = 0; i < gr.NodesCount; i++) { gr[i].Data = r[i].Data; } for (int i = 0; i < gr.NodesCount; i++) { for (int j = 0; j < gr.NodesCount; j++) { if (matrix[i, j] != null) { gr.NonDirectedConnect(i, j, matrix[i, j]); } } } var viz = new GraphVisualizer <PathStat, NodeInfo>(); viz.GetX = z => (double)z.Data.Location.X; viz.GetY = z => (double)z.Data.Location.Y; Func <PathStat, string> stat = z => z.pathes.Count().ToString();; viz.EdgeCaption = z => stat(z.Data); viz.NodeCaption = z => z.Data.Location.ToString(); viz.Window(500, gr); }
public ConstructorSolver(ProblemSpec spec) { this.spec = spec; int i = 0; GivenPolygons = PolygonFinder.GetRealPolygons(spec).Select(p => { p.Id = i++; return(p); }).ToArray(); i = 0; GivenGraph = GivenPolygons.SelectMany(polygon => polygon.Segments.Select(segment => new { polygon, segment })) .GroupBy(pair => pair.segment) .Select(group => { group.Key.Id = i++; group.ForEach(pair => pair.segment.Id = group.Key.Id); return(group); }) .ToDictionary(pair => pair.Key, pair => pair.Select(s => s.polygon).ToList()); }
static void Main(string[] args) { var problem = File.ReadAllText("../../../problems/049.spec.txt"); var spec = ProblemSpec.Parse(problem); var solver = new ConstructorSolver(spec); var solution = solver.Work(); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); var form = new PolygonsAndSegmentsForm(); form.SetData(solution.Polygons, new Segment[0]); Application.Run(form); }
public static PointProjectionSolver CreateSolver(ProblemSpec spec) { // spec = spec.MoveToOrigin(); var solver = new PointProjectionSolver { spec = spec }; var r = Pathfinder.MakeSegmentsWithIntersections(spec.Segments); solver.vectors = r.Item2; solver.SegmentFamilies = r.Item1; solver.AllSegments = r.Item1.SelectMany(z => z.Segments).ToList(); solver.Graph = Pathfinder.BuildGraph(solver.AllSegments, solver.vectors); return(solver); }
private static SolutionSpec TryGetInitialSolution(ProblemSpec problem, TimeSpan?timeout = null) { timeout = timeout ?? TimeSpan.FromSeconds(10); SolutionSpec initialSolution = null; var t = new Thread(() => { initialSolution = new ImperfectSolver().SolveMovingAndRotatingInitialSquare(problem); }) { IsBackground = true }; t.Start(); if (!t.Join(timeout.Value)) { t.Abort(); t.Join(); Console.Write($"Failed to get initial solution in {timeout}! Skipping"); } return(initialSolution); }
public static double TrySolveAndSend(ProblemSpec problemSpec) { var res = 0.0; var t = new Thread(() => { var spec = UltraSolver.AutoSolve(problemSpec); res = Post(spec, problemSpec.id); }) { IsBackground = true }; t.Start(); if (!t.Join(5000)) { t.Abort(); t.Join(); } return(res); }
private void Form1_Paint(object sender, PaintEventArgs e) { var spec = @"1 10 -4267/58289,-11692/524601 469/1672,36437/52668 174/1001,1 0,1 0,23096929/23647932 -38493988/94603047,30998098/31534349 -96477/233156,156742/291445 -27719/58289,28517/58289 -751181/1806959,746582/1806959 -39957373/94603047,-532478/31534349 11 -4267/58289,-11692/524601 -27719/58289,28517/58289 -4267/58289,-11692/524601 -39957373/94603047,-532478/31534349 0,52/63 0,1 -39957373/94603047,-532478/31534349 -38493988/94603047,30998098/31534349 -4267/58289,-11692/524601 469/1672,36437/52668 469/1672,36437/52668 174/1001,1 0,52/63 9380/51293,286093/293769 -27719/58289,28517/58289 174/1001,1 469/1672,36437/52668 0,52/63 9380/51293,286093/293769 -38493988/94603047,30998098/31534349 0,1 174/1001,1 "; var problem = ProblemSpec.Parse(spec); var polygons = PolygonFinder.GetRealPolygons(problem); var painter = new Painter(); problem.Segments = polygons[8].Segments; painter.Paint(e.Graphics, e.ClipRectangle.Height, problem); Update(); }
public static List <Segment> GetRealSegments(ProblemSpec problem) { return(problem.Segments.SelectMany(segment => { var points = problem.Segments .Where(seg => !seg.Equals(segment)) .Select(intersector => intersector.GetIntersection(segment)) .Where(point => point != null) .Select(point => point.Value) .OrderBy(point => { if (segment.Start.X == segment.End.X) { return point.Y - segment.Start.Y; } return point.X - segment.Start.X; }) .Distinct() .ToArray(); return points.Take(points.Length - 1).Select((point, i) => new Segment(point, points[i + 1])).ToList(); }).ToList()); }
private static void SolveWithProjectionSolverRunner(ProblemSpec problemSpec) { var thread = new Thread(() => { try { var solution = UltraSolver.AutoSolve(problemSpec); if (solution == null || solution.Size() > 5000 || !solution.AreFacetsValid()) { return; } Console.WriteLine(" posting... "); var ps = ProblemsSender.Post(solution, problemSpec.id); Console.Write($" perfect score: {ps}"); } catch (Exception e) { if (e is ThreadAbortException) { return; } Console.WriteLine($"Exception in ProjectionSolverRunner: {e}"); } }) { IsBackground = true }; thread.Start(); if (!thread.Join(TimeSpan.FromSeconds(25))) { thread.Abort(); thread.Join(); } }
public static Graph <EdgeInfo, NodeInfo> BuildGraph(ProblemSpec spec) { var r = MakeSegmentsWithIntersections(spec.Segments); return(BuildGraph(r.Item1.SelectMany(z => z.Segments).ToList(), r.Item2)); }