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); }
/// <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; }