예제 #1
0
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            _spriteBatch.Begin();
            for (int y = 0; y < G.GetSize(); y++)
            {
                for (int x = 0; x < G.GetSize(); x++)
                {
                    int   v  = G.GetAtom(x, y);
                    Color pc = ColorMap[v];
                    _spriteBatch.Draw(OnePx, new Rectangle(x * CellWidth, y * CellHeight, CellWidth, CellHeight), pc);
                }
            }
            _spriteBatch.End();

            {
                // Do some simulated annealing.
                // Putting this in Update method ruins the animation due to large computation time.
                for (int i = 0; i < G.GetSize() * G.GetSize() * 10; i++)
                {
                    SA.AnnealStep();
                }

                // Slowly reduce temperature but don't allow it to go too low.
                if (SA.T > 0.1)
                {
                    SA.T *= 0.99f;
                }
            }


            base.Draw(gameTime);
        }
        public int AnnealStep()
        {
            // 1. Get current known energy
            int energy = G.GetSystemEnergy();
            // 2. Preturb the system

            // Let's pick 2 random locations and swap them.
            int x1        = R.Next(0, G.GetSize());
            int y1        = R.Next(0, G.GetSize());
            int x2        = R.Next(0, G.GetSize());
            int y2        = R.Next(0, G.GetSize());
            int oldState1 = G.GetAtom(x1, y1);
            int oldState2 = G.GetAtom(x2, y2);

            G.SetAtom(x1, y1, oldState2);
            G.SetAtom(x2, y2, oldState1);
            int deltaE = G.GetSystemEnergy() - energy;

            // Negative delta E is good, keep the state change.
            // This part is the metropolis algorithm.
            if (deltaE > 0)
            {
                float r = (float)R.NextDouble();

                float p = (float)Math.Pow(Math.E, -deltaE / T); // Probablity we take the perturbation.
                if (r >= p)
                {
                    // Reject the perturbation. Restore the prev state
                    G.SetAtom(x1, y1, oldState1);
                    G.SetAtom(x2, y2, oldState2);
                    return(0);
                }
            }

            return(deltaE);
        }