问题描述
所以我在运行此代码时遇到问题。任务是使用遗传算法实现N = 8或更高的N-皇后问题。问题是,当我尝试运行程序时,出现“无法解析符号“染色体””错误,并且找不到ArrayList。如果这有所作为,我还将在IntelliJ中使用Java实现该问题。有人有解决问题的建议吗?
//CODE
import java.util.ArrayList;
import java.util.Random;
import java.util.Collections;
import java.util.*;
// genetic algorithm along with necessary parameters for solving the problem
public class geneticAlgorithmNQueen {
// Declare parameters for genetic algorithm
/* MAX_LENGTH = chess board width(N)
- START_SIZE = population size at start of problem
- MAX_EPOCHS = arbitrary number of test cycles
- MATING_PROBABILITY = probability of two chromosomes mating
*Range: 0.0 < MATING_PROBABILITY < 1.0*
- MUTATION_RATE = mutation rate
*Range: 0.0 < MUTATION_RATE < 1.0*
- MIN_SELECT = minimum parents allowed for selection
- MAX_SELECT = maximum parents allowed for selection
*Range: MIN_SELECT < MAX_SELECT < START_SIZE*
- OFFSPRING_PER_GENERATION = new offspring created per generation
*Range: 0 < OFFSPRING_PER_GENERATION < MAX_SELECT*
- MINIMUM_SHUFFLES = used for randomizing starting chromosomes
- MAXIMUM_SHUFFLES = used for randomizing starting chromosomes
*/
private int MAX_LENGTH;
private int START_SIZE;
private int MAX_EPOCHS;
private double MATING_PROBABILITY;
private double MUTATION_RATE;
private int MIN_SELECT;
private int MAX_SELECT;
private int OFFSPRING_PER_GENERATION;
private int MINIMUM_SHUFFLES;
private int MAXIMUM_SHUFFLES;
// Schedules mutations
private int nextMutation;
private ArrayList<Chromosome> population;
private ArrayList<Chromosome> solutions;
private Random rand;
private int childCount;
private int mutations;
private int epoch;
private int populationSize;
// Constructor with necessary parameters
public geneticAlgorithmNQueen(int n) {
// Set constant values
MAX_LENGTH = n;
START_SIZE = 40;
MAX_EPOCHS = 1000;
MATING_PROBABILITY = 0.7;
MUTATION_RATE = 0.001;
MIN_SELECT = 10;
MAX_SELECT = 30;
OFFSPRING_PER_GENERATION = 20;
MINIMUM_SHUFFLES = 8;
MAXIMUM_SHUFFLES = 20;
epoch = 0;
populationSize = 0;
}
// Beginning of the genetic algorithm solving for n queens problem
public boolean algorithm() {
population = new ArrayList<Chromosome>();
solutions = new ArrayList<Chromosome>();
rand = new Random();
nextMutation = 0;
childCount = 0;
mutations = 0;
epoch = 0;
populationSize = 0;
boolean done = false;
Chromosome thisChromo = null;
nextMutation = getRandNumber(0,(int)Math.round(1.0 / MUTATION_RATE));
initialize();
while(!done) {
populationSize = population.size();
for(int i = 0; i < populationSize; i++) {
thisChromo = population.get(i);
//If solution is found to the problem
if((thisChromo.getConflicts() == 0)) {
done = true;
}
}
//If max number of cycles is reached
if(epoch == MAX_EPOCHS) {
done = true;
}
getfitness();
rouletteSelection();
mating();
prepNextEpoch();
epoch++;
System.out.println("Epoch: " + epoch);
}
if(epoch >= MAX_EPOCHS) {
System.out.println("No solution found/");
done = false;
} else {
populationSize = population.size();
// Prints the solutions if found within mnc
for(int i = 0; i < populationSize; i++) {
thisChromo = population.get(i);
if(thisChromo.getConflicts() == 0) {
solutions.add(thisChromo);
printSolution(thisChromo);
}
}
}
System.out.println("done.");
System.out.println("Completed " + epoch + " epochs.");
System.out.println("Encountered " + mutations + " mutations in " + childCount + " offspring.");
return done;
}
// Begins the the mating process with the selected chromosomes
public void mating() {
int getRand = 0;
int parentA = 0;
int parentB = 0;
int newIndex1 = 0;
int newIndex2 = 0;
Chromosome newChromo1 = null;
Chromosome newChromo2 = null;
for(int i = 0; i < OFFSPRING_PER_GENERATION; i++) {
parentA = selectParent();
// Test the probability of mating
getRand = getRandNumber(0,100);
if(getRand <= MATING_PROBABILITY * 100) {
parentB = selectParent(parentA);
newChromo1 = new Chromosome(MAX_LENGTH);
newChromo2 = new Chromosome(MAX_LENGTH);
population.add(newChromo1);
newIndex1 = population.indexOf(newChromo1);
population.add(newChromo2);
newIndex2 = population.indexOf(newChromo2);
// Partially mapped crossover technique
partMappedCross(parentA,parentB,newIndex1,newIndex2);
if(childCount - 1 == nextMutation) {
exMutation(newIndex1,1);
} else if (childCount == nextMutation) {
exMutation(newIndex2,1);
}
population.get(newIndex1).computeConflicts();
population.get(newIndex2).computeConflicts();
childCount += 2;
// Schedules the next mutation
if(childCount % (int)Math.round(1.0 / MUTATION_RATE) == 0) {
nextMutation = childCount + getRandNumber(0,(int)Math.round(1.0 / MUTATION_RATE));
}
}
}
}
// Method partMappedCross crossovers two chromosome parents
// Uses partiallyMappedCrossover technique
// @param: parent A,parent B
// @param: child A,child B
public void partMappedCross(int chromA,int chromB,int child1,int child2) {
int j = 0;
int item1 = 0;
int item2 = 0;
int pos1 = 0;
int pos2 = 0;
Chromosome thisChromo = population.get(chromA);
Chromosome thatChromo = population.get(chromB);
Chromosome newChromo1 = population.get(child1);
Chromosome newChromo2 = population.get(child2);
int crosspoint1 = getRandNumber(0,MAX_LENGTH - 1);
int crosspoint2 = getExRandNumber(MAX_LENGTH - 1,crosspoint1);
// Retrieves the crosspoint from swapping location
if(crosspoint2 < crosspoint1) {
j = crosspoint1;
crosspoint1 = crosspoint2;
crosspoint2 = j;
}
// copies parent genes to offspring
for(int i = 0; i < MAX_LENGTH; i++) {
newChromo1.setGene(i,thisChromo.getGene(i));
newChromo2.setGene(i,thatChromo.getGene(i));
}
for(int i = crosspoint1; i <= crosspoint2; i++) {
// Retrieves the items to swap
item1 = thisChromo.getGene(i);
item2 = thatChromo.getGene(i);
// Retrieves the items and positions them in the offspring
for(j = 0; j < MAX_LENGTH; j++) {
if(newChromo1.getGene(j) == item1) {
pos1 = j;
} else if (newChromo1.getGene(j) == item2) {
pos2 = j;
}
}
// Swaps items
if(item1 != item2) {
newChromo1.setGene(pos1,item2);
newChromo1.setGene(pos2,item1);
}
// Retrieves the items and positions them in the offspring
for(j = 0; j < MAX_LENGTH; j++) {
if(newChromo2.getGene(j) == item2) {
pos1 = j;
} else if(newChromo2.getGene(j) == item1) {
pos2 = j;
}
}
// Swaps items
if(item1 != item2) {
newChromo2.setGene(pos1,item1);
newChromo2.setGene(pos2,item2);
}
}
}
// Method selectParent() chooses a randomly selected parent
// @return: random index of parent
public int selectParent() {
// Overloaded function
int parent = 0;
Chromosome thisChromo = null;
boolean done = false;
while(!done) {
// Randomly pick an eligible parent
parent = getRandNumber(0,population.size() - 1);
thisChromo = population.get(parent);
if(thisChromo.isSelected() == true) {
done = true;
}
}
return parent;
}
// Method selectParent(int parentA) chooses a randomly selected parent that is not the parameter
// @param: selected parent index
// @return: random index of parent
public int selectParent(int parentA) {
// Overloaded function
int parent = 0;
Chromosome thisChromo = null;
boolean done = false;
while(!done) {
// Randomly choose an eligible parent.
parent = getRandNumber(0,population.size() - 1);
if(parent != parentA){
thisChromo = population.get(parent);
if(thisChromo.isSelected() == true){
done = true;
}
}
}
return parent;
}
// Method rouletteSelection chooses selected parents based on roulette selection.
public void rouletteSelection() {
int j = 0;
int populationSize = population.size();
int maximumToSelect = getRandNumber(MIN_SELECT,MAX_SELECT);
double genTotal = 0.0;
double selTotal = 0.0;
double rouletteSpin = 0.0;
Chromosome thisChromo = null;
Chromosome thatChromo = null;
boolean done = false;
for(int i = 0; i < populationSize; i++) { //get total fitness
thisChromo = population.get(i);
genTotal += thisChromo.getfitness();
}
genTotal *= 0.01;
for(int i = 0; i < populationSize; i++) {
thisChromo = population.get(i);
// Set selection probability
thisChromo.setSelectionProbability(thisChromo.getfitness() / genTotal);
}
// Select most fit parents
for(int i = 0; i < maximumToSelect; i++) {
rouletteSpin = getRandNumber(0,99);
j = 0;
selTotal = 0;
done = false;
while(!done) {
thisChromo = population.get(j);
selTotal += thisChromo.getSelectionProbability();
if(selTotal >= rouletteSpin) {
if(j == 0) {
thatChromo = population.get(j);
} else if(j >= populationSize - 1) {
thatChromo = population.get(populationSize - 1);
} else {
thatChromo = population.get(j-1);
}
thatChromo.setSelected(true);
done = true;
} else {
j++;
}
}
}
}
// Method getfitness() sets the fitness of each chromosome based on its conflicts
public void getfitness() {
// Lowest error = 100%
// Highest error = 0%
int populationSize = population.size();
Chromosome thisChromo = null;
double bestscore = 0;
double worstscore = 0;
// The best score would be the lowest energy,vice versa for worse
worstscore = Collections.max(population).getConflicts();
// Convert scores to a weighted percentage.
bestscore = worstscore - Collections.min(population).getConflicts();
for(int i = 0; i < populationSize; i++) {
thisChromo = population.get(i);
thisChromo.setfitness((worstscore - thisChromo.getConflicts()) * 100.0 / bestscore);
}
}
//Method prepNextEpoch() resets all flags in the selection
public void prepNextEpoch() {
int populationSize = 0;
Chromosome thisChromo = null;
// Reset flags for selected individuals
populationSize = population.size();
for(int i = 0; i < populationSize; i++) {
thisChromo = population.get(i);
thisChromo.setSelected(false);
}
}
// Method printSolution() prints an NxN chessboard with queens
// @param: a chromosome
public void printSolution(Chromosome solution) {
String board[][] = new String[MAX_LENGTH][MAX_LENGTH];
// Clears the chessboard
for(int x = 0; x < MAX_LENGTH; x++) {
for(int y = 0; y < MAX_LENGTH; y++) {
board[x][y] = "";
}
}
for(int x = 0; x < MAX_LENGTH; x++) {
board[x][solution.getGene(x)] = "Q";
}
// display the board.
System.out.println("Board:");
for(int y = 0; y < MAX_LENGTH; y++) {
for(int x = 0; x < MAX_LENGTH; x++) {
if(board[x][y] == "Q") {
System.out.print("Q ");
} else {
System.out.print(". ");
}
}
System.out.print("\n");
}
}
// Method initialize() initializes all of the chromosomes' placement of queens in ramdom positions
public void initialize() {
int shuffles = 0;
Chromosome newChromo = null;
int chromoIndex = 0;
for(int i = 0; i < START_SIZE; i++) {
newChromo = new Chromosome(MAX_LENGTH);
population.add(newChromo);
chromoIndex = population.indexOf(newChromo);
// Randomly choose the number of shuffles to perform.
shuffles = getRandNumber(MINIMUM_SHUFFLES,MAXIMUM_SHUFFLES);
exMutation(chromoIndex,shuffles);
population.get(chromoIndex).computeConflicts();
}
}
// Method exMutation() changes the position of the queens in a chromosome randomly according to the number of exchanges
// @param: index of the chromosome
// @param: number of exhanges
public void exMutation(int index,int exchanges) {
int tempData = 0;
int gene1 = 0;
int gene2 = 0;
Chromosome thisChromo = null;
thisChromo = population.get(index);
for(int i = 0; i < exchanges; i++) {
gene1 = getRandNumber(0,MAX_LENGTH - 1);
gene2 = getExRandNumber(MAX_LENGTH - 1,gene1);
// Exchange the chosen genes
tempData = thisChromo.getGene(gene1);
thisChromo.setGene(gene1,thisChromo.getGene(gene2));
thisChromo.setGene(gene2,tempData);
}
mutations++;
}
// Method getExRandNumber() gets a random number with the exception of the parameter
// @param: max random number
// @param: number being chosen
// @return: random number
public int getExRandNumber(int high,int except) {
boolean done = false;
int getRand = 0;
while(!done) {
getRand = rand.nextInt(high);
if(getRand != except){
done = true;
}
}
return getRand;
}
// Method getRandNumber() gets a random number in the range of the parameters
// @param: min random number
// @param: max random number
// @return: random number
public int getRandNumber(int low,int high) {
return (int)Math.round((high - low) * rand.nextDouble() + low);
}
// Method getSolutions() returns the solutions
public ArrayList<Chromosome> getSolutions() {
return solutions;
}
// Method getEpoch() returns epoch
public int getEpoch() {
return epoch;
}
// Method getPopSize() returns population size
public int getPopSize() {
return population.size();
}
// Method getStartSize() returns starting size
public int getStartSize() {
return START_SIZE;
}
// Method getMatingProb() returns mating probability
public double getMatingProb() {
return MATING_PROBABILITY;
}
// Method getMutationRate() returns mutation rate
public double getMutationRate() {
return MUTATION_RATE;
}
// Method getMinSelect() returns minimum start size
public int getMinSelect() {
return MIN_SELECT;
}
// Method getMaxSelect() returns maximum start size
public double getMaxSelect() {
return MAX_SELECT;
}
// Method getMaxEpochs() returns max epoch per cycle
public int getMaxEpoch() {
return MAX_EPOCHS;
}
// Method setEpoch(0 sets new max epoch
public void setEpoch(int newMaxEpoch) {
this.MAX_EPOCHS = newMaxEpoch;
}
// Method getShuffleMin() returns minimum shuffles
public int getShuffleMin() {
return MINIMUM_SHUFFLES;
}
// Method getShuffleMax() returns maximum shuffles
public int getShuffleMax() {
return MAXIMUM_SHUFFLES;
}
// Method getoffspring() gets the mutation rate
public double getoffspring() {
return OFFSPRING_PER_GENERATION;
}
// Method setMutRate() sets new mutation rate
public void setMutRate(double newMutation) {
this.MUTATION_RATE = newMutation;
}
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)