示例#1
0
        static void Main(string[] args)
        {
            ulong totalLegalPuzzles;

            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();
            totalLegalPuzzles = NurikabeInstance.StartMultithreadedRun(8, 4);
            stopwatch.Stop();
            Console.WriteLine(totalLegalPuzzles);
            Console.WriteLine(stopwatch.Elapsed);
            Console.WriteLine();

            Console.WriteLine("Done. Enter 'exit' to exit. Case sensitive.");
            string response;

            while ((response = Console.ReadLine()) != "exit")
            {
                Console.WriteLine("Done. Enter 'exit' to exit. Case sensitive.");
            }
        }
示例#2
0
        /// <summary>
        /// Starts a multithreaded run of a nurikabe puzzle. It partitions the possible patterns into the desired number of threads.
        /// For thread counts and puzzle sizes that do not divide evenly, the last thread does the remaining puzzles.
        /// This is an overloaded method that uses a start point and end point.
        /// </summary>
        /// <param name="numOfThreads">The desired number of threads to use.</param>
        /// <param name="sizeOfPuzzle">The length or width of an n x n nurikabe puzzle.</param>
        /// <param name="startPoint">The starting integer of a puzzle to work on. <strong><em>DO NOT</em></strong> start at 0.
        /// It is already included if this method is started at 1.</param>
        /// <param name="endPoint">The last integer of a puzzle to work on.</param>
        /// <returns></returns>
        public static ulong StartMultithreadedRun(int numOfThreads, int sizeOfPuzzle, ulong startPoint, ulong endPoint)
        {
            NurikabeInstance[] nurikabes    = new NurikabeInstance[numOfThreads];
            ThreadStart[]      threadStarts = new ThreadStart[numOfThreads];
            List <Thread>      threads      = new List <Thread>();

            // There is no Math.Pow for integers.
            int lengthOfPattern = sizeOfPuzzle * sizeOfPuzzle;

            // -1 because we already account for the trivial case.
            ulong numberOfPatterns = endPoint - startPoint + 1;

            ulong shareSize = numberOfPatterns / (ulong)numOfThreads;
            ulong extra     = numberOfPatterns % (ulong)numOfThreads;
            ulong sum       = startPoint - 1;

            for (int i = 0; i < numOfThreads; i++)
            {
                nurikabes[i] = new NurikabeInstance(sum + 1, 0, lengthOfPattern, sizeOfPuzzle);
                sum         += shareSize;
                if (i == numOfThreads - 1)
                {
                    sum += extra;
                }
                nurikabes[i].StopPoint = sum;
                threadStarts[i]        = new ThreadStart(nurikabes[i].GenerateLegalNurikabe);
            }

            // Set up all threads
            for (int i = 0; i < numOfThreads; i++)
            {
                threads.Add(new Thread(threadStarts[i]));
            }

            // Start all threads.
            for (int i = 0; i < numOfThreads; i++)
            {
                threads[i].Start();
            }

            // Find better way to wait for all threads to finish. Join ties up threads.

            bool stillBusy = true;

            while (stillBusy)
            {
                stillBusy = false;
                for (int i = 0; i < numOfThreads; i++)
                {
                    if (threads[i].IsAlive)
                    {
                        stillBusy = true;
                        Thread.Sleep(1);
                        break;
                    }
                }
            }


            // Add up all puzzles.
            ulong totalLegalPuzzles = 0;

            for (int i = 0; i < numOfThreads; i++)
            {
                totalLegalPuzzles += nurikabes[i].LegalPuzzles;
            }
            //Each instance of a nurikabe puzzle includes the trivial case.
            if (startPoint == 1)
            {
                return(totalLegalPuzzles - (ulong)numOfThreads + 1);
            }
            else
            {
                return(totalLegalPuzzles - (ulong)numOfThreads);
            }
        }
示例#3
0
        // Extend upper limit on puzzles by using BigInteger Class. May just be too hard to go past 8.
        /// <summary>
        /// Starts a multithreaded run of a nurikabe puzzle. It partitions the possible patterns into the desired number of threads.
        /// For thread counts and puzzle sizes that do not divide evenly, the last thread does the remaining puzzles.
        /// </summary>
        /// <param name="numOfThreads">The desired number of threads to use.</param>
        /// <param name="sizeOfPuzzle">The length or width of an n x n nurikabe puzzle.</param>
        public static ulong StartMultithreadedRun(int numOfThreads, int sizeOfPuzzle)
        {
            NurikabeInstance[] nurikabes    = new NurikabeInstance[numOfThreads];
            ThreadStart[]      threadStarts = new ThreadStart[numOfThreads];
            List <Thread>      threads      = new List <Thread>();

            // There is no Math.Pow for integers.
            int lengthOfPattern = sizeOfPuzzle * sizeOfPuzzle;

            // Just for the purpose of Math.Pow. Does not allow implicit conversion of int to double.
            double lengthOfPatternDouble = sizeOfPuzzle * sizeOfPuzzle;

            // -1 because we already account for the trivial case.
            ulong numberOfPatterns = (ulong)Math.Pow(2, lengthOfPatternDouble) - 1;

            ulong shareSize = numberOfPatterns / (ulong)numOfThreads;
            ulong extra     = numberOfPatterns % (ulong)numOfThreads;
            ulong sum       = 0;

            for (int i = 0; i < numOfThreads; i++)
            {
                nurikabes[i] = new NurikabeInstance(sum + 1, 0, lengthOfPattern, sizeOfPuzzle);
                sum         += shareSize;
                if (i == numOfThreads - 1)
                {
                    sum += extra;
                }
                nurikabes[i].StopPoint = sum;
                threadStarts[i]        = new ThreadStart(nurikabes[i].GenerateLegalNurikabe);
            }

            // Set up all threads
            for (int i = 0; i < numOfThreads; i++)
            {
                threads.Add(new Thread(threadStarts[i]));
            }

            // Start all threads.
            for (int i = 0; i < numOfThreads; i++)
            {
                threads[i].Start();
            }

            // Find better way to wait for all threads to finish. Join ties up threads.
            bool stillBusy = true;

            while (stillBusy)
            {
                stillBusy = false;
                for (int i = 0; i < numOfThreads; i++)
                {
                    if (threads[i].IsAlive)
                    {
                        stillBusy = true;
                        Thread.Sleep(1);
                        break;
                    }
                }
            }


            // Add up all puzzles.
            ulong totalLegalPuzzles = 0;

            for (int i = 0; i < numOfThreads; i++)
            {
                totalLegalPuzzles += nurikabes[i].LegalPuzzles;
            }
            //Each instance of a nurikabe puzzle includes the trivial case. This subtracts each extra trivial case and adds one back in.
            return(totalLegalPuzzles - (ulong)numOfThreads + 1);
        }