-
Notifications
You must be signed in to change notification settings - Fork 25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add chess_position example #266
Conversation
examples/chess_position.py
Outdated
(((board[1,1] == p) & (board[1,3] == p) & (board[1,0] == p) & (board[0,2] == b)).implies(Xor([board[0,1] == r,board[0,0] == r]))), | ||
(((board[1,4] == p) & (board[1,6] == p) & (board[1,7] == p) & (board[0,5] == b)).implies(Xor([board[0,6] == r,board[0,7] == r]))), | ||
# If both bishops are stuck and pawns are in starting position, king and queen are also in starting position | ||
(((board[1,1] == p) & (board[1,2] == p) & (board[1,3] == p) & (board[1,4] == p) & (board[1,5] == p) & (board[1,6] == p)).implies((board[0,3] == q) | (board[0,4] == k))), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here maybe you mean implies((board[0,3] == q) & (board[0,4] == k)))?
In the description you say that this means that both King and queen are in starting position, not at least one of them
examples/chess_position.py
Outdated
(((board[1,4] == p) & (board[1,6] == p) & (board[1,7] == p) & (board[0,5] == b)).implies(Xor([board[0,6] == r,board[0,7] == r]))), | ||
# If both bishops are stuck and pawns are in starting position, king and queen are also in starting position | ||
(((board[1,1] == p) & (board[1,2] == p) & (board[1,3] == p) & (board[1,4] == p) & (board[1,5] == p) & (board[1,6] == p)).implies((board[0,3] == q) | (board[0,4] == k))), | ||
(((board[6,1] == P) & (board[6,2] == P) & (board[6,3] == P) & (board[6,4] == P) & (board[6,5] == P) & (board[6,6] == P)).implies((board[7,3] == Q) | (board[7,4] == K))), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above
examples/chess_position.py
Outdated
# All the constraints that a chess board has to follow | ||
model = Model( | ||
# Both colors have only one king | ||
(sum(board[l,c] == k for l in range(0,8) for c in range(0,8)) == 1), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't it be better to use a count constraint for k (and resp. K) for this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is just a
Count(board, k) == 1,
Count(board, K) == 1,
...
examples/chess_position.py
Outdated
return dict.get(x, x) | ||
|
||
|
||
piece_probabilities = np.array([[-1.1558e+01, -1.8940e-01, -1.0785e+01, -8.4097e+00, -1.3034e+01, -8.7986e+00, -2.6694e+00, 1.2009e+01, -3.5726e+00, -9.1412e-01, -2.0600e+00, -5.9005e-01], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need a lot more documentation on what these are. We know from the report, but if it is added as an example in CPMpy, not everyone will have read the report. Need far more explanation on what this is, and maybe some references on what you can use to get these probabilities from an image.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, these are not probabilities. I assume it is the output of the NNs for the prediction. It is a bit weird for output, with the range of the values. It should be explained how you got them.
examples/chess_position.py
Outdated
[-1.0578e+01, -9.6113e+00, -1.0476e+01, -6.9775e+00, -3.4868e+00, -9.2788e+00, 2.2917e-01, 1.6189e+00, -1.9423e+00, 9.8658e-01, 8.7442e+00, 1.9664e+00], | ||
[ 1.7821e+00, 2.5520e+00, 2.3929e+00, -3.7030e-01, -3.3090e-01, 1.9798e-01, -6.8749e+00, -6.4092e+00, -5.7582e+00, -5.6637e+00, -8.7920e+00, -7.5211e+00]]) | ||
|
||
occupancy_in_board = np.array([False, False, False, False, False, False, True, False, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same for this, some more explanation (and maybe before the probabilities, as it is predicted first.
examples/chess_position.py
Outdated
(sum(board[l,c] < 6 for l in range(0,8) for c in range(0,8)) <= 16), | ||
(sum(((board[l,c] >= 6) & (board[l,c] < 12)) for l in range(0,8) for c in range(0,8)) <= 16), | ||
# Both colors have maximum 8 pawns | ||
(sum(board[l,c] == p for l in range(0,8) for c in range(0,8)) <= 8), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again,
Count(board, p) <= 8,
Count(board, P) <= 8,
examples/chess_position.py
Outdated
(sum(board[0,c] == p for c in range(0,8)) == 0), | ||
(sum(board[0,c] == P for c in range(0,8)) == 0), | ||
(sum(board[7,c] == p for c in range(0,8)) == 0), | ||
(sum(board[7,c] == P for c in range(0,8)) == 0), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general the constraints can be written in a better way, See previous comments
examples/chess_position.py
Outdated
((board[1,1] == p) & (board[0,0] == b)).implies(sum(board[l,c] == P for l in range(0,8) for c in range(0,8)) <= 7), | ||
) | ||
|
||
# Put the index of the maximum value into the second row of the pieces variable |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The following 'for' is not needed, it is overcomplicated for something that can be done in a much more straightforward way, and it will make the solving process much slower too.
You try to match the probabilities with the pieces, while you already have the probabilities and you already have the pieces in different arrays, but you created new variables for the matching although it is 1 to 1.
You have 22 pieces in this example. why not match directly the 22 cells in the board that are predicted to have a piece (which you can just take by using board[occupancy_in_board]) with the 22 rows of pieces_values? You can do that in the objective function and avoid all these variables, and constraints.
examples/chess_position.py
Outdated
model += (board[int(i/8), i%8] == pieces[1, index]) | ||
index += 1 | ||
else: | ||
model += (board[int(i/8), i%8] == E) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The above for is not needed either.
To force the empty cells, you can just do
model += board[occupancy_in_board == False] == E
and for the non empty cells, you can link directly with the probabilities in the objective function. So, you use only the board variables.
examples/chess_position.py
Outdated
model += (board[int(i/8), i%8] == E) | ||
|
||
# Maximize the probabilites of the pieces to get the most likely board | ||
model.maximize(sum(pieces[0])) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Based also on my comments before, regarding the variables for pieces that are not needed, I suggest to replace with
obj = sum(lp[v] for lp, v in zip(pieces_values, board[occupancy_in_board]))
model.maximize(obj)
This way, you directly linked the probabilities in pieces_values, with the cells in the board that need to be predicted.
Already tried the above and yield to the same solution.
And importantly, from 264 seconds that were needed to solve, it dropped to less than 0.5s.
The model makes a chess board that can be played in an actual game of chess from the probabilities of every piece and the squares where pieces are present.