I have used an existing genetic algorithm from
here
and reworked it I but don't know what I'm doing wrong
This is the error that I get
Exception in thread "main" java.lang.NullPointerException at
simpleGa.Algorithm.crossover(Algorithm.java:69) at
simpleGa.Algorithm.evolvePopulation(Algorithm.java:34) at
simpleGa.GAprisonerdilemma.main(GAprisonerdilemma.java:41)
I can't figure out exactly where the mistake is. Read a lot about NullPointerException but couldn't figure it out
package simpleGa;
public class Population {
public static Individual[] individuals;
/*
* Constructors
*/
// Create a population
public Population(int populationSize, boolean initialise) {
individuals = new Individual[populationSize];
// Initialise population
if (initialise) {
// Loop and create individuals
for (int i = 0; i < size(); i++) {
Individual newIndividual = new Individual();
newIndividual.generateIndividual();
saveIndividual(i, newIndividual);
}
for(int i=0;i<size();i++)
{
if(i%2==1){Individual individual1=individuals[i-1];
Individual individual2=individuals[i];
if(individuals[i-1].getGene(i-1)==0 && individuals[i].getGene(i)==0){
individuals[i-1].fitness=individual1.fitness+1;
individuals[i].fitness=individual2.fitness+1;
}
if(individuals[i-1].getGene(i-1)==1 && individuals[i].getGene(i)==1){
individuals[i-1].fitness=individual1.fitness+2;
individuals[i].fitness=individual2.fitness+2;
}
if(individuals[i-1].getGene(i-1)==0 && individuals[i].getGene(i)==1){
individuals[i-1].fitness=individual1.fitness+3;
individuals[i].fitness=individual2.fitness+0;
}
if(individuals[i-1].getGene(i-1)==1 && individuals[i].getGene(i)==0){
individuals[i-1].fitness=individual1.fitness+0;
individuals[i].fitness=individual2.fitness+3;
}
}}}
}
/* Getters */
public Individual getIndividual(int index) {
return individuals[index];
}
public Individual getFittest() {
Individual fittest = individuals[0];
// Loop through individuals to find fittest
for (int i = 1; i < size(); i++) {
if (fittest.getFitness() <= getIndividual(i).getFitness()) {
fittest = getIndividual(i);
}
}
return fittest;
}
/* Public methods */
// Get population size
public int size() {
return individuals.length;
}
// Save individual
public void saveIndividual(int index, Individual indiv) {
individuals[index] = indiv;
}
}
package simpleGa;
public class Individual {
static int defaultGeneLength = 1000;
private long[] genes =new long [defaultGeneLength];
// Cache
public static int fitness = 0;
// Create a random individual
public void generateIndividual() {
for (int i = 0; i < size(); i++) {
long gene = Math.round(Math.random());
genes[i] = gene;
}
}
/* Getters and setters */
// Use this if you want to create individuals with different gene lengths
public static void setDefaultGeneLength(int length) {
defaultGeneLength = length;
}
public long getGene(int i) {
return genes[i];
}
public void setGene(int index, long value) {
genes[index] = value;
fitness = 0;
}
/* Public methods */
public int size() {
return genes.length;
}
public static int getFitness() {
return fitness;
}
public void setFitness(int i) {
fitness=i;
}
#Override
public String toString() {
String geneString = "";
for (int i = 0; i < size(); i++) {
geneString += getGene(i);
}
return geneString;
}
}
package simpleGa;
public class Algorithm {
/* GA parameters */
private static final double uniformRate = 0.5;
private static final double mutationRate = 0.015;
private static final int tournamentSize = 5;
private static final boolean elitism = true;
/* Public methods */
// Evolve a population
public static Population evolvePopulation(Population pop) {
Population newPopulation = new Population(pop.size(), false);
// Keep our best individual
if (elitism) {
newPopulation.saveIndividual(0, pop.getFittest());
}
// Crossover population
int elitismOffset;
if (elitism) {
elitismOffset = 1;
} else {
elitismOffset = 0;
}
// Loop over the population size and create new individuals with
// crossover
for (int i = elitismOffset; i < pop.size(); i++) {
Individual indiv1 = tournamentSelection(pop);
Individual indiv2 = tournamentSelection(pop);
Individual newIndiv = crossover(indiv1, indiv2);
newPopulation.saveIndividual(i, newIndiv);
}
// Mutate population
for (int i = elitismOffset; i < newPopulation.size(); i++) {
mutate(newPopulation.getIndividual(i));
}
for(int i=0;i<pop.size();i++)
{for(int j=0;j<pop.getIndividual(i).size();j++)
{if(i%2==1){Individual individual1=Population.individuals[i-1];
Individual individual2=Population.individuals[i];
if(Population.individuals[i-1].getGene(i-1)==0 && Population.individuals[i].getGene(i)==0){
Population.individuals[i-1].fitness=individual1.fitness+1;
Population.individuals[i].fitness=individual2.fitness+1;
}
if(Population.individuals[i-1].getGene(i-1)==1 && Population.individuals[i].getGene(i)==1){
Population.individuals[i-1].fitness=individual1.fitness+2;
Population.individuals[i].fitness=individual2.fitness+2;
}
if(Population.individuals[i-1].getGene(i-1)==0 && Population.individuals[i].getGene(i)==1){
Population.individuals[i-1].fitness=individual1.fitness+3;
Population.individuals[i].fitness=individual2.fitness+0;
}
if(Population.individuals[i-1].getGene(i-1)==1 && Population.individuals[i].getGene(i)==0){
Population.individuals[i-1].fitness=individual1.fitness+0;
Population.individuals[i].fitness=individual2.fitness+3;
} }}}``
return newPopulation;
}
// Crossover individuals
private static Individual crossover(Individual indiv1, Individual indiv2) {
Individual newSol = new Individual();
// Loop through genes
for (int i = 0; i < indiv1.size(); i++) {
// Crossover
if (Math.random() <= uniformRate) {
newSol.setGene(i, indiv1.getGene(i));
} else {
newSol.setGene(i, indiv2.getGene(i));
}
}
return newSol;
}
// Mutate an individual
private static void mutate(Individual indiv) {
// Loop through genes
for (int i = 0; i < indiv.size(); i++) {
if (Math.random() <= mutationRate) {
// Create random gene
long gene = Math.round(Math.random());
indiv.setGene(i, gene);
}
}
}
// Select individuals for crossover
private static Individual tournamentSelection(Population pop) {
// Create a tournament population
Population tournament = new Population(tournamentSize, false);
// For each place in the tournament get a random individual
for (int i = 0; i < tournamentSize; i++) {
int randomId = (int) (Math.random() * pop.size());
tournament.saveIndividual(i, pop.getIndividual(randomId));
}
// Get the fittest
Individual fittest = tournament.getFittest();
return fittest;
}
package simpleGa;
public class FitnessCalc {
/* Public methods */
// Set a candidate solution as a byte array
// To make it easier we can use this method to set our candidate solution
// with string of 0s and 1s
// Calculate inidividuals fittness by comparing it to our candidate solution
static int getFitness(Individual individual) {
int fitness = 0;
// Loop through our individuals genes and compare them to our cadidates
fitness=Individual.fitness;
return fitness;
}
}
// Get optimum fitness
}
package simpleGa;
import java.util.Scanner;
public class GAprisonerdilemma {
public static void main(String[] args) {
// Set a candidate solution
Scanner keyboard = new Scanner(System.in);
System.out.println("Input number of games!");
int k = keyboard.nextInt();
Individual.setDefaultGeneLength(k);
// Create an initial population
System.out.println("Input number of individuals in the population!");
int p = keyboard.nextInt();
Population myPop = new Population(p, true);
System.out.println("Input acceptable number of generations!");
int l = keyboard.nextInt();
// Evolve our population until we reach an optimum solution
int generationCount = 0;
int j=l+1;
System.out.println("Input requiered fitness value !");
int f = keyboard.nextInt();
int h=0;
// Evolve our population until we reach an optimum solution
for(int i=0;i<j;i++)
{
if(i==0){}
else{
if(myPop.getFittest().getFitness()>=f){if(h==0){h++;}
else{ System.out.println("Solution found!");
System.out.println("Generation: " + generationCount);
System.out.println( "Fitness(Points): " + myPop.getFittest().getFitness());
break;}
}else {myPop = Algorithm.evolvePopulation(myPop);
generationCount++;
System.out.println("Generation: " + generationCount + " Fittest: " + myPop.getFittest().getFitness());
}
if(i==j-1){ if(myPop.getFittest().getFitness()>=f)System.out.println("Solution found !");
else System.out.println("Solution not found closest solution is!");
System.out.println("Generation: " + generationCount);
System.out.println( " Fitness(Points): " + myPop.getFittest().getFitness());}
}
}
System.out.println("0 for betrays in that turn 1 for cooperates!");
System.out.println("Turns:");
System.out.println(myPop.getFittest());
}
}
Related
Having trouble with this code below. It is implementation of population evolution. In my case the max fitness is struck at a local maxima everytime and is unable to reach max possible value. Kindly suggest necessary edits and reason for the same.
Individual.java
package genetic.algorithm.project;
import java.util.Random;
public class Individual {
public static int SIZE = 300;
private int[] genes = new int[SIZE];
private double fitnessValue = 0.0;
// Getters and Setters
public void setGene(int index,int gene){
this.genes[index] = gene;
}
public int getGene(int index){
return this.genes[index];
}
public void setFitnessValue(double fitness){
this.fitnessValue = fitness;
}
public double getFitnessValue(){
return this.fitnessValue;
}
//Function to generate a new individual with random set of genes
public void generateIndividual(){
Random rand = new Random();
for(int i=0;i<SIZE;i++){
this.setGene(i, rand.nextInt(2));
}
}
//Mutation Function
public void mutate(){
Random rand = new Random();
int index = rand.nextInt(SIZE);
this.setGene(index, 1-this.getGene(index)); // Flipping value of gene
}
//Function to set Fitness value of an individual
public int evaluate(){
int fitness = 0;
for(int i=0; i<SIZE; ++i) {
fitness += this.getGene(i);
}
this.setFitnessValue(fitness);
return fitness;
}
}
Population.java
import java.util.Random;
public class Population {
final static int ELITISM = 1;
final static int POP_SIZE = 200+ELITISM; //Population size + Elitism (1)
final static int MAX_ITER = 2000;
final static double MUTATION_RATE = 0.05;
final static double CROSSOVER_RATE = 0.7;
private static Random rand = new Random();
private double totalFitness;
private Individual[] pop;
//Constructor
public Population(){
pop = new Individual[POP_SIZE];
//Initialising population
for(int i=0;i<POP_SIZE;i++){
pop[i] = new Individual();
pop[i].generateIndividual();
}
this.evaluate();
}
//Storing new generation in population
public void setPopulation(Individual[] newPop) {
this.pop = newPop;
}
//Method to find total fitness of population
public double evaluate(){
this.totalFitness = 0.0;
for (int i = 0; i < POP_SIZE; i++) {
this.totalFitness += pop[i].evaluate();
}
return this.totalFitness;
}
//Getters
public Individual getIndividual(int index) {
return pop[index];
}
//Function to find fittest individual for elitism
public Individual getFittest() {
Individual fittest = pop[0];
for (int i = 0; i < POP_SIZE; i++) {
if (fittest.getFitnessValue() <= getIndividual(i).getFitnessValue()) {
fittest = getIndividual(i);
}
}
return fittest;
}
//CROSSOVER Function : Takes 2 individuals and returns 2 new individuals
public static Individual[] crossover(Individual indiv1,Individual indiv2) {
Individual[] newIndiv = new Individual[2];
newIndiv[0] = new Individual();
newIndiv[1] = new Individual();
int randPoint = rand.nextInt(Individual.SIZE);
int i;
for (i=0; i<randPoint; ++i) {
newIndiv[0].setGene(i, indiv1.getGene(i));
newIndiv[1].setGene(i, indiv2.getGene(i));
}
for (; i<Individual.SIZE; ++i) {
newIndiv[0].setGene(i, indiv2.getGene(i));
newIndiv[1].setGene(i, indiv1.getGene(i));
}
return newIndiv;
}
//Roulette Wheel Selection Function
public Individual rouletteWheelSelection() {
double randNum = rand.nextDouble() * this.totalFitness;
int idx;
for (idx=0; idx<POP_SIZE && randNum>0; idx++) {
randNum -= pop[idx].getFitnessValue();
}
return pop[idx-1];
}
//Main method
public static void main(String[] args) {
Population pop = new Population();
Individual[] newPop = new Individual[POP_SIZE];
Individual[] indiv = new Individual[2];
//Current Population Stats
System.out.println("Total Fitness = "+pop.totalFitness);
System.out.println("Best Fitness = "+pop.getFittest().getFitnessValue());
int count;
for(int iter=0;iter<MAX_ITER;iter++){
count =0;
//Elitism
newPop[count] = pop.getFittest();
count++;
//Creating new population
while(count < POP_SIZE){
//Selecting parents
indiv[0] = pop.rouletteWheelSelection();
indiv[1] = pop.rouletteWheelSelection();
// Crossover
if (rand.nextDouble() < CROSSOVER_RATE ) {
indiv = crossover(indiv[0], indiv[1]);
}
// Mutation
if ( rand.nextDouble() < MUTATION_RATE ) {
indiv[0].mutate();
}
if ( rand.nextDouble() < MUTATION_RATE ) {
indiv[1].mutate();
}
// add to new population
newPop[count] = indiv[0];
newPop[count+1] = indiv[1];
count += 2;
}
// Saving new population in pop
pop.setPopulation(newPop);
//Evaluating new population
pop.evaluate();
System.out.print("Total Fitness = " + pop.totalFitness);
System.out.println(" ; Best Fitness = " +pop.getFittest().getFitnessValue());
}
Individual bestIndiv = pop.getFittest();
}
}
The max possible value of fitness is 300 in my case but it always stucks around 200-230.
Replaced this function :
public void setPopulation(Individual[] newPop) {
this.pop = newPop;
}
with
public void setPopulation(Individual[] newPop) {
System.arraycopy(newPop, 0, this.pop, 0, POP_SIZE);
}
and it works fine now.
Question:
How do I update numberOfWins in the db as the program runs(rounds of poker are played), & at the end of program execution, display the data in/from my db?
Background:
This is a fairly standard console based poker game. Table is a dealer(creates hands) & executes rounds. PokerGameMain, the main. I also have classes for Card, Deck, Player, Wallet. 3 players are dealt cards, creating a hand, the hands are played, there is a winner & looser, this is a round. I have included my current code on these classes for context.
My questions are about two database/JDBC/SQLite classes(SQLiteJDBC, Database) I am attempting to implement. I've added these solely for learning purposes. I'm attempting to gain knowledge of database/JDBC/SQLite & maven(which I have used to manage my SQLite dependency).
I've working pretty diligently at this program but I'm having a little trouble seeing how to pull it together.
Question Again:
Primary) How do I:
Create a db(poker)...done I think.
Create a table(players), with 2 columns(palyerName, numberOfWins)...done I think.
Create 3 rows(player1-3)...done I think.
Update numberOfWins in the db as the program runs(rounds of poker are played), & at the end of program execution, display the data in my db
Secondary) Suggestions regarding:
My exception handling & design in SQLiteJDBC & Database
SQLiteJDBC
Note:
The only errors in the program that I know of are an unchecked exception & a can not resolve method. Both in SQLiteJDBC, here & here:
try {
db.execute(dropTable);
db.execute(createTable);
db.execute(insertInto1);
db.execute(insertInto2);
db.execute(insertInto3);
ResultSet resultSets = db.executeQuery(selectFrom);
try {
while (resultSets.next()) {
// read the result set
System.out.println("player = " + resultSets.getString("playerName"));
System.out.println("number of wins = " + resultSets.getInt("numberOfWins"));
}
}
try {
db.close();
}
package com.craigreedwilliams.utilities;
import java.sql.*;
/**
* Created by Reed on 7/10/2015.
*/
public class SQLiteJDBC {
public static void passQuery() {
String dropTable = "DROP TABLE if EXISTS players";
String createTable = "CREATE TABLE players(VARCHAR(25) playerName, INTEGER numberOfWins)";
String insertInto1 = "INSERT INTO player1 VALUES ('player1', 0)";
String insertInto2 = "INSERT INTO player2 VALUES ('player2', 0)";
String insertInto3 = "INSERT INTO player3 VALUES ('player3', 0)";
String selectFrom = "SELECT * FROM players";
// Url for SqlLite
String jdbcDbType = "jdbc:sqlite";
String dbName = "poker.db";
String dbUrl = jdbcDbType + ":" + dbName;
Database db = new Database(dbUrl);
try {
db.execute(dropTable);
db.execute(createTable);
db.execute(insertInto1);
db.execute(insertInto2);
db.execute(insertInto3);
ResultSet resultSets = db.executeQuery(selectFrom);
try {
while (resultSets.next()) {
// read the result set
System.out.println("player = " + resultSets.getString("playerName"));
System.out.println("number of wins = " + resultSets.getInt("numberOfWins"));
}
}
finally {
try {
resultSets.close();
}
catch (Exception ignore) {
}
}
}
finally {
try {
db.close();
}
catch (Exception ignore) {
}
}
}
}
Database
package com.craigreedwilliams.utilities;
import java.sql.*;
/**
* Created by Reed on 7/10/2015.
*/
public class Database {
public String dbUrl;
private String sqliteDriver = "org.sqlite.JDBC";
private String driver;
private Connection connection = null;
private Statement statement = null;
public Database() {
}
public Database(String dbUrl) {
this.dbUrl = dbUrl;
// sqliteDriver = getDriverString(dbUrl);
try {
setConnection();
} catch (Exception e) {
e.printStackTrace();
}
}
private void setConnection() throws Exception {
try {
// registered DriverName using the current class loader
Class.forName(sqliteDriver);
}
catch (Exception e) {
// connection failed
System.out.println("DriverName: " + driver + " was not available");
System.err.println(e);
throw e;
}
// create a database connection
connection = DriverManager.getConnection(dbUrl);
try {
statement = connection.createStatement();
}
catch (Exception e) {
try {
connection.close();
}
catch (Exception ignore) {
}
connection = null;
}
}
// this method should undoubtedly be public as we'll want to call this
// to close connections externally to the class
public void closeConnection() {
if (statement!=null) {
try {
statement.close();
}
catch (Exception ignore) {
}
}
if (connection!=null) {
try {
connection.close();
}
catch (Exception ignore) {
}
}
}
// and we will definitely want to be able to call the following two
// functions externally since they expose the database
// behaviour which we are trying to access
public ResultSet executeQuery(String query) throws SQLException {
return statement.executeQuery(query);
}
public void execute(String query) throws SQLException {
statement.executeUpdate(query);
}
}
PokerGameMain
package com.craigreedwilliams.game;
import java.util.Scanner;
/**
* Hello world!
*
*/
public class PokerGameMain
{
public static void main(String[] args) {
//Input Object of the scanner class
Scanner input = new Scanner(System.in);
int choice;
System.out.println("Welcome to Poker Table! May the odds forever be in your favor :)");
do {
printMainGameWelcomeMenu();
choice = input.nextInt();
switch (choice){
case 1:
//call start game method or class here
startGame();
break;
case 2:
//end game here
printMainGameGoodbyeMessage();
break;
default:
System.out.println("The value you entered is outside of the range required for this application...");
}
} while (choice != 2);
}
public static void printMainGameWelcomeMenu(){
System.out.println("This is the poker game's menu: \n"
+ "To start the game enter: 1\n"
+ "To end game enter: 2\n");
}
public static void printMainGameGoodbyeMessage(){
System.out.println("Thank you for playing the poker game! Hope you enjoyed your experience. Have a great day! :D");
}
public static void startGame(){
int count = 1;
Table table = new Table();
getUserInput(table);
while (count < 4) {
System.out.println("Round : " + count + "...\n");
table.dealCards();
table.showCards();
count++;
}
}
public static void getUserInput(Table table){
Scanner usrInput = new Scanner(System.in);
boolean anteSet = false;
System.out.println("Before the game starts, I will need some information...\n");
System.out.println("What is your name?");
String name = usrInput.nextLine();
//set player name
table.getPlayerAt(0).setPlayerName(name);
// set ante
do {
System.out.println("How much are you willing to bet for every round? Keep in mind there will have to be at least three rounds...");
Double ante = usrInput.nextDouble();
if(checkAnte(ante, table.getPlayerAt(0).getWallet())) {
table.getPlayerAt(0).setAnteValue(ante);
anteSet = true;
}
}while (!(anteSet));
}
public static boolean checkAnte(double ante, Wallet wallet){
if (ante * 3.0 > wallet.getBalance()) {
System.out.println("Sorry your wallet balance is less than you think...Please reconsider the ante value");
return false;
}
else
{
wallet.deductFromBalance(ante);
System.out.println("Your ante for each round is set to be: " + ante + ". Good luck!");
return true;
}
}
}
Table
package com.craigreedwilliams.game;
/**
* Created by Reed on 7/10/2015.
*/
public class Table {
// two private attributes
private Player[] players;
private Deck deck;
private double pot;
private Player winner;
/******************************************
** The array is set in the following way:
******************************************
** pairs are each given 1 point **
** three of a kind are given 3 points **
** straights are given 5 points **
** flush are given 7 points **
** four of a kind are given 8 points **
** royal straights are given 10 points **
** royal flush are given 12 points **
******************************************
*/
private int[][] game = new int [7][2];
// constructor initializes the deck and cards
public Table() {
deck = new Deck();
players = new Player[3];
players[0] = new Player();
players[1] = new Player();
players[2] = new Player();
deck.shuffle();
}
// getter for player at the given index
public Player getPlayerAt(int index){
return players[index];
}
// deals the card to each player
public void dealCards() {
int count = 0;
for (int i = 0; i < players[0].getCards().length; i++) {
for (int j = 0; j < players.length; j++) {
players[j].setCardAtIndex(deck.getCard(count++), i);
}
}
}
// simulates the game and shows the result
public void showCards() {
for (int i = 0; i < players.length; i++) {
System.out.print("Player " + (i + 1) + ": \n");
for (int j = 0; j < players[0].getCards().length; j++) {
System.out.println("{" + players[i].getCardAtIndex(j).toString() + "} ");
}
if(players[i].countPair() > 0) {
System.out.println("Pair(S):" + players[i].countPair() + "! \n");
game[0][i] += players[i].countPair();
}
if(players[i].isFlush()) {
System.out.println("Flush! ");
}
if(players[i].isRoyalFlush())
System.out.println("Royal Flush!!\n");
if(players[i].isThreeOfAkind())
System.out.println("Three of a kind! ");
if(players[i].isFourOfAkind())
System.out.println("Four of a kind!!\n");
if(players[i].isStraight())
System.out.println("Straight! \n");
if(players[i].isRoyalStraight())
System.out.println("Royal Straight!!\n");
else
System.out.print("\n");
}
}
}
Wallet
package com.craigreedwilliams.game;
import java.util.Random;
/**
* Created by Reed on 7/11/2015.
*/
public class Wallet {
private double balance;
/**
* default Wallet constructor
*/
public Wallet() {
setRandomStartingBalance(50.0, 500.0);
}
private void setRandomStartingBalance(double minimum, double maximum) {
Random random = new Random();
double randomStartingBalance = minimum + (maximum - minimum) * random.nextDouble();
balance = randomStartingBalance;
}
public double getBalance() {
return balance;
}
public void deductFromBalance(double price) {
this.balance = balance - price;
}
}
Player
package com.craigreedwilliams.game;
/**
* Created by Reed on 7/10/2015.
*/
public class Player {
private final static int MAX = 5;
private Card cards[]; //hand
private Deck tempDeck = new Deck();
private Double anteValue = 0.0;
private Wallet wallet;
private String playerName = "";
int gamesWon = 0;
// private bools for checks
private boolean pair = false;
private boolean threeOfAkind = false;
private boolean fourOfAkind = false;
private boolean royalStraight = false;
private boolean royalFlush = false;
//constructor initializes 5 cards in each hand
public Player() {
cards = new Card[MAX];
wallet = new Wallet();
}
// getters are setters for name and ante value
public String getPlayerName() {
return playerName;
}
public void setPlayerName(String playerName) {
this.playerName = playerName;
}
public Double getAnteValue() {
return anteValue;
}
public void setAnteValue(Double anteValue) {
this.anteValue = anteValue;
}
// getter for wallet for player object
public Wallet getWallet() {
return wallet;
}
// getter and setter for games won so far...
public int getGamesWon() {
return gamesWon;
}
public void setGamesWon(int gamesWon) {
this.gamesWon = gamesWon;
}
//returns all the cards in hand
public Card[] getCards() {
return cards;
}
//get the cards at a particular position
public Card getCardAtIndex(int index) {
return (index >= 0 && index < MAX) ? cards[index] : null;
}
//sets the card at particular position
public void setCardAtIndex(Card c, int index) {
if(index >= 0 && index < MAX)
cards[index] = c;
}
// basic bool return functions
public boolean isRoyalStraight() {
return royalStraight;
}
public boolean isThreeOfAkind() {
return threeOfAkind;
}
public boolean isFourOfAkind() {
return fourOfAkind;
}
public boolean isRoyalFlush() {
return royalFlush;
}
//Main Logic here : public functions that check for all winning hands and change private boolean variables
// appropriately
//counts number of matched pair
public int countPair() {
int count = 0;
//boolean pairCheck = ((!(threeOfAkind) && (!(fourOfAkind))));
for (int i = 0; i < cards.length; i++) {
for (int j = i + 1; j < cards.length; j++)
{
if (cards[i].getRank().equals(cards[j].getRank())){
count++;
if (count == 1)
pair = true;
else if ((pair) && (count == 3)) {
threeOfAkind = true;
pair = false;
}
else if ((threeOfAkind) && (count == 4)) {
fourOfAkind = true;
threeOfAkind = false;
}
}
}
}
return (pair) ? count : 0;
}
//checks if it is a flush or not i.e all five cards of same suit also checks for royal flush
public boolean isFlush()
{
int count = 0;
for (int i = 0; i < cards.length; i++) {
for (int j = i + 1; j < cards.length; j++) {
if (cards[i].getSuit().equals(cards[j].getSuit())) {
count++;
}
}
if (count == 5){
if (cards[i].getRankInt() == tempDeck.getRankInt(12))
royalFlush = true;
}
}
return ((count == 5) && (!(royalFlush))) ? true : false;
}
//checks to see if it is a straight or royal straight or neither
public boolean isStraight(){
int count = 0;
for (int i = 0; i < cards.length - 1; i++){
if ((cards[i].getRankInt() + 1 == cards[i + 1].getRankInt()) && (count < 4)){
count++;
}
else if (count == 4){
if (cards[i].getRankInt() == tempDeck.getRankInt(13)){
royalStraight = true;
}
}
}
return ((count == 4) && (!(royalStraight))) ? true : false;
}
}
Deck
package com.craigreedwilliams.game;
import java.util.Calendar;
import java.util.Random;
/**
* Created by Reed on 7/10/2015.
*/
public class Deck {
private final String rank[] = {"2","3","4","5","6","7","8","9","10","Jack","Queen","King", "Ace"};
private final String suits[]={"Hearts","Diamonds","Clubs","Spades"};
private final int rankInt[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14};
private final int suitsInt[] = {1, 2, 3, 4};
private Card deck[];
private final int MAX = 52;
private Random randNum;
//makes the deck, constructor - no arguments
public Deck() {
deck = new Card[MAX];
//uses calendar object to get time stamp
Calendar cal = Calendar.getInstance();
long seed = cal.getTimeInMillis();
randNum = new Random(seed); // random generated using time seed
// uses modulus operator
for(int i = 0; i < deck.length; i++ ){
deck[i] = new Card( rank[i % 13], suits[i / 13], rankInt[i % 13], suitsInt[i / 13]);
}
}
//shuffles the deck
public void shuffle(){
for(int i = 0; i < deck.length; i++ ){
int j = randNum.nextInt(MAX);
Card c = deck[i];
deck[i] = deck[j];
deck[j] = c;
}
}
//returns the individual card in the deck
public Card getCard(int index){
return deck[index];
}
//returns rankInt from the deck object at the given index value
public int getRankInt(int index) {
return rankInt[index];
}
}
Card
package com.craigreedwilliams.game;
/**
* Created by Reed on 7/10/2015.
*/
public class Card {
private String rank;
private String suit;
private int rankInt;
// TODO: remove this if actually never used
private int suitInt;
//four argument constructor initializes Cards rank and suit (stings and ints)
public Card(String rank, String suit, int rankInt, int suitInt) {
super();
this.rank = rank;
this.suit = suit;
this.rankInt = rankInt;
this.suitInt = suitInt;
}
//getter method to return the rank value
public String getRank() {
return rank;
}
//getter method to return the suit value
public String getSuit() {
return suit;
}
//setter method to initialize the suit
public int getRankInt() {
return rankInt;
}
//return String representation of Card object
public String toString() {
return rank + " : " + suit;
}
}
Your SQL query should look like this:
Select Player,Wins From yourtable Set Wins=Wins + 1 Where Player=playerid
The columns are just examples because I don't know how you called them ;)
And at the end of each round you just need to query your SQL-Server.
I have written a simple genetic algorithm program in java. What it is does is maximize the decimal value represented by the bits in the chromosome. Somehow mutation is not working as expected, e.g. causing two genes to mutate when just one is to change. The print statements I have included there show which to mutate, but in addition to that some more chromosomes get mutated. I can't figure out what the problem is :-(
Here are my java classes.
Gene.java
public class Gene {
private int value;
public Gene() {
value = Math.random() < 0.5 ? 0 : 1;
}
public Gene(int value) {
if (value != 0 && value != 1) {
throw new IllegalArgumentException("value must be either 0 or 1");
}
else {
this.value = value;
}
}
public void mutate() {
value = 1 - value;
}
public int value() {
return value;
}
#Override
public String toString() {
return String.valueOf(value);
}
}
Chromosome.java
import java.util.ArrayList;
import java.util.List;
public class Chromosome implements Comparable {
private ArrayList<Gene> genes;
private final int chromosomeLength;
public Chromosome(int length) {
this.genes = new ArrayList<>();
this.chromosomeLength = length > 0 ? length : 16;
for (int i = 0; i < chromosomeLength; i++) {
this.genes.add(i, new Gene());
}
}
public List<Gene> getAllele(int fromIndex, int toIndex) {
return new ArrayList<>(genes.subList(fromIndex, toIndex));
}
public void setAllele(int fromIndex, List<Gene> allele) {
int lastIndex = fromIndex + allele.size();
if (lastIndex > chromosomeLength) {
throw new IndexOutOfBoundsException("the allele exceeds beyond the size of the chromosome");
}
for (int i = fromIndex, j = 0; i < lastIndex; i++, j++) {
genes.set(i, allele.get(j));
}
}
public int getChromosomeLength() {
return chromosomeLength;
}
public void setGeneAt(int index, Gene gene) {
genes.set(index, gene);
}
public Gene getGeneAt(int index) {
return genes.get(index);
}
public int value() {
return Integer.parseInt(this.toString(), 2);
}
#Override
public String toString() {
StringBuilder chromosome = new StringBuilder("");
genes.stream().forEach((Gene g) -> chromosome.append(g));
return chromosome.toString();
}
#Override
public int compareTo(Object anotherChromosome) {
Chromosome c = (Chromosome) anotherChromosome;
return this.value() - c.value();
}
}
GenePool.java
import java.util.ArrayList;
import java.util.Arrays;
public class GenePool {
private final ArrayList<Chromosome> genePool;
private final int genePoolSize;
private final int chromosomeLength;
private final double crossOverRate;
private final double mutationRate;
private int[] crossPoints;
public GenePool(int numOfChromosome, int chromosomeLength, double crossOverRate, double mutationRate) {
this.genePoolSize = numOfChromosome;
this.chromosomeLength = chromosomeLength > 0 ? chromosomeLength : 16;
this.crossOverRate = crossOverRate;
this.mutationRate = mutationRate;
crossPoints = new int[1];
crossPoints[0] = this.chromosomeLength / 2;
genePool = new ArrayList<>();
for (int i = 0; i < numOfChromosome; i++) {
genePool.add(new Chromosome(chromosomeLength));
}
}
public int getGenePoolSize() {
return genePoolSize;
}
public Chromosome getChromosomeAt(int index) {
return genePool.get(index);
}
public void setChromosomeAt(int index, Chromosome c) {
genePool.set(index, c);
}
public int getChromosomeLength() {
return chromosomeLength;
}
public Chromosome[] crossOver(Chromosome c1, Chromosome c2) {
Chromosome[] offsprings = new Chromosome[2];
offsprings[0] = new Chromosome(c1.getChromosomeLength());
offsprings[1] = new Chromosome(c1.getChromosomeLength());
Chromosome[] parentChromosomes = {c1, c2};
int selector = 0;
for (int i = 0, start = 0; i <= crossPoints.length; i++) {
int crossPoint = i == crossPoints.length ? c1.getChromosomeLength() : crossPoints[i];
offsprings[0].setAllele(start, parentChromosomes[selector].getAllele(start, crossPoint));
offsprings[1].setAllele(start, parentChromosomes[1 - selector].getAllele(start, crossPoint));
selector = 1 - selector;
start = crossPoint;
}
return offsprings;
}
public void mutateGenePool() {
int totalGeneCount = genePoolSize * chromosomeLength;
System.out.println("Mutating genes:");
for (int i = 0; i < totalGeneCount; i++) {
double prob = Math.random();
if (prob < mutationRate) {
System.out.printf("Chromosome#: %d\tGene#: %d\n", i / chromosomeLength, i % chromosomeLength);
genePool.get(i / chromosomeLength).getGeneAt(i % chromosomeLength).mutate();
}
}
System.out.println("");
}
public int getLeastFitIndex() {
int index = 0;
int min = genePool.get(index).value();
int currentValue;
for (int i = 1; i < genePoolSize; i++) {
currentValue = genePool.get(i).value();
if (currentValue < min) {
index = i;
min = currentValue;
}
}
return index;
}
public void saveFittest(ArrayList<Chromosome> offsprings) {
// sort in ascending order
offsprings.sort(null);
offsprings.stream().forEach((offspring) -> {
int leastFitIndex = getLeastFitIndex();
if (offspring.value() > genePool.get(leastFitIndex).value()) {
genePool.set(leastFitIndex, offspring);
}
});
}
public void evolve(int noOfGeneration) {
for (int generation = 1; generation <= noOfGeneration; generation++) {
System.out.println("Generation :" + generation);
ArrayList<Integer> selection = new ArrayList<>();
for (int i = 0; i < genePoolSize; i++) {
if (Math.random() <= crossOverRate) {
selection.add(i);
}
}
if (selection.size() % 2 == 1) {
selection.remove(selection.size() - 1);
}
ArrayList<Chromosome> offsprings = new ArrayList<>();
for (int i = 0; i < selection.size(); i += 2) {
int index1 = selection.get(i);
int index2 = selection.get(i + 1);
offsprings.addAll(Arrays.asList(crossOver(genePool.get(index1), genePool.get(index2))));
}
System.out.println("Before saving the offsprings");
displayChromosomes(genePool, "GenePool");
displayChromosomes(offsprings, "Offsprings");
saveFittest(offsprings);
System.out.println("Before mutation:");
displayChromosomes(genePool, "GenePool");
mutateGenePool();
System.out.println("After mutation:");
displayChromosomes(genePool, "GenePool");
System.out.println("\n\n");
}
}
public void displayChromosomes(ArrayList<Chromosome> geneList, String name) {
System.out.println(name);
if (geneList.isEmpty()) {
System.out.println("Empty list");
}
geneList.stream().forEach((c) -> {
System.out.println(c + " -> " + c.value());
});
System.out.println("");
}
}
GADemo.java
public class GADemo {
public static void main(String[] args) {
GenePool gp = new GenePool(6, 8, 0.25, 0.01);
gp.evolve(10);
}
}
After evolving for a number of generations, the chromosomes all tend to become exactly the same, or very similar. And the problem is that that value is not the maximum for that many bits, and sometimes even a small value. For example, for 8 bits the values should (tend to) approach 255, but this doesn't do so in my code. Someone please provide a hint where/how to look for and solve the problem.
Focus on these lines and imagine the references. These are from setAllele()
for (int i = fromIndex, j = 0; i < lastIndex; i++, j++) {
genes.set(i, allele.get(j));
}
You are basically copying the reference from one onto the other. They are the same Gene so whatever mutation you do on those genes, will also affect even other Chromosomes.
You must produce a deep copy here.
Initially each chromosome has an own list of genes. But when you do the crossover operation you set gene objects from one chromosome into the gene list of other chromosome.
When you evolve the system, the number of shared genes will rise and therefore ultimately all chromosomes will share the same genes. No matter how you mutate a gene the chromosomes are not affected.
EDIT:
As Incognito also answered the setAllele method seems to be the culprit where gene sharing starts. You may want to introduce a method in the gene class where you can set its value given another gene.
We had a lab in Comsci I couldn't figure out. I did a lot of research on this site and others for help but they were over my head. What threw me off were the arrays. Anyway, thanks in advance. I already got my grade, just want to know how to do this :D
PS: I got mean, I just couldn't find the even numbered median and by mode I just gave up.
import java.util.Arrays;
import java.util.Random;
public class TextLab06st
{
public static void main(String args[])
{
System.out.println("\nTextLab06\n");
System.out.print("Enter the quantity of random numbers ===>> ");
int listSize = Expo.enterInt();
System.out.println();
Statistics intList = new Statistics(listSize);
intList.randomize();
intList.computeMean();
intList.computeMedian();
intList.computeMode();
intList.displayStats();
System.out.println();
}
}
class Statistics
{
private int list[]; // the actual array of integers
private int size; // user-entered number of integers in the array
private double mean;
private double median;
private int mode;
public Statistics(int s)
{
size = s;
list = new int[size];
mean = median = mode = 0;
}
public void randomize()
{
Random rand = new Random(12345);
for (int k = 0; k < size; k++)
list[k] = rand.nextInt(31) + 1; // range of 1..31
}
public void computeMean()
{
double total=0;
for (int f = 0; f < size; f++)
{
total = total + list[f];
}
mean = total / size;
}
public void computeMedian()
{
int total2 = 0;
Arrays.sort(list);
if (size / 2 == 1)
{
// total2 =
}
else
{
total2 = size / 2;
median = list[total2];
}
}
public void computeMode()
{
// precondition: The list array has exactly 1 mode.
}
public void displayStats()
{
System.out.println(Arrays.toString(list));
System.out.println();
System.out.println("Mean: " + mean);
System.out.println("Median: " + median);
System.out.println("Mode: " + mode);
}
}
Here are two implementations for your median() and mode() methods:
public void computeMedian() {
Arrays.sort(list);
if ( (list.size & 1) == 0 ) {
// even: take the average of the two middle elements
median = (list[(size/2)-1] + list[(size/2)]) / 2;
} else {
// odd: take the middle element
median = list[size/2];
}
}
public void computeMode() {
// precondition: The list array has exactly 1 mode.
Map<Integer, Integer> values = new HashMap<Integer, Integer>();
for (int i=0; i < list.size; ++i) {
if (values.get(list[i]) == null) {
values.put(list[i], 1);
} else {
values.put(list[i], values.get(list[i])+1);
}
}
int greatestTotal = 0;
// iterate over the Map and find element with greatest occurrence
Iterator it = values.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry)it.next();
if (pair.getValue() > greatestTotal) {
mode = pair.getKey();
greatestTotal = pair.getValue();
}
it.remove();
}
}
The program I am working on is a simple shipping program. What I am having difficulty with is populating a multidimensional array factoring in certain variables.
Example
320 items need to be shipped out to 1 receiver using different box sizes.
XL can hold 50 items
LG can hold 20 items
MD can hold 5 items
SM can hold 1 items
Use the least number of boxes so far.
Code
This is my code so far.
import java.util.Scanner;
public class Shipping {
public static void main(String [] args) {
Scanner kbd = new Scanner(System.in);
final int EXTRA_LARGE = 50;
final int LARGE = 20;
final int MEDIUM = 5;
final int SMALL = 1;
String sBusinessName = "";
int iNumberOfGPS = 0;
int iShipmentCount = 0;
displayHeading(kbd);
iShipmentCount = enterShipments(kbd);
int[][] ai_NumberOfShipments = new int [iShipmentCount][4];
String[] as_BusinessNames = new String [iShipmentCount];
for (int iStepper = 0; iStepper < iShipmentCount; iStepper++) {
sBusinessName = varifyBusinessName(kbd);
as_BusinessNames[iStepper] = sBusinessName;
iNumberOfGPS = varifyGPS(kbd);
calculateBoxes(ai_NumberOfShipments[iStepper],iNumberOfGPS, EXTRA_LARGE, LARGE, MEDIUM, SMALL);
}
//showArray(as_BusinessNames);
}
public static void displayHeading(Scanner kbd) {
System.out.println("Red River Electronics");
System.out.println("Shipping System");
System.out.println("---------------");
return;
}
public static int enterShipments(Scanner kbd) {
int iShipmentCount = 0;
boolean bError = false;
do {
bError = false;
System.out.print("How many shipments to enter? ");
iShipmentCount = Integer.parseInt(kbd.nextLine());
if (iShipmentCount < 1) {
System.out.println("\n**Error** - Invalid number of shipments\n");
bError = true;
}
} while (bError == true);
return iShipmentCount;
}
public static String varifyBusinessName(Scanner kbd) {
String sBusinessName = "", sValidName = "";
do {
System.out.print("Business Name: ");
sBusinessName = kbd.nextLine();
if (sBusinessName.length() == 0) {
System.out.println("");
System.out.println("**Error** - Name is required\n");
} else if (sBusinessName.length() >= 1) {
sValidName = sBusinessName;
}
} while (sValidName == "");
return sValidName;
}
public static int varifyGPS(Scanner kbd) {
int iCheckGPS = 0;
int iValidGPS = 0;
do {
System.out.print("Enter the number of GPS receivers to ship: ");
iCheckGPS = Integer.parseInt(kbd.nextLine());
if (iCheckGPS < 1) {
System.out.println("\n**Error** - Invalid number of shipments\n");
} else if (iCheckGPS >= 1) {
iValidGPS = iCheckGPS;
}
} while(iCheckGPS < 1);
return iValidGPS;
}
public static void calculateBoxes(int[] ai_ToFill, int iNumberOfGPS) {
for (int iStepper = 0; iStepper < ai_ToFill.length; iStepper++)
}
//public static void showArray( String[] ai_ToShow) {
// for (int iStepper = 0; iStepper < ai_ToShow.length; iStepper++) {
// System.out.println("Integer at position " + iStepper + " is " + ai_ToShow[iStepper]);
// }
//}
}
Change your definition of calculateBoxes() to also take an array that represents the volume of each of the boxes (in your case this will be {50, 20, 5, 1}:
public static void calculateBoxes(int[] ai_ToFill, int[] boxVolumes, int iNumberOfGPS) {
// for each box size
for (int iStepper = 0; iStepper < ai_ToFill.length; iStepper++) {
// while the remaining items to pack is greater than the current box size
while(iNumberOfGPS >= boxVolumes[iStepper]) {
// increment the current box type
ai_ToFill[iStepper]++;
// subtract the items that just got packed
iNumberOfGPS -= boxVolumes[iStepper];
}
}
}
Another way of calculating this (using / and % instead of a while loop) would be:
public static void calculateBoxes(int[] ai_ToFill, int[] boxVolumes, int iNumberOfGPS) {
// for each box size
for (int iStepper = 0; iStepper < ai_ToFill.length; iStepper++) {
if(iNumberOfGPS >= boxVolumes[iStepper]) {
// calculate the number of boxes that could be filled by the items
ai_ToFill[iStepper] = iNumberOfGPS/boxVolumes[iStepper];
// reset the count of items to the remainder
iNumberOfGPS = iNumberOfGPS%boxVolumes[iStepper];
}
}
}