Skip to content

Commit d01f5bf

Browse files
committed
improve reactor injection && updated docs/options.md
1 parent cde6a94 commit d01f5bf

3 files changed

Lines changed: 26 additions & 52 deletions

File tree

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

Lines changed: 12 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,6 @@ class CroAlgorithm<T> : AbstractGeneticAlgorithm<T>() where T : Individual {
1414

1515
private val molecules: MutableList<Molecule<T>> = mutableListOf()
1616
private lateinit var reactor: CroReactor<T>
17-
private var reactorFactory:
18-
(EMConfig,
19-
org.evomaster.core.search.service.Randomness,
20-
(WtsEvalIndividual<T>) -> Unit,
21-
(WtsEvalIndividual<T>) -> Double,
22-
(WtsEvalIndividual<T>, WtsEvalIndividual<T>) -> Unit) -> CroReactor<T> =
23-
{ emConfig, randomnessService, mutateFn, potentialFn, crossoverFn ->
24-
CroReactor(emConfig, randomnessService, mutateFn, potentialFn, crossoverFn)
25-
}
2617

2718
// container is the global energy reservoir.
2819
// It collects kinetic energy lost in reactions and can be borrowed to enable otherwise infeasible decompositions, keeping total energy conserved.
@@ -43,14 +34,16 @@ class CroAlgorithm<T> : AbstractGeneticAlgorithm<T>() where T : Individual {
4334
// Initialize the underlying GA population to reuse sampling utilities
4435
super.setupBeforeSearch()
4536

46-
// Initialize reactor with dependencies once (allow overriding via factory for tests)
47-
reactor = reactorFactory(
48-
config,
49-
randomness,
50-
this::mutate,
51-
this::potential,
52-
this::xover
53-
)
37+
// Initialize reactor with dependencies once (allow overriding via useReactor in tests)
38+
if (!this::reactor.isInitialized) {
39+
reactor = CroReactor(
40+
config,
41+
randomness,
42+
this::mutate,
43+
this::potential,
44+
this::xover
45+
)
46+
}
5447

5548
// Convert GA population to CRO molecules with initial KE
5649
getViewOfPopulation().forEach { evaluatedSuite ->
@@ -62,18 +55,10 @@ class CroAlgorithm<T> : AbstractGeneticAlgorithm<T>() where T : Individual {
6255
}
6356

6457
/**
65-
* Allows tests to inject a deterministic reactor without reflection.
58+
* Allows tests or callers to override the reactor instance.
6659
* Must be called before [setupBeforeSearch].
6760
*/
68-
fun setReactorFactoryForTesting(factory:
69-
(EMConfig,
70-
org.evomaster.core.search.service.Randomness,
71-
(WtsEvalIndividual<T>) -> Unit,
72-
(WtsEvalIndividual<T>) -> Double,
73-
(WtsEvalIndividual<T>, WtsEvalIndividual<T>) -> Unit) -> CroReactor<T>
74-
) {
75-
this.reactorFactory = factory
76-
}
61+
fun useReactor(reactor: CroReactor<T>) { this.reactor = reactor }
7762

7863
/**
7964
* Read-only snapshot of molecules for assertions in tests.

core/src/test/kotlin/org/evomaster/core/search/algorithms/CroAlgorithmTest.kt

Lines changed: 8 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,7 @@ class CroAlgorithmTest {
8080
val potentialFn: (WtsEvalIndividual<OneMaxIndividual>) -> Double = { _ -> potentials.removeFirst() }
8181
val mutateFn: (WtsEvalIndividual<OneMaxIndividual>) -> Unit = { }
8282
val xoverFn: (WtsEvalIndividual<OneMaxIndividual>, WtsEvalIndividual<OneMaxIndividual>) -> Unit = { _, _ -> }
83-
cro.setReactorFactoryForTesting { cfg, rnd, _, _, _ ->
84-
CroReactor(cfg, rnd, mutateFn, potentialFn, xoverFn)
85-
}
83+
cro.useReactor(CroReactor(config, randomness, mutateFn, potentialFn, xoverFn))
8684

8785
// Initialize algorithm (creates molecules and initialEnergy)
8886
cro.setupBeforeSearch()
@@ -127,9 +125,7 @@ class CroAlgorithmTest {
127125
val potentialFn: (WtsEvalIndividual<OneMaxIndividual>) -> Double = { _ -> potentials.removeFirst() }
128126
val mutateFn: (WtsEvalIndividual<OneMaxIndividual>) -> Unit = { }
129127
val xoverFn: (WtsEvalIndividual<OneMaxIndividual>, WtsEvalIndividual<OneMaxIndividual>) -> Unit = { _, _ -> }
130-
cro.setReactorFactoryForTesting { cfg, rnd, _, _, _ ->
131-
CroReactor(cfg, rnd, mutateFn, potentialFn, xoverFn)
132-
}
128+
cro.useReactor(CroReactor(config, randomness, mutateFn, potentialFn, xoverFn))
133129

134130
cro.setupBeforeSearch()
135131
val before = cro.getMoleculesSnapshot()[0]
@@ -169,9 +165,7 @@ class CroAlgorithmTest {
169165
val potentialFn: (WtsEvalIndividual<OneMaxIndividual>) -> Double = { _ -> potentials.removeFirst() }
170166
val mutateFn: (WtsEvalIndividual<OneMaxIndividual>) -> Unit = { }
171167
val xoverFn: (WtsEvalIndividual<OneMaxIndividual>, WtsEvalIndividual<OneMaxIndividual>) -> Unit = { _, _ -> }
172-
cro.setReactorFactoryForTesting { cfg, rnd, _, _, _ ->
173-
CroReactor(cfg, rnd, mutateFn, potentialFn, xoverFn)
174-
}
168+
cro.useReactor(CroReactor(config, randomness, mutateFn, potentialFn, xoverFn))
175169

176170
cro.setupBeforeSearch()
177171

@@ -215,9 +209,7 @@ class CroAlgorithmTest {
215209
val potentialFn: (WtsEvalIndividual<OneMaxIndividual>) -> Double = { _ -> potentials.removeFirst() }
216210
val mutateFn: (WtsEvalIndividual<OneMaxIndividual>) -> Unit = { }
217211
val xoverFn: (WtsEvalIndividual<OneMaxIndividual>, WtsEvalIndividual<OneMaxIndividual>) -> Unit = { _, _ -> }
218-
cro.setReactorFactoryForTesting { cfg, rnd, _, _, _ ->
219-
CroReactor(cfg, rnd, mutateFn, potentialFn, xoverFn)
220-
}
212+
cro.useReactor(CroReactor(config, randomness, mutateFn, potentialFn, xoverFn))
221213

222214
cro.setupBeforeSearch()
223215
val before = cro.getMoleculesSnapshot()[0]
@@ -258,9 +250,7 @@ class CroAlgorithmTest {
258250
val potentialFn: (WtsEvalIndividual<OneMaxIndividual>) -> Double = { _ -> potentials.removeFirst() }
259251
val mutateFn: (WtsEvalIndividual<OneMaxIndividual>) -> Unit = { }
260252
val xoverFn: (WtsEvalIndividual<OneMaxIndividual>, WtsEvalIndividual<OneMaxIndividual>) -> Unit = { _, _ -> }
261-
cro.setReactorFactoryForTesting { cfg, rnd, _, _, _ ->
262-
CroReactor(cfg, rnd, mutateFn, potentialFn, xoverFn)
263-
}
253+
cro.useReactor(CroReactor(config, randomness, mutateFn, potentialFn, xoverFn))
264254

265255
cro.setupBeforeSearch()
266256
val before = cro.getMoleculesSnapshot()
@@ -299,9 +289,7 @@ class CroAlgorithmTest {
299289
val potentialFn: (WtsEvalIndividual<OneMaxIndividual>) -> Double = { _ -> potentials.removeFirst() }
300290
val mutateFn: (WtsEvalIndividual<OneMaxIndividual>) -> Unit = { }
301291
val xoverFn: (WtsEvalIndividual<OneMaxIndividual>, WtsEvalIndividual<OneMaxIndividual>) -> Unit = { _, _ -> }
302-
cro.setReactorFactoryForTesting { cfg, rnd, _, _, _ ->
303-
CroReactor(cfg, rnd, mutateFn, potentialFn, xoverFn)
304-
}
292+
cro.useReactor(CroReactor(config, randomness, mutateFn, potentialFn, xoverFn))
305293

306294
cro.setupBeforeSearch()
307295
val before = cro.getMoleculesSnapshot()
@@ -345,9 +333,7 @@ class CroAlgorithmTest {
345333
val potentialFn: (WtsEvalIndividual<OneMaxIndividual>) -> Double = { _ -> potentials.removeFirst() }
346334
val mutateFn: (WtsEvalIndividual<OneMaxIndividual>) -> Unit = { }
347335
val xoverFn: (WtsEvalIndividual<OneMaxIndividual>, WtsEvalIndividual<OneMaxIndividual>) -> Unit = { _, _ -> }
348-
cro.setReactorFactoryForTesting { cfg, rnd, _, _, _ ->
349-
CroReactor(cfg, rnd, mutateFn, potentialFn, xoverFn)
350-
}
336+
cro.useReactor(CroReactor(config, randomness, mutateFn, potentialFn, xoverFn))
351337

352338
cro.setupBeforeSearch()
353339
val before = cro.getMoleculesSnapshot()
@@ -391,9 +377,7 @@ class CroAlgorithmTest {
391377
val potentialFn: (WtsEvalIndividual<OneMaxIndividual>) -> Double = { _ -> potentials.removeFirst() }
392378
val mutateFn: (WtsEvalIndividual<OneMaxIndividual>) -> Unit = { }
393379
val xoverFn: (WtsEvalIndividual<OneMaxIndividual>, WtsEvalIndividual<OneMaxIndividual>) -> Unit = { _, _ -> }
394-
cro.setReactorFactoryForTesting { cfg, rnd, _, _, _ ->
395-
CroReactor(cfg, rnd, mutateFn, potentialFn, xoverFn)
396-
}
380+
cro.useReactor(CroReactor(config, randomness, mutateFn, potentialFn, xoverFn))
397381

398382
cro.setupBeforeSearch()
399383
val before = cro.getMoleculesSnapshot()

docs/options.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ There are 3 types of options:
6868
|`addPreDefinedTests`| __Boolean__. Add predefined tests at the end of the search. An example is a test to fetch the schema of RESTful APIs. *Default value*: `true`.|
6969
|`addTestComments`| __Boolean__. Add summary comments on each test. *Default value*: `true`.|
7070
|`advancedBlackBoxCoverage`| __Boolean__. Apply more advanced coverage criteria for black-box testing. This can result in larger generated test suites. *Default value*: `true`.|
71-
|`algorithm`| __Enum__. The algorithm used to generate test cases. The default depends on whether black-box or white-box testing is done. *Valid values*: `DEFAULT, SMARTS, MIO, RANDOM, WTS, MOSA, RW, StandardGA, MonotonicGA, SteadyStateGA, BreederGA, CellularGA, OnePlusLambdaLambdaGA, MuLambdaEA`. *Default value*: `DEFAULT`.|
71+
|`algorithm`| __Enum__. The algorithm used to generate test cases. The default depends on whether black-box or white-box testing is done. *Valid values*: `DEFAULT, SMARTS, MIO, RANDOM, WTS, MOSA, RW, StandardGA, MonotonicGA, SteadyStateGA, BreederGA, CellularGA, OnePlusLambdaLambdaGA, MuLambdaEA, CRO`. *Default value*: `DEFAULT`.|
7272
|`allowInvalidData`| __Boolean__. When generating data, allow in some cases to use invalid values on purpose. *Default value*: `true`.|
7373
|`appendToStatisticsFile`| __Boolean__. Whether should add to an existing statistics file, instead of replacing it. *Default value*: `false`.|
7474
|`archiveAfterMutationFile`| __String__. Specify a path to save archive after each mutation during search, only useful for debugging. *DEBUG option*. *Default value*: `archive.csv`.|
@@ -83,6 +83,11 @@ There are 3 types of options:
8383
|`coveredTargetSortedBy`| __Enum__. Specify a format to organize the covered targets by the search. *Valid values*: `NAME, TEST`. *Default value*: `NAME`.|
8484
|`createConfigPathIfMissing`| __Boolean__. If there is no configuration file, create a default template at given configPath location. However this is done only on the 'default' location. If you change 'configPath', no new file will be created. *Default value*: `true`.|
8585
|`createTests`| __Boolean__. Specify if test classes should be created as output of the tool. Usually, you would put it to 'false' only when debugging EvoMaster itself. *Default value*: `true`.|
86+
|`croDecompositionThreshold`| __Int__. CRO: Decomposition threshold d_t (min number of collisions before decomposition). *Constraints*: `min=0.0`. *Default value*: `500`.|
87+
|`croInitialKineticEnergy`| __Double__. CRO: Initial kinetic energy assigned to each molecule. *Constraints*: `min=0.0`. *Default value*: `1000.0`.|
88+
|`croKineticEnergyLossRate`| __Double__. CRO: Kinetic energy loss rate k_r (lower bound of retained fraction after on-wall). *Constraints*: `probability 0.0-1.0`. *Default value*: `0.2`.|
89+
|`croMolecularCollisionRate`| __Double__. CRO: Molecular collision rate c_r (probability of binary reactions). *Constraints*: `probability 0.0-1.0`. *Default value*: `0.2`.|
90+
|`croSynthesisThreshold`| __Double__. CRO: Synthesis KE threshold s_t (molecule can synthesize if KE ≤ s_t). *Constraints*: `min=0.0`. *Default value*: `10.0`.|
8691
|`customNaming`| __Boolean__. Enable custom naming and sorting criteria. *Default value*: `true`.|
8792
|`d`| __Double__. When weight-based mutation rate is enabled, specify a percentage of calculating mutation rate based on a number of candidate genes to mutate. For instance, d = 1.0 means that the mutation rate fully depends on a number of candidate genes to mutate, and d = 0.0 means that the mutation rate fully depends on weights of candidates genes to mutate. *Constraints*: `probability 0.0-1.0`. *Default value*: `0.8`.|
8893
|`dependencyFile`| __String__. Specify a file that saves derived dependencies. *DEBUG option*. *Default value*: `dependencies.csv`.|

0 commit comments

Comments
 (0)