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