trai
* @param currentSolution The solution to be altered by the mutation operator
* @return The altered solution after mutation
*/
- private int[] mutation(int[] currentSolution) {
+ private int[] mutation(int... currentSolution) {
return Arrays.stream(currentSolution).map(x -> ThreadLocalRandom.current().nextDouble() < mutationRate ? 1 - x : x).toArray();
}
@@ -279,7 +283,7 @@ private int[] mutation(int[] currentSolution) {
* @param currentSolution The solution to be altered by the mutation operator
* @return The altered solution after inversion mutation
*/
- private int[] inversionMutation(int[] currentSolution) {
+ private int[] inversionMutation(int... currentSolution) {
int rand1 = new Random().nextInt(currentSolution.length);
int rand2 = new Random().nextInt(currentSolution.length);
while (rand1 >= rand2) {
@@ -292,6 +296,26 @@ private int[] inversionMutation(int[] currentSolution) {
return currentSolution;
}
+ /**
+ * Sswapped mutation
+ *
+ * see:
+ *
+ * Ming-Wen Tsai et al.
+ * "A Two-Dimensional Genetic Algorithm and Its Application to Aircraft Scheduling Problem", 2015.
+ *
+ * @param currentSolution The solution to be altered by the mutation operator
+ * @return The altered solution after swapped mutation
+ */
+ private int[] swappedMutation(int... currentSolution) {
+ int firstGeneIndex = new Random().nextInt(currentSolution.length);
+ int secondGeneIndex = new Random().nextInt(currentSolution.length);
+ int secondGene = currentSolution[secondGeneIndex];
+ currentSolution[secondGeneIndex] = currentSolution[firstGeneIndex];
+ currentSolution[firstGeneIndex] = secondGene;
+ return currentSolution;
+ }
+
/**
* The main equation of Jaya optimization algorithm
*
@@ -307,8 +331,7 @@ private int[] inversionMutation(int[] currentSolution) {
*/
private int[] jayaOperator(int[] currentSolution, int[] currentBest, int[] currentWorst) {
int[] newSolution = new int[currentSolution.length];
- Arrays.setAll(newSolution, i -> (int) transferFunction.applyAsDouble(currentSolution[i] + new Random().nextDouble() * (currentBest[i] - currentSolution[i]) -
- new Random().nextDouble() * (currentWorst[i] - currentSolution[i])));
+ Arrays.setAll(newSolution, i -> (int) transferFunction.applyAsDouble(currentSolution[i] + new Random().nextDouble() * (currentBest[i] - currentSolution[i]) - new Random().nextDouble() * (currentWorst[i] - currentSolution[i])));
return newSolution;
}
From 7670a28f974649ed1dafaea1edccda1bcd4b89f7 Mon Sep 17 00:00:00 2001
From: Mohammed Al-Eiadeh
<93108547+Mohammed-Ryiad-Eiadeh@users.noreply.github.com>
Date: Sun, 16 Jul 2023 10:20:50 +0300
Subject: [PATCH 34/39] Update CuckooSearchOptimizer.java
---
.../Optimizers/CuckooSearchOptimizer.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Classification/FeatureSelection/src/main/java/org/tribuo/classification/fs/FS_Wrapper_Approaches/Optimizers/CuckooSearchOptimizer.java b/Classification/FeatureSelection/src/main/java/org/tribuo/classification/fs/FS_Wrapper_Approaches/Optimizers/CuckooSearchOptimizer.java
index aaf668d6d..737807fa4 100644
--- a/Classification/FeatureSelection/src/main/java/org/tribuo/classification/fs/FS_Wrapper_Approaches/Optimizers/CuckooSearchOptimizer.java
+++ b/Classification/FeatureSelection/src/main/java/org/tribuo/classification/fs/FS_Wrapper_Approaches/Optimizers/CuckooSearchOptimizer.java
@@ -190,9 +190,9 @@ public SelectedFeatureSet select(Dataset dataset) {
keepBestAfterEvaluation(dataset, trainer, FMap, jayaSolution, setOfSolutions[subSet.get()]);
}
Arrays.stream(setOfSolutions).map(subSet -> new CuckooSearchFeatureSet(subSet, evaluateSolution(this, trainer, dataset, FMap, subSet))).forEach(subSet_fScores::add);
- subSet_fScores.sort(Comparator.comparing(CuckooSearchFeatureSet::score).reversed());
- selectedFeatureSet = getSFS(this, dataset, FMap, subSet_fScores.get(0).subSet);
}
+ subSet_fScores.sort(Comparator.comparing(CuckooSearchFeatureSet::score).reversed());
+ selectedFeatureSet = getSFS(this, dataset, FMap, subSet_fScores.get(0).subSet);
return selectedFeatureSet;
}
From 0993bc0b92e71aedaa593d8aeff191e5cf3e0bda Mon Sep 17 00:00:00 2001
From: Mohammed Al-Eiadeh
<93108547+Mohammed-Ryiad-Eiadeh@users.noreply.github.com>
Date: Sun, 23 Jul 2023 23:22:51 +0300
Subject: [PATCH 35/39] Update CuckooSearchOptimizer.java
---
.../Optimizers/CuckooSearchOptimizer.java | 24 +++++++++++--------
1 file changed, 14 insertions(+), 10 deletions(-)
diff --git a/Classification/FeatureSelection/src/main/java/org/tribuo/classification/fs/FS_Wrapper_Approaches/Optimizers/CuckooSearchOptimizer.java b/Classification/FeatureSelection/src/main/java/org/tribuo/classification/fs/FS_Wrapper_Approaches/Optimizers/CuckooSearchOptimizer.java
index 737807fa4..bcd495549 100644
--- a/Classification/FeatureSelection/src/main/java/org/tribuo/classification/fs/FS_Wrapper_Approaches/Optimizers/CuckooSearchOptimizer.java
+++ b/Classification/FeatureSelection/src/main/java/org/tribuo/classification/fs/FS_Wrapper_Approaches/Optimizers/CuckooSearchOptimizer.java
@@ -284,16 +284,18 @@ private int[] mutation(int... currentSolution) {
* @return The altered solution after inversion mutation
*/
private int[] inversionMutation(int... currentSolution) {
- int rand1 = new Random().nextInt(currentSolution.length);
- int rand2 = new Random().nextInt(currentSolution.length);
+ int[] solution = new int[currentSolution.length];
+ System.arraycopy(currentSolution, 0, solution, 0, solution.length);
+ int rand1 = new Random().nextInt(solution.length);
+ int rand2 = new Random().nextInt(solution.length);
while (rand1 >= rand2) {
- rand1 = new Random().nextInt(currentSolution.length);
- rand2 = new Random().nextInt(currentSolution.length);
+ rand1 = new Random().nextInt(solution.length);
+ rand2 = new Random().nextInt(solution.length);
}
for (; rand1 < rand2; rand1++) {
- currentSolution[rand1] = 1 - currentSolution[rand1];
+ solution[rand1] = 1 - solution[rand1];
}
- return currentSolution;
+ return solution;
}
/**
@@ -308,12 +310,14 @@ private int[] inversionMutation(int... currentSolution) {
* @return The altered solution after swapped mutation
*/
private int[] swappedMutation(int... currentSolution) {
+ int[] solution = new int[currentSolution.length];
+ System.arraycopy(currentSolution, 0, solution, 0, solution.length);
int firstGeneIndex = new Random().nextInt(currentSolution.length);
int secondGeneIndex = new Random().nextInt(currentSolution.length);
- int secondGene = currentSolution[secondGeneIndex];
- currentSolution[secondGeneIndex] = currentSolution[firstGeneIndex];
- currentSolution[firstGeneIndex] = secondGene;
- return currentSolution;
+ int secondGene = solution[secondGeneIndex];
+ solution[secondGeneIndex] = solution[firstGeneIndex];
+ solution[firstGeneIndex] = secondGene;
+ return solution;
}
/**
From 9038ef4550e010873f5c920d87807a466250e289 Mon Sep 17 00:00:00 2001
From: Mohammed Al-Eiadeh
<93108547+Mohammed-Ryiad-Eiadeh@users.noreply.github.com>
Date: Wed, 9 Aug 2023 01:11:25 +0300
Subject: [PATCH 36/39] Update CuckooSearchOptimizer.java
---
.../Optimizers/CuckooSearchOptimizer.java | 45 ++++++++++---------
1 file changed, 25 insertions(+), 20 deletions(-)
diff --git a/Classification/FeatureSelection/src/main/java/org/tribuo/classification/fs/FS_Wrapper_Approaches/Optimizers/CuckooSearchOptimizer.java b/Classification/FeatureSelection/src/main/java/org/tribuo/classification/fs/FS_Wrapper_Approaches/Optimizers/CuckooSearchOptimizer.java
index bcd495549..f3bc9d227 100644
--- a/Classification/FeatureSelection/src/main/java/org/tribuo/classification/fs/FS_Wrapper_Approaches/Optimizers/CuckooSearchOptimizer.java
+++ b/Classification/FeatureSelection/src/main/java/org/tribuo/classification/fs/FS_Wrapper_Approaches/Optimizers/CuckooSearchOptimizer.java
@@ -157,42 +157,45 @@ public boolean isOrdered() {
@Override
public SelectedFeatureSet select(Dataset dataset) {
ImmutableFeatureMap FMap = new ImmutableFeatureMap(dataset.getFeatureMap());
- setOfSolutions = GeneratePopulation(dataset.getFeatureMap().size());
- List subSet_fScores = Arrays.stream(setOfSolutions).map(setOfSolution -> new CuckooSearchFeatureSet(setOfSolution, evaluateSolution(this, trainer,dataset, FMap, setOfSolution))).sorted(Comparator.comparing(CuckooSearchFeatureSet::score).reversed()).collect(Collectors.toList());
- SelectedFeatureSet selectedFeatureSet = null;
- for (int i = 0; i < maxIteration; i++) {
- for (int solution = 0; solution < populationSize; solution++) {
+ setOfSolutions = generatePopulation(FMap.size());
+ List subSet_fScores = new ArrayList<>();
+ SelectedFeatureSet selectedFeatureSet;
+ for (int iter = 0; iter < maxIteration; iter++) {
+ for (int solution = 0; solution < setOfSolutions.length; solution++) {
AtomicInteger subSet = new AtomicInteger(solution);
+ int[] evolvedSolution = new int[setOfSolutions[0].length];
// Update the solution based on the levy flight function
- int[] evolvedSolution = Arrays.stream(setOfSolutions[subSet.get()]).map(x -> (int) transferFunction.applyAsDouble(x + stepSizeScaling * Math.pow(subSet.get() + 1, -lambda))).toArray();
+ for (int i = 0; i < setOfSolutions[0].length; i++) {
+ evolvedSolution[i] = (int) transferFunction.applyAsDouble(setOfSolutions[subSet.get()][i] + stepSizeScaling * Math.pow(subSet.get() + 1, -lambda));
+ }
int[] randomCuckoo = setOfSolutions[rng.nextInt(setOfSolutions.length)];
- keepBestAfterEvaluation(dataset, trainer, FMap, evolvedSolution, randomCuckoo);
+ setOfSolutions[subSet.get()] = keepBestAfterEvaluation(dataset, FMap, evolvedSolution, randomCuckoo);
// Update the solution based on the abandone nest function
- if (rng.nextDouble() < worstNestProbability) {
+ if (new Random().nextDouble() < worstNestProbability) {
int r1 = rng.nextInt(setOfSolutions.length);
int r2 = rng.nextInt(setOfSolutions.length);
- for (int j = 0; j < setOfSolutions[subSet.get()].length; j++) {
+ for (int j = 0; j < setOfSolutions[0].length; j++) {
evolvedSolution[j] = (int) transferFunction.applyAsDouble(setOfSolutions[subSet.get()][j] + delta * (setOfSolutions[r1][j] - setOfSolutions[r2][j]));
}
- keepBestAfterEvaluation(dataset, trainer, FMap, evolvedSolution, setOfSolutions[subSet.get()]);
+ setOfSolutions[subSet.get()] = keepBestAfterEvaluation(dataset, FMap, evolvedSolution, setOfSolutions[subSet.get()]);
}
// Update the solution based on mutation operator
int[] mutedSolution = mutation(setOfSolutions[subSet.get()]);
- keepBestAfterEvaluation(dataset, trainer, FMap, mutedSolution, setOfSolutions[subSet.get()]);
+ setOfSolutions[subSet.get()] = keepBestAfterEvaluation(dataset, trainer, FMap, mutedSolution, setOfSolutions[subSet.get()]);
// Update the solution based on inversion mutation
mutedSolution = inversionMutation(setOfSolutions[subSet.get()]);
- keepBestAfterEvaluation(dataset, trainer, FMap, mutedSolution, setOfSolutions[subSet.get()]);
+ setOfSolutions[subSet.get()] = keepBestAfterEvaluation(dataset, trainer, FMap, mutedSolution, setOfSolutions[subSet.get()]);
// Update the solution based on swapped mutation
mutedSolution = swappedMutation(setOfSolutions[subSet.get()]);
- keepBestAfterEvaluation(dataset, trainer, FMap, mutedSolution, setOfSolutions[subSet.get()]);
+ setOfSolutions[subSet.get()] = keepBestAfterEvaluation(dataset, trainer, FMap, mutedSolution, setOfSolutions[subSet.get()]);
// Updata the solution based on Jaya operator
int[] jayaSolution = jayaOperator(setOfSolutions[subSet.get()], subSet_fScores.get(0).subSet(), subSet_fScores.get(subSet_fScores.size() - 1).subSet());
- keepBestAfterEvaluation(dataset, trainer, FMap, jayaSolution, setOfSolutions[subSet.get()]);
+ setOfSolutions[subSet.get()] = keepBestAfterEvaluation(dataset, trainer, FMap, jayaSolution, setOfSolutions[subSet.get()]);
}
- Arrays.stream(setOfSolutions).map(subSet -> new CuckooSearchFeatureSet(subSet, evaluateSolution(this, trainer, dataset, FMap, subSet))).forEach(subSet_fScores::add);
+ Arrays.stream(setOfSolutions).map(subSet -> new CuckooSearchFeatureSet(subSet, FN.EvaluateSolution(this, dataset, FMap, subSet))).forEach(subSet_fScores::add);
}
- subSet_fScores.sort(Comparator.comparing(CuckooSearchFeatureSet::score).reversed());
- selectedFeatureSet = getSFS(this, dataset, FMap, subSet_fScores.get(0).subSet);
+ subSet_fScores.sort(Comparator.comparing(CuckooSearchFeatureSet::score).reversed());
+ selectedFeatureSet = FN.getSFS(this, dataset, FMap, subSet_fScores.get(0).subSet);
return selectedFeatureSet;
}
@@ -251,10 +254,12 @@ private > SelectedFeatureSet getSFS(T optimize
* @param alteredSolution The modified solution
* @param oldSolution The old solution
*/
- private void keepBestAfterEvaluation(Dataset dataset, Trainer trainer, ImmutableFeatureMap FMap, int[] alteredSolution, int[] oldSolution) {
- if (evaluateSolution(this, trainer, dataset, FMap, alteredSolution) > evaluateSolution(this, trainer, dataset, FMap, oldSolution)) {
- System.arraycopy(alteredSolution, 0, oldSolution, 0, alteredSolution.length);
+ public int[] keepBestAfterEvaluation(Dataset dataset, ImmutableFeatureMap FMap, int[] alteredSolution, int... oldSolution) {
+ if (FN.EvaluateSolution(this, dataset, FMap, alteredSolution) > FN.EvaluateSolution(this, dataset, FMap, oldSolution)) {
+ return alteredSolution;
}
+ else
+ return oldSolution;
}
/**
From 76dc7154b40ac40e9e46331e83724bb8d032b781 Mon Sep 17 00:00:00 2001
From: Mohammed Al-Eiadeh
<93108547+Mohammed-Ryiad-Eiadeh@users.noreply.github.com>
Date: Thu, 10 Aug 2023 01:40:22 +0300
Subject: [PATCH 37/39] Update CuckooSearchOptimizer.java
---
.../Optimizers/CuckooSearchOptimizer.java | 23 +++++++++----------
1 file changed, 11 insertions(+), 12 deletions(-)
diff --git a/Classification/FeatureSelection/src/main/java/org/tribuo/classification/fs/FS_Wrapper_Approaches/Optimizers/CuckooSearchOptimizer.java b/Classification/FeatureSelection/src/main/java/org/tribuo/classification/fs/FS_Wrapper_Approaches/Optimizers/CuckooSearchOptimizer.java
index f3bc9d227..226edb042 100644
--- a/Classification/FeatureSelection/src/main/java/org/tribuo/classification/fs/FS_Wrapper_Approaches/Optimizers/CuckooSearchOptimizer.java
+++ b/Classification/FeatureSelection/src/main/java/org/tribuo/classification/fs/FS_Wrapper_Approaches/Optimizers/CuckooSearchOptimizer.java
@@ -162,35 +162,34 @@ public SelectedFeatureSet select(Dataset dataset) {
SelectedFeatureSet selectedFeatureSet;
for (int iter = 0; iter < maxIteration; iter++) {
for (int solution = 0; solution < setOfSolutions.length; solution++) {
- AtomicInteger subSet = new AtomicInteger(solution);
int[] evolvedSolution = new int[setOfSolutions[0].length];
- // Update the solution based on the levy flight function
+ // Update the solution based on the levy flight function 0.5 + 0.8 * (new Random().nextGaussian() / Math.pow(Math.abs(new Random().nextGaussian()), 1.0 / 3.0))
for (int i = 0; i < setOfSolutions[0].length; i++) {
- evolvedSolution[i] = (int) transferFunction.applyAsDouble(setOfSolutions[subSet.get()][i] + stepSizeScaling * Math.pow(subSet.get() + 1, -lambda));
+ evolvedSolution[i] = (int) transferFunction.applyAsDouble(setOfSolutions[solution][i] + stepSizeScaling * Math.pow(solution + 1, -lambda));
}
- int[] randomCuckoo = setOfSolutions[rng.nextInt(setOfSolutions.length)];
- setOfSolutions[subSet.get()] = keepBestAfterEvaluation(dataset, FMap, evolvedSolution, randomCuckoo);
+ int randomCuckooIndex = rng.nextInt(setOfSolutions.length);
+ System.arraycopy(retrieveBestAfterEvaluation(dataset, FMap, evolvedSolution, setOfSolutions[randomCuckooIndex]), 0, setOfSolutions[randomCuckooIndex], 0, setOfSolutions[randomCuckooIndex].length);
// Update the solution based on the abandone nest function
if (new Random().nextDouble() < worstNestProbability) {
int r1 = rng.nextInt(setOfSolutions.length);
int r2 = rng.nextInt(setOfSolutions.length);
for (int j = 0; j < setOfSolutions[0].length; j++) {
- evolvedSolution[j] = (int) transferFunction.applyAsDouble(setOfSolutions[subSet.get()][j] + delta * (setOfSolutions[r1][j] - setOfSolutions[r2][j]));
+ evolvedSolution[j] = (int) transferFunction.applyAsDouble(setOfSolutions[solution][j] + delta * (setOfSolutions[r1][j] - setOfSolutions[r2][j]));
}
- setOfSolutions[subSet.get()] = keepBestAfterEvaluation(dataset, FMap, evolvedSolution, setOfSolutions[subSet.get()]);
+ System.arraycopy(retrieveBestAfterEvaluation(dataset, FMap, evolvedSolution, setOfSolutions[solution]), 0, setOfSolutions[solution], 0, setOfSolutions[solution].length);
}
// Update the solution based on mutation operator
int[] mutedSolution = mutation(setOfSolutions[subSet.get()]);
- setOfSolutions[subSet.get()] = keepBestAfterEvaluation(dataset, trainer, FMap, mutedSolution, setOfSolutions[subSet.get()]);
+ System.arraycopy(retrieveBestAfterEvaluation(dataset, FMap, mutedSolution, setOfSolutions[solution]), 0, setOfSolutions[solution], 0, setOfSolutions[solution].length);
// Update the solution based on inversion mutation
mutedSolution = inversionMutation(setOfSolutions[subSet.get()]);
- setOfSolutions[subSet.get()] = keepBestAfterEvaluation(dataset, trainer, FMap, mutedSolution, setOfSolutions[subSet.get()]);
+ System.arraycopy(retrieveBestAfterEvaluation(dataset, FMap, mutedSolution, setOfSolutions[solution]), 0, setOfSolutions[solution], 0, setOfSolutions[solution].length);
// Update the solution based on swapped mutation
mutedSolution = swappedMutation(setOfSolutions[subSet.get()]);
- setOfSolutions[subSet.get()] = keepBestAfterEvaluation(dataset, trainer, FMap, mutedSolution, setOfSolutions[subSet.get()]);
+ System.arraycopy(retrieveBestAfterEvaluation(dataset, FMap, mutedSolution, setOfSolutions[solution]), 0, setOfSolutions[solution], 0, setOfSolutions[solution].length);
// Updata the solution based on Jaya operator
int[] jayaSolution = jayaOperator(setOfSolutions[subSet.get()], subSet_fScores.get(0).subSet(), subSet_fScores.get(subSet_fScores.size() - 1).subSet());
- setOfSolutions[subSet.get()] = keepBestAfterEvaluation(dataset, trainer, FMap, jayaSolution, setOfSolutions[subSet.get()]);
+ System.arraycopy(retrieveBestAfterEvaluation(dataset, FMap, jayaSolution, setOfSolutions[solution]), 0, setOfSolutions[solution], 0, setOfSolutions[solution].length);
}
Arrays.stream(setOfSolutions).map(subSet -> new CuckooSearchFeatureSet(subSet, FN.EvaluateSolution(this, dataset, FMap, subSet))).forEach(subSet_fScores::add);
}
@@ -254,7 +253,7 @@ private > SelectedFeatureSet getSFS(T optimize
* @param alteredSolution The modified solution
* @param oldSolution The old solution
*/
- public int[] keepBestAfterEvaluation(Dataset dataset, ImmutableFeatureMap FMap, int[] alteredSolution, int... oldSolution) {
+ public int[] retrieveBestAfterEvaluation(Dataset dataset, ImmutableFeatureMap FMap, int[] alteredSolution, int... oldSolution) {
if (FN.EvaluateSolution(this, dataset, FMap, alteredSolution) > FN.EvaluateSolution(this, dataset, FMap, oldSolution)) {
return alteredSolution;
}
From 28509c025a66b52c70ccd6c0e33ffd21c529f464 Mon Sep 17 00:00:00 2001
From: Mohammed Al-Eiadeh
<93108547+Mohammed-Ryiad-Eiadeh@users.noreply.github.com>
Date: Thu, 10 Aug 2023 01:40:51 +0300
Subject: [PATCH 38/39] Update CuckooSearchOptimizer.java
From 2910d99bfd03e5fee853cf0813ca7cf42b3bb16b Mon Sep 17 00:00:00 2001
From: Mohammed Al-Eiadeh
<93108547+Mohammed-Ryiad-Eiadeh@users.noreply.github.com>
Date: Fri, 11 Aug 2023 00:13:43 +0300
Subject: [PATCH 39/39] Update CuckooSearchOptimizer.java
---
.../FS_Wrapper_Approaches/Optimizers/CuckooSearchOptimizer.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Classification/FeatureSelection/src/main/java/org/tribuo/classification/fs/FS_Wrapper_Approaches/Optimizers/CuckooSearchOptimizer.java b/Classification/FeatureSelection/src/main/java/org/tribuo/classification/fs/FS_Wrapper_Approaches/Optimizers/CuckooSearchOptimizer.java
index 226edb042..2c6a80492 100644
--- a/Classification/FeatureSelection/src/main/java/org/tribuo/classification/fs/FS_Wrapper_Approaches/Optimizers/CuckooSearchOptimizer.java
+++ b/Classification/FeatureSelection/src/main/java/org/tribuo/classification/fs/FS_Wrapper_Approaches/Optimizers/CuckooSearchOptimizer.java
@@ -163,7 +163,7 @@ public SelectedFeatureSet select(Dataset dataset) {
for (int iter = 0; iter < maxIteration; iter++) {
for (int solution = 0; solution < setOfSolutions.length; solution++) {
int[] evolvedSolution = new int[setOfSolutions[0].length];
- // Update the solution based on the levy flight function 0.5 + 0.8 * (new Random().nextGaussian() / Math.pow(Math.abs(new Random().nextGaussian()), 1.0 / 3.0))
+ // Update the solution based on the levy flight function
for (int i = 0; i < setOfSolutions[0].length; i++) {
evolvedSolution[i] = (int) transferFunction.applyAsDouble(setOfSolutions[solution][i] + stepSizeScaling * Math.pow(solution + 1, -lambda));
}