Two point crossover in Java - java

I have implemented a one point crossover as follows;
public void onePointCrossover(Individual indi) {
if (SGA.rand.nextDouble() < pc) {
int xoverpoint = SGA.rand.nextInt(length);
int tmp;
for (int i=xoverpoint; i<length; i++){
tmp = chromosome[i];
chromosome[i] = indi.chromosome[i];
indi.chromosome[i] = tmp;
}
}
}
One point crossover - crossover point is selected, binary string from beginning of chromosome to the crossover point is copied from one parent, the rest is copied from the second parent.
Parent 1 = chromosome and Parent 2 = indi.
I am turning the parents into children inplace.
I now need to also do a two point crossover but having some trouble, this is what I have so far but I believe the bottom half of the code is doing the same thing as a one point crossover rather than swapping the middle sections.
public void twoPointCrossover(Individual indi) {
if (SGA.rand.nextDouble() < pc) {
int xoverpoint = SGA.rand.nextInt(length);
int xoverpoint2 = SGA.rand.nextInt(length);
int tmp;
if (xoverpoint > xoverpoint2){
tmp = xoverpoint;
xoverpoint = xoverpoint2;
xoverpoint2 = tmp;
}
for (int i=xoverpoint; i<xoverpoint2; i++){
tmp = chromosome[i];
chromosome[i] = indi.chromosome[i];
indi.chromosome[i] = tmp;
}
}
}
}
This does not seem right and any help will be appreciated so much! Thanks!

You should check for i < (or <=) xoverpoint2 rather than i<length in the loop.

I'm working on the same problem now. Here is my solution:
// Two-Point Crossover function
public Genome twoPtCrossover(Genome partner) {
Genome child = new Genome(partner.genome.length);
int crosspoint1 = xd.nextInt(genome.length);
int crosspoint2 = xd.nextInt(genome.length);
// Ensure crosspoints are different...
if (crosspoint1 == crosspoint2){
if(crosspoint1 == 0){
crosspoint2++;
} else {
crosspoint1--;
}
}
// .. and crosspoint1 is lower than crosspoint2
if (crosspoint2 < crosspoint1) {
int temp = crosspoint1;
crosspoint1 = crosspoint2;
crosspoint2 = temp;
}
for (int i = 0; i < genome.length; i++) {
if (i < crosspoint1 || i > crosspoint2)
child.genome[i] = genome[i];
else
child.genome[i] = partner.genome[i];
}
return child;
}

Related

Why doesn't my Max Heap Heapsort method work?

So I'm working with the java implementation of Max Heaps. My Insert, bubbleUp and deleteMax (on its own) methods seem to work fine, but my heapsort method (which calls deleteMax) doesn't work as its supposed to (it doesn't cause an error message; it just doesn't sort them in the order it's supposed to). I've included the code below. Any help understanding the problem is greatly appreciated. Thanks!
The whole class can be found at: https://repl.it/repls/FrequentPartialBlockchain
'''
public int deleteMax(){
if(this.numNodes == 0)
throw new NoSuchElementException();
else if(this.numNodes == 1){
int elemToReturn = heapArr[0];
heapArr[0] = null;
return elemToReturn;
}
int elemToReturn = heapArr[0];
heapArr[0] = heapArr[numNodes-1];
heapArr[numNodes-1] = null;
this.numNodes--;
bubbleDown();
return elemToReturn;
}
private void bubbleDown(){
int n = 0;
int L = 2 * n + 1; // L will hold the index of the left child
while(L < this.numNodes - 1){
int max = L;
int R = L + 1; // R will hold the index of the right child
if(R < this.numNodes - 1){
if(heapArr[R] >= heapArr[L])
max++;
}
int temp;
if(heapArr[n] < heapArr[max]){
// swap
temp = heapArr[n];
heapArr[n] = heapArr[max];
heapArr[max] = temp;
n = max;
L = 2 * n + 1;
}
else{
break;
}
}
}
public static void heapsort(Integer[] arrayToSort){
MaxHeap tempHeap = new MaxHeap(arrayToSort);
for(int i = 0; i < tempHeap.numNodes; i++)
arrayToSort[i] = (Integer) tempHeap.deleteMax();
}
'''
This while statement seems wrong:
while(L < this.numNodes - 1){
If this.numNodes is the number of nodes in the heap, then this.numNodes - 1 is the last node. This condition, then, prevents the loop from being entered if L is the last node in the heap.
On a related note, your special case in deletMax is broken. You remove the only node in the heap, but you forgot to set numNodes to 0.

Can't get code to complie

I'm trying to learn Prim's algorithm and I'm using this website to do so, but I'm having trouble making the code part of it run. I'm confused with what goes in public static int Prims(Vector<Vector<node>> adjList) and how to get the code to compile and run. (New to java so excuse me if its a silly question).
edit: This is the code I'm trying to run:
class node implements Comparable<node> {
int weight, index;
public node(int weight, int index) {
this.weight = weight;
this.index = index;
}
public int compareTo(node e) {
return weight - e.weight;
}
}public static int Prims(Vector<Vector<node>> adjList) {
// Current cost of MST.
int cost = 0;
int n = adjList.size();
PriorityQueue<node> pq = new PriorityQueue<node>();
// Keep track if each node is visited.
boolean visited[] = new boolean[n];
for (int i = 0; i < n; i++) {
visited[i] = false;
}
// Number of nodes visited.
int inTree = 1;
// Mark starting node as visited.
visited[0] = true;
// Add all edges of starting node.
for (int i = 0; i < adjList.get(0).size(); i++) {
pq.add(adjList.get(0).get(i));
}
// Keep going until all nodes visited.
while (!pq.isEmpty() && inTree < n) {
// Get the edge with the smallest weight.
node cur = pq.poll();
// Skip if node already used.
if (visited[cur.index]) {
continue;
}
inTree++;
visited[cur.index] = true;
cost += cur.weight;
// Add all the edges of the new node to the priority queue.
for (int i = 0; i < adjList.get(cur.index).size(); i++) {
pq.add(adjList.get(cur.index).get(i));
}
}
// Graph not connected if number of nodes used is less than total nodes.
if (inTree < n) {
return -1;
}
return cost;
}
Your method public static int Prims(Vector<Vector<node>> adjList) does not appear to be a member of a class. It needs to be. The leading } on the line
}public static int Prims(Vector<Vector<node>> adjList) {
should probable be moved to the end of the file.
If you do not use an IDE to compile and run a code you need to issue the following commands:
javac MyCode.java
java MyCode
where I suppose your code resides in a file named MyCode.java and there is no package defined.

How to use the alphabeta pruning for connect four like game

Could someone be so kind to help me understand how to use the alpha-beta pruning algorithm? I'm making a game similar to connect four. The only differences is there is no diagonal win, and a player can mark an square at any given time (unless it is already occupied, of course). I think I understand how to code the algorithm, I just think I am using it wrong. What I have been doing is having a for loop that looks something like this
for(i=0; i<size; i++)
for(j=0; j<size; j++)
val = alphabeta();
if(val > max)
max = val;
move = set(i,j);
setBoard(move); //sets the to the returned value from alphabeta()
the problem I am having is that the first run of alphabeta returns the max val, so therefore none of the next values are greater, and the board will just be set at board[0][0]. Does anyone know what I am doing wrong?
public int alphabeta(Placement place, int depth, int alpha, int beta, boolean maxPlayer)
{
Placement p = null;
if(depth==0 || board.isWinner())
{
return evaluate(place, maxPlayer);
}
if(maxPlayer)
{
int i=0, j=0;
for(i=0; i<board.size; i++)
{
for(j=0; j<board.size; j++)
{
if(board.validMove(i,j)&&(board.canGetFour(i,j, opponent)&&board.canGetFour(i,j,player)))
{
board.board[i][j] = opponent;
p = new Placement(i, j);
alpha = Math.max(alpha, alphabeta(p, depth-1, alpha, beta, false));
board.board[i][j] = 0;
}
if(beta<=alpha)
break;
}
if(beta<=alpha)
break;
}
return alpha;
}
else
{
int i=0, j=0;
for(i=0; i<board.size; i++)
{
for(j=0; j<board.size; j++)
{
if(board.validMove(i,j)&&(board.canGetFour(i,j,opponent)&&board.canGetFour(i,j,player)))
{
board.board[i][j] = player;
p = new Placement(i, j);
beta = Math.min(beta, alphabeta(p, depth-1, alpha, beta, true));
System.out.println(board);
board.board[i][j] = 0;
}
if(beta<=alpha)
break;
}
if(beta<=alpha)
break;
}
return beta;
}
}
This is the function that makes the move
public void makeMove()
{
int max = -1;
Placement p = null;
int val = -1;
for(int i=0; i<size; i++)
for(int j=0; j<size; j++)
{
if(board.validMove(i, j))
{
if(board.canGetFour(i, j, opponent)||(board.canGetFour(i,j,player)&&board.canGetFour(i,j,opponent)))
{
board.board[i][j] = player;
val = alphabeta(new Placement(i,j), 5, -5000, 5000, true);
board.board[i][j] = 0;
if(val > max)
{
max = val;
p = new Placement(i, j);
}
}
}
}
board.board[p.row][p.col] = player;
board.moves++;
}
So here's my updated code, still not working
public Placement alphabeta(Placement p)
{
int v = max(p,6,-500000, 500000);
return successors(v);
}
public int max(Placement p, int depth, int alpha, int beta)
{
if(depth == 0 || board.isWinner())
{
return evaluateMax(p,player);
}
int v = -500000;
for(int i=0; i<successors.size(); i++)
{
Placement place = new Placement(successors.get(i));
board.board[place.row][place.col] = player;
v = Math.max(v, min(place, depth-1, alpha,beta));
board.board[place.row][place.col] = 0;
if(v>= beta)
return v;
alpha = Math.max(alpha, v);
}
return v;
}
public int min(Placement p, int depth, int alpha, int beta)
{
if(depth == 0||board.isWinner())
{
return evaluateMax(p,opponent);
}
int v = 500000;
for(int i=0; i<successors.size(); i++)
{
Placement place = new Placement(successors.get(i));
board.board[place.row][place.col] = opponent;
v = Math.min(v, max(place,depth-1, alpha,beta));
board.board[place.row][place.col] = 0;
if(v<= alpha)
return v;
beta = Math.min(alpha, v);
}
return v;
}
public void makeMove()
{
Placement p = null;
for(int i=0; i<successors.size(); i++)
{
Placement temp = successors.get(i);
//board.board[temp.row][temp.col] = player;
p = alphabeta(temp);
//board.board[temp.row][temp.col] = 0;
}
System.out.println("My move is "+p.row + p.col);
board.board[p.row][p.col] = player;
successors.remove(p);
}
I changed the algorithm slightly just so I can clearly see what going on with min and max, however, it still does not play correctly
Ok, took some time but I think I have it.
In your evaluate function, you should be returning how good the state is for the actual player. If placement is a canGetFour for the "otherPlayer", that is a bad state (the worst state). So you return a small number. However, if placement is a canGetFour for the "actualPlayer" you return a large number (its a good state).
Then in your makeMove, you are just checking whether the state is the best state possible. Note, that using a 2d array for this is just about the least efficient way of storing the "child nodes". It would make a lot more sense to have a placement.getPossibleMoves() which returns an array of all the empty squares (both real and temporary), and iterate over that. Otherwise your algorithm is going to be exponential time in the order of the board size.
private Placement bestNext;
private List<Placement> tempMoves = new ArrayList<>();
private int alpha;
private int beta;
public int alphabeta(Placement place, int depth, boolean maxPlayer)
{
Placement p = null;
if(depth == maxDepth){/* (unnasigned squares in actual board) */
return evaluate(place, maxPlayer)
}
int i=0, j=0;
for(i=0; i<board.size; i++)
{
for(j=0; j<board.size; j++)
{
if(board.validMove(i,j)){
p = new Placement(i, j);
tempMoves.add(placement);
int tmp = Math.max(alpha, alphabeta(p, depth += 1, actualPlayer.getOpponent()));
if(maxPlayer){
alpha = tmp
}
else{
beta = tmp
}
tempMoves.remove(placement);
}
if(beta<=alpha)
break;
}
if(beta<=alpha)
break;
}
return maxPlayer ? alpha : beta;
}

Array index out of bounds java heap [duplicate]

This question already has answers here:
What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?
(26 answers)
Closed 1 year ago.
I know this is an amaetuer error, i understand what it means but i dont understand why i cant fix it. Ive been trying everything. Im trying to take an array of type T and switch its values around so it correctly corresponds to the rules of a heap, where the parent is always greater than the 2 children. The error is in my while loop
please dont be harsh if its something easily fixable. ive been struggling heavily and cant seem to find an answer.
public class myheap<T extends Comparable<T>> extends heap<T>
{
// constructors of the subclass should be written this way:
public myheap(int max) { super(max); }
public myheap(T[] A) {super(A);}
public void buildheap(T[] Arr){
int size = Arr.length;
int startsize = (size-1)/2;
for(int i=startsize;i>0;i--){
int l = left(i);
int r = right(i);
T temp = null;
while((Arr[r]!=null) && Arr[i].compareTo(Arr[r])<0){
if (Arr[l].compareTo(Arr[r])>0){
temp = Arr[l];
Arr[l] = Arr[i];
Arr[i] = temp;
}//if left is greater than right
else //then right must be greater than parent
temp = Arr[r];
Arr[r] = Arr[i];
Arr[i] = temp;
}//whileloop
if((Arr[r]==null) && Arr[i].compareTo(Arr[l])<0)
temp = Arr[l];
Arr[l] = Arr[i];
Arr[i] = temp;
}//for
}//buildheap
public static void main(String[] args){
String[] array = {"SH","AH","AB","YA","AY","AA","AB","LM","LL","LO"};
myheap<String> New = new myheap<String>(array.length);
for(int i=0;i<array.length;i++){
New.insert(array[i]);
}//insert
New.buildheap(array);
New.drawheap();
for(int i=0;i<array.length;i++){
System.out.println(New.deletemax() + " ");
}//for
System.out.println();
} //main
}
Heap superclass that myheap is extending
/*
Polymorphic priority heaps, largest value on top.
Heap axiom. The value at every node cannot be smaller than the values
at each of its children nodes.
Use internal array to implement heap "tree", with index 0 representing
the root. Given node index i, left(i)= 2*i+1 and right(i)=2*i+2, while
parent(i) = (i-1)/2.
*/
class heap<T extends Comparable<T>>
{
protected T[] H; // internal array representing heap.
protected int size; // size of current heap, not same as H.length!
public int size() { return size; } // size is read-only externally.
public int maxsize() { return H.length; }
public heap(T[] A) { H = A; size=0; } // preferred constructor
public heap(int m) // will cause compiler warning (ok to ignore)
{
H = (T[]) new Comparable[m]; // downcast from Object is OK.
size = 0;
}
protected int left(int i) { return 2*i+1; }
protected int right(int i) { return 2*i+2; }
protected int parent(int i) { return (i-1)/2; }
// protected is important!
// lookup heap, without delete
public T getmax()
{
if (size<1) return null;
return H[0];
}
// insert x into heap: place at end, then propagate upwards
// returns false on failure.
public boolean insert(T x)
{
if (size > H.length-1) return false;
H[size++] = x; // place at end, inc size
// propagate upwards
int cur = size-1; // current position
int p = parent(cur);
while (cur>0 && H[cur].compareTo(H[p])>0)
{ // propagate upwards
T temp = H[cur];
H[cur] = H[p]; H[p] = temp;
cur = p; // switch current to parent
p = parent(cur); // recalc parent
}//while
return true;
}//insert
// deletetop: take last element, move to top, propagate downwards:
public T deletemax()
{
if (size<0) return null;
T answer = H[0];
H[0] = H[--size]; // place at top:
// now propagate downwards.
boolean done = false;
int i = 0; // current position
int c = 0; // swap candidate
while (c != -1)
{
int l = left(i);
int r = right(i);
c = -1; // swap candidate
if (l<size && H[l].compareTo(H[i])>0) c = l; // set candidate to left
if (r<size && H[r].compareTo(H[i])>0 && H[r].compareTo(H[l])>0) c=r;
if (c!= -1)
{
T temp = H[i]; H[i] = H[c]; H[c] = temp;
i = c;
}
}//while
return answer;
}//deletemax
// but search is not log(n). Why?
public boolean search(T x)
{
for(int i=0;i<size;i++) {if (x.compareTo(H[i])==0) return true;}
return false;
}
public void drawheap() // use only with heapdisplay.java program
{
heapdisplay W = new heapdisplay(1024,768);
W.drawtree(H,size);
}
}//heap
public class heaps14
{
/**public static void main(String[] args){
heap<Integer> HI = new heap<Integer>(200);
for(int i=0;i<100;i++) HI.insert((int)(Math.random()*1000));
HI.drawheap();
for(int i=0;i<100;i++) System.out.print(HI.deletemax() + " ");
System.out.println();
}//main**/
}
You may check for null in your while loop, (Arr[r]!=null) but the problem is that you can't even get a value from the array to determine if it's null or not. You should check the index is within the range before trying to access the value from the array, using r < Arr.length or similar.
(If null) isnt the problem, arrayIndexOutofBounds means you are geting a value of an array that isnt there
Eg. Array.length =5; and you search Array[6]; - out of bounds....
The problem i think is your method right(i);
which is. i*2+2 and the array
So change the for loop to this
for(int i=startsize-2;i>0;i--)
comment if this helps.

Recursive binary search in an int array using only 1 parameter

How can i implement a recursive binary search in an int array using only 1 parameter in java ?
it tried but my code doesn't work. I implemented a class which its instances are objects having arrays and a count variable to detect how many elements are their in the array. any idea how can i implement the recursive binary search using only 1 parameter ?
public class LinearSortedArray {
int count;
int[] a;
public LinearSortedArray() {
count = 0;
}
public LinearSortedArray(int size) {
count = 0;
a = new int[size];
}
public static int[] copyingMethod(int startPoint, int endPoint,
LinearSortedArray arrayObj) {
int[] copyingArray = new int[endPoint - startPoint];
int j = startPoint;
for (int i = 0; i < copyingArray.length; i++) {
copyingArray[i] = arrayObj.a[j];
j++;
}
return copyingArray;
}
public int binarySearchRec(int x) {
if (count == 0) {
return -1;
}
int pivot = count / 2;
LinearSortedArray newArrayObj;
if (x > a[pivot]) {
newArrayObj = new LinearSortedArray(count - pivot);
newArrayObj.count = newArrayObj.a.length;
newArrayObj.a = copyingMethod(pivot, count, this);
for (int i = 0; i < newArrayObj.a.length; i++) {
System.out.print(newArrayObj.a[i]);
System.out.print(" ");
}
System.out.println();
return pivot + newArrayObj.binarySearchRec(x);
} else if (x < a[pivot]) {
newArrayObj = new LinearSortedArray(pivot);
newArrayObj.count = newArrayObj.a.length;
newArrayObj.a = copyingMethod(0, pivot, this);
for (int i = 0; i < newArrayObj.a.length; i++) {
System.out.print(newArrayObj.a[i]);
System.out.print(" ");
}
System.out.println();
return newArrayObj.binarySearchRec(x);
} else {
return pivot;
}
}
}
P.S.: The arrays are already sorted
Binary search really requires a range and a target value -- so if you're only passing one parameter, this has to be the target and this must encapsulate the array & range.
public class ArraySegment {
protected int[] array;
protected int boundLo;
protected int boundHi;
public class ArraySegment (int[] array) {
// entire array.
this( array, 0, array.length);
}
public class ArraySegment (int[] array, int lo, int hi) {
this.array = array;
this.boundLo = lo;
this.boundHi = hi;
}
public int binarySearch (int target) {
if (boundHi <= boundLo) {
return -1; // Empty; not found.
}
int pivot = (boundLo + boundHi) / 2;
int pivotEl = array[ pivot];
if (target == pivotEl) {
return pivot; // Found!
}
if (target < pivotEl) {
// recurse Left of pivot.
ArraySegment sub = new ArraySegment( array, boundLo, pivot);
return sub.binarySearch( target);
} else {
// recurse Right of pivot.
ArraySegment sub = new ArraySegment( array, pivot, boundHi);
return sub.binarySearch( target);
}
}
}
It's a little bit questionable what kind of result you should return -- there isn't a good answer with the question posed like this, as an "integer index" kinda defeats the purpose of the ArraySegment/ range wrapper, and returning an ArraySegment containing only the found value is also fairly useless.
PS: You really shouldn't be copying the array or it's contents, just passing round references to ranges on that array. Like java.lang.String is a range on a character array.
You could contrive a single-parameter by using the Value Object Pattern, where you pass one "wrapper" object, but the object has many fields.
For example:
class SearchParams {
int target;
int start;
int end;
SearchParams(t, s, e) {
target = t;
start = s;
end = e'
}
}
int search(SearchParams params) {
// some impl
return search(new SearchParams(params.target, a, b));
}
Technically, this is one parameter. Although it may not be in the spirit of the rules.

Categories

Resources