I have created a class for complex numbers:
public class Complex {
private double x; //Real part x of the complex number x+iy.
private double y; //Imaginary part y of the complex number x+iy.
public Complex(double x, double y) { //Constructor: Initializes x, y.
this.x=x;
this.y=y;
}
public Complex(double x) { //Real constructor - initialises with a real number.
this(x, 0.0);
}
public Complex() { //Default constructor; initialiase x and y to zero.
this(0.0, 0.0);
}
}
What I would like to do is create a function Polynomial, which would take an array of coefficients, and filter it so that if for example [1,0,0,1,0,0,0,0,0...], it would return an array of length 4. Since the zero's that are left, have no use in a polynomial.
Here's how a complex array would look like
Complex [] coeff = new Complex [] {
new Complex(-1.0 ,0.0), new Complex(),
new Complex() , new Complex(1.0, 0.0)
};
A polynomial would be defined as
Polynomial p = new Polynomial(coeff);
Here's the problem formulation:
Here is how the polynomial would have to look like, typing in the complex array coefficients
I was thinking of constructing an algorithm which searches for the first zero of the zero sequence(which is until the end of the array), and then deletes the zeros.
Also I was thinking of inverting the entries of the array so that [0,1,1,0,1,0,0,0] would be [0,0,0,1,0,1,1,0] and then creating a function which would start "recording" my new array from the first non Trivial entry.
How would I go with creating such a function?
My attempt for this is:
int j=0;
for(int i=coeff.length-1; i>=0; i-=1)
{
if(coeff[i].getReal()== 0 && coeff[i].getImag() == 0 ){
j=+1;
}
else {
break;
}
}
int a = coeff.length-j;
this.coeff = new Complex[a];
for (int i=0;i<this.coeff.length;i+=1){
this.coeff[i]=coeff[i];
}
}
And for example I would like to print :
Complex a1=new Complex(-3, 1);
Complex a2=new Complex(2, 0.3);
Complex a3=new Complex();
Complex b=new Complex();
Complex[] com=new Complex[] {a1,b, a2, a3,b};
and the output is :
(-3.0+1.0i)+ (0.0+0.0i)X^1+(2.0+0.3i)X^2+(0.0+0.0i)X^3
But is supposed to be :
(-3.0+1.0i)+ (0.0+0.0i)X^1+(2.0+0.3i)X^2
And I've tried adding a "-1" to int a = coeff.length-j; :
int a = coeff.length-j-1;
but then if i print out
Complex[] com=new Complex[] {a1,b, a2, a3,b,b,b,b,b,b};
It's going to give me the same results (ie storing the trivial coefficients).
How can i make the contructor not store those trivial coefficients?
I think that the way to go in here is by iterating over the Array for the end to the start, just like you were trying. The problem with your code is the next:
if(coeff[i].getReal()== 0 && coeff[i].getImag() == 0 ){
j=+1; //Here! I think you wanted to do j+=1
}
At doing j=+1 you are making j to always have a value of 1. So, changing j=+1 to j+=1 will fix this.
Also, I did a different code if you want to check it. At the end, it does the same but I think is cleaner.
public class Polynomial {
private Complex[] coeff;
public Polynomial(Complex[] coeff) {
this.coeff = cleanCoeff(coeff);
}
private Complex[] cleanCoeff(Complex[] coeff) {
int length = coeff.length;
Complex complex = null;
for (int i = coeff.length - 1; i >= 0 ; i--) {
complex = coeff[i];
if(complex.getX() == 0 && complex.getY() == 0) {
length--;
}else {
break;
}
}
return Arrays.copyOf(coeff, length);
}
public Complex[] getCoeff() {
return coeff;
}
}
I hope this answer helps you.
This could be done relatively easily using something like the following:
int effective_len(Complex coeff[]) {
int pos = 0;
Complex zero();
for (int i=0; i<coeff.lengh; i++) {
if (!zero.equals(coeff[i])) {
pos = i;
}
}
return pos + 1;
}
For this you will need to define the equals method where you just check the real and imaginary components, but this should get you where you need to go.
---------------
Actual Question
---------------
Ok, the real problem is not with alpha-beta pruning vs minimax algorithms. The problem is that minimax algorithm when in a tree will give only the best solutions whereas alpha-beta will give the correct value, but multiple children have that best value and some of these children shouldn't have this value.
I guess the ultimate question is, what is the most efficient way to get the best (could be multiple in the case of a tie) child of the root node.
The algorithm produces the correct value, but multiple nodes tie with that value, even though some of the moves are obviously wrong.
Example:
TickTackToe
-|-|O
-|X|-
-|X|-
will produce the values as:
(0,1) and (1,0) with value of -0.06 with my heuristic
(0,1) is the correct value as it will block my X's but (0,1) is wrong as then next move i can put an X at (0,1) and win.
When i run the same algorithm without the
if(beta<=alpha)
break;
It only returns the (0,1) with value -0.06
---------------
Originally posted question, now just sugar
---------------
I've spent days trying to figure out why my min max algorithm works, but when i add alpha beta pruning to it, it doesn't work. I understand they should give the same results and I even made a quick test of that.
My question, is why doesn't my implementation produce the same results?
This is a tic tak toe implementation in android. I can beat the algorithm sometimes when
if(beta<=alpha) break;
is not commented out, but when it is commented out it is undefeatable.
private static double minimax(Node<Integer,Integer> parent, int player, final int[][] board, double alpha, double beta, int depth) {
List<Pair<Integer, Integer>> moves = getAvailableMoves(board);
int bs = getBoardScore(board);
if (moves.isEmpty() || Math.abs(bs) == board.length)//leaf node
return bs+(player==X?-1:1)*depth/10.;
double bestVal = player == X ? -Integer.MAX_VALUE : Integer.MAX_VALUE;
for(Pair<Integer, Integer> s : moves){
int[][] b = clone(board);
b[s.getFirst()][s.getSecond()]=player;
Node<Integer, Integer> n = new Node<>(bs,b.hashCode());
parent.getChildren().add(n);
n.setParent(parent);
double score = minimax(n,player==O?X:O,b,alpha,beta, depth+1);
n.getValues().put("score",score);
n.getValues().put("pair",s);
if(player == X) {
bestVal = Math.max(bestVal, score);
alpha = Math.max(alpha,bestVal);
} else {
bestVal = Math.min(bestVal, score);
beta = Math.min(beta,bestVal);
}
/*
If i comment these two lines out it works as expected
if(beta<= alpha)
break;
*/
}
return bestVal;
}
Now this wouldn't be a problem for tick tack toe due to the small search tree, but i then developed it for checkers and noticed the same phenomenon.
private double alphaBeta(BitCheckers checkers, int depth, int absDepth, double alpha, double beta){
if(checkers.movesWithoutAnything >= 40)
return 0;//tie game//needs testing
if(depth == 0 || checkers.getVictoryState() != INVALID)
return checkers.getVictoryState()==INVALID?checkers.getBoardScore()-checkers.getPlayer()*moves/100.:
checkers.getPlayer() == checkers.getVictoryState() ? Double.MAX_VALUE*checkers.getPlayer():
-Double.MAX_VALUE*checkers.getPlayer();
List<Pair<Pair<Integer, Integer>, Pair<Integer, Integer>>> moves;
if(absDepth == maxDepth)
moves = (List<Pair<Pair<Integer, Integer>, Pair<Integer, Integer>>>) node.getValues().get("moves");
else
moves = checkers.getAllPlayerMoves();
if(moves.isEmpty()) //no moves left? then this player loses
return checkers.getPlayer() * -Double.MAX_VALUE;
double v = checkers.getPlayer() == WHITE ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;
for(Pair<Pair<Integer, Integer>, Pair<Integer, Integer>> i : moves){
BitCheckers c = checkers.clone();
c.movePiece(i.getFirst().getFirst(),i.getFirst().getSecond(),i.getSecond().getFirst(),i.getSecond().getSecond());
int newDepth = c.getPlayer() == checkers.getPlayer() ? depth : depth - 1;
if(checkers.getPlayer() == WHITE) {
v = Math.max(v, alphaBeta(c, newDepth, absDepth - 1, alpha, beta));
alpha = Math.max(alpha,v);
}else {
v = Math.min(v, alphaBeta(c, newDepth, absDepth - 1, alpha, beta));
beta = Math.min(beta,v);
}
if(absDepth == maxDepth) {
double finalScore = v;
for(Node n : node.getChildren())
if(n.getData().equals(i)){
n.setValue(finalScore);
break;
}
}
/*
If i comment these two lines out it works as expected
if(beta<= alpha)
break;
*/
}
return v;
}
I tested it with pvs and it gives the same results as alpha-beta pruning, ie not nearly as good as just minimax.
public double pvs(BitCheckers checkers, int depth, int absDepth, double alpha, double beta){
if(checkers.movesWithoutAnything >= 40)
return 0;//tie game//needs testing
if(depth == 0 || checkers.getVictoryState() != INVALID)
return checkers.getVictoryState()==INVALID?checkers.getBoardScore()-checkers.getPlayer()*moves/100.:
checkers.getPlayer() == checkers.getVictoryState() ? Double.MAX_VALUE*checkers.getPlayer():
-Double.MAX_VALUE*checkers.getPlayer();
List<Pair<Pair<Integer, Integer>, Pair<Integer, Integer>>> moves;
if(absDepth == maxDepth)
moves = (List<Pair<Pair<Integer, Integer>, Pair<Integer, Integer>>>) node.getValues().get("moves");
else
moves = checkers.getAllPlayerMoves();
if(moves.isEmpty()) //no moves left? then this player loses
return checkers.getPlayer() * -Double.MAX_VALUE;
int j = 0;
double score;
for(Pair<Pair<Integer, Integer>, Pair<Integer, Integer>> i : moves){
BitCheckers c = checkers.clone();
c.movePiece(i.getFirst().getFirst(),i.getFirst().getSecond(),i.getSecond().getFirst(),i.getSecond().getSecond());
int newDepth = c.getPlayer() == checkers.getPlayer() ? depth : depth - 1;
double sign = c.getPlayer() == checkers.getPlayer()? -1 : 1;
if(j++==0)
score = -pvs(c,newDepth,absDepth-1,sign*-beta,sign*-alpha);
else {
score = -pvs(c,newDepth, absDepth-1,sign*-(alpha+1),sign*-alpha);
if(alpha<score || score<beta)
score = -pvs(c,newDepth,absDepth-1,sign*-beta,sign*-score);
}
if(absDepth == maxDepth) {
double finalScore = score;
for(Node n : node.getChildren())
if(n.getData().equals(i)){
n.setValue(finalScore);
break;
}
}
alpha = Math.max(alpha,score);
if(alpha>=beta)
break;
}
return alpha;
}
Checkers without alpha beta pruning is good, but not great. I know with a working version of alpha-beta it could be really great. Please help fix my alpha-beta pruning.
I understand it should give the same result, my question is why is my implementation not giving the same results?
To confirm that it should give the same results, i made a quick test class implementation.
public class MinimaxAlphaBetaTest {
public static void main(String[] args) {
Node<Double,Double> parent = new Node<>(0.,0.);
int depth = 10;
createTree(parent,depth);
Timer t = new Timer().start();
double ab = alphabeta(parent,depth+1,Double.NEGATIVE_INFINITY,Double.POSITIVE_INFINITY,true);
t.stop();
System.out.println("Alpha Beta: "+ab+", time: "+t.getTime());
t = new Timer().start();
double mm = minimax(parent,depth+1,true);
t.stop();
System.out.println("Minimax: "+mm+", time: "+t.getTime());
t = new Timer().start();
double pv = pvs(parent,depth+1,Double.NEGATIVE_INFINITY,Double.POSITIVE_INFINITY,1);
t.stop();
System.out.println("PVS: "+pv+", time: "+t.getTime());
if(ab != mm)
System.out.println(ab+"!="+mm);
}
public static void createTree(Node n, int depth){
if(depth == 0) {
n.getChildren().add(new Node<>(0.,(double) randBetween(1, 100)));
return;
}
for (int i = 0; i < randBetween(2,10); i++) {
Node nn = new Node<>(0.,0.);
n.getChildren().add(nn);
createTree(nn,depth-1);
}
}
public static Random r = new Random();
public static int randBetween(int min, int max){
return r.nextInt(max-min+1)+min;
}
public static double pvs(Node<Double,Double> node, int depth, double alpha, double beta, int color){
if(depth == 0 || node.getChildren().isEmpty())
return color*node.getValue();
int i = 0;
double score;
for(Node<Double,Double> child : node.getChildren()){
if(i++==0)
score = -pvs(child,depth-1,-beta,-alpha,-color);
else {
score = -pvs(child,depth-1,-alpha-1,-alpha,-color);
if(alpha<score || score<beta)
score = -pvs(child,depth-1,-beta,-score,-color);
}
alpha = Math.max(alpha,score);
if(alpha>=beta)
break;
}
return alpha;
}
public static double alphabeta(Node<Double,Double> node, int depth, double alpha, double beta, boolean maximizingPlayer){
if(depth == 0 || node.getChildren().isEmpty())
return node.getValue();
double v = maximizingPlayer ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;
for(Node<Double,Double> child : node.getChildren()){
if(maximizingPlayer) {
v = Math.max(v, alphabeta(child, depth - 1, alpha, beta, false));
alpha = Math.max(alpha, v);
}else {
v = Math.min(v,alphabeta(child,depth-1,alpha,beta,true));
beta = Math.min(beta,v);
}
if(beta <= alpha)
break;
}
return v;
}
public static double minimax(Node<Double,Double> node, int depth, boolean maximizingPlayer){
if(depth == 0 || node.getChildren().isEmpty())
return node.getValue();
double v = maximizingPlayer ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;
for(Node<Double,Double> child : node.getChildren()){
if(maximizingPlayer)
v = Math.max(v,minimax(child,depth-1,false));
else
v = Math.min(v,minimax(child,depth-1,true));
}
return v;
}
}
This does in fact give what i expected alpha-beta and pvs are about the same speed (pvs is slower because the children are in random order) and produce the same results as minimax. This proves that the algorithms are correct, but for whatever reason, my implementation of them are wrong.
Alpha Beta: 28.0, time: 25.863126 milli seconds
Minimax: 28.0, time: 512.6119160000001 milli seconds
PVS: 28.0, time: 93.357653 milli seconds
Source Code for Checkers implementation
Pseudocode for pvs
Pseudocode for alpha beta i'm following
Full Souce Code for the Tick Tack Toe Implementation
I think you might be misunderstanding AB pruning.
AB pruning should give you the same results as MinMax, it's just a way of not going down certain branches because you know making that move would have been worse than another move that you examined which helps when you have massive trees.
Also, MinMax without using a heuristic and cutting off your search will always be undefeatable because you've computed every possible path to reach every terminating state. So I would've expected that AB pruning and MinMax would both be unbeatable so I think something is wrong with your AB pruning. If your minmax is undefeatable, so should your approach using AB pruning.
I followed an example about a Genetic Algorithm in Java. Although I understand the concept of this application, I do not understand how I would apply a formula of my choice and let the Genetic Algorithm find it's highest value with x (an Individual' gene).
I tried the following code, by having the fitness return the value of the formula as followed:
static int getFitness(Individual individual) {
int fitness = 0;
Integer x = Integer.parseInt(individual.toString(), 2);
fitness = calculateFormula(x);
return fitness;
}
public static int calculateFormula(int x) {
int result = (-x * x) + (7 * x);
return result;
}
But with the tutorial I followed, you are supposed to specify a solution at the beginning. But when I do this, it is going to search for that solution and not the value of x that will return the highest result. By not specifying a solution, it will just end when it has found the gene representing 0.
So the question:
How would I apply a formula to the Genetic Algorithm, so it will look for the highest result of the formula -x² + 7x?
By "specifying a solution" you probably mean the following function in the blog:
static int getMaxFitness() {
int maxFitness = solution.length;
return maxFitness;
}
Which is causing trouble in your case. The dumb solution:
static int getMaxFitness() {
return 12;
}
Now the algorithm will find 3 (00011 you only need 5 bits/genes to check 0 to 31) or 4 (00100) as it is supposed to.
For a more intelligent solution we have to look at the termination criteria:
int generationCount = 0;
while(myPop.getFittest().getFitness() < FitnessCalc.getMaxFitness()){
generationCount++;
System.out.println("Generation: "+generationCount+" Fittest: "+myPop.getFittest().getFitness());
myPop = Algorithm.evolvePopulation(myPop);
}
You could stop looking for a solution when there was no improvement for X generations:
int bestFitness = Integer.MIN_VALUE;
Individual bestIndividual = null;
int noImprovementCount = 0;
for (int generationCount = 1;; generationCount++) {
System.out.println("Generation: "+generationCount+" Fittest: "+myPop.getFittest().getFitness());
myPop = Algorithm.evolvePopulation(myPop);
if (bestFitness < myPop.getFittest().getFitness()) {
bestIndividual = myPop.getFittest();
bestFitness = bestIndividual.getFitness();
noImprovementCount = 0;
} else if (++noImprovementCount == 5) { // X = 5
break;
}
}
I'm having difficulty writing a program to solve this exercise from a Java text book:
Write a method raiseRealToPower that takes a floating-point value x and an integer
k and returns xk. Implement your method so that it can correctly calculate the result
when k is negative, using the relationship
x^(-k) = 1 / x^k.
Use your method to display a table of values of πk for all values of k from –4 to 4.
I didn't done this part with PI, i know that, if my programs starts to work... this is what i done... tell me please, what is wrong.
import acm.program.*;
public class vjezba55 extends ConsoleProgram {
private static final double PI = 3.14159253;
public void run() {
double x = readDouble ("x: ");
double k = readDouble ("k: ");
println ("x^k = " + raiseDoublePower(x,k));
}
/* Method that counts x^k */
private double raiseDoublePower (double x, double k){
if (k >= 0) {
return Math.pow(x, k);
}
else {
double total = 1;
for (int i= 0; i>k; i--) {
total = (double) 1 / x;
}
return total;
}
}
}
Take a look at your loop code. You are just recalculating total from scratch on each iteration, rather than updating the previous result.
I don't understand the part in the question regarding PI, but your method may be much simpler (according to using the relationship x^(-k) = 1 / x^k):
private double raiseDoublePower (double x, double k){
if (k >= 0) {
return Math.pow(x, k);
}
else {
return 1 / Math.pow(x, -k);
}
}