I'm programming card and deck classes for a school assignment, and my shuffling method isn't consistently passing the test code for it. We are supposed to be using online resources specifically instead of grader/instructor support for this one, and I quickly found the Fisher Yates shuffle method, but I'm having trouble understanding some of the details of it. I'd like to incorporate some of what I came up with and some of it seems pretty similar. Can anyone explain what I'm missing and what it does? Here's my method:
public void shuffle() {
/**
* I'm trying an orginial idea for the shuffle method of taking the
* element at each index and switching it out with another element
* at a random index
*/
Card placeHolder;
int i;
for (int c = 0; c < cardNum; c++) {
i = (int) (Math.random() * (cardNum-1));
placeHolder = deckList[i];
deckList[i] = deckList[c];
deckList[c] = placeHolder;
}
}
You're really close. I'd recommend changing this:
i = (int) (Math.random() * (cardNum-1));
To this:
i = (int) (Math.random() * (cardNum - i) + i);
Or use ThreadLocalRandom.current().nextInt(origin, bound) (assuming you are on 1.7 or greater).
Related
code
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class SynchronizedObjEffectArea {
interface Func {
void run();
}
private volatile int index = 0;
private static final int size = 20000;
public static void main(String[] args) {
final List<Func> threadList = new ArrayList<>();
final SynchronizedObjEffectArea obj = new SynchronizedObjEffectArea();
for (int i = 0; i < size; i++) {
threadList.add(obj::task1);
threadList.add(obj::task2);
}
Collections.shuffle(threadList);
for (final Func thread : threadList) {
thread.run();
}
}
private void task1() {
synchronized (SynchronizedObjEffectArea.this) {
index = index + 1;
}
}
private void task2() {
synchronized (SynchronizedObjEffectArea.this) {
index = index + 1;
if (index == size * 2) {
System.out.println("index: " + index);
}
}
}
}
With the code like above, i usually can got the output "index: 40000" or sometimes can not.
By comment out the code Collections.shuffle(threadList);, the code works fine, it always output "index: 40000"
I confuse that what shuffle function do cause the result like above? Can anyone explain this?
I don't think you're really asking about what Collections.shuffle does in general: I think you're asking why Collections.shuffle affects the output:
You are creating a load of tasks of two kinds: one of them increments a value ("kind 1"); the other increments a value and sometimes prints a message ("kind 2"). These are put into a list, and executed sequentially.
If you put an equal number of these two kinds of tasks into a list, shuffle them, and execute them sequentially, the item at a position is going to be a "kind 1" task 50% of the time, and a "kind 2" task the rest of the time.
Since "kind 2" tasks only prints for a specific value, you will only get something printed if it is a "kind 2" task at position 2 * size - 1, which will be 50% of the time.
If you don't shuffle them, but add "kind 1" and "kind 2" in turn, the item at position 2 * size - 1 will always be a "kind 2", so it will always print.
Collections.shuffle() Randomly permutes the specified list using a default source of randomness. All permutations occur with approximately equal likelihood.
So if tasks ar shuffled, sometimes task2 run first and then output is different.
This is the javadoc and source code for java.util.Collections.shuffle():
/**
* Randomly permute the specified list using the specified source of
* randomness. All permutations occur with equal likelihood
* assuming that the source of randomness is fair.<p>
*
* This implementation traverses the list backwards, from the last element
* up to the second, repeatedly swapping a randomly selected element into
* the "current position". Elements are randomly selected from the
* portion of the list that runs from the first element to the current
* position, inclusive.<p>
*
* This method runs in linear time. If the specified list does not
* implement the {#link RandomAccess} interface and is large, this
* implementation dumps the specified list into an array before shuffling
* it, and dumps the shuffled array back into the list. This avoids the
* quadratic behavior that would result from shuffling a "sequential
* access" list in place.
*
* #param list the list to be shuffled.
* #param rnd the source of randomness to use to shuffle the list.
* #throws UnsupportedOperationException if the specified list or its
* list-iterator does not support the <tt>set</tt> operation.
*/
#SuppressWarnings({"rawtypes", "unchecked"})
public static void shuffle(List<?> list, Random rnd) {
int size = list.size();
if (size < SHUFFLE_THRESHOLD || list instanceof RandomAccess) {
for (int i=size; i>1; i--)
swap(list, i-1, rnd.nextInt(i));
} else {
Object arr[] = list.toArray();
// Shuffle array
for (int i=size; i>1; i--)
swap(arr, i-1, rnd.nextInt(i));
// Dump array back into list
// instead of using a raw type here, it's possible to capture
// the wildcard but it will require a call to a supplementary
// private method
ListIterator it = list.listIterator();
for (int i=0; i<arr.length; i++) {
it.next();
it.set(arr[i]);
}
}
}
So, as out common knowledge of the English language tells us, shuffle will randomly re-order the contents of the Collection you specify.
That's also what the javadoc says.
So seeing you have this problem, next time
Look up the English term in a translator or dictionary
Use an IDE. That will show you the javadoc for the methods, and as a bonus it will do the formatting of your source code for you
Run a test with 3-10 items on a list, this will also show you what happens
I tried to make a program (in Java) that calculates pi with the Chudnovsky algorithm but it has the output NaN (Not a Number). Please help me find mistakes in my code, or improve my code. (I don't have a lot of Java programming knowledge)
You can find Chudnovsky's algorithm here:
https://en.wikipedia.org/wiki/Chudnovsky_algorithm
here is my code:
package main;
public class Class1 {
public static void main(String[] args)
{
double nr1=0,nr2=0,nr3=0,pi=0;
int fo1=1, fo2=1, fo3=1;
for(int i=0; i<=20; i++){
for(int fl1=1; fl1<=(6*i); fl1++){fo1 = fo1 * fl1;}
for(int fl2=1; fl2<=(3*i); fl2++){fo2 = fo2 * fl2;}
for(int fl3=1; fl3<=(i); fl3++){fo3 = fo3 * fl3;}
nr1 = ( (Math.pow(-1, i)) * (fo1) * ((545140134*i) + 13591409) );
nr2 = ( (fo2) * (Math.pow(fo3, i)) * ( Math.pow(Math.pow(640320, 3), (i+(1/2)) )) );
nr3 = 12 * (nr1/nr2);
}
pi = 1/nr3;
System.out.println((Math.PI));
System.out.println(pi);
}
}
There are many issues here.
As Andy mentioned, 1/2 is not 0.5.
You are using integers to compute things like 120! which is completely out of bounds for any primitive type.
f01,f02,f03 should be initialized inside each loop, otherwise they grow even bigger
It is not trivial to fix it. You can take a look at
Error calculating pi using the Chudnovsky algorithm - Java
and
http://www.craig-wood.com/nick/articles/pi-chudnovsky/
for some hints, but don't expect built-in primitive types to work with that algorithm.
I am trying to build a 4 x 4 sudoku solver by using the genetic algorithm. I have some issues with values converging to local minima. I am using a ranked approach and removing the bottom two ranked answer possibilities and replacing them with a crossover between the two highest ranked answer possibilities. For additional help avoiding local mininma, I am also using mutation. If an answer is not determined within a specific amount of generation, my population is filled with completely new and random state values. However, my algorithm seems to get stuck in local minima. As a fitness function, I am using:
(Total Amount of Open Squares * 7 (possible violations at each square; row, column, and box)) - total Violations
population is an ArrayList of integer arrays in which each array is a possible end state for sudoku based on the input. Fitness is determined for each array in the population.
Would someone be able to assist me in determining why my algorithm converges on local minima or perhaps recommend a technique to use to avoid local minima. Any help is greatly appreciated.
Fitness Function:
public int[] fitnessFunction(ArrayList<int[]> population)
{
int emptySpaces = this.blankData.size();
int maxError = emptySpaces*7;
int[] fitness = new int[populationSize];
for(int i=0; i<population.size();i++)
{
int[] temp = population.get(i);
int value = evaluationFunc(temp);
fitness[i] = maxError - value;
System.out.println("Fitness(i)" + fitness[i]);
}
return fitness;
}
Crossover Function:
public void crossover(ArrayList<int[]> population, int indexWeakest, int indexStrong, int indexSecStrong, int indexSecWeak)
{
int[] tempWeak = new int[16];
int[] tempStrong = new int[16];
int[] tempSecStrong = new int[16];
int[] tempSecWeak = new int[16];
tempStrong = population.get(indexStrong);
tempSecStrong = population.get(indexSecStrong);
tempWeak = population.get(indexWeakest);
tempSecWeak = population.get(indexSecWeak);
population.remove(indexWeakest);
population.remove(indexSecWeak);
int crossoverSite = random.nextInt(14)+1;
for(int i=0;i<tempWeak.length;i++)
{
if(i<crossoverSite)
{
tempWeak[i] = tempStrong[i];
tempSecWeak[i] = tempSecStrong[i];
}
else
{
tempWeak[i] = tempSecStrong[i];
tempSecWeak[i] = tempStrong[i];
}
}
mutation(tempWeak);
mutation(tempSecWeak);
population.add(tempWeak);
population.add(tempSecWeak);
for(int j=0; j<tempWeak.length;j++)
{
System.out.print(tempWeak[j] + ", ");
}
for(int j=0; j<tempWeak.length;j++)
{
System.out.print(tempSecWeak[j] + ", ");
}
}
Mutation Function:
public void mutation(int[] mutate)
{
if(this.blankData.size() > 2)
{
Blank blank = this.blankData.get(0);
int x = blank.getPosition();
Blank blank2 = this.blankData.get(1);
int y = blank2.getPosition();
Blank blank3 = this.blankData.get(2);
int z = blank3.getPosition();
int rando = random.nextInt(4) + 1;
if(rando == 2)
{
int rando2 = random.nextInt(4) + 1;
mutate[x] = rando2;
}
if(rando == 3)
{
int rando2 = random.nextInt(4) + 1;
mutate[y] = rando2;
}
if(rando==4)
{
int rando3 = random.nextInt(4) + 1;
mutate[z] = rando3;
}
}
The reason you see rapid convergence is that your methodology for "mating" is not very good. You are always producing two offspring from "mating" of the top two scoring individuals. Imagine what happens when one of the new offspring is the same as your top individual (by chance, no crossover and no mutation, or at least none that have an effect on the fitness). Once this occurs, the top two individuals are identical which eliminates the effectiveness of crossover.
A more typical approach is to replace EVERY individual on every generation. There are lots of possible variations here, but you might do a random choice of two parents weighted fitness.
Regarding population size: I don't know how hard of a problem sudoku is given your genetic representation and fitness function, but I suggest that you think about millions of individuals, not dozens.
If you are working on really hard problems, genetic algorithms are much more effective when you place your population on a 2-D grid and choosing "parents" for each point in the grid from the nearby individuals. You will get local convergence, but each locality will have converged on different solutions; you get a huge amount of variation produced from the borders between the locally-converged areas of the grid.
Another technique you might think about is running to convergence from random populations many times and store the top individual from each run. After you build up a bunch of different local minima genomes, build a new random population from those top individuals.
I think the Sudoku is a permutation problem. therefore i suggest you to use random permutation numbers for initializing population and use the crossover method which Compatible to permutation problems.
I'm working on an assignment and it's going fairly well, but I am confused about one thing so far. The point is to learn about inheritance and reading through existing code. Without adding another method, I need to make the getMove() method return the same random number three times in a row, and then pick a new random number and have it return the new number three times. etc. etc.
There are several other classes, including a class that maintains a count separate from the one I established here. If it would be useful to see any of those classes let me know and I'll post them, but I think they are fairly irrelevant to the question.
Edit: Clarification
I need to make the getMove() method return one int per call. The 1st 3 calls should return the same randomInt. After that a new randomInt should be chosen, and that should be returned for the next three calls. This should repeat as long as it's called.
The final solution:
public class Crab extends SeaCreature {
private static final char CRAB = 'C';
private int direction = rand.nextInt(4);
private int count;
/**
* Construct a SeaCreature object with the given character representation
* #param c the character for this SeaCreature
*/
public Crab(){
super(CRAB);
}
/** Answers back the next move for this SeaCreature.
* #return 0, 1, 2, or 3
*/
public int getMove() {
if (count < 3) {
count ++;
return direction;
}
count = 1;
direction = rand.nextInt(4);
return direction;
}
}
Not that it's a "problem", but your fields should be instance fields (ie not static).
However, to isolate the problem from your classes, here's code that works. Note that you can get the same move on subsequent calls to rand().
private static int direction = rand();
private static int count;
public static int getMove()
{
if (count < 3)
{
count++;
return direction;
}
count = 0;
direction = rand();
return direction;
}
private static int rand()
{
return (int) (Math.random() * 4); // 0, 1, 2 or 3
}
I can see the problem I think.
Hint - you need to think through carefully which state belongs to all Crabs, and which state is specific to an individual Crab. You've currently got that wrong, and all Crabs are sharing some state that they shouldn't. Assuming that there are lots of live Crab instances, this will result in getMove() not behaving as you want it to.
I need your help, and thank you for reading my question!
I am currently writing a java Programm that will use an Direket Form 2 Transposed Filter. I know that the function filter in Matlab will do that just fine, but i have to use Java.
So does anyone know you to implement this Direkt Form 2 Transposed , this Math Function:
y(n) = b(1)*x(n) + b(2)*x(n-1) + ... + b(nb+1)*x(n-nb)
- a(2)*y(n-1) - ... - a(na+1)*y(n-na)
in any Programmm Language? All it takes is hopefully a point to the wrigth direction so i can figure it out! Maybe there is an C Lib that implements some of the matlab functions, just anything.
So thank you for your time
yours Elektro
Follow up:
I tried for a couple of days to understand your function but i couldn't.
This is the function from Matlab: filter
http://www.mathworks.com/access/helpdesk/help/techdoc/index.html?/access/helpdesk/help/techdoc/ref/filter.html&http://www.google.de/search?hl=de&q=filter+matlab&btnG=Google-Suche&meta=&aq=f&oq=
All i know is that i use in matlab the function like this:
newArray = filter(1,LPC_Faktor,OldArray)
All I have to do is to implement the filter function.
So could you help again?
Thanks
Elektro
Whatever language you use, the direct form II transposed structure is quite simple.
For example, in C, it could be something like:
float myFilter( float u)
{
static float[nb] x = {0,0,0,...,0); // initialize x
static float[na] y = {0,0,0,...,0); // initialize y
static float b1 = ....; // put b(1) here
static float[nb] b = {...,...,...,...,...}; // put b(2) to b(nb+1) here
static float[na] a = {...,...,...,...,...}; // put a(2) to a(na+1) values here
// initialization
float sum = 0;
int i=0;
// compute the value
for(i=0;i<nb;i++)
sum += b[i]*x[i];
for(i=0;i<na;i++)
sum -= a[i]*y[i];
sum += b1*u;
// prepare the values for the next time
for(i=1;i<nb;i++)
x[i] = x[i-1];
x[0] = u;
for(i=1;i<na;i++)
y[i] = y[i-1];
y[0] = sum;
// return the value
return sum;
}
I did not test the code, but it is something like that.
The Direct Form II transposed is the simplest form to implement a FIR filter (numerically, and specially in fixed-point, it is not the best, but it is the form that requires the less operations).
Of course, it is possible to have a better implementation (with cycling array, for example). If needed, I can provide it, too.
EDIT: I answered too quickly. The algorithm you provide
y(n) = b(1)x(n) + b(2)x(n-1) + ... + b(nb+1)x(n-nb) - a(2)y(n-1) - ... - a(na+1)*y(n-na)
is not the Direct Form II, but the direct form I. It requires to store na+nb values (n is the order of your filter), whereas the Direct Form II requires only max(na,nb).
The algorithm used for the Direct Form II is
e(n) = u(n) - a(1)*e(n-1) - a(2)*e(n-2) - ... - a(na)*e(n-na)
y(n) = b(1)*e(n-1) + b(2)*e(n-2) + ... + b(nb)*e(n-nb)
Tell me if you need this form or not.
after long searching i found the answer,
thank you showed the rigth way:
filter(int ord, float *a, float *b, int np, float *x, float *y)
{
int i,j;
y[0]=b[0] * x[0];
for (i=1;i<ord+1;i++)
{
y[i]=0.0;
for (j=0;j<i+1;j++)
y[i]=y[i]+b[j]*x[i-j];
for (j=0;j<i;j++)
y[i]=y[i]-a[j+1]*y[i-j-1];
}
/* end of initial part */
for (i=ord+1;i<np+1;i++)
{
y[i]=0.0;
for (j=0;j<ord+1;j++)
y[i]=y[i]+b[j]*x[i-j];
for (j=0;j<ord;j++)
y[i]=y[i]-a[j+1]*y[i-j-1];
}
} /* end of filter */