|
| 1 | +package it.unibo.alchemist.model.terminators |
| 2 | + |
| 3 | +import it.unibo.alchemist.model.Environment |
| 4 | +import it.unibo.alchemist.model.Position |
| 5 | +import it.unibo.alchemist.model.TerminationPredicate |
| 6 | +import it.unibo.alchemist.model.Time |
| 7 | +import it.unibo.alchemist.model.Time.Companion.ZERO |
| 8 | + |
| 9 | +/** |
| 10 | + * [stableForTime] for how much time the [metricsToCheck] should be stable. |
| 11 | + * [timeIntervalToCheck] every time-step it should check, if zero it checks at every invocation. |
| 12 | + * [equalTimes] how many times it should be stable. |
| 13 | + */ |
| 14 | +class MetricsStableForTime<T> |
| 15 | +@JvmOverloads |
| 16 | +constructor( |
| 17 | + private val stableForTime: Time, |
| 18 | + private val timeIntervalToCheck: Time = ZERO, |
| 19 | + private val equalTimes: Long, |
| 20 | + private val metricsToCheck: (Environment<T, Position<*>>) -> Map<String, T>, |
| 21 | +): TerminationPredicate<T, Position<*>> { |
| 22 | + private var timeStabilitySuccess: Time = ZERO |
| 23 | + private var lastChecked: Time = ZERO |
| 24 | + private var equalSuccess: Long = 0 |
| 25 | + private var lastUpdatedMetrics: Map<String, T> = emptyMap() |
| 26 | + |
| 27 | + init { |
| 28 | + require(stableForTime > ZERO) { |
| 29 | + "The amount of time to check the stability should be more than zero." |
| 30 | + } |
| 31 | + } |
| 32 | + |
| 33 | + override fun invoke(environment: Environment<T, Position<*>>): Boolean { |
| 34 | + val simulationTime = environment.simulation.time |
| 35 | + val checkedInterval = simulationTime - lastChecked |
| 36 | + return when { |
| 37 | + checkedInterval >= timeIntervalToCheck -> { |
| 38 | + val metrics: Map<String, T> = metricsToCheck(environment) |
| 39 | + require(metrics.isNotEmpty()) { |
| 40 | + "There should be at least one metric to check." |
| 41 | + } |
| 42 | + lastChecked = simulationTime |
| 43 | + when { |
| 44 | + lastUpdatedMetrics == metrics -> { |
| 45 | + timeStabilitySuccess += checkedInterval |
| 46 | + if(timeStabilitySuccess >= stableForTime) { |
| 47 | + timeStabilitySuccess = ZERO |
| 48 | + ++equalSuccess >= equalTimes |
| 49 | + } else false |
| 50 | + } |
| 51 | + else -> { |
| 52 | + timeStabilitySuccess = ZERO |
| 53 | + equalSuccess = 0 |
| 54 | + lastUpdatedMetrics = metrics |
| 55 | + false |
| 56 | + } |
| 57 | + } |
| 58 | + } |
| 59 | + else -> false |
| 60 | + } |
| 61 | + } |
| 62 | +} |
0 commit comments