Skip to content

Commit 56136ea

Browse files
committed
EpsilonGreedy
1 parent c82a3c4 commit 56136ea

File tree

4 files changed

+101
-1
lines changed

4 files changed

+101
-1
lines changed
+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Wei Chen - Epsilon Greedy Search
2+
// 2020-03-08
3+
4+
package com.scalaml.algorithm
5+
6+
class EpsilonGreedy {
7+
var currentScores: Array[Double] = null
8+
9+
def search(
10+
evaluation: Array[Double] => Double,
11+
choices: Array[Array[Double]],
12+
scores: Array[Double] = null,
13+
epsilon: Double = 0.1
14+
): Array[Double] = {
15+
val size = choices.size
16+
if (scores != null)
17+
currentScores = scores
18+
if (currentScores == null)
19+
currentScores = new Array[Double](size)
20+
if (math.random < epsilon) {
21+
val randSelect = (math.random * size).toInt
22+
val value = evaluation(choices(randSelect))
23+
currentScores(randSelect) = value
24+
}
25+
choices(currentScores.indexOf(currentScores.max))
26+
}
27+
}

Diff for: src/main/scala/algorithm/optimization/GeneAlgorithm.scala

+13-1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,18 @@ class GeneAlgorithm {
2424
breeding(parents(ai), parents(bi))
2525
}
2626
seeds = parents ++ kids
27-
return parents.last // return the best
27+
parents.last // return the best
28+
}
29+
30+
def search(
31+
evaluation: Array[Double] => Double,
32+
breeding: (Array[Double], Array[Double]) => Array[Array[Double]],
33+
generationsize: Int = 100,
34+
elitesize: Int = 3,
35+
generationcount: Int = 10
36+
): Array[Double] = {
37+
for (i <- 1 until generationcount)
38+
evolve(evaluation, breeding, generationsize, elitesize)
39+
evolve(evaluation, breeding, generationsize, elitesize)
2840
}
2941
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Wei Chen - Epsilon Greedy Search Test
2+
// 2020-03-08
3+
4+
import com.scalaml.general.MatrixFunc._
5+
import com.scalaml.algorithm.EpsilonGreedy
6+
import org.scalatest.funsuite.AnyFunSuite
7+
8+
class EpsilonGreedySuite extends AnyFunSuite {
9+
10+
val eg = new EpsilonGreedy()
11+
12+
13+
def evaluation(arr: Array[Double]): Double = 1 / ((arr.head - 0.7).abs + 1)
14+
15+
val choices: Array[Array[Double]] = Array(
16+
Array(0.7),
17+
Array(0.8),
18+
Array(1.0),
19+
Array(0.5)
20+
)
21+
val epsilon: Double = 0.1
22+
23+
test("GeneAlgorithm Test : Initial") {
24+
assert(eg.currentScores == null)
25+
}
26+
27+
test("GeneAlgorithm Test : Search - Start") {
28+
for (i <- 0 until 1000)
29+
eg.search(evaluation, choices, null, epsilon)
30+
assert(eg.currentScores.size == choices.size)
31+
32+
val best = eg.search(evaluation, choices, null, epsilon)
33+
assert((best.head - 0.7).abs < 0.05)
34+
}
35+
36+
test("GeneAlgorithm Test : Search - Continue") {
37+
var scores: Array[Double] = Array(0, 0, 1 / 1.3, 0)
38+
for (i <- 0 until 1000) {
39+
eg.search(evaluation, choices, scores, epsilon)
40+
scores = eg.currentScores
41+
}
42+
assert(eg.currentScores.size == scores.size)
43+
44+
val best = eg.search(evaluation, choices, scores, epsilon)
45+
assert((best.head - 0.7).abs < 0.05)
46+
}
47+
48+
}

Diff for: src/test/scala/algorithm/optimization/GeneAlgorithmTest.scala

+13
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ class GeneAlgorithmSuite extends AnyFunSuite {
2222

2323
val generationsize: Int = 100
2424
val elitesize: Int = 3
25+
val generationcount: Int = 10
2526

2627
test("GeneAlgorithm Test : Initial") {
2728
assert(ga.seeds == null)
@@ -38,4 +39,16 @@ class GeneAlgorithmSuite extends AnyFunSuite {
3839
assert((best.head - 0.7).abs < 0.05)
3940
}
4041

42+
test("GeneAlgorithm Test : Search") {
43+
val best = ga.search(
44+
evaluation,
45+
breeding,
46+
generationsize,
47+
elitesize,
48+
generationcount
49+
)
50+
assert(ga.seeds.size == generationsize)
51+
assert((best.head - 0.7).abs < 0.05)
52+
}
53+
4154
}

0 commit comments

Comments
 (0)