예제 #1
0
파일: y1r.cs 프로젝트: solismb/procon25
        public static String run(int[,] map2d)
        {
            // y1r-Solverは2xM, Nx2のパズルには対応していないため,
            // この時は横長, 縦長に強いSolver1を流用する
            if (Problem.row == 2 || Problem.column == 2)
            {
                return Solver1.run(map2d);
            }

            int[] puzzle = new int[Problem.partNum];
            for (int i = 0; i < Problem.row; i++)
                for (int j = 0; j < Problem.column; j++)
                    puzzle[i * Problem.column + j] = map2d[i, j];

            Puzzle initial = new Puzzle( puzzle, Problem.column, Problem.row, Problem.selectionLimit, Problem.selectionCost, Problem.replacementCost);
            PuzzleSolver solver = new PuzzleSolver(initial, initial);

            solver.Solve();

            //        test(initial, solver.Puzzle.GetSolution());

            Puzzle miniMap = solver.Puzzle;

            return MiniPuzzleSolver.Solve(miniMap);
        }
예제 #2
0
        /// <summary>
        /// パズルをサイズダウンします.
        /// </summary>
        /// <returns>解けたらtrue, 解けなければfalseを返します</returns>
        public bool Solve()
        {
            Puzzle best = null;
            List<Puzzle> nodes = new List<Puzzle>(8 * this._puzzle.Row * this._puzzle.Column);

            PuzzleSolver solver;

            /*
            if (this._puzzle.RowOrig == this._puzzle.Row + 2 || this._puzzle.ColumnOrig == this._puzzle.Column + 2)
            {
                y1r.test((Puzzle)initial.Clone(), this._puzzle.GetSolution());
                Console.ReadKey();
            }
            */

            if (this._puzzle.Column == 2 || this._puzzle.Row == 2 || ( this._puzzle.Column <= 3 && this._puzzle.Row <= 3 ))
            {
                    return true;
            }

            if (this._puzzle.maxChoice != 1)
            {
                for (int i = 0; i < this._puzzle.Column * this._puzzle.Row; i++)
                {
                    Puzzle tmp = (Puzzle)this._puzzle.Clone();
                    tmp.Choice(i);

                    if (tmp.Column > 3)
                    {
                        if (tmp.CanUse(Puzzle.Position.Left))
                        {
                            solver = new PuzzleSolver(initial, tmp);
                            if (solver.Solve(Puzzle.Position2.LD))
                                nodes.Add(solver._puzzle);

                            solver = new PuzzleSolver(initial, tmp);
                            if (solver.Solve(Puzzle.Position2.LU))
                                nodes.Add(solver._puzzle);
                        }

                        if (tmp.CanUse(Puzzle.Position.Right))
                        {
                            solver = new PuzzleSolver(initial, tmp);
                            if (solver.Solve(Puzzle.Position2.RD))
                                nodes.Add(solver._puzzle);

                            solver = new PuzzleSolver(initial, tmp);
                            if (solver.Solve(Puzzle.Position2.RU))
                                nodes.Add(solver._puzzle);
                        }
                    }
                    if (tmp.Row > 3)
                    {
                        if (tmp.CanUse(Puzzle.Position.Up))
                        {
                            solver = new PuzzleSolver(initial, tmp);
                            if (solver.Solve(Puzzle.Position2.UR))
                                nodes.Add(solver._puzzle);

                            solver = new PuzzleSolver(initial, tmp);
                            if (solver.Solve(Puzzle.Position2.UL))
                                nodes.Add(solver._puzzle);
                        }

                        if (tmp.CanUse(Puzzle.Position.Down))
                        {
                            solver = new PuzzleSolver(initial, tmp);
                            if (solver.Solve(Puzzle.Position2.DR))
                                nodes.Add(solver._puzzle);

                            solver = new PuzzleSolver(initial, tmp);
                            if (solver.Solve(Puzzle.Position2.DL))
                                nodes.Add(solver._puzzle);
                        }
                    }
                }
            }
            else
            {
                // 幅と高さのどちらかが3でなければサイズダウンする.
                if (this._puzzle.Column > 3)
                {
                    if (this._puzzle.CanUse(Puzzle.Position.Left))
                    {
                        solver = new PuzzleSolver(initial, this._puzzle);
                        if (solver.Solve(Puzzle.Position2.LD))
                            nodes.Add(solver._puzzle);

                        solver = new PuzzleSolver(initial, this._puzzle);
                        if (solver.Solve(Puzzle.Position2.LU))
                            nodes.Add(solver._puzzle);
                    }

                    if (this._puzzle.CanUse(Puzzle.Position.Right))
                    {
                        solver = new PuzzleSolver(initial, this._puzzle);
                        if (solver.Solve(Puzzle.Position2.RD))
                            nodes.Add(solver._puzzle);

                        solver = new PuzzleSolver(initial, this._puzzle);
                        if (solver.Solve(Puzzle.Position2.RU))
                            nodes.Add(solver._puzzle);
                    }
                }
                if (this._puzzle.Row > 3)
                {
                    if (this._puzzle.CanUse(Puzzle.Position.Up))
                    {
                        solver = new PuzzleSolver(initial, this._puzzle);
                        if (solver.Solve(Puzzle.Position2.UR))
                            nodes.Add(solver._puzzle);

                        solver = new PuzzleSolver(initial, this._puzzle);
                        if (solver.Solve(Puzzle.Position2.UL))
                            nodes.Add(solver._puzzle);
                    }
                    if (this._puzzle.CanUse(Puzzle.Position.Down))
                    {
                        solver = new PuzzleSolver(initial, this._puzzle);
                        if (solver.Solve(Puzzle.Position2.DR))
                            nodes.Add(solver._puzzle);

                        solver = new PuzzleSolver(initial, this._puzzle);
                        if (solver.Solve(Puzzle.Position2.DL))
                            nodes.Add(solver._puzzle);
                    }
                }
            }

            // 貪欲法

            while (nodes.Count != 0)
            {
                best = nodes.Min();
                nodes.Remove(best);
                solver = new PuzzleSolver(initial, best);
                if (solver.Solve())
                {
                    this._puzzle = solver.Puzzle;
                    return true;
                }
            }

            /*
            List<Puzzle> list = new List<Puzzle>(100);
            for (int i = 0; i < (2 < nodes.Count ? 2 : nodes.Count); i++)
            {
                best = nodes.Min();
                nodes.Remove(best);
                solver = new PuzzleSolver(best);
                if (solver.Solve())
                {
                    list.Add(solver._puzzle);
                }
            }

            best = list.Min();

            // TODO
            if (best == null)
                return false;
            else
            {
                this._puzzle = best;
                return true;
            }
            */

            return false;

            /*
            best = nodes.Min();

            if (best == null)
                return false;

            solver = new PuzzleSolver(best);
            if (!solver.Solve())
                return false;

            this._puzzle = solver.Puzzle;
            */

            // 最適解

            /*
            for (int i = 0; i < nodes.Count; i++)
            {
                solver = new PuzzleSolver(nodes[i]);
                if (!solver.Solve())
                    nodes.RemoveAt(i);
                else
                    nodes[i] = solver._puzzle;
            }

            best = nodes.Min();
            this._puzzle = best;
            */

            //            return true;
        }