[Gurobi Study Notes] Flip Game: Mathematical model and Python call Gurobi implementation


Preface

Flip Game is a video game that became popular in the 1990s. The game consists of a 5*5 grid with one circle in each cell. The initial state of the game is that the colors in the 25 circles are the same. Clicking on any circle will cause it and the circles in the adjacent grid to change color. The goal of the game is to color all the circles in as few clicks as possible.

Let’s take an example of Flip Game to help understand the rules of the game:
Initial state:
Figure 1 Initial state
Click (3, 3):
Figure 2 First click
Click (3, 1):
Figure 2 Second click
This article introduces how to use mathematical programming methods to solve Flip Game. The main contents of this article are as follows:

  1. Flip Game problem description;
  2. Mathematical programming model of Flip Game;
  3. Python calls Gurobi to solve the Flip Game model.

Problem Description

The problem with Flap Game is described as follows:

Given a 5*5 square matrix, the circles in the grid have different colors on both sides, such as either green facing up or red facing up, and the initial circle colors are the same. Clicking on the circle can flip it, change its color, and also change the color of all adjacent cells. The purpose of the game is:

  1. Make all circles different from the initial color;
  2. As few clicks as possible.

mathematical model

The Flip Game can be constructed as an integer program and solved using a solver. This section will introduce the mathematical programming model of Flip Game.

1. Organize data and parameters

  • 5*5 grid

Figure 3 Data and parameters

2. Define decision variables

  • Decision: Which grid to click
  • 变量: x i , j ( i , j = 1 , 2 , … , 5 ) x_{i, j}(i, j = 1,2,\ldots,5) xi,j(i,j=1,2,,5)
  • =1 if ( i , j ) (i,j)(i,j ) is clicked, otherwise it is 0
  • Type: 0-1

3. Construct the objective function

  • Minimize number of clicks
  • min ∑ i , j = 1 , … , 5 x i , j \sum_{i,j=1,\ldots,5}x_{i,j} i,j=1,,5xi,j

4. Set constraints

  • It is simpler to express it with logical constraints
  • x i , j + x i − 1 , j + x i + 1 , j + x i , j − 1 + x i , j + 1 x_{i, j}+x_{i-1, j}+x_{i+1, j}+x_{i, j-1}+x_{i, j+1} xi,j+xi1,j+xi+1,j+xi,j1+xi,j+1is an odd number, ∀ i , j = 1 , … , 5 \forall i, j=1, \ldots, 5i,j=1,,5
  • x i , j = 0 , ∀ i , j < 1 x_{i, j}=0, \forall i, j<1 xi,j=0,i,j<1 i , j > 5 i, j>5 i,j>5

How to translate the above constraints into mathematical form?

  • Introduce auxiliary variables yi, j y_{i, j}yi,j
  • 0 ≤ y i , j ≤ 2 , y i , j 0 \leq y_{i, j} \leq 2, y_{i, j} 0yi,j2,yi,jis an integer, ∀ i , j = 1 , … , 5 \forall i, j=1, \ldots, 5i,j=1,,5
  • x i , j + x i − 1 , j + x i + 1 , j + x i , j − 1 + x i , j + 1 = 2 y i , j + 1 , ∀ i , j = 1 , … , 5 x_{i, j}+x_{i-1, j}+x_{i+1, j}+x_{i, j-1}+x_{i, j+1}=2 y_{i, j}+1,\forall i, j=1, \ldots, 5 xi,j+xi1,j+xi+1,j+xi,j1+xi,j+1=2 yi,j+1,i,j=1,,5

5. Model establishment

Based on the above process, we give the mathematical programming model of Flip Game.
min ⁡ ∑ i , j = 1 , … , 5 xi , j st xi , j + xi − 1 , j + xi + 1 , j + xi , j − 1 + xi , j + 1 = 2 yi , j + 1 , ∀ i , j = 1 , … , 5 0 ≤ yi , j ≤ 2 , yi , j are integers, ∀ i , j = 1 , … , 5 xi , j = 0 , otherwise \begin{aligned} & \min \sum_{i,j=1,\ldots,5}x_{i,j} \\ & \text { st } x_{i, j}+x_{i-1, j}+x_{i+1, j}+x_{i, j-1}+x_{i, j+1}=2 y_{i, j}+1,\forall i, j=1, \ldots, 5\\ & \quad\quad0 \leq y_{i, j} \leq 2, y_{i, j} \text {is an integer, }\forall i, j=1, \ldots, 5 \\ & \quad \quad x_{i, j} =0\text{, otherwise} \\ & \end{aligned}mini,j=1,,5xi,j s.t. xi,j+xi1,j+xi+1,j+xi,j1+xi,j+1=2 yi,j+1,i,j=1,,50yi,j2,yi,jis an integer i ,j=1,,5xi,j=0 , otherwise

Python calls Gurobi to solve

We give the code that uses Python to call Gurobi to solve the above integer programming model:

import gurobipy as gp
from gurobipy import GRB

# create the model object
model = gp.Model("Flap Game")

# define decision variables
x = {
    
    }
y = {
    
    }
for i in range(0, 7):
    for j in range(0, 7):
        if i < 1 or i > 5 or j < 1 or j > 5:
            x[i, j] = model.addVar(vtype=GRB.BINARY, ub=0, name=f"x_{
      
      i}_{
      
      j}")
        else:
            x[i, j] = model.addVar(vtype=GRB.BINARY, name=f"x_{
      
      i}_{
      
      j}")
            y[i, j] = model.addVar(lb=0, ub=2, vtype=GRB.INTEGER, name=f"y_{
      
      i}_{
      
      j}")

# set the objective function
model.setObjective(gp.quicksum(x[i, j] for i in range(1, 6) for j in range(1, 6)), GRB.MINIMIZE)

# add the constraint x[i, j] + x[i-1, j] + x[i+1, j] + x[i, j-1] + x[i, j+1] = 2*y[i, j] + 1
for i in range(1, 6):
    for j in range(1, 6):
        model.addConstr(x[i, j] + x[i-1, j] + x[i+1, j] + x[i, j-1] + x[i, j+1] == 2*y[i, j] + 1)

# optimize the model
model.Params.outputFlag = 0
model.optimize()

# print the results
if model.status == GRB.OPTIMAL:
    print("Optimal objective value:", model.objVal)
    print("Optimal solution:")
    for i in range(1, 6):
        for j in range(1, 6):
            print(f"x_{
      
      i}_{
      
      j} = {
      
      x[i, j].x}, y_{
      
      i}_{
      
      j} = {
      
      y[i, j].x}")
else:
    print("No optimal solution found.")

The solution results are as follows:

Optimal objective value: 15.0
Optimal solution:
x_1_1 = -0.0, y_1_1 = 0.0
x_1_2 = 1.0, y_1_2 = 1.0
x_1_3 = 1.0, y_1_3 = 1.0
x_1_4 = 0.0, y_1_4 = 1.0
x_1_5 = 1.0, y_1_5 = 0.0
x_2_1 = 0.0, y_2_1 = -0.0
x_2_2 = 1.0, y_2_2 = 1.0
x_2_3 = 1.0, y_2_3 = 2.0
x_2_4 = 1.0, y_2_4 = 1.0
x_2_5 = 0.0, y_2_5 = 1.0
x_3_1 = -0.0, y_3_1 = -0.0
x_3_2 = 0.0, y_3_2 = 1.0
x_3_3 = 1.0, y_3_3 = 1.0
x_3_4 = 1.0, y_3_4 = 2.0
x_3_5 = 1.0, y_3_5 = 1.0
x_4_1 = 1.0, y_4_1 = 1.0
x_4_2 = 1.0, y_4_2 = 1.0
x_4_3 = 0.0, y_4_3 = 1.0
x_4_4 = 1.0, y_4_4 = 1.0
x_4_5 = 1.0, y_4_5 = 1.0
x_5_1 = 1.0, y_5_1 = 1.0
x_5_2 = 1.0, y_5_2 = 1.0
x_5_3 = 0.0, y_5_3 = -0.0
x_5_4 = 0.0, y_5_4 = -0.0
x_5_5 = 0.0, y_5_5 = 0.0

It can be seen that the model has a solution, and we have found the optimal clicking strategy to win the game.


Summarize

This article introduces the mathematical programming model of Flip Game, and gives the complete code for Python to call Gurobi to solve the mathematical programming model of Flip Game. The author has not conducted game verification because my level is limited. If the model and code are wrong, please criticize and correct them.

Guess you like

Origin blog.csdn.net/cros1/article/details/132134622