예제 #1
0
        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);
        }
예제 #2
0
 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;
         }
     }
 }
예제 #3
0
        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();
        }
예제 #4
0
        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());
        }
예제 #5
0
        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());
        }
예제 #6
0
        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);
        }
예제 #7
0
        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);
        }
예제 #8
0
        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);
        }
예제 #9
0
        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('|'));
        }
예제 #10
0
        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));
        }
예제 #11
0
        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));
        }