Get minimax move in string - algorithm

I'm following this pseudocode to write my code in Java. Everything is clear and works as expected except for actually capturing the best move. It seems that my added if condition inside the maximizing player condition returns the last playable move in the current board. So it always plays down. How can I track the best possible move?
Here's the pseudocode
function minimax(position, depth, alpha, beta, maximizingPlayer)
if depth == 0 or game over in position
return static evaluation of position
if maximizingPlayer
maxEval = -infinity
for each move of validMoves
eval = minimax(child, depth - 1, alpha, beta false)
maxEval = max(maxEval, eval)
alpha = max(alpha, eval)
if depth == 3
bestmove = move (Is this correct?)
if beta <= alpha
break
return maxEval
else
minEval = +infinity
for each move of validMoves
eval = minimax(child, depth - 1, alpha, beta true)
minEval = min(minEval, eval)
beta = min(beta, eval)
if beta <= alpha
break
return minEval
// initial call
minimax(currentPosition, 3, -∞, +∞, true)

You're not actually checking that the move is better than the others, so you're just getting the last move.
You need to check the the move's score is higher than that of the others seen before it. Since you already have maxEval which contains the highest score seen so far, you can simply add the check that eval == maxEval before updating bestmove.

Related

Fastest way to find path from top left to bottom right of a matrix

Say we have an n x m matrix with the cells either empty or full. The top left and bottom right cells are both empty. You can move up, down, left, or right. What is the fastest method to see if a path of length <= T of empty cells connects the top left and bottom right corner? I've tried both DFS and BFS with a matrix keeping track of how long it took to get to a particular cell, but both methods were too slow.
EDIT: I don't have access to the code anymore, but here's the pseudocode of what I did.
def find_path(grid, T):
visited = array(grid.dims)
visited.fill(0)
stack = []
stack.append((0, 0, T))
while len(queue) > 0:
pos = stack.pop()
if pos[0] == len(grid) and pos[1] == len(grid[0]):
return True
if pos[2] > 0:
if pos[0] < len(grid)-1 and grid[pos[0]+1][pos[1]] == empty and visited[pos[0]+1][pos[1]] < T-1:
visited[pos[0]+1][pos[1]] = T-1
stack.append(pos[0]+1, pos[1], T-1)
{same for right, left, up}
return False
I'm not quite sure what you're trying to do with the visited array, but "keeping track of how long it took to get to a particular cell" is not going to work with DFS, and is unnecessary with BFS. Probably the problems with your real code are in there somewhere.
The straightforward way to solve this is with a level-by-level BFS, like (in similar pseudocode):
def hasPath(grid,T):
gridcopy = copy(grid)
level=[(0,0)]
for pathlen in 1..T-1:
# Invariant: the positions in level are at path length pathlen
nextlevel=[]
for (x,y) in level:
# each valid direction is north plus maybe southwest and maybe southeast
for sw in 0..1, se in 0..1:
testx = x-sw+se
testy = y-1+sw+se
if testx >= 0 and
testy >= 0 and
testx < grid.width and
testy < grid.height and
gridcopy[testy][testx] == empty:
if testx==grid.width-1 and testy==grid.height-1
return True
nextlevel.append((testx,testy))
gridcopy[testy][testx] = blocked
level = nextlevel
return false

Implementing the CCL (Connected Component Labeling) algorithm without the union-find data structure?

Hello fellow programmers!
A week ago I have been asigned the task of implementing the Connected Components Algorithm, mainly to extract the number of objects from an image.
You can read more about the algorithm here (https://en.wikipedia.org/wiki/Connected-component_labeling), the variant I am trying to implement is the two pass one.
This is my current attempt:
% ------------------------------------------------------------------------------
% -> Connected Component Labeling (CCL) Algorithm
% -> 4-Connectivity Version
% ------------------------------------------------------------------------------
% ------------------------------------------------------------------------------
% - [ Pre-Scan Code To Get Everything Ready ] -
% ------------------------------------------------------------------------------
% Starting With A Clean (Workspace) And (Command Window).
clear, clc;
% Instead Of Loading An Actual Image, We Are Creating A Matrix Of Zeros And Ones, Representing A Binary Image.
originalImage = [ ...
0 1 0
1 0 1
0 1 0 ];
% Creating A Bigger Matrix That We Will Use To Store The Original Image In Its Middle, This Will Help Us Eliminate Border Checking In The Raster Scan.
binaryImage = zeros(size(originalImage) + 2);
% Copying The Pixels From The Original Image Into The Middle Of The Larger Matrix We Created.
binaryImage(2:size(originalImage, 1) + 1, 2:size(originalImage, 2) + 1) = originalImage;
% Getting The Number Of Rows (Height) And Number Of Columns (Width) Of The Binary Image.
[imageRows, imageColumns] = size(binaryImage);
% Creating A Matrix The Same Dimensions As The Binary Image In Which The Labeling Will Happen.
labeledImage = zeros(imageRows, imageColumns);
% Creating A Label Counter That We Will Use To Assign When We Create New Labels.
labelCounter = 1;
% ------------------------------------------------------------------------------
% - [First Scan: Assigning Labels To Indices] -
% ------------------------------------------------------------------------------
% Going Over Each Row In The Image One By One.
for r = 1:imageRows
% Going Over Each Column In The Image One By One.
for c = 1:imageColumns
% If The Pixel Currently Being Scanned Is A Foreground Pixel (1).
if (binaryImage(r, c) == 1)
% Since We Are Working With 4-Connectivity We Only Need To Read 2 Labels, Mainly The (Left) And (Top) Labels.
% Storing Them In Variables So Referencing Them Is Easier.
left = labeledImage(r, c - 1);
top = labeledImage(r - 1, c);
% If Left == 0 And Top == 0 -> Create A New Label, And Increment The Label Counter, Also Add The Label To The Equivalency List.
if (left == 0 && top == 0)
labeledImage(r, c) = labelCounter;
labelCounter = labelCounter + 1;
% If Left == 0 And Top >= 1 -> Copy The Top Label.
elseif (left == 0 && top >= 1)
labeledImage(r, c) = top;
% If Left >= 1 And Top == 0 -> Copy The Left Label.
elseif (left >= 1 && top == 0)
labeledImage(r, c) = left;
% If Left >= 1 And Top >= 1 -> Find The Minimum Of The Two And Copy It, Also Add The Equivalent Labels To The Equivalency List, So We Can Fix Them In The Second Scan.
elseif (left >= 1 && top >= 1)
labeledImage(r, c) = min(left, top);
end
end
end
end
% ------------------------------------------------------------------------------
% - [Second Scan: Fixing The Connected Pixels But Mismatched Labels] -
% ------------------------------------------------------------------------------
for r = 1:imageRows
for c = 1:imageColumns
end
end
This first pass is going through without any issues, I have tried multiple tests on it, however I have no idea how to implement the second pass, in which I have to fix the equivalent labels in the labeled matrix.
I did do my research online, and the preferred way to do it is to use the union-find (disjoint set) data structure to store the equivalences between the labels.
However, since I am using MATLAB and the union-find data structure is not implemented, I have to implement it myself, which is cumbersome and requires massive time and hard work due to MATLAB being an interpreted language.
So, I am open to ideas on implementing the second pass without having to use the union-find data structure.
Thanks in advance!
If you don't want to use union-find, then you should really do the flood-fill-each-component algorithm (the other one in Wikipedia).
Union-find is neither difficult nor slow, however, and it's what I would use to solve this problem. To make a simple and fast implementation:
Use a matrix of integers the same shape as your image to represent the sets -- each integer in the matrix represents the set of the corresponding pixel.
An integer x represents a set as follows: If x < 0, then it is a root set of size -x. If x>=0 then it's a child set with parent set x (i.e., row x/width, column x%width)). Initialize all sets to -1 since they all start off as roots with size 1.
Use union-by-size and path compression

What is wrong with my Gradient Descent algorithm

Hi I'm trying to implement Gradient Descent algorithm for a function:
My starting point for the algorithm is w = (u,v) = (2,2). The learning rate is eta = 0.01 and bound = 10^-14. Here is my MATLAB code:
function [resultTable, boundIter] = gradientDescent(w, iters, bound, eta)
% FUNCTION [resultTable, boundIter] = gradientDescent(w, its, bound, eta)
%
% DESCRIPTION:
% - This function will do gradient descent error minimization for the
% function E(u,v) = (u*exp(v) - 2*v*exp(-u))^2.
%
% INPUTS:
% 'w' a 1-by-2 vector indicating initial weights w = [u,v]
% 'its' a positive integer indicating the number of gradient descent
% iterations
% 'bound' a real number indicating an error lower bound
% 'eta' a positive real number indicating the learning rate of GD algorithm
%
% OUTPUTS:
% 'resultTable' a iters+1-by-6 table indicating the error, partial
% derivatives and weights for each GD iteration
% 'boundIter' a positive integer specifying the GD iteration when the error
% function got below the given error bound 'bound'
%
% The error function
E = #(u,v) (u*exp(v) - 2*v*exp(-u))^2;
% Partial derivative of E with respect to u
pEpu = #(u,v) 2*(u*exp(v) - 2*v*exp(-u))*(exp(v) + 2*v*exp(-u));
% Partial derivative of E with respect to v
pEpv = #(u,v) 2*(u*exp(v) - 2*v*exp(-u))*(u*exp(v) - 2*exp(-u));
% Initialize boundIter
boundIter = 0;
% Create a table for holding the results
resultTable = zeros(iters+1, 6);
% Iteration number
resultTable(1, 1) = 0;
% Error at iteration i
resultTable(1, 2) = E(w(1), w(2));
% The value of pEpu at initial w = (u,v)
resultTable(1, 3) = pEpu(w(1), w(2));
% The value of pEpv at initial w = (u,v)
resultTable(1, 4) = pEpv(w(1), w(2));
% Initial u
resultTable(1, 5) = w(1);
% Initial v
resultTable(1, 6) = w(2);
% Loop all the iterations
for i = 2:iters+1
% Save the iteration number
resultTable(i, 1) = i-1;
% Update the weights
temp1 = w(1) - eta*(pEpu(w(1), w(2)));
temp2 = w(2) - eta*(pEpv(w(1), w(2)));
w(1) = temp1;
w(2) = temp2;
% Evaluate the error function at new weights
resultTable(i, 2) = E(w(1), w(2));
% Evaluate pEpu at the new point
resultTable(i, 3) = pEpu(w(1), w(2));
% Evaluate pEpv at the new point
resultTable(i, 4) = pEpv(w(1), w(2));
% Save the new weights
resultTable(i, 5) = w(1);
resultTable(i, 6) = w(2);
% If the error function is below a specified bound save this iteration
% index
if E(w(1), w(2)) < bound
boundIter = i-1;
end
end
This is an exercise in my machine learning course, but for some reason my results are all wrong. There must be something wrong in the code. I have tried debugging and debugging it and haven't found anything wrong...can someone identify what is my problem here?...In other words can you check that the code is valid gradient descent algorithm for the given function?
Please let me know if my question is too unclear or if you need more info :)
Thank you for your effort and help! =)
Here is my results for five iterations and what other people got:
PARAMETERS: w = [2,2], eta = 0.01, bound = 10^-14, iters = 5
As discussed below the question: I would say the others are wrong... your minimization leads to smaller values of E(u,v), check:
E(1.4,1.6) = 37.8 >> 3.6 = E(0.63, -1.67)
Not a complete answer but lets go for it:
I added a plotting part in your code, so you can see whats going on.
u1=resultTable(:,5);
v1=resultTable(:,6);
E1=E(u1,v1);
E1(E1<bound)=NaN;
[x,y]=meshgrid(-1:0.1:5,-5:0.1:2);Z=E(x,y);
surf(x,y,Z)
hold on
plot3(u1,v1,E1,'r')
plot3(u1,v1,E1,'r*')
The result shows that your algorithm is doing the right thing for that function. So, as other said, or all the others are wrong, or you are not using the right equation from the beggining.
(I apologize for not just commenting, but I'm new to SO and cannot comment.)
It appears that your algorithm is doing the right thing. What you want to be sure is that at each step the energy is shrinking (which it is). There are several reasons why your data points may not agree with the others in the class: they could be wrong (you or others in the class), they perhaps started at a different point, they perhaps used a different step size (what you are calling eta I believe).
Ideally, you don't want to hard-code the number of iterations. You want to continue until you reach a local minimum (which hopefully is the global minimum). To check this, you want both partial derivatives to be zero (or very close). In addition, to make sure you're at a local min (not a local max, or saddle point) you should check the sign of E_uu*E_vv - E_uv^2 and the sign of E_uu look at: http://en.wikipedia.org/wiki/Second_partial_derivative_test for details (the second derivative test, at the top). If you find yourself at a local max or saddle point, your gradient will tell you not to move (since the partial derivatives are 0). Since you know this isn't optimal, you have to just perturb your solution (sometimes called simulated annealing).
Hope this helps.

dynamic programming approach in a non-specific direction calculation

I am trying to solve Ball Removal problem on topcoder, pasting the problem statement here as login is required to access this link.
Problem Statement
You have N balls, where N is odd. The balls are numbered from 0 to N-1. In that order, they are arranged into a row going from the left to the right.
In addition to the number, each ball has either the word "left" or the word "right" written on it. For simplicity, we will use the character '<' instead of "left", and the character '>' instead of "right". You are given the labels on all balls as the String label. For each i, character i of label represents the word on ball i.
You will now repeat the following procedure:
Choose a ball that is not at either end of the row of balls.
If the chosen ball has the label '<', remove the chosen ball and also the ball immediately to the left of it. Otherwise, remove the chosen ball and also the ball to the right of it.
Without reordering the remaining balls, push them together to get rid of the gap created in the previous step.
The process ends when only one ball remains in the row. That ball is called the survivor. Note that the numbers on the balls do not change during the process.
Find all possible survivors. Your method must return a String containing exactly N characters. If ball i can be the survivor, character i of the return value must be 'o' (lowercase oh). Otherwise, the corresponding character must be '.' (a period).
Constraints
label will contain between 3 and 49 characters, inclusive.
label will contain an odd number of characters.
Each character of label will be either '>' or '<'.
Examples
"<<>"
Returns: "..o"
Initially, you have three balls. Since you cannot choose balls at the ends of the row, you have to choose ball 1. As its label is '<', you remove balls 0 and 1. Hence the only possible survivor is ball 2.
1)
">>><<"
Returns: "o...o"
If you choose ball 2 or ball 3 first, you have to choose ball 1 next, and the survivor will be ball 0. If you choose ball 1 first, you have to choose ball 3 next, and the survivor will be ball 4.
2)
"<<><<"
Returns: "....o"
3)
"<><<><>"
Returns: "o.....o"
4)
">>><<<>>>>><<<>"
Returns: "o.....o.o.....o"
I am thinking of a dynamic programming approach to this problem, I am thinking of having an boolean array to mark which of the characters have been deleted and then find which is next left and next right but that makes the approach quite inefficient and I have to write a recursive method. For implementing a dynamic programming approach I need to maintain a state. But I am not able to figure out what I should keep as state, in my thinking a state is combination of both current string and current index, but maintaining a string for state doesn't seem correct to me.
One more problem I am facing is that in this case I don't have a particular direction if I change direction result changes also if I move left to right I might need to move right to left also.
Please help me in finding a proper approach to this problem.
The state can be boolean - DP[left][right][isLeftBoundary][isRightBoundary].
This means if the substring starting at left and finishing at right can be fully eliminated.
isLeftBoundary is just a boolean flag if the left symbol is the leftmost of the string.
isRightBoundary is just a boolean flag if the right symbol is the rightmost of the string.
if DP[0][i - 1][1][0] and DP[i + 1][N][0][1] are true, it means the ball at position i can remain.
int canDelete(int l, int r, int st, int en)
{
if (l > r) return 1; //we succeeded in removing the whole string
if (DP[l][r][st][en] != -1)
return DP[l][r][st][en];
int ans = 0;
//i is the last removed ball, which will eliminate the whole string[l, r]
for (int i = l + st; i <= r - en; i++)
{
if (inp[i] == '<') //it will remove a ball to the left, but which one?
{
for (int j = l; j < i; j++) //ball i will remove ball j
{
if (canDelete(l, j - 1, st, 0)
&& canDelete(j + 1, i - 1, 0, 0)
&& canDelete(i + 1, r, 0, en))
ans = 1;
}
}
else
if (inp[i] == '>') //it will remove a ball to the right, but which one?
{
for (int j = i + 1; j <= r; j++) //ball i will remove ball j
{
if (canDelete(l, i - 1, st, 0)
&& canDelete(i + 1, j - 1, 0, 0)
&& canDelete(j + 1, r, 0, en))
ans = 1;
}
}
}
return ans;
}

alternative rank function RBTree (red black tree)

I have an order-statistic augmented red black tree.
it works for the most part. but i need to implement a fast function (O(lg n)) that mostly returns the place of a node in sorted order. like the OS-rank function from my textbook. but with one twist: the return value if two nodes have the same score, should be the same. here is the os-rank function (in pseudocode, for a given node x, where root is the root of the tree).
OS-Rank(x)
r=x.left.size+1
y=x
while y!=root
if y==y.p.right
r+=y.p.left.size+1
y=y.p
return r
But: what i need is something where if A has key 1 and Node B has key 1, the function returns 1 for both. and so on. I tried myself with something like this.
rank(x)
start with value r=1
check that x.right is not Nil
case x.right has the same key as x
add x.right.#nodeswithkeyhigher(x.key) to r
other cases: add x.right.size to r
y=x
while y != root
if y.parent.left == y
case y.parent.right.key>x.key
add y.parent.right to r
other cases
add y.parent.right.#nodeswithkeyhigher(x.key) to r
y=y.parent
return r
Guess what: a testcase failed. I'd like to know if this is a correct way of doing things, or if perhaps i made some mistake i am not seeing (else the mistake is in the Node.#nodeswithkeyhigher(key) function).
edit: final paragraph for answer, thanks to Sticky.
tl;dr: skip to last paragraphs
This is the same issue I'm having trouble with. (Yes DS aswell). So far all runs except 5 are correct. I've tested several things, one being a very simple one: Just exchange left and right in OSRank. In some cases it gave a correct answer but in the harder cases it was quite a bit off. Oh I also added that if y.score == y.parent.score I only add the right size of y.parent, if not I add the right size + 1.
public int OSRank(Node x)
{
int r = x.Right.Size + 1;
Node y = x;
while (y != root)
{
if (y == y.Parent.Left)
{
if (y.Score == y.Parent.Score)
r = r + y.Parent.Right.Size;
else
r = r + y.Parent.Right.Size + 1;
}
y = y.Parent;
}
return r;
}
Let's first test this method on the tree on page 340 (figure 14.1). We'll search for the rank of 38 (which should return 4 because 39, 47 and 41 are higher):
r = 1 + 1 = 2 //Right side + 1
r = 2 //nothing happens because we're a right child
r = r + 1 + 1 = 4 //we're a left child, the key of our parent is larger and parent.Right.size = 1
r = 4 //nothing happens because we're a right child
So in this case the result is correct. But what if we add another node with key 38 to our tree. That reshapes our tree a bit, the right part of node 26 now looks like:
(I'm not allowed to add images yet so look here:http://i47.tinypic.com/358ynhh.png)
If we would use the same algorithm we'd get the following result (picking the red one):
r = 0 + 1 = 1 //no right side
r = 1 //we're a right child
r = 1 //we're a right child
r = 1 + 3 + 1 = 5 //The 3 comes from the size of node 41.
r = 5 //we're a right child
Though we expect rank 4 here. While I was typing this out I noticed that we check if y.Score == y.Parent.Score, but I completely forgot y changes. So in line 4 the clause "y.Score == y.Parent.Score" was false because we compared node 30 with 38. So if we change that line to:
if (x.Score == y.Parent.Score)
The algorithm outputs rank 4, which is correct. This means we eliminated another issue. But there are more, which I didn't figure out either:
The case in which Y.Parent.Right contains duplicate keys. Technically if we have 3 nodes with the same key, they should count as 1.
The case in which Y.Parent.Right contains keys that are equal to x.Key (the node you want the rank of). That would put us a few ranks back, incorrectly.
I suppose you could keep another integer which holds the amount of nodes with a higher score. Upon insertion you could climb the tree and adjust values if the subtree of that node doesn't contain a node with the same score. But how this is done (and efficiently) is unknown to me right now.
edit: First find the final successor of x with the same score x. Then calculate the rank the normal way. The code above works.

Resources