i'll look into it
# getting-started
h
i'll look into it
k
Can you just quickly say what extra behavior you want? It's difficult to really give advice like this 😄
h
i'm writing a genetic algorithm, and so i have functions for selection, repopulation, and mutation
to be specific...
Copy code
package agents

import agents.Settings.NUM_SELECTIONS
import java.util.Random
import java.util.concurrent.ThreadLocalRandom

class Population(private val maxSize: Int = 100) : ArrayList<Member>(maxSize) {
    init {
        repeat(maxSize) { this += Member() }
    }

    private
    val randomMember
        get() = this[rand.nextInt(size)]

    val mostFit
        get() = max()!!

    fun selection(times: Int = NUM_SELECTIONS) =
        repeat(times) {
            randomMember.battle(randomMember).also { result ->
                if (result.winnerLives) kill(result.loser) else kill(result.winner)
            }
        }

    private
    fun kill(member: Member) {
        this -= member
    }

    private
    fun Member.findMate() =
        List(numCandidateMates) { randomMember }
            .minBy { it.similarityTo(this) }!!

    fun repopulate(type: MatingType = MatingType.Crossover, d: Double = 0.5) {
        while (size < maxSize) {
            val mother = randomMember
            val father = mother.findMate()

            this += Member { c ->
                when (type) {
                    MatingType.Cloning       -> mother[c]
                    MatingType.Crossover     -> if (rand.nextBoolean()) mother[c] else father[c]
                    MatingType.Interpolation -> d * mother[c] + (1 - d) * father[c]
                    MatingType.Extrapolation -> d * mother[c] + (1 - d) * father[c]
                }
            }
        }
    }

    fun mutation(catastrophic: Boolean = false) =
        forEach {
            if (catastrophic) it.mutate(300, 1.0) else it.mutate()
        }

    enum class MatingType {
        Crossover, Cloning, Interpolation, Extrapolation;
    }

    companion object {
        val rand: Random get() = ThreadLocalRandom.current()
    }
}
k
I definitely wouldn't extend
ArrayList
for this, even delegating feels wrong.
👍🏼 1
h
what do you recommend?
d
Keep the list as a member instead.
👆 1
h
honestly... i just think it reads and writes better to be able to do things like
population -= memberA
instead of
population.members -= memberA
and yeah, i can write out some operator funs to do that for me, but at that point why not just extend
ArrayList
?
d
Maybe extend
AbstractMutableList
.
It's a bit cleaner.
h
i didn't know that was a thing!
k
Yikes -_-. I'd say this is a perfect use case for extension functions.
h
yeah, but don't you think extension functions make for a somewhat messy project structure if you are too reliant on them?
k
True, it's nice if you can maybe make them private in the file you're actually using them in but that's not always possible.
d
Only if they're too generic.
ArrayList<Member>
is quite specific.
k
And make that
MutableList<Member>
if possible
h
i thought kotlin's mutable list is literally just java's arraylist anyways?
k
No, both
MutableList
and
List
compile to
java.lang.List
.
mutableListOf()
in it's current implementation returns an
ArrayList
though, but doesn't guarantee that.