예제 #1
0
        } // Error

        /// <summary>
        /// This creates a new random solution and maps that solution onto provided problem
        /// </summary>
        /// <param name="problem">int[][]</param>
        /// <param name="rand">pass in your random object if you got one</param>
        /// <returns></returns>
        public static int[][] GetRandomMatrix(int[][] problem, Random rand = null)
        {
            Random rnd = rand ?? new Random();
            // make a copy of the current puzzle
            var newRandomMatrix = SudokuTool.DuplicateMatrix(problem);


            for (var block = 0; block < Constants.BoardSize; ++block)
            {
                // fill them with 1 through 9
                var corners = SudokuTool.Corner(block);
                var vals    = new List <int>(Constants.BoardSize);
                for (var i = 1; i <= Constants.BoardSize; ++i)
                {
                    vals.Add(i);
                }

                // shuffle each cell with a value from another cell
                for (var k = 0; k < vals.Count; ++k)
                {
                    var ri  = rnd.Next(k, vals.Count);
                    var tmp = vals[k];
                    vals[k]  = vals[ri];
                    vals[ri] = tmp;
                }

                // remove the random cell values from the known cell values
                var r = corners[0];
                var c = corners[1];
                for (var i = r; i < r + 3; ++i)
                {
                    for (var j = c; j < c + 3; ++j)
                    {
                        var v = problem[i][j];
                        if (v != 0) // a fixed starting number is assumed correct
                        {
                            vals.Remove(v);
                        }
                    }
                }

                // walk thru block and add the new values to the random solution output
                var ptr = 0; // pointer into List
                for (var i = r; i < r + 3; ++i)
                {
                    for (var j = c; j < c + 3; ++j)
                    {
                        if (newRandomMatrix[i][j] == 0) // not occupied
                        {
                            var v = vals[ptr];          // get value from List
                            newRandomMatrix[i][j] = v;
                            ++ptr;                      // move to next value in List
                        }
                    }
                }
            } // each block, k

            return(newRandomMatrix);
        } // RandomMatrix
예제 #2
0
        } // RandomMatrix

        /// <summary>
        /// Randomly swap the values in two cells of a random block of the supplied matrix
        /// </summary>
        /// <param name="problem">the original puzzle </param>
        /// <param name="matrix">the current working solution</param>
        /// <param name="rand">pass in your random object if you got one</param>
        /// <returns></returns>
        public static int[][] EvolveMatrixAsync(int[][] problem, int[][] matrix, Random rand = null)
        {
            Random rnd = rand ?? new Random();
            // pick a random 3x3 block,
            // pick two random cells in block
            // swap values

            var result = SudokuTool.DuplicateMatrix(matrix);

            var block = rnd.Next(0, 9); // [0,8]
            //Console.WriteLine("block = " + block);
            var corners = SudokuTool.Corner(block);
            //Console.WriteLine("corners = " + corners[0] + " " + corners[1]);


            // look for at minimum 2 cells in the neighbor matrix that might be useful in the problem
            var cells = new List <int[]>();

            for (var i = corners[0]; i < corners[0] + 3; ++i)
            {
                for (var j = corners[1]; j < corners[1] + 3; ++j)
                {
                    //Console.WriteLine("problem " + i + " " + j + " = " + problem[i][j]);
                    if (problem[i][j] == 0) // a non-fixed value
                    {
                        cells.Add(new[] { i, j });
                    }
                }
            }

            if (cells.Count < 2)
            {
                // _sb.AppendLine($"Found only {cells.Count} useful cell in the neighbor.");
                throw new Exception("block " + block + " doesn't have two values to swap!");
            }

            // pick two. suppose there are 4 possible cells 0,1,2,3
            var k1  = rnd.Next(0, cells.Count); // 0,1,2,3
            var inc = rnd.Next(1, cells.Count); // 1,2,3
            var k2  = (k1 + inc) % cells.Count;
            //Console.WriteLine("k1 k2 = " + k1 + " " + k2);

            var r1 = cells[k1][0];
            var c1 = cells[k1][1];
            var r2 = cells[k2][0];
            var c2 = cells[k2][1];

            //Console.WriteLine("r1 c1 = " + r1 + " " + c1);
            //Console.WriteLine("r2 c2 = " + r2 + " " + c2);

            var tmp = result[r1][c1];

            result[r1][c1] = result[r2][c2];
            result[r2][c2] = tmp;

            return(result);
        } // NeighborMatrix
예제 #3
0
        } // NeighborMatrix

        /// <summary>
        /// for each block (3x3) in matrix2, there's a 50% chance to be added into matrix1
        /// </summary>
        /// <param name="matrix1">mating partner 1</param>
        /// <param name="matrix2">mating partner 2</param>
        /// <param name="chance">0.50 or some percential double value</param>
        /// <param name="rand">pass in your random object if you got one</param>
        /// <returns>a single matrix with some relationships between both provided</returns>
        public static int[][] MatingResult(int[][] matrix1, int[][] matrix2, double chance = 0.50, Random rand = null)
        {
            Random rnd    = rand ?? new Random();
            var    result = SudokuTool.DuplicateMatrix(matrix1);

            for (var block = 0; block < 9; ++block)
            {
                if (rnd.NextDouble() < chance)
                {
                    var corners = SudokuTool.Corner(block);
                    for (var i = corners[0]; i < corners[0] + 3; ++i)
                    {
                        for (var j = corners[1]; j < corners[1] + 3; ++j)
                        {
                            result[i][j] = matrix2[i][j];
                        }
                    }
                }
            }
            return(result);// Task.FromResult(result);
        }