public static SolutionSpec Solve(Polygon poly, SolutionSpec initialSolution, TimeSpan?timeout = null) { if (poly.GetSignedSquare() < 0) { throw new InvalidOperationException("poly.GetSignedSquare() < 0"); } timeout = timeout ?? TimeSpan.FromSeconds(20); var sw = Stopwatch.StartNew(); var solution = initialSolution ?? SolutionSpec.CreateTrivial(x => x); do { var foldsCount = 0; foreach (var segment in poly.Segments) { var s = solution.Fold(segment); if (s != solution) { foldsCount++; } solution = s; } if (foldsCount == 0) { return(solution); } } while (sw.Elapsed < timeout); Console.Write($"Solution folding failed to complete in: {timeout.Value} "); return(solution); }
public void Solve(int problemId) { var problemsRepo = new ProblemsRepo(); var problem = problemsRepo.Get(problemId); var poly = problem.Polygons.Single(); // var dx = (int) problem.Polygons.SelectMany(p => p.Vertices).Select(x => x.X.Denomerator).Max(); // var dy = (int) problem.Polygons.SelectMany(p => p.Vertices).Select(x => x.Y.Denomerator).Max(); // foreach (var x in Enumerable.Range(0, dx).Select(x => new Rational(x, dx))) // foreach (var y in Enumerable.Range(0, dy).Select(y => new Rational(y, dy))) { // var shift = new Vector(x, y); var shift = new Vector(0, 0); var initialSolution = SolutionSpec.CreateTrivial(v => v + shift); var solution = ConvexPolygonSolver.Solve(poly.GetConvexBoundary(), initialSolution); var packedSolution = solution.Pack(); var packedSolutionSize = packedSolution.Size(); var solutionSize = solution.Size(); Console.WriteLine($"{shift}: {solutionSize}; packed: {packedSolutionSize}"); if (packedSolutionSize <= 5000) { ProblemsSender.Post(packedSolution, problemId, false); // return; } } }
public void Fold_Demo() { var origSolution = SolutionSpec.CreateTrivial(x => x); var result = origSolution.Fold("1,3/4 0,1/4"); result = result.Fold("1,1 1/4,0"); result.CreateVisualizerForm().ShowDialog(); }
public void Fold_ByMiddleLine(string segment, string expectedSrcPoints, string expectedDestPoints, string expectedFacets) { var origSolution = SolutionSpec.CreateTrivial(x => x); var result = origSolution.Fold(segment); result.SourcePoints.Should().Equal(expectedSrcPoints.Split('|').Select(Vector.Parse).ToArray()); result.Facets.Select(FacetToString).ToArray().Should().BeEquivalentTo(expectedFacets.Split('|')); result.DestPoints.Should().Equal(expectedDestPoints.Split('|').Select(Vector.Parse).ToArray()); }
public void Fold_ByBoundary(string segment, string expectedDestPoints) { var origSolution = SolutionSpec.CreateTrivial(x => x); var result = origSolution.Fold(segment); result.SourcePoints.Should().Equal(origSolution.SourcePoints); result.Facets.Should().Equal(origSolution.Facets); result.DestPoints.Should().Equal(expectedDestPoints.Split('|').Select(Vector.Parse).ToArray()); }
public void Fold_Nothing(string segment) { var origSolution = SolutionSpec.CreateTrivial(x => x); var result = origSolution.Fold(segment); result.SourcePoints.Should().Equal(origSolution.SourcePoints); result.Facets.Should().Equal(origSolution.Facets); result.DestPoints.Should().Equal(origSolution.DestPoints); }
public void PackWithRotations_EmptySolution() { var origSolution = SolutionSpec.CreateTrivial(); var result = origSolution.PackWithRotations(); result.SourcePoints.Should().Equal(origSolution.SourcePoints); result.Facets.Select(FacetToString).ToArray().Should().BeEquivalentTo(origSolution.Facets.Select(FacetToString)); result.DestPoints.Should().Equal(origSolution.DestPoints); }
public void RemoveBadFacetsVertices_EmptySolution() { var origSolution = SolutionSpec.CreateTrivial(); var result = origSolution.RemoveBadFacetsVertices(); result.SourcePoints.Should().Equal(origSolution.SourcePoints); result.Facets.Select(FacetToString).ToArray().Should().BeEquivalentTo(origSolution.Facets.Select(FacetToString)); result.DestPoints.Should().Equal(origSolution.DestPoints); }
public void PackFacetNumbers_TwiceFoldedSolution() { var origSolution = SolutionSpec.CreateTrivial().Fold("1/2,0 1/2,1").Fold("1/2,1/2 0,1/2"); var result = origSolution.PackFacetNumbers(); var expectedSourcePoints = "1/2,1/2|1/2,0|0,1/2|1/2,1|1,1/2|0,0|0,1|1,0|1,1"; var expectedDestPoints = "1/2,1/2|1/2,0|0,1/2|1/2,0|0,1/2|0,0|0,0|0,0|0,0"; var expectedFacets = "5 1 0 2|0 3 6 2|1 7 4 0|4 8 3 0"; result.SourcePoints.Should().Equal(expectedSourcePoints.Split('|').Select(Vector.Parse).ToArray()); result.DestPoints.Should().Equal(expectedDestPoints.Split('|').Select(Vector.Parse).ToArray()); result.Facets.Select(FacetToString).ToArray().Should().BeEquivalentTo(expectedFacets.Split('|')); }
public SolutionSpec SolveMovingAndRotatingInitialSquare(ProblemSpec problem, int dpi = 10) { var shift = GetShift(problem); var ts = from dx in Range(0, 1, dpi) from dy in Range(0, 1, dpi) let finalShift = shift.Move(dx, dy) from x in Range(0, 1, dpi * 2) select(Func <Vector, Vector>)(v => v.Rotate(x) + finalShift); var transform = ts.Select(t => Tuple.Create(t, SolutionEvaluator.EvaluateX(problem, SolutionSpec.CreateTrivial(t), dpi * 2))) .OrderByDescending(t => t.Item2) .FirstOrDefault()?.Item1; return(SolutionSpec.CreateTrivial(transform)); }
public static SolutionSpec GetInitialSolutionAlongRationalEdge(Segment rationalEdge) { var initialSolution = SolutionSpec.CreateTrivial(x => x + rationalEdge.Start); var edgeLen = new Rational(Arithmetic.Sqrt(rationalEdge.QuadratOfLength.Numerator), Arithmetic.Sqrt(rationalEdge.QuadratOfLength.Denomerator)); var a = rationalEdge.ToVector() / edgeLen; var b = Vector.Parse("1,0"); if (b.VectorProdLength(a) == 0) { if (b.ScalarProd(a) > 0) { return(initialSolution); } return(initialSolution.Reflect(rationalEdge)); } var bisect = new Segment(rationalEdge.Start, a + b + rationalEdge.Start); return(initialSolution.Reflect(bisect).Reflect(rationalEdge)); }