Documente Academic
Documente Profesional
Documente Cultură
nct nici una s nu fie ameninat de o alt dam (s nu fie poziionate pe aceeai linie, coloan sau
diagonal) cu ajutorul algorimtilor genetici.
REZOLVARE:
-
NOTA !:
-
package georgiu.ioan.finder.adapters;
import java.util.ArrayList;
import java.util.Random;
public class NQueen1 {
/**
*Se initializeaza numarul populatie la start.
*/
private static final int START_SIZE = 75;
/**
*Se allege un numar arbitrar pentru ciclurile de test.
*/
private static final int MAX_EPOCHS = 1000;
/**
*Probabilitatea ca 2 cromozomi sa formeze o pereche.
Probabilitatea variaza intre 0.0 si MATING_PROBABILITY < 1.0
*/
private static final double MATING_PROBABILITY = 0.7;
/**
*Se selecteaza rata mutatiei. Aceasta variaza intre 0.0 <
MUTATION_RATE < 1.0
*/
private static final double MUTATION_RATE = 0.001;
/**
*Se allege numarul minim de parinti pentru selectie.
*/
private static final int MIN_SELECT = 10;
/**
* Se allege numarul maxim de parinti pentru selectie. Acesta
variaza intre: MIN_SELECT < MAX_SELECT < START_SIZE
*/
} else
//
//
//
{
daca j nu depasteste numarul de indivizi
si nu este ultimul individ
get ultimul individ de la pozitia j-1 pentru
ca
// numaratoarea incepe de la 0
thatChromo = population.get(j - 1);
}
thatChromo.setSelected(true);
done = true;
} else {
j++;
}
}
}
}
/**
* Aceasta metoda creeaza noi indivizi prin combinarea asptectelor
diecarui individ selectat. Se presupune ca prin combinarea anumitor
elemente din doi sau mai multi indivizi se va crea un offsping care
va mosteni cele mai bune parti ale ambilor parinti *
* @param mappedMating true este un parametru folosit pentru metoda
crossover mapped partial si false pentru metoda crossover
pozitionata.
*/
private static void mating(boolean mappedMating) {
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++) {
// Se alege random un parinte eligibil
parentA = chooseParent();
// Se alege random probabilitatea de a se crea o pereche
getRand = getRandomNumber(0, 100);
// Se testeaza probabilitatea de a se crea o pereche
if (getRand <= MATING_PROBABILITY * 100) {
// Se allege primul parinte
parentB = chooseParent(parentA);
newChromo1 = new Chromosome();
newChromo2 = new Chromosome();
population.add(newChromo1);
newIndex1 = population.indexOf(newChromo1);
population.add(newChromo2);
newIndex2 = population.indexOf(newChromo2);
// Se allege oricare dintre aceste metode:
if (mappedMating) {
partiallyMappedCrossover(parentA, parentB,
newIndex1, newIndex2);
} else {
positionBasedCrossover(parentA, parentB, newIndex1,
newIndex2);
}
if (childCount - 1 == nextMutation) {
exchangeMutation(newIndex1, 1);
} else if (childCount == nextMutation) {
exchangeMutation(newIndex2, 1);
}
population.get(newIndex1).computeConflicts();
population.get(newIndex2).computeConflicts();
childCount += 2;
// Se programeaza o noua mutare.
if (childCount % (int) Math.round(1.0 / MUTATION_RATE)
== 0) {
nextMutation = childCount + getRandomNumber(0,
(int) Math.round(1.0 / MUTATION_RATE));
}
}
}
}
private static void partiallyMappedCrossover(int chromA, int
chromB, int child1, int child2) {
int j = 0;
int item1 = 0;
int item2 = 0;
int pos1 = 0;
int pos2 = 0;
int crossPoint1 = getRandomNumber(0, MAX_LENGTH - 1);
int crossPoint2 = getExclusiveRandomNumber(MAX_LENGTH - 1,
crossPoint1);
Chromosome thisChromo = population.get(chromA);
Chromosome thatChromo = population.get(chromB);
Chromosome newChromo1 = population.get(child1);
Chromosome newChromo2 = population.get(child2);
if (crossPoint2 < crossPoint1) {
j = crossPoint1;
crossPoint1 = crossPoint2;
crossPoint2 = j;
}
// Copy Parent genereaza noi indivizi.
for (int i = 0; i < MAX_LENGTH; i++) {
newChromo1.setData(i, thisChromo.getData(i));
newChromo2.setData(i, thatChromo.getData(i));
}
for (int i = crossPoint1; i <= crossPoint2; i++) {
// Cei doi itemi isi schimba pozitia.
item1 = thisChromo.getData(i);
item2 = thatChromo.getData(i);
// Selecteaza itemii in offspring.
for (j = 0; j < MAX_LENGTH; j++) {
if (newChromo1.getData(j) == item1) {
pos1 = j;
} else if (newChromo1.getData(j) == item2) {
pos2 = j;
}
} // j
// Se efectueaza schimbarea.
if (item1 != item2) {
newChromo1.setData(pos1, item2);
newChromo1.setData(pos2, item1);
}
// Selecteaza itemii in offspring.
for (j = 0; j < MAX_LENGTH; j++) {
if (newChromo2.getData(j) == item2) {
pos1 = j;
} else if (newChromo2.getData(j) == item1) {
pos2 = j;
}
}
// Se efectueaza schimbarea.
if (item1 != item2) {
newChromo2.setData(pos1, item1);
newChromo2.setData(pos2, item2);
}
}
}
private static void positionBasedCrossover(int chromA, int chromB,
int child1, int child2) {
int k = 0;
int numPoints = 0;
int tempArray1[] = new int[MAX_LENGTH];
int tempArray2[] = new int[MAX_LENGTH];
boolean matchFound = false;
Chromosome thisChromo = population.get(chromA);
Chromosome thatChromo = population.get(chromB);
Chromosome newChromo1 = population.get(child1);
Chromosome newChromo2 = population.get(child2);
// Selectarea si alegerea crosspoints.
numPoints = getRandomNumber(0, PBC_MAX);
int crossPoints[] = new int[numPoints];
for (int i = 0; i < numPoints; i++) {
crossPoints[i] = getRandomNumber(0, MAX_LENGTH - 1,
crossPoints);
} // i
//Prin Get se aleg itemii care nu au fost alesi pentru al
doilea parinte.
k = 0;
for (int i = 0; i < MAX_LENGTH; i++) {
matchFound = false;
for (int j = 0; j < numPoints; j++) {
if (thatChromo.getData(i) ==
thisChromo.getData(crossPoints[j])) {
matchFound = true;
}
} // j
if (!matchFound) {
tempArray1[k] = thatChromo.getData(i);
k++;
}
} // i
// Se insereaza itemii alesi in child 1.
for (int i = 0; i < numPoints; i++) {
newChromo1.setData(crossPoints[i],
thisChromo.getData(crossPoints[i]));
}
// Se completeaza itemii care nu au fost alesi in child 1.
k = 0;
for (int i = 0; i < MAX_LENGTH; i++) {
matchFound = false;
for (int j = 0; j < numPoints; j++) {
if (i == crossPoints[j]) {
matchFound = true;
}
} // j
if (!matchFound) {
newChromo1.setData(i, tempArray1[k]);
k++;
}
} // i
//Prin Get se aleg itemii care nu au fost alesi pentru primul
parinte.
k = 0;
for (int i = 0; i < MAX_LENGTH; i++) {
matchFound = false;
for (int j = 0; j < numPoints; j++) {
if (thisChromo.getData(i) ==
thatChromo.getData(crossPoints[j])) {
matchFound = true;
}
} // j
if (!matchFound) {
tempArray2[k] = thisChromo.getData(i);
k++;
}
} // i
// Se insereaza itemii alesi in child 2.
for (int i = 0; i < numPoints; i++) {
newChromo2.setData(crossPoints[i],
thatChromo.getData(crossPoints[i]));
}
int parent = 0;
boolean done = false;
Chromosome thisChromo = null;
while (!done) {
// Se allege un parinte potrivit.
parent = getRandomNumber(0, population.size() - 1);
// Daca parentA este egal cu -1 atunci inseamna ca
// trebuie sa alegem primul parinte
if (parentA == -1) {
thisChromo = population.get(parent);
// see if the individual is one of the
// previously selected ones
// and finish the loop
if (thisChromo.isSelected()) {
done = true;
}
// daca parentA nu etse egal cu -1 atunci inseamna ca
// trebuie sa alegem al doilea parinte
// si trebuie sa verificam daca parintele selectat
// nu este la fel cu primul parinte selectat
} else if (parent != parentA) {
thisChromo = population.get(parent);
// Se verifica daca individul selectat este unul dintre
// indivizii selectati anterior
if (thisChromo.isSelected()) {
done = true;
}
}
}
return parent;
}
/**
* Aceasta metoda reseteaza informatia pentru fiecare individ
selectat.
*/
private static void prepNextEpoch() {
int popSize = 0;
Chromosome thisChromo = null;
// Se reseteaza informatia prin isSelected indivizi.
popSize = population.size();
for (int i = 0; i < popSize; i++) {
thisChromo = population.get(i);
thisChromo.setSelected(false);
}
}
private static void printBestSolution(Chromosome bestSolution) {
String board[][] = new String[MAX_LENGTH][MAX_LENGTH];
// Se sterge, curate table de sah.
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][bestSolution.getData(x)] = "Q";
}
// Se afiseaza tabela de sah.
System.out.println("Board:");
for (int y = 0; y < MAX_LENGTH; y++) {
for (int x = 0; x < MAX_LENGTH; x++) {
if (board[x][y].equals("Q")) {
System.out.print("Q ");
} else {
System.out.print(". ");
}
}
System.out.print("\n");
}
}
private static int getRandomNumber(final int low, final int high) {
return (int) Math.round((high - low) * new
Random().nextDouble() + low);
}
private static int getExclusiveRandomNumber(final int high, final
int except) {
boolean done = false;
int getRand = 0;
while (!done) {
getRand = new Random().nextInt(high);
if (getRand != except) {
done = true;
}
}
return getRand;
}
private static int getRandomNumber(int low, int high, int[] except)
{
boolean done = false;
int getRand = 0;
if (high != low) {
while (!done) {
done = true;
getRand = (int) Math.round((high - low) * new
Random().nextDouble() + low);
for (int anExcept : except) {
if (getRand == anExcept) {
done = false;
}
} // i
}
return getRand;
} else {
return high; // sau low (nu conteaza care dintre cele 2
variabile).
}
}
private static int minimum() {
// Returneaza un array index.
int popSize = 0;
int winner = 0;
boolean foundNewWinner = false;
boolean done = false;
Chromosome thisChromo = null;
Chromosome thatChromo = null;
while (!done) {
foundNewWinner = false;
popSize = population.size();
for (int i = 0; i < popSize; i++) {
if (i != winner) {
// Avoid selfcomparison.
thisChromo = population.get(i);
thatChromo = population.get(winner);
if (thisChromo.getConflicts() <
thatChromo.getConflicts()) {
winner = i;
foundNewWinner = true;
}
}
}
if (!foundNewWinner) {
done = true;
}
}
return winner;
}
private static int maximum() {
// Returneaza un array index.
int popSize = 0;
Chromosome thisChromo = null;
Chromosome thatChromo = null;
int winner = 0;
boolean foundNewWinner = false;
boolean done = false;
while (!done) {
foundNewWinner = false;
popSize = population.size();
for (int i = 0; i < popSize; i++) {
if (i != winner) {
// Avoid selfcomparison.
thisChromo = population.get(i);
thatChromo = population.get(winner);
if (thisChromo.getConflicts() >
thatChromo.getConflicts()) {
winner = i;
foundNewWinner = true;
}
}
}
if (!foundNewWinner) {
done = true;
}
}
return winner;
}
/**
* Aceasta metoda initializeaza cromozomii prin folosirea {@link
START_SIZE}
* ca si marime a populatiei
*/
private static void initializeChromosomes() {
int shuffles = 0;
int chromoIndex = 0;
Chromosome newChromo = null;
for (int i = 0; i < START_SIZE; i++) {
newChromo = new Chromosome();
population.add(newChromo);
chromoIndex = population.indexOf(newChromo);
// Se allege random numarul de iteratii care sa fie
realizate.
shuffles = getRandomNumber(MINIMUM_SHUFFLES,
MAXIMUM_SHUFFLES);
//Se adauga informatii pentru fiecare cromozom ales
individual
exchangeMutation(chromoIndex, shuffles);
population.get(chromoIndex).computeConflicts();
}
}
private static class Chromosome {
private int mConflicts = 0;
private int mData[] = new int[MAX_LENGTH];
private double mFitness = 0.0;
private double mSelectionProbability = 0.0;
private boolean mSelected = false;
/**
* Constructor
* Creeaza data de la 1 la {@link MAX_LENGTH}
*/
public Chromosome() {
for (int i = 0; i < MAX_LENGTH; i++) {
this.mData[i] = i;
}
}
public void computeConflicts() {
int x = 0;
int y = 0;
int tempx = 0;
int tempy = 0;
int conflicts = 0;
int dx[] = new int[]{-1, 1, -1, 1};
int dy[] = new int[]{-1, 1, 1, -1};
boolean done = false;
String board[][] = new String[MAX_LENGTH][MAX_LENGTH];
// Se face clear la
for (int i = 0; i <
for (int j = 0;
board[i][j]
}
}
table de sah.
MAX_LENGTH; i++) {
j < MAX_LENGTH; j++) {
= "";
}
public double getSelectionProbability() {
return this.mSelectionProbability;
}
public void setSelectionProbability(final double SelProb) {
this.mSelectionProbability = SelProb;
}
public boolean isSelected() {
return this.mSelected;
}
public void setSelected(final boolean sValue) {
this.mSelected = sValue;
}
public double getFitness() {
return this.mFitness;
}
public void setFitness(final double score) {
this.mFitness = score;
}
public int getData(final int index) {
return this.mData[index];
}
public void setData(final int index, final int value) {
this.mData[index] = value;
}
}
public static void main(String[] args) {
algorithm();
}
}
ScreenShots: