Permalink
Browse files

added option to collect snapshots of statics at different time intervals

  • Loading branch information...
arcuri82 committed Sep 24, 2017
1 parent a945cd1 commit e5f53a2666c7d2d0130c11f9cce9110b064f81e6
View
@@ -35,3 +35,4 @@ e2e-tests/spring-examples/target/
experiments/target/
/e2e-tests/spring-examples/src/em/EvoMasterTest.java
/e2e-tests/dropwizard-examples/src/em/
/snapshot.csv
@@ -313,7 +313,7 @@ class EMConfig {
" But then of course the test generation will take longer." +
" Only applicable depending on the stopping criterion.")
@Min(1.0)
var maxActionEvaluations = 1000;
var maxActionEvaluations = 1000
@Cfg("Whether or not writing statistics of the search process. " +
"This is only needed when running experiments with different parameter settings")
@@ -325,6 +325,14 @@ class EMConfig {
@Cfg("Whether should add to an existing statistics file, instead of replacing it")
var appendToStatisticsFile = false
@Cfg("If positive, check how often, in percentage % of the budget, to collect statistics snapshots." +
" For example, every 5% of the time.")
@Max(50.0)
var snapshotInterval = -1.0
@Cfg("Where the snapshot file (if any) is going to be written (in CSV format)")
var snapshotStatisticsFile = "snapshot.csv"
@Cfg("An id that will be part as a column of the statistics file (if any is generated)")
var statisticsColumnId = "-"
@@ -241,6 +241,10 @@ class Main {
val statistics = injector.getInstance(Statistics::class.java)
statistics.writeStatistics(solution)
if(config.snapshotInterval > 0){
statistics.writeSnapshot()
}
}
}
}
@@ -25,6 +25,9 @@ class RestModule : AbstractModule(){
bind(object : TypeLiteral<Archive<RestIndividual>>() {})
.asEagerSingleton()
bind(object : TypeLiteral<Archive<*>>() {})
.to(object : TypeLiteral<Archive<RestIndividual>>() {})
bind(RemoteController::class.java)
.asEagerSingleton()
@@ -33,7 +33,7 @@ class Archive<T> where T : Individual {
*
* Value -> sorted list of best individuals for that target
*/
private val map = mutableMapOf<Int, MutableList<EvaluatedIndividual<T>>>()
private val populations = mutableMapOf<Int, MutableList<EvaluatedIndividual<T>>>()
/**
* Key -> id of the target
@@ -65,10 +65,18 @@ class Archive<T> where T : Individual {
fun extractSolution(): Solution<T> {
val overall = FitnessValue(0.0)
/*
Note: no equals() is defined, so Set is based
on refs to the heap.
This is not an issue, as each individual is copied
when sampled.
Here, as an individual can go to many populations,
we want to avoiding it counting it several times.
*/
val uniques = mutableSetOf<EvaluatedIndividual<T>>()
val overall = FitnessValue(0.0)
map.entries.forEach { e ->
populations.entries.forEach { e ->
if (isCovered(e.key)) {
val ind = e.value[0]
uniques.add(ind)
@@ -81,7 +89,7 @@ class Archive<T> where T : Individual {
}
fun isEmpty() = map.isEmpty()
fun isEmpty() = populations.isEmpty()
/**
* Get a copy of an individual in the archive.
@@ -97,14 +105,14 @@ class Archive<T> where T : Individual {
var toChooseFrom = notCoveredTargets()
if (toChooseFrom.isEmpty()) {
//this means all current targets are covered
toChooseFrom = map.keys.toSet()
toChooseFrom = populations.keys.toSet()
}
val chosenTarget = chooseTarget(toChooseFrom)
lastChosen = chosenTarget
val candidates = map[chosenTarget] ?:
val candidates = populations[chosenTarget] ?:
//should never happen, unless of bug
throw IllegalStateException("Target $chosenTarget has no candidate individual")
@@ -197,11 +205,20 @@ class Archive<T> where T : Individual {
*/
fun encounteredTargetDescriptions(): List<String> {
return map.entries
return populations.entries
.map { e -> "key ${e.key}: ${idMapper.getDescriptiveId(e.key)} , size=${e.value.size}" }
.sorted()
}
fun numberOfCoveredTargets(): Int {
return populations.keys.stream().filter { isCovered(it) }.count().toInt()
}
fun numberOfReachedButNotCoveredTargets(): Int {
return populations.keys.stream().filter { ! isCovered(it) }.count().toInt()
}
/**
* Get all known targets that are not fully covered
*
@@ -215,15 +232,16 @@ class Archive<T> where T : Individual {
iterating over them is expensive
*/
return map.keys.filter { k -> !isCovered(k) }.toSet()
return populations.keys.filter { !isCovered(it) }.toSet()
}
fun wouldReachNewTarget(ei: EvaluatedIndividual<T>): Boolean {
return ei.fitness.getViewOfData()
.filter { d -> d.value.distance > 0.0 }
.map { d -> d.key }
.any { k -> map[k]?.isEmpty() ?: true }
.filter { it.value.distance > 0.0 }
.map { it.key }
.any { populations[it]?.isEmpty() ?: true }
}
/**
@@ -244,7 +262,7 @@ class Archive<T> where T : Individual {
continue
}
val current = map.getOrPut(k, { mutableListOf() })
val current = populations.getOrPut(k, { mutableListOf() })
//ind does reach a new target?
if (current.isEmpty()) {
@@ -371,7 +389,7 @@ class Archive<T> where T : Individual {
fun isCovered(target: Int): Boolean {
val current = map[target] ?: return false
val current = populations[target] ?: return false
if (current.size != 1) {
return false
@@ -0,0 +1,7 @@
package org.evomaster.core.search.service
interface SearchListener {
fun newActionEvaluated()
}
@@ -28,16 +28,25 @@ class SearchTimeController {
private var startTime = 0L
private val listeners = mutableListOf<SearchListener>()
fun startSearch(){
searchStarted = true
startTime = System.currentTimeMillis()
}
fun newIndividualEvaluation() = evaluatedIndividuals++
fun addListener(listener: SearchListener){
listeners.add(listener)
}
fun newIndividualEvaluation() {
evaluatedIndividuals++
}
fun newActionEvaluation(n: Int = 1) {
evaluatedActions += n
listeners.forEach{it.newActionEvaluated()}
}
fun newCoveredTarget(){
@@ -69,7 +78,7 @@ class SearchTimeController {
}
/**
* Return how much percentage [0,1] of search budget has been used so far
* Return how much percentage `[0,1]` of search budget has been used so far
*/
fun percentageUsedBudget() : Double{
Oops, something went wrong.

0 comments on commit e5f53a2

Please sign in to comment.