Skip to content

Commit 2455f5a

Browse files
committed
added simplified algorithm
1 parent fa68e83 commit 2455f5a

File tree

3 files changed

+103
-1
lines changed

3 files changed

+103
-1
lines changed

core/src/main/kotlin/org/evomaster/core/EMConfig.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1162,7 +1162,7 @@ class EMConfig {
11621162

11631163
enum class Algorithm {
11641164
DEFAULT, SMARTS, MIO, RANDOM, WTS, MOSA, RW,
1165-
StandardGA, MonotonicGA, SteadyStateGA // These 3 are still work-in-progress
1165+
StandardGA, MonotonicGA, SteadyStateGA, LIPS
11661166
}
11671167

11681168
@Cfg("The algorithm used to generate test cases. The default depends on whether black-box or white-box testing is done.")

core/src/main/kotlin/org/evomaster/core/Main.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,9 @@ class Main {
645645
EMConfig.Algorithm.StandardGA ->
646646
Key.get(object : TypeLiteral<StandardGeneticAlgorithm<GraphQLIndividual>>() {})
647647

648+
EMConfig.Algorithm.LIPS ->
649+
Key.get(object : TypeLiteral<org.evomaster.core.search.algorithms.LIPSAlgorithm<GraphQLIndividual>>() {})
650+
648651

649652
else -> throw IllegalStateException("Unrecognized algorithm ${config.algorithm}")
650653
}
@@ -670,6 +673,8 @@ class Main {
670673

671674
EMConfig.Algorithm.RW ->
672675
Key.get(object : TypeLiteral<RandomWalkAlgorithm<RPCIndividual>>() {})
676+
EMConfig.Algorithm.LIPS ->
677+
Key.get(object : TypeLiteral<org.evomaster.core.search.algorithms.LIPSAlgorithm<RPCIndividual>>() {})
673678
else -> throw IllegalStateException("Unrecognized algorithm ${config.algorithm}")
674679
}
675680
}
@@ -694,6 +699,8 @@ class Main {
694699

695700
EMConfig.Algorithm.RW ->
696701
Key.get(object : TypeLiteral<RandomWalkAlgorithm<WebIndividual>>() {})
702+
EMConfig.Algorithm.LIPS ->
703+
Key.get(object : TypeLiteral<org.evomaster.core.search.algorithms.LIPSAlgorithm<WebIndividual>>() {})
697704
else -> throw IllegalStateException("Unrecognized algorithm ${config.algorithm}")
698705
}
699706
}
@@ -727,6 +734,8 @@ class Main {
727734

728735
EMConfig.Algorithm.RW ->
729736
Key.get(object : TypeLiteral<RandomWalkAlgorithm<RestIndividual>>() {})
737+
EMConfig.Algorithm.LIPS ->
738+
Key.get(object : TypeLiteral<org.evomaster.core.search.algorithms.LIPSAlgorithm<RestIndividual>>() {})
730739

731740
else -> throw IllegalStateException("Unrecognized algorithm ${config.algorithm}")
732741
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
package org.evomaster.core.search.algorithms
2+
3+
import org.evomaster.core.EMConfig
4+
import org.evomaster.core.search.Individual
5+
import org.evomaster.core.search.algorithms.wts.WtsEvalIndividual
6+
7+
/**
8+
* LIPS (Linearly Independent Path-based Search).
9+
* Single-objective GA that optimizes one target (branch) at a time.
10+
*
11+
* Simplified adaptation:
12+
* - Picks a current target from the uncovered set.
13+
* - Freezes scoring on that target only.
14+
* - Runs one GA generation to evolve the population towards the current target.
15+
* - Adds discovered individuals to archive; when targets are covered, picks a new target.
16+
*/
17+
class LIPSAlgorithm<T> : AbstractGeneticAlgorithm<T>() where T : Individual {
18+
19+
private var currentTarget: Int? = null
20+
21+
override fun getType(): EMConfig.Algorithm = EMConfig.Algorithm.LIPS
22+
23+
override fun searchOnce() {
24+
beginGeneration()
25+
26+
// Compute uncovered goals
27+
val uncovered = archive.notCoveredTargets()
28+
if (uncovered.isEmpty()) {
29+
endGeneration()
30+
return
31+
}
32+
33+
// Pick target if none, or if previously covered
34+
if (currentTarget == null || !uncovered.contains(currentTarget)) {
35+
currentTarget = uncovered.last()
36+
}
37+
38+
// Focus scoring on the single selected target
39+
frozenTargets = setOf(currentTarget!!)
40+
41+
// Ensure population exists
42+
if (population.isEmpty()) {
43+
initPopulation()
44+
}
45+
46+
val n = config.populationSize
47+
val nextPop: MutableList<WtsEvalIndividual<T>> = formTheNextPopulation(population)
48+
49+
while (nextPop.size < n) {
50+
beginStep()
51+
52+
val p1 = tournamentSelection()
53+
val p2 = tournamentSelection()
54+
55+
val o1 = p1.copy()
56+
val o2 = p2.copy()
57+
58+
if (randomness.nextBoolean(config.xoverProbability)) {
59+
xover(o1, o2)
60+
}
61+
if (randomness.nextBoolean(config.fixedRateMutation)) {
62+
mutate(o1)
63+
}
64+
if (randomness.nextBoolean(config.fixedRateMutation)) {
65+
mutate(o2)
66+
}
67+
68+
// Keep best wrt frozen target
69+
val a = if (score(o1) >= score(o2)) o1 else o2
70+
nextPop.add(a)
71+
72+
// Stop if time is up
73+
if (!time.shouldContinueSearch()) {
74+
endStep()
75+
break
76+
}
77+
endStep()
78+
}
79+
80+
population.clear()
81+
population.addAll(nextPop)
82+
83+
// If target got covered (score 1 for any in pop), refresh target next time
84+
val coveredNow = population.any { score(it) >= 1.0 }
85+
if (coveredNow) {
86+
currentTarget = null
87+
}
88+
89+
endGeneration()
90+
}
91+
}
92+
93+

0 commit comments

Comments
 (0)