@@ -58,67 +58,9 @@ class CroAlgorithm<T> : AbstractGeneticAlgorithm<T>() where T : Individual {
5858 override fun searchOnce () {
5959
6060 if (randomness.nextDouble() > config.croMolecularCollisionRate || molecules.size == 1 ) {
61- // Uni-molecular collision
62- val moleculeIndex = randomness.nextInt(molecules.size)
63- val selectedMolecule = molecules[moleculeIndex]
64-
65- if (decompositionCheck(selectedMolecule)) {
66- val energyCtx = EnergyContext (container)
67- val decomposedOffspring = decomposition(
68- parent = selectedMolecule,
69- energy = energyCtx,
70- )
71- container = energyCtx.container
72- if (decomposedOffspring != null ) {
73- molecules.removeAt(moleculeIndex)
74- molecules.addAll(decomposedOffspring)
75- }
76- } else {
77- val energyCtx = EnergyContext (container)
78- val collidedMolecule = onWallIneffectiveCollision(
79- molecule = selectedMolecule,
80- energy = energyCtx,
81- )
82- container = energyCtx.container
83- if (collidedMolecule != null ) {
84- molecules[moleculeIndex] = collidedMolecule
85- }
86- }
61+ performUniMolecularCollision()
8762 } else {
88- // Inter-molecular collision
89- val firstIndex = randomness.nextInt(molecules.size)
90- var secondIndex = randomness.nextInt(molecules.size)
91- while (secondIndex == firstIndex) {
92- // find a different molecule as an inter-molecular collision involves at least two molecules
93- secondIndex = randomness.nextInt(molecules.size)
94- }
95-
96- val firstMolecule = molecules[firstIndex]
97- val secondMolecule = molecules[secondIndex]
98-
99- val shouldSynthesize = synthesisCheck(firstMolecule) && synthesisCheck(secondMolecule)
100- if (shouldSynthesize) {
101- val fusedOffspring = synthesis(
102- first = firstMolecule,
103- second = secondMolecule,
104- )
105- if (fusedOffspring != null ) {
106- val lowIndex = minOf(firstIndex, secondIndex)
107- val highIndex = maxOf(firstIndex, secondIndex)
108- molecules[lowIndex] = fusedOffspring
109- molecules.removeAt(highIndex)
110- }
111- } else {
112- val updatedPair = intermolecularIneffectiveCollision(
113- first = firstMolecule,
114- second = secondMolecule,
115- )
116- if (updatedPair != null ) {
117- val (updatedFirst, updatedSecond) = updatedPair
118- molecules[firstIndex] = updatedFirst
119- molecules[secondIndex] = updatedSecond
120- }
121- }
63+ performInterMolecularCollision()
12264 }
12365
12466 // Adjust container if external factors changed fitness values, to conserve energy
@@ -137,6 +79,72 @@ class CroAlgorithm<T> : AbstractGeneticAlgorithm<T>() where T : Individual {
13779 }
13880 }
13981
82+ private fun performUniMolecularCollision () {
83+ // Uni-molecular collision
84+ val moleculeIndex = randomness.nextInt(molecules.size)
85+ val selectedMolecule = molecules[moleculeIndex]
86+
87+ if (decompositionCheck(selectedMolecule)) {
88+ val energyCtx = EnergyContext (container)
89+ val decomposedOffspring = decomposition(
90+ parent = selectedMolecule,
91+ energy = energyCtx,
92+ )
93+ container = energyCtx.container
94+ if (decomposedOffspring != null ) {
95+ molecules.removeAt(moleculeIndex)
96+ molecules.addAll(decomposedOffspring)
97+ }
98+ } else {
99+ val energyCtx = EnergyContext (container)
100+ val collidedMolecule = onWallIneffectiveCollision(
101+ molecule = selectedMolecule,
102+ energy = energyCtx,
103+ )
104+ container = energyCtx.container
105+ if (collidedMolecule != null ) {
106+ molecules[moleculeIndex] = collidedMolecule
107+ }
108+ }
109+ }
110+
111+ private fun performInterMolecularCollision () {
112+ // Inter-molecular collision
113+ val firstIndex = randomness.nextInt(molecules.size)
114+ var secondIndex = randomness.nextInt(molecules.size)
115+ while (secondIndex == firstIndex) {
116+ // find a different molecule as an inter-molecular collision involves at least two molecules
117+ secondIndex = randomness.nextInt(molecules.size)
118+ }
119+
120+ val firstMolecule = molecules[firstIndex]
121+ val secondMolecule = molecules[secondIndex]
122+
123+ val shouldSynthesize = synthesisCheck(firstMolecule) && synthesisCheck(secondMolecule)
124+ if (shouldSynthesize) {
125+ val fusedOffspring = synthesis(
126+ first = firstMolecule,
127+ second = secondMolecule,
128+ )
129+ if (fusedOffspring != null ) {
130+ val lowIndex = minOf(firstIndex, secondIndex)
131+ val highIndex = maxOf(firstIndex, secondIndex)
132+ molecules[lowIndex] = fusedOffspring
133+ molecules.removeAt(highIndex)
134+ }
135+ } else {
136+ val updatedPair = intermolecularIneffectiveCollision(
137+ first = firstMolecule,
138+ second = secondMolecule,
139+ )
140+ if (updatedPair != null ) {
141+ val (updatedFirst, updatedSecond) = updatedPair
142+ molecules[firstIndex] = updatedFirst
143+ molecules[secondIndex] = updatedSecond
144+ }
145+ }
146+ }
147+
140148 protected open fun computePotential (evaluatedSuite : WtsEvalIndividual <T >): Double = - evaluatedSuite.calculateCombinedFitness()
141149
142150 protected open fun applyMutation (wts : WtsEvalIndividual <T >) {
0 commit comments