I am having trouble creating a Genetic Algorithm in java. I am competing in an online GA contest. I am trying to save the best result each time back into index 0, but it just becomes a reference to the original index. Meaning when I evolve the rest of the indexes, if it evolves the best members original index I lose it.
I have tried shimming it with a getClone method that converts the objects data to and int array and creates a new object from it.
Individual class:
class Individual {
public int[] angle;
public int[] thrust;
public double fitness;
public Individual(){
angle = new int[2];
thrust = new int[2];
for (int i = 0; i < 2; i++) {
this.angle[i] = ThreadLocalRandom.current().nextInt(0, 37) - 18;
this.thrust[i] = ThreadLocalRandom.current().nextInt(0, 202);
this.thrust[i] = ( (this.thrust[i] == 201) ? 650 : this.thrust[i] );
}
this.fitness = Double.MIN_VALUE;
}
public Individual(int[][] genes, double f){
this.fitness = f;
angle = new int[2];
thrust = new int[2];
this.angle[0] = genes[0][0];
this.angle[1] = genes[0][1];
this.thrust[0] = genes[1][0];
this.thrust[1] = genes[1][1];
}
public Individual getClone() {
int[][] genes = new int[2][2];
genes[0][0] = (int)this.angle[0];
genes[0][1] = (int)this.angle[1];
genes[1][0] = (int)this.thrust[0];
genes[1][1] = (int)this.thrust[1];
return ( new Individual(genes, this.fitness) );
}
public Individual crossover(Individual other) {
int[][] genes = new int[2][2];
genes[0][0] = (int)( (this.angle[0] + other.angle[0])/2 );
genes[0][1] = (int)( (this.angle[1] + other.angle[1])/2 );
genes[1][0] = ( (this.thrust[0] == 650 || other.thrust[0] == 650) ? 650: (int)( (this.thrust[0] + other.thrust[0])/2 ) );
genes[1][1] = ( (this.thrust[1] == 650 || other.thrust[1] == 650) ? 650: (int)( (this.thrust[1] + other.thrust[1])/2 ) );
return ( new Individual(genes, Double.MIN_VALUE) );
}
public void mutate() {
for (int i = 0; i < 2; i++) {
if(ThreadLocalRandom.current().nextInt(0, 2)==1) {
this.angle[i] = ThreadLocalRandom.current().nextInt(0, 37) - 18;
}
if(ThreadLocalRandom.current().nextInt(0, 2)==1) {
this.thrust[i] = ThreadLocalRandom.current().nextInt(0, 202);
this.thrust[i] = ( (this.thrust[i] == 201) ? 650 : this.thrust[i] );
}
}
}
Population class:
class Population {
public Individual[] individuals;
public Population(int populationSize) {
individuals = new Individual[populationSize];
for (int i = 0; i < populationSize; i ++) {
individuals[i] = new Individual();
}
}
public void resetFitness() {
for (int i = 0; i < individuals.length; i++) {
individuals[i].fitness = Double.MIN_VALUE;
}
}
public void setIndividual(int i, Individual indiv) {
individuals[i] = indiv.getClone();
}
public Individual getIndividual(int i) {
return individuals[i].getClone();
}
public int size() {
return this.individuals.length;
}
public Individual getFittest() {
int fittest = 0;
// Loop through individuals to find fittest
for (int i = 0; i < individuals.length; i++) {
if (individuals[i].fitness > individuals[fittest].fitness) {
fittest = i;
}
}
return individuals[fittest].getClone();
}
}
The necessaries from the sim class:
class simGA {
private Population pop;
private final static int TSIZE = 5; //tournement size
public simGA (int poolsize) {
this.pop = new Population(poolsize);
}
public Individual search(int generations, int totalMoves) {
//this.pop.resetFitness();
for (int g = 0; g < generations; g++) {
for (int i = 0; i < this.pop.individuals.length; i++) {
this.pop.individuals[i].fitness = sim(this.pop.individuals[i],totalMoves);
}
System.err.print("Generation " + g + " ");
this.pop = evolvePopulation(this.pop);
}
return pop.getFittest();
}
private Population evolvePopulation(Population p) {
//save fittest
Population tempPop = new Population(p.individuals.length);
tempPop.setIndividual(0, p.getFittest().getClone() );
System.err.print("Best move: " + tempPop.individuals[0].fitness);
System.err.println();
for (int i = 1; i < p.individuals.length; i++) {
Individual indiv1 = tournamentSelection(p);
Individual indiv2 = tournamentSelection(p);
Individual newIndiv = indiv1.crossover(indiv2);
newIndiv.mutate();
tempPop.setIndividual(i, newIndiv.getClone() );
}
return tempPop;
}
// Select individuals for crossover
private Individual tournamentSelection(Population pop) {
// Create a tournament population
Population tournament = new Population(TSIZE);
// For each place in the tournament get a random individual
for (int i = 0; i < TSIZE; i++) {
int randomId = ThreadLocalRandom.current().nextInt(1, this.pop.individuals.length);
tournament.setIndividual(i, pop.getIndividual(randomId).getClone() );
}
// Get the fittest
return tournament.getFittest().getClone();
}
private double sim(Individual s, int moves) {
return score; //score of simmed moves
}
How can I make sure that the best individual is getting saved, not as a reference? When I error print the best score, sometimes it is lost and a worse scoring move is chosen. I don't think it is necessarily a object cloning issue, I can clone the game objects that are simulated just fine, resetting them each run.
As I said, this is for a contest, so I cannot use any libraries on the site, and also is the reason I am not posting the full code, the intricacies of the simulator it self that scores the moves are not to be just given away. But suffice it to say the scores come back as expected for the move when worked out on paper.
I response to NWS, I thought my getClone method was doing a deep copy.
Reference used beside wiki and other knowledge on Genetic Algorithms: http://www.theprojectspot.com/tutorial-post/creating-a-genetic-algorithm-for-beginners/3
I have fixed it by not resimming the individual at index 0. However this means there are other issue with my code not related to the question.
Individual newIndiv = indiv1.crossover(indiv2);
Above line is resetting the fitness to Double.MIN_VALUE. So, whenever evolvePopulation is called, only individual at index 0 is fittest.
I have fixed it by not resimming the individual at index 0. However this means there are other issue with my code not related to the question, since resimming the same individual from the same point in time as before should not change it's fitness.
Related
so basically i tried to call method that return array from other class java, it works perfectly except it double the size or length of the array 2 times from original.
here is my code to return the array and the length.
public static double [] get_days(){
//extracted days from table into array
readFile();
double[] data = new double[list.size()];
System.out.println(list.size());
Integer[] daysArray = list.stream().map(Product::getDay)
.toArray(Integer[]::new);
for(int i = 0; i < daysArray.length; i++){
data[i] = Double.valueOf(daysArray[i]) ;
}
System.out.println("Array Size (Supposed to have 230 Data only) "+ data.length);
return data;
}
here is how I call the method on the other class
public class order_Picking extends AbstractProblem{
get_Product test = new get_Product();
public order_Picking(){
super(161,1,1);
}
public double [] var = new double[numberOfVariables];
public double [] Days = test.get_days();
#Override
public void evaluate (Solution solution){
System.out.println(Days.length);
//Jumlah produk pada batch ke-i pada picking list ke-i pada lokasi yang ke-i
for(int i=0; i< var.length;i++){
var[i]= EncodingUtils.getInt(solution.getVariable(i));
}
//jumlah ketersedian produk
int k1 = 100;
int k2 = 250;
int k3 = 150;
//Picking list-1
double [] pl1 = new double[3] ;
int p1 =100;
pl1[0]= p1;
int p2 = 20;
pl1[1]= p2;
int p3 = 40;
pl1[2]= p3;
int totalpl1 = p1+p2+p3;
//picking list-2
double [] pl2 = new double[3] ;
int p4 = 10;
pl2[0]= p4;
int p5 = 20;
pl2[1]= p5;
int p6 = 15;
pl2[2]= p6;
int totalpl2 = p4+p5+p6;
// Fungsi Tujuan untuk minimasi jarak
double f1 = distance(var) ;
double c1 = 0;
double c2 = 0;
for (int i = 0 ; i < var.length;i++){
c1 = (var[i]+var[i]*var[i])-totalpl1 ;
}
for (int i = 0 ; i < var.length;i++){
c2 = (var[i]+var[i]*var[i])-totalpl2 ;
}
//constraint picking list-1
//constraint picking list-2
solution.setObjective(0, f1);
solution.setConstraint(0,c1 == 0.0 ? 0.0 : c1);
solution.setConstraint(0,c2 == 0.0 ? 0.0 : c1);
}
#Override
public Solution newSolution() {
Solution solution = new Solution(161, 1, 1);
for (int i = 0 ; i<var.length;i++){
solution.setVariable(i,EncodingUtils.newBinaryInt(0,1));
}
return solution;
}
public static void main(String[] args) {
order_Picking value = new order_Picking();
NondominatedPopulation result = new Executor()
.withAlgorithm("GA")
.withProblemClass(order_Picking.class)
.withProperty("Populationsize",100)
.withProperty("sbx.rate",0.2)
.withProperty("pm",0.5)
.withMaxEvaluations(10000)
.run();
for (Solution solution : result) {
if (solution.violatesConstraints()) {
System.out.println("Solution for index 0 : " + +solution.getObjective(0));
for (int i = 0; i < value.var.length; i++){
System.out.println("Solusi variabel ke-"+i+" adalah "+ solution.getVariable(i));
}
}
}
}
public double distance (double [] x){
double a = 0;
for (int i = 0; i < x.length ; i++){
a += x[i];
}
return a;
}
}
There is nothing wrong with the method but when i called it on other classs outside the public static void main it seems to run twice as it return the size of the array more than 230, i dont understand why it become 460 while it supposed to 230
here is the result on console
I genuinely do not see your list variable nor do I see your readFile() method (apologies if it's super obvious and I'm pulling a facepalm). My current hypothesis is so: when you read the file perhaps you do not empty the destination and it just loads up extra data leading to doubling.
Maybe it is a class-level StringBuilder? Please include this part in your question :)
private StringBuilder list = null;
Then inside the file reading method:
public static void readFile()
{
// can empty with a new instance
list = new StringBuilder();
// or reset the length
list.setLength(0);
...
// perform reading, now with an empty StringBuilder
}
Without ^ this ^ you could be doing something similar to the following example:
list = new StringBuilder("1").append(", ").append("2");
readFile(); // in method -> list.append("1").append(", ").append("2");
Which would give the StringBuilder the output:
["1", ", ", "2", "1", ", ", "2"]
With the length of 6, instead of the desired:
["1", ", ", "2"]
With the length of 3. I could see this being responsible for an exact double count.
at the Moment i do a 2D strategy game using pathfinding to navigate my Units over the (still small) tilemap. The tiles are 32x32 and the map is 50x100 big so ist very small :) . It works all so far but i have the more laggs the more Units i create. Till 30 Units it works as it should but more makes my Programm lagg very strong.
So i use an ArrayList for my openSet and (after doing some googling) i know thats bad. So i need to Keep my openList sorted by using TreeSet, but by using TreeSet its necessary to Override compareTo(). Im not fit enough with comparisions like this.
What must i compare exactly, the f value or the Signum? I dont know that and i Need some help.
Here is the A* Algorithm:
public static List<Tile> findPath(int startx,int starty,int endx,int endy){
for(int i = 0; i < width; i++){
for(int j = 0;j < height;j++){
tiles[i][j] = new Tile(i,j,size,size,obstacles[i][j],false);
}
}
for(int i = 0; i < width; i++){
for(int j = 0;j < height;j++){
tiles[i][j].addNeighbours(tiles,width,height);
}
}
List<Tile> openList = new ArrayList<Tile>(); // Here i want a TreeSet
HashSet<Tile> closedList = new HashSet<Tile>();
List<Tile> path = null;
Tile start = tiles[startx][starty];
Tile end = tiles[endx][endy];
Tile closest = start;
closest.h = heuristic(closest,end);
openList.add(start);
while(!openList.isEmpty()) {
int winner = 0;
for (int i = 0; i < openList.size(); i++) {
if (openList.get(i).f < openList.get(winner).f) {
winner = i;
}
}
Tile current = openList.get(winner);
openList.remove(current);
if (current == end) {
path = new ArrayList<Tile>();
Tile tmp = current;
path.add(tmp);
while (tmp.previous != null) {
path.add(tmp);
tmp = tmp.previous;
}
return path;
}
closedList.add(current);
List<Tile> neighbours = current.neighbours;
for (int i = 0; i < neighbours.size(); i++) {
Tile neighbour = neighbours.get(i);
int cost = current.g + heuristic(current,neighbour);
if (openList.contains(neighbour) && cost < neighbour.g) {
openList.remove(neighbour);
}
if (closedList.contains(neighbour) && cost < neighbour.g) {
closedList.remove(neighbour);
}
int newcost = heuristic(neighbour, end);
if (!openList.contains(neighbour) && !closedList.contains(neighbour) && !neighbour.obstacle) {
neighbour.h = newcost;
if (neighbour.h < closest.h) {
closest = neighbour;
}
}
if (!openList.contains(neighbour) && !closedList.contains(neighbour) && !neighbour.obstacle) {
neighbour.g = cost;
openList.add(neighbour);
neighbour.f = neighbour.g + neighbour.h;
neighbour.previous = current;
}
}
}
Tile tmp = closest;
path = new ArrayList<Tile>();
path.add(tmp);
while (tmp.previous != null) {
path.add(tmp);
tmp = tmp.previous;
}
return path;
}
public static int heuristic(Tile A,Tile B) {
int dx = Math.abs(A.x - B.x);
int dy = Math.abs(A.y - B.y);
return 1 * (dx + dy) + (1 - 2 * 1) * Math.min(dx,dy);
}
And i have another Problem. I load the whole entire map inclusive ist obstacle during calling the finPath-Method, but i didnt find another solution, where i can load it only once. And i really tried a lot believe me... .
So here my two Questions:
What must i exactly compare within the compareTo Method to make it work?
Where can i load my TiledMap once, so A* havent got to update it during it is called?
I've been submitting programs to this problem at ACM. Problem ID=1922 but my solution keeps getting Time Limit Exceeded on test 3.
My idea is to use brute-force but with some branches-cutting-off. The below is my Java code, any faster solutions or improvements would be appreciated... I guess this isn't difficult at all because the difficulty is only 195, but I just can't get it accepted.
Finally got it accepted. The algorithm is to first sort the heroes, and start with the smallest-wish first. Just O(n)..
My Java code is so far the fastest Solution Rank
Many thanks!
public class testtest
{
static boolean[] used;
// length of heros
static int ulen;
// list of heros
static Wish[] w;
// number of possible teams
static int count = 0;
// and output
static StringBuilder str = new StringBuilder();
// add the team
// check if it is a valid team
static boolean check(int len)
{
for (int i = 0; i < ulen; i ++)
{
if (!used[i])
{
// adding another hero makes it reliable, so invalid
if (w[i].wish <= len + 1)
{
return false;
}
}
}
return true;
}
// search the teams, team size = total, current pick = len, start from root + 1
static void search(int root, int total, int len)
{
if (len >= total) // finish picking len heros
{
if (check(total)) // valid
{
print(total); // add to output
}
return;
}
for (int i = root + 1; i < ulen; i ++)
{
if (w[i].wish > len + ulen - i)
{
return; // no enough heros left, so return
}
else
if (w[i].wish <= total) // valid hero for this team
{
used[i] = true;
search(i, total, len + 1); // search next hero
used[i] = false;
}
}
}
public static void main(String[] args) throws IOException
{
BufferedReader rr = new BufferedReader(new InputStreamReader(System.in));
ulen = Integer.parseInt(rr.readLine());
w = new Wish[ulen];
for (int i = 0; i < ulen; i ++)
{
w[i] = new Wish(i + 1, Integer.parseInt(rr.readLine()));
}
Arrays.sort(w);
used = new boolean[ulen];
Arrays.fill(used, false);
for (int i = 1; i <= ulen; i ++)
{
for (int j = 0; j <= ulen - i; j ++)
{
if (w[j].wish <= i) // this hero is valid
{
used[j] = true;
search(j, i, 1);
used[j] = false;
}
}
}
System.out.println(count);
System.out.print(str);
}
}
First, my results (of Java) is the fastest.
http://acm.timus.ru/rating.aspx?space=1&num=1922&lang=java
The fact that I didn't make full use before is that I have sorted list of heroes according to their wishes.
Therefore, the main loop just needs to be changed to O(n) instead of O(n^2)
for (int i = 1; i <= ulen; i ++)
{
if (w[0].wish <= i)
{
used[0] = true;
search(0, i, 1);
used[0] = false;
}
}
Here is what I have that executes for the sample test in ~0.00013 seconds (on my CPU):
import java.io.*;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.Arrays;
/**
* Hero.java
*
* This program solves the Super Hero problem put forth by Timus Online Judge
* http://acm.timus.ru/problem.aspx?space=1&num=1922
*
* #author Hunter McMillen
* #version 1.0 12/29/2012
*/
public class Hero {
private static Map<Integer, Integer> indexMap = new HashMap<Integer, Integer>();
private static List<Integer> indices = new ArrayList<Integer>();
private static boolean[] used;
/**
* Entry point into the application
*
* #args command line arguments
*/
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
int numHeroes, wish;
List<Integer> heroes = new ArrayList<Integer>();
List<List<Integer>> groups;
// read number of heroes
numHeroes = Integer.parseInt(in.readLine());
// read 'numHeroes' wishes from stdin
// filter out heroes that have a minimum required that exceeds
// the number of heroes
for(int i = 0; i < numHeroes; i++) {
wish = Integer.parseInt(in.readLine());
if(wish <= numHeroes)
heroes.add(wish);
}
// split into groups
groups = reliableGroups(heroes);
// output results
System.out.println(groups.size());
for(List<Integer> g : groups) {
System.out.println(g.size() + " " + g.toString().replaceAll("[\\]\\[\\,]", ""));
}
}
/**
* Determines whether a group is effective, meaning that all wishes
* for that group are met
*
* #group The group to evaluate for effectiveness
*/
public static boolean isEffective(List<Integer> group) {
int maxWish = Integer.MIN_VALUE;
int temp;
// find the maximum wish size of all members in group
for(int i = 0; i < group.size(); i++) {
if((temp = indexMap.get(group.get(i))) > maxWish)
maxWish = temp;
}
// make sure that the maximum wish size is respected
return group.size() >= maxWish;
}
/**
* Checks to see if there exists some other superhero
* that when added to this group makes another effective group
*
* #effectiveGroup The current grouping that is effective but might
* not be reliable
*/
public static boolean isReliable(List<Integer> effectiveGroup) {
for(int i = 1; i <= indices.size(); i++) {
if(!used[i]) {
// add another hero to this group to see if it remains effective
effectiveGroup.add(i);
// if it is still effective, then this group is not reliable
if(isEffective(effectiveGroup))
return false;
// remove the hero that was temporarily added
effectiveGroup.remove(effectiveGroup.size()-1);
}
}
// true if adding any unused member to this group made it ineffective
return true;
}
/**
* Separates the List<Integer> of heroes into reliable groups
*
* #heroes The List of heroes
*/
public static List<List<Integer>> reliableGroups(List<Integer> heroes) {
List<List<Integer>> groups = new ArrayList<List<Integer>>();
boolean effective = true;
int h, current;
// create HashMap with mapping between hero wish values and their index
for(int i = 1; i <= heroes.size(); i++) {
indices.add(i);
indexMap.put(i, heroes.get(i-1));
}
// create an array to track which heroes have been used
used = new boolean[indices.size()+1];
Arrays.fill(used, false);
List<int[]> combinations;
List<Integer> tempList;
for(int i = 1; i <= indices.size(); i++) {
h = indexMap.get(i);
combinations = combination(heroes, h);
// iterate over all combinations making sure the wish values are below
// the threshold for this hero at map index `i`
for(int[] aCombination : combinations) {
for(int j = 0; j < aCombination.length; j++) {
current = aCombination[j];
used[current] = true;
if(indexMap.get(current) > h) {
effective = false;
break;
}
}
// create a List from the integer[] combination
tempList = asList(aCombination);
// if the group makeup is reliable, save it
if(effective && !groups.contains(tempList) && isReliable(tempList))
groups.add(new ArrayList<Integer>(tempList));
// reset flags
effective = true;
Arrays.fill(used, false);
}
}
return groups;
}
/**
* Helper method that returns a List<Integer> given
* an array of primitive ints
*
* #array The array to convert to a List<Integer>
*/
public static List<Integer> asList(int[] array) {
List<Integer> boxed = new ArrayList<Integer>();
for(int i = 0; i < array.length; i++) {
boxed.add(array[i]);
}
return boxed;
}
/**
* Generates the intial r combination in ascending order
* i.e [1, 2, 3, 4, ..., r]
*
* #r The size of the intial combination
*/
public static int[] initialCombination(int r) {
int[] indices = new int[r];
for(int i = 0; i < r; i++)
indices[i] = i+1;
return indices;
}
/**
* Generates the next combination given an array of indices
*
* #indicesIn The array of indices
* #n The size of this combination
*/
public static int[] nextCombination(int[] indicesIn, int n) {
int[] indices = (int[])indicesIn.clone();
int r = indices.length;
// find the rightmost index that is not at its final highest value
int i = 0;
for (i = r - 1; i >= 0; i--) {
if (indices[i] != (i + n - r + 1)) {
break;
}
}
// return null if no more combinations exist
if (i == -1)
return null;
// increment rightmost index
indices[i]++;
// reset all the indices to the right of indices[i]
// to their smallest possible value.
for (int j = i + 1; j < r; j++) {
indices[j] = indices[j-1] + 1;
}
return indices;
}
/**
* Generates all r-combinations of the indices array
*
* #heroes The array of heroes wishes
* #r The length of the combination to generate
*/
public static List<int[]> combination(List<Integer> heroes, int r) {
List<int[]> combinations = new ArrayList<int[]>();
int[] indices = initialCombination(r);
while(indices != null) {
combinations.add(indices);
indices = nextCombination(indices, heroes.size());
}
return combinations;
}
}
In my last question seen here: Sudoku - Region testing I asked how to check the 3x3 regions and someone was able to give me a satisfactory answer (although it involved a LOT of tinkering to get it working how I wanted to, since they didn't mention what the class table_t was.)
I finished the project and was able to create a sudoku generator, but it feels like it's contrived. And I feel like I've somehow overcomplicated things by taking a very brute-force approach to generating the puzzles.
Essentially my goal is to create a 9x9 grid with 9- 3x3 regions. Each row / col / region must use the numbers 1-9 only once.
The way that I went about solving this was by using a 2-dimensional array to place numbers at random, 3 rows at a time. Once the 3 rows were done it would check the 3 rows, and 3 regions and each vertical col up to the 3rd position. As it iterated through it would do the same until the array was filled, but due to the fact that I was filling with rand, and checking each row / column / region multiple times it felt very inefficient.
Is there an "easier" way to go about doing this with any type of data construct aside from a 2d array? Is there an easier way to check each 3x3 region that might coincide with checking either vert or horizontal better? From a standpoint of computation I can't see too many ways to do it more efficiently without swelling the size of the code dramatically.
I built a sudoku game a while ago and used the dancing links algorithm by Donald Knuth to generate the puzzles. I found these sites very helpful in learning and implementing the algorithm
http://en.wikipedia.org/wiki/Dancing_Links
http://cgi.cse.unsw.edu.au/~xche635/dlx_sodoku/
http://garethrees.org/2007/06/10/zendoku-generation/
import java.util.Random;
import java.util.Scanner;
public class sudoku {
/**
* #antony
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int p = 1;
Random r = new Random();
int i1=r.nextInt(8);
int firstval = i1;
while (p == 1) {
int x = firstval, v = 1;
int a[][] = new int[9][9];
int b[][] = new int[9][9];
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if ((x + j + v) <= 9)
a[i][j] = j + x + v;
else
a[i][j] = j + x + v - 9;
if (a[i][j] == 10)
a[i][j] = 1;
// System.out.print(a[i][j]+" ");
}
x += 3;
if (x >= 9)
x = x - 9;
// System.out.println();
if (i == 2) {
v = 2;
x = firstval;
}
if (i == 5) {
v = 3;
x = firstval;
}
}
int eorh;
Scanner in = new Scanner(System.in);
System.out
.println("hey lets play a game of sudoku:take down the question and replace the 0's with your digits and complete the game by re entering your answer");
System.out.println("enter your option 1.hard 2.easy");
eorh = in.nextInt();
switch (eorh) {
case 1:
b[0][0] = a[0][0];
b[8][8] = a[8][8];
b[0][3] = a[0][3];
b[0][4] = a[0][4];
b[1][2] = a[1][2];
b[1][3] = a[1][3];
b[1][6] = a[1][6];
b[1][7] = a[1][7];
b[2][0] = a[2][0];
b[2][4] = a[2][4];
b[2][8] = a[2][8];
b[3][2] = a[3][2];
b[3][8] = a[3][8];
b[4][2] = a[4][2];
b[4][3] = a[4][3];
b[4][5] = a[4][5];
b[4][6] = a[4][6];
b[5][0] = a[5][0];
b[5][6] = a[5][6];
b[6][0] = a[6][0];
b[6][4] = a[6][4];
b[6][8] = a[6][8];
b[7][1] = a[7][1];
b[7][2] = a[7][2];
b[7][5] = a[7][5];
b[7][6] = a[7][6];
b[8][4] = a[8][4];
b[8][5] = a[8][5];
b[0][0] = a[0][0];
b[8][8] = a[8][8];
break;
case 2:
b[0][3] = a[0][3];
b[0][4] = a[0][4];
b[1][2] = a[1][2];
b[1][3] = a[1][3];
b[1][6] = a[1][6];
b[1][7] = a[1][7];
b[1][8] = a[1][8];
b[2][0] = a[2][0];
b[2][4] = a[2][4];
b[2][8] = a[2][8];
b[3][2] = a[3][2];
b[3][5] = a[3][5];
b[3][8] = a[3][8];
b[4][0] = a[4][0];
b[4][2] = a[4][2];
b[4][3] = a[4][3];
b[4][4] = a[4][4];
b[4][5] = a[4][5];
b[4][6] = a[4][6];
b[5][0] = a[5][0];
b[5][1] = a[5][1];
b[5][4] = a[5][4];
b[5][6] = a[5][6];
b[6][0] = a[6][0];
b[6][4] = a[6][4];
b[6][6] = a[6][6];
b[6][8] = a[6][8];
b[7][0] = a[7][0];
b[7][1] = a[7][1];
b[7][2] = a[7][2];
b[7][5] = a[7][5];
b[7][6] = a[7][6];
b[8][2] = a[8][2];
b[8][4] = a[8][4];
b[8][5] = a[8][5];
break;
default:
System.out.println("entered option is incorrect");
break;
}
for (int y = 0; y < 9; y++) {
for (int z = 0; z < 9; z++) {
System.out.print(b[y][z] + " ");
}
System.out.println("");
}
System.out.println("enter your answer");
int c[][] = new int[9][9];
for (int y = 0; y < 9; y++) {
for (int z = 0; z < 9; z++) {
c[y][z] = in.nextInt();
}
}
for (int y = 0; y < 9; y++) {
for (int z = 0; z < 9; z++)
System.out.print(c[y][z] + " ");
System.out.println();
}
int q = 0;
for (int y = 0; y < 9; y++) {
for (int z = 0; z < 9; z++)
if (a[y][z] == c[y][z])
continue;
else {
q++;
break;
}
}
if (q == 0)
System.out
.println("the answer you have entered is correct well done");
else
System.out.println("oh wrong answer better luck next time");
System.out
.println("do you want to play a different game of sudoku(1/0)");
p = in.nextInt();
firstval=r.nextInt(8);
/*if (firstval > 8)
firstval -= 9;*/
}
}
}
I think you can use a 1D array, in much the same way a 1D array can model a binary tree. For example, to look at the value below a number, add 9 to the index.
I just made this up, but could something like this work?
private boolean makePuzzle(int [] puzzle, int i)
{
for (int x = 0; x< 10 ; x++)
{
if (//x satisfies all three conditions for the current square i)
{
puzzle[i]=x;
if (i==80) return true //terminal condition, x fits in the last square
else
if makePuzzle(puzzle, i++);//find the next x
return true;
}// even though x fit in this square, an x couldn't be
// found for some future square, try again with a new x
}
return false; //no value for x fit in the current square
}
public static void main(String[] args )
{
int[] puzzle = new int[80];
makePuzzle(puzzle,0);
// print out puzzle here
}
Edit: its been a while since I've used arrays in Java, sorry if I screwed up any syntax. Please consider it pseudo code :)
Here is the code as described below in my comment.
public class Sudoku
{
public int[] puzzle = new int[81];
private void makePuzzle(int[] puzzle, int i)
{
for (int x = 1; x< 10 ; x++)
{
puzzle[i]=x;
if(checkConstraints(puzzle))
{
if (i==80)//terminal condition
{
System.out.println(this);//print out the completed puzzle
puzzle[i]=0;
return;
}
else
makePuzzle(puzzle,i+1);//find a number for the next square
}
puzzle[i]=0;//this try didn't work, delete the evidence
}
}
private boolean checkConstraints(int[] puzzle)
{
int test;
//test that rows have unique values
for (int column=0; column<9; column++)
{
for (int row=0; row<9; row++)
{
test=puzzle[row+column*9];
for (int j=0;j<9;j++)
{
if(test!=0&& row!=j&&test==puzzle[j+column*9])
return false;
}
}
}
//test that columns have unique values
for (int column=0; column<9; column++)
{
for(int row=0; row<9; row++)
{
test=puzzle[column+row*9];
for (int j=0;j<9;j++)
{
if(test!=0&&row!=j&&test==puzzle[column+j*9])
return false;
}
}
}
//implement region test here
int[][] regions = new int[9][9];
int[] regionIndex ={0,3,6,27,30,33,54,57,60};
for (int region=0; region<9;region++) //for each region
{
int j =0;
for (int k=regionIndex[region];k<regionIndex[region]+27; k=(k%3==2?k+7:k+1))
{
regions[region][j]=puzzle[k];
j++;
}
}
for (int i=0;i<9;i++)//region counter
{
for (int j=0;j<9;j++)
{
for (int k=0;k<9;k++)
{
if (regions[i][j]!=0&&j!=k&®ions[i][j]==regions[i][k])
return false;
}
}
}
return true;
}
public String toString()
{
String string= "";
for (int i=0; i <9;i++)
{
for (int j = 0; j<9;j++)
{
string = string+puzzle[i*9+j];
}
string =string +"\n";
}
return string;
}
public static void main(String[] args)
{
Sudoku sudoku=new Sudoku();
sudoku.makePuzzle(sudoku.puzzle, 0);
}
}
Try this code:
package com;
public class Suduku{
public static void main(String[] args ){
int k=0;
int fillCount =1;
int subGrid=1;
int N=3;
int[][] a=new int[N*N][N*N];
for (int i=0;i<N*N;i++){
if(k==N){
k=1;
subGrid++;
fillCount=subGrid;
}else{
k++;
if(i!=0)
fillCount=fillCount+N;
}
for(int j=0;j<N*N;j++){
if(fillCount==N*N){
a[i][j]=fillCount;
fillCount=1;
System.out.print(" "+a[i][j]);
}else{
a[i][j]=fillCount++;
System.out.print(" "+a[i][j]);
}
}
System.out.println();
}
}
}
Hi i need some help to improve my code. I am trying to use Radixsort to sort array of 10 numbers (for example) in increasing order.
When i run the program with array of size 10 and put 10 random int numbers in like
70
309
450
279
799
192
586
609
54
657
i get this out:
450
309
192
279
54
192
586
657
54
609
DonĀ“t see where my error is in the code.
class IntQueue
{
static class Hlekkur
{
int tala;
Hlekkur naest;
}
Hlekkur fyrsti;
Hlekkur sidasti;
int n;
public IntQueue()
{
fyrsti = sidasti = null;
}
// First number in queue.
public int first()
{
return fyrsti.tala;
}
public int get()
{
int res = fyrsti.tala;
n--;
if( fyrsti == sidasti )
fyrsti = sidasti = null;
else
fyrsti = fyrsti.naest;
return res;
}
public void put( int i )
{
Hlekkur nyr = new Hlekkur();
n++;
nyr.tala = i;
if( sidasti==null )
f yrsti = sidasti = nyr;
else
{
sidasti.naest = nyr;
sidasti = nyr;
}
}
public int count()
{
return n;
}
public static void radixSort(int [] q, int n, int d){
IntQueue [] queue = new IntQueue[n];
for (int k = 0; k < n; k++){
queue[k] = new IntQueue();
}
for (int i = d-1; i >=0; i--){
for (int j = 0; j < n; j++){
while(queue[j].count() != 0)
{
queue[j].get();
}
}
for (int index = 0; index < n; index++){
// trying to look at one of three digit to sort after.
int v=1;
int digit = (q[index]/v)%10;
v*=10;
queue[digit].put(q[index]);
}
for (int p = 0; p < n; p++){
while(queue[p].count() != 0) {
q[p] = (queue[p].get());
}
}
}
}
}
I am also thinking can I let the function take one queue as an
argument and on return that queue is in increasing order? If so how?
Please help. Sorry if my english is bad not so good in it.
Please let know if you need more details.
import java.util.Random;
public class RadTest extends IntQueue {
public static void main(String[] args)
{
int [] q = new int[10];
Random r = new Random();
int t = 0;
int size = 10;
while(t != size)
{
q[t] = (r.nextInt(1000));
t++;
}
for(int i = 0; i!= size; i++)
{
System.out.println(q[i]);
}
System.out.println("Radad: \n");
radixSort(q,size,3);
for(int i = 0; i!= size; i++)
{
System.out.println(q[i]);
}
}
}
Hope this is what you were talking about...
Thank you for your answer, I will look into it. Not looking for someone to solve the problem for me. Looking for help and Ideas how i can solve it.
in my task it says:
Implement a radix sort function for integers that sorts with queues.
The function should take one queue as an
argument and on return that queue should contain the same values in ascending
order You may assume that the values are between 0 and 999.
Can i put 100 int numbers on my queue and use radixsort function to sort it or do i need to put numbers in array and then array in radixsort function which use queues?
I understand it like i needed to put numbers in Int queue and put that queue into the function but that has not worked.
But Thank for your answers will look at them and try to solve my problem. But if you think you can help please leave comment.
This works for the test cases I tried. It's not entirely well documented, but I think that's okay. I'll leave it to you to read it, compare it to what you're currently doing, and find out why what you have might be different than mine in philosophy. There's also other things that are marked where I did them the "lazy" way, and you should do them a better way.
import java.util.*;
class Radix {
static int[] radixSort(int[] arr) {
// Bucket is only used in this method, so I declare it here
// I'm not 100% sure I recommend doing this in production code
// but it turns out, it's perfectly legal to do!
class Bucket {
private List<Integer> list = new LinkedList<Integer>();
int[] sorted;
public void add(int i) { list.add(i); sorted = null;}
public int[] getSortedArray() {
if(sorted == null) {
sorted = new int[list.size()];
int i = 0;
for(Integer val : list) {
sorted[i++] = val.intValue(); // probably could autobox, oh well
}
Arrays.sort(sorted); // use whatever method you want to sort here...
// Arrays.sort probably isn't allowed
}
return sorted;
}
}
int maxLen = 0;
for(int i : arr) {
if(i < 0) throw new IllegalArgumentException("I don't deal with negative numbers");
int len = numKeys(i);
if(len > maxLen) maxLen = len;
}
Bucket[] buckets = new Bucket[maxLen];
for(int i = 0; i < buckets.length; i++) buckets[i] = new Bucket();
for(int i : arr) buckets[numKeys(i)-1].add(i);
int[] result = new int[arr.length];
int[] posarr = new int[buckets.length]; // all int to 0
for(int i = 0; i < result.length; i++) {
// get the 'best' element, which will be the most appropriate from
// the set of earliest unused elements from each bucket
int best = -1;
int bestpos = -1;
for(int p = 0; p < posarr.length; p++) {
if(posarr[p] == buckets[p].getSortedArray().length) continue;
int oldbest = best;
best = bestOf(best, buckets[p].getSortedArray()[posarr[p]]);
if(best != oldbest) {
bestpos = p;
}
}
posarr[bestpos]++;
result[i] = best;
}
return result;
}
static int bestOf(int a, int b) {
if(a == -1) return b;
// you'll have to write this yourself :)
String as = a+"";
String bs = b+"";
if(as.compareTo(bs) < 0) return a;
return b;
}
static int numKeys(int i) {
if(i < 0) throw new IllegalArgumentException("I don't deal with negative numbers");
if(i == 0) return 1;
//return (i+"").length(); // lame method :}
int len = 0;
while(i > 0) {
len++;
i /= 10;
}
return len;
}
public static void main(String[] args) {
int[] test = {1, 6, 31, 65, 143, 316, 93, 736};
int[] res = radixSort(test);
for(int i : res) System.out.println(i);
}
}
One thing that looks strange:
for (int p = 0; p < n; p++){
while(queue[p].count() != 0) {
q[p] = (queue[p].get());
}
}
Is p supposed to be the index in q, which ranges from 0 to n-1, or in queue, which ranges from 0 to 9? It is unlikely to be both ...
Another:
for (int index = 0; index < n; index++){
// trying to look at one of three digit to sort after.
int v=1;
int digit = (q[index]/v)%10;
v*=10;
queue[digit].put(q[index]);
}
Why are you multiplying v by 10, only to overwrite it by v = 1 in the next iteration? Are you aware than v will always be one, and you will thus look at the same digit in every iteration?
Well I don't think I can help without almost posting the solution (just giving hints is more exhausting and I'm a bit tired, sorry), so I'll just contribute a nice little fuzz test so you can test your solution. How does that sound? :-)
Coming up with a good fuzztester is always a good idea if you're implementing some algorithm. While there's no 100% certainty if that runs with your implementation chances are it'll work (radix sort doesn't have any strange edge cases I'm aware of that only happen extremely rarely)
private static void fuzztest() throws Exception{
Random rnd = new Random();
int testcnt = 0;
final int NR_TESTS = 10000;
// Maximum size of array.
final int MAX_DATA_LENGTH = 1000;
// Maximum value allowed for each integer.
final int MAX_SIZE = Integer.MAX_VALUE;
while(testcnt < NR_TESTS){
int len = rnd.nextInt(MAX_DATA_LENGTH) + 1;
Integer[] array = new Integer[len];
Integer[] radix = new Integer[len];
for(int i = 0; i < len; i++){
array[i] = rnd.nextInt(MAX_SIZE);
radix[i] = new Integer(array[i]);
}
Arrays.sort(array);
sort(radix); // use your own sort function here.
for(int i = 0; i < len; i++){
if(array[i].compareTo(radix[i]) != 0){
throw new Exception("Not sorted!");
}
}
System.out.println(testcnt);
testcnt++;
}