Skip to content

Commit 623ba38

Browse files
committed
improve algorithm
1 parent 0ee3a23 commit 623ba38

File tree

1 file changed

+40
-38
lines changed

1 file changed

+40
-38
lines changed

core/src/main/kotlin/org/evomaster/core/search/algorithms/LIPSAlgorithm.kt

Lines changed: 40 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -8,26 +8,24 @@ import org.evomaster.core.search.algorithms.wts.WtsEvalIndividual
88
* LIPS (Linearly Independent Path-based Search).
99
* Single-objective GA that optimizes one target (branch) at a time.
1010
*
11-
* Simplified adaptation:
1211
* - Picks a current target from the uncovered set.
13-
* - Freezes scoring on that target only.
1412
* - 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.
13+
* - when current target is covered or its budget is spent, select a new current target.
1614
*/
1715
class LIPSAlgorithm<T> : AbstractGeneticAlgorithm<T>() where T : Individual {
1816

1917
private var currentTarget: Int? = null
20-
private val budgetLeftPerTarget: MutableMap<Int, Int> = mutableMapOf()
18+
private var budgetLeftForCurrentTarget: Int = 0
2119

2220
override fun getType(): EMConfig.Algorithm = EMConfig.Algorithm.LIPS
2321

2422
override fun initPopulation() {
2523
population.clear()
2624

27-
// 1) Generate i
25+
// 1) Generate Random Individual
2826
val i = sampleSuite()
2927

30-
// 2) Compute uncovered
28+
// 2) Get Uncovered Targets
3129
val uncovered = archive.notCoveredTargets()
3230
if (uncovered.isEmpty()) {
3331
return
@@ -38,9 +36,8 @@ class LIPSAlgorithm<T> : AbstractGeneticAlgorithm<T>() where T : Individual {
3836
currentTarget = target
3937
frozenTargets = setOf(target)
4038

41-
// 4) initialize per-target budget
42-
val perTarget = calculatePerTargetBudget(uncovered.size)
43-
budgetLeftPerTarget.putIfAbsent(target, perTarget)
39+
// 4) initialize budget for this target
40+
budgetLeftForCurrentTarget = calculatePerTargetBudget(uncovered.size)
4441

4542
// 5) P <- RandomPopulation(ps-1) ∪ {i}
4643
population.add(i)
@@ -59,9 +56,14 @@ class LIPSAlgorithm<T> : AbstractGeneticAlgorithm<T>() where T : Individual {
5956
return
6057
}
6158

62-
// Pick target if none, or if previously covered
59+
// current target is null if covered by previous generation or out of budget
60+
61+
// Pick target if null, or if previously covered
6362
if (currentTarget == null || !uncovered.contains(currentTarget)) {
64-
currentTarget = uncovered.last()
63+
val target = uncovered.last()
64+
currentTarget = target
65+
// Initialize budget for this NEW target
66+
budgetLeftForCurrentTarget = calculatePerTargetBudget(uncovered.size)
6567
}
6668

6769
// Focus scoring on the single selected target
@@ -73,11 +75,6 @@ class LIPSAlgorithm<T> : AbstractGeneticAlgorithm<T>() where T : Individual {
7375
// record budget usage for this generation
7476
val startActions = time.evaluatedActions
7577
val startSeconds = time.getElapsedSeconds()
76-
77-
val t = currentTarget!!
78-
val targetBudgetLeft = budgetLeftPerTarget.getOrPut(t) {
79-
calculatePerTargetBudget(uncovered.size)
80-
}
8178

8279
while (nextPop.size < n) {
8380
beginStep()
@@ -98,18 +95,13 @@ class LIPSAlgorithm<T> : AbstractGeneticAlgorithm<T>() where T : Individual {
9895
mutate(o2)
9996
}
10097

101-
// Keep best wrt frozen target
102-
val a = if (score(o1) >= score(o2)) o1 else o2
103-
nextPop.add(a)
98+
nextPop.add(o1)
99+
nextPop.add(o2)
104100

105101
// Stop if global budget or target budget is up
106-
val usedForTarget = when (config.stoppingCriterion) {
107-
EMConfig.StoppingCriterion.ACTION_EVALUATIONS -> time.evaluatedActions - startActions
108-
EMConfig.StoppingCriterion.TIME -> time.getElapsedSeconds() - startSeconds
109-
else -> 0
110-
}
102+
val usedForTarget = usedForCurrentTarget(startActions, startSeconds)
111103

112-
if (!time.shouldContinueSearch() || usedForTarget >= targetBudgetLeft) {
104+
if (!time.shouldContinueSearch() || usedForTarget >= budgetLeftForCurrentTarget) {
113105
endStep()
114106
break
115107
}
@@ -120,18 +112,12 @@ class LIPSAlgorithm<T> : AbstractGeneticAlgorithm<T>() where T : Individual {
120112
population.addAll(nextPop)
121113

122114
// Update budget usage for this target
123-
currentTarget?.let { target ->
124-
val usedForTarget = when (config.stoppingCriterion) {
125-
EMConfig.StoppingCriterion.ACTION_EVALUATIONS -> time.evaluatedActions - startActions
126-
EMConfig.StoppingCriterion.TIME -> time.getElapsedSeconds() - startSeconds
127-
else -> 0
128-
}
129-
budgetLeftPerTarget[target] = (budgetLeftPerTarget[target] ?: 0) - usedForTarget
130-
}
115+
val usedForTarget = usedForCurrentTarget(startActions, startSeconds)
116+
budgetLeftForCurrentTarget -= usedForTarget
131117

132118
// Check if target is covered or out of budget
133119
val coveredNow = population.any { score(it) >= 1.0 }
134-
val outOfBudget = currentTarget?.let { (budgetLeftPerTarget[it] ?: 1) <= 0 } ?: false
120+
val outOfBudget = budgetLeftForCurrentTarget <= 0
135121

136122
if (coveredNow || outOfBudget) {
137123
currentTarget = null
@@ -146,13 +132,29 @@ class LIPSAlgorithm<T> : AbstractGeneticAlgorithm<T>() where T : Individual {
146132
*/
147133
private fun calculatePerTargetBudget(uncoveredSize: Int): Int {
148134
return when (config.stoppingCriterion) {
149-
EMConfig.StoppingCriterion.ACTION_EVALUATIONS ->
150-
config.maxEvaluations / uncoveredSize
151-
EMConfig.StoppingCriterion.TIME ->
152-
config.timeLimitInSeconds() / uncoveredSize
135+
EMConfig.StoppingCriterion.ACTION_EVALUATIONS -> {
136+
val remaining = (config.maxEvaluations - time.evaluatedActions).coerceAtLeast(0)
137+
remaining / uncoveredSize
138+
}
139+
EMConfig.StoppingCriterion.TIME -> {
140+
val remaining = (config.timeLimitInSeconds() - time.getElapsedSeconds()).coerceAtLeast(0)
141+
remaining / uncoveredSize
142+
}
153143
else -> Int.MAX_VALUE
154144
}
155145
}
146+
147+
/**
148+
* Compute the budget spent since the start of the current generation,
149+
* based on the active stopping criterion.
150+
*/
151+
private fun usedForCurrentTarget(startActions: Int, startSeconds: Int): Int {
152+
return when (config.stoppingCriterion) {
153+
EMConfig.StoppingCriterion.ACTION_EVALUATIONS -> time.evaluatedActions - startActions
154+
EMConfig.StoppingCriterion.TIME -> time.getElapsedSeconds() - startSeconds
155+
else -> 0
156+
}
157+
}
156158
}
157159

158160

0 commit comments

Comments
 (0)