Skip to content

Commit

Permalink
Merge pull request #778 from kusumotolab/modify-output-message
Browse files Browse the repository at this point in the history
出力メッセージの調整
  • Loading branch information
hnymA authored Sep 2, 2020
2 parents 5994489 + 282c31b commit 6e40150
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 14 deletions.
74 changes: 60 additions & 14 deletions src/main/java/jp/kusumotolab/kgenprog/KGenProgMain.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package jp.kusumotolab.kgenprog;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jp.kusumotolab.kgenprog.fl.FaultLocalization;
Expand Down Expand Up @@ -100,6 +102,8 @@ public List<Variant> run() throws RuntimeException {
final StopWatch stopwatch = new StopWatch(config.getTimeLimitSeconds());
stopwatch.start();

ExitStatus exitStatus;

while (true) {

// 新しい世代に入ったことをログ出力
Expand All @@ -114,38 +118,41 @@ public List<Variant> run() throws RuntimeException {
// 世代別サマリの出力
logGenerationSummary(stopwatch.toString(), variantsByMutation, variantsByCrossover);
stopwatch.split();
variantStore.updateVariantCounts(
Stream.concat(variantsByMutation.stream(), variantsByCrossover.stream())
.collect(Collectors.toList()));

// しきい値以上の completedVariants が生成された場合は,GA を抜ける
if (areEnoughCompletedVariants(variantStore.getFoundSolutions())) {
log.info("enough solutions have been found.");
logGAStopped(variantStore.getGenerationNumber());
exitStatus = ExitStatus.SUCCESS;
break;
}

// 制限時間に達した場合には GA を抜ける
if (stopwatch.isTimeout()) {
log.info("GA reached the time limit.");
logGAStopped(variantStore.getGenerationNumber());
exitStatus = ExitStatus.FAILURE_TIME_LIMIT;
break;
}

// 最大世代数に到達した場合には GA を抜ける
if (reachedMaxGeneration(variantStore.getGenerationNumber())) {
log.info("GA reached the maximum generation.");
logGAStopped(variantStore.getGenerationNumber());
exitStatus = ExitStatus.FAILURE_MAXIMUM_GENERATION;
break;
}

// 次世代に向けての準備
variantStore.proceedNextGeneration();
}

log.info("GA stopped.");
// 出力処理を行う
exporters.exportAll(variantStore);

stopwatch.unsplit();
strategies.finish();
log.info("execution time: " + stopwatch.toString());
logGAStopped(variantStore.getGenerationNumber(), variantStore.getVariantCount(),
variantStore.getSyntaxValidVariantCount(), variantStore.getBuildSuccessVariantCount(),
stopwatch.toString(), exitStatus);

return variantStore.getFoundSolutions(config.getRequiredSolutionsCount());
}
Expand Down Expand Up @@ -206,6 +213,7 @@ private void logGenerationSummary(final String timeText, final List<Variant> var
variants.addAll(variantsByMutation);
variants.addAll(variantsByCrossover);
final StringBuilder sb = new StringBuilder();
final DecimalFormat df = createDecimalFormat();
sb//
.append(System.lineSeparator())
.append("----------------------------------------------------------------")
Expand All @@ -229,7 +237,7 @@ private void logGenerationSummary(final String timeText, final List<Variant> var
.append(", min ")
.append(getMinText(variants))
.append(", ave ")
.append(getAverage(variants))
.append(df.format(getAverage(variants)))
.append(System.lineSeparator())
.append("----------------------------------------------------------------")
.append(System.lineSeparator());
Expand All @@ -249,7 +257,8 @@ private String getMaxText(final List<Variant> variants) {
}
final Map.Entry<Double, Long> max =
Collections.max(frequencies.entrySet(), Map.Entry.comparingByKey());
return max.getKey() + "(" + max.getValue() + ")";
final DecimalFormat df = createDecimalFormat();
return df.format(max.getKey()) + "(" + max.getValue() + ")";
}

private String getMinText(final List<Variant> variants) {
Expand All @@ -259,7 +268,8 @@ private String getMinText(final List<Variant> variants) {
}
final Map.Entry<Double, Long> min =
Collections.min(frequencies.entrySet(), Map.Entry.comparingByKey());
return min.getKey() + "(" + min.getValue() + ")";
final DecimalFormat df = createDecimalFormat();
return df.format(min.getKey()) + "(" + min.getValue() + ")";
}

private double getAverage(final List<Variant> variants) {
Expand All @@ -281,12 +291,48 @@ private double getNormalizedFitnessValue(final Variant variant) {
.getNormalizedValue();
}

private void logGAStopped(final OrdinalNumber generation) {
private DecimalFormat createDecimalFormat() {
return new DecimalFormat("#.###");
}

private void logGAStopped(final OrdinalNumber generation, final int variantCount,
final int syntaxValidCount, final int buildSuccessCount, final String time,
final ExitStatus exitStatus) {
final StringBuilder sb = new StringBuilder();
sb//
.append("GA stopped at the era of ")
.append(generation.toString())
.append(" generation.");
.append("Summary")
.append(System.lineSeparator())
.append("Reached generation = ")
.append(generation.intValue())
.append(System.lineSeparator())
.append("Generated variants = ")
.append(variantCount)
.append(System.lineSeparator())
.append("Syntax valid variants = ")
.append(syntaxValidCount)
.append(System.lineSeparator())
.append("Build succeeded variants = ")
.append(buildSuccessCount)
.append(System.lineSeparator())
.append("Time elapsed = ")
.append(time)
.append(System.lineSeparator())
.append("Exit status = ")
.append(exitStatus.getCode());
log.info(sb.toString());
}

private enum ExitStatus {
SUCCESS("SUCCESS"), FAILURE_MAXIMUM_GENERATION(
"FAILURE (maximum generation)"), FAILURE_TIME_LIMIT("FAILURE (time limit)");
private final String code;

ExitStatus(String code) {
this.code = code;
}

String getCode() {
return code;
}
}
}
42 changes: 42 additions & 0 deletions src/main/java/jp/kusumotolab/kgenprog/ga/variant/VariantStore.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ public class VariantStore {
private final AtomicLong variantCounter;
private final Function<HistoricalElement, HistoricalElement> elementReplacer;
private final Consumer<Variant> variantRecorder;
private int variantCount;
private int syntaxValidVariantCount;
private int buildSuccessVariantCount;

/**
* @param config 設定
Expand All @@ -57,6 +60,9 @@ public VariantStore(final Configuration config, final Strategies strategies) {
foundSolutions = new ArrayList<>();
// 最後に次の世代番号に進めておく
generation.incrementAndGet();
variantCount = 0;
syntaxValidVariantCount = 0;
buildSuccessVariantCount = 0;
}

/**
Expand Down Expand Up @@ -129,6 +135,27 @@ public List<Variant> getFoundSolutions(final int maxNumber) {
return foundSolutions.subList(0, length);
}

/**
* @return 今まで生成した個体数
*/
public int getVariantCount() {
return variantCount;
}

/**
* @return 今まで生成した個体のうち、Syntax Valid な個体数
*/
public int getSyntaxValidVariantCount() {
return syntaxValidVariantCount;
}

/**
* @return 今まで生成した個体のうち、ビルド成功個体数
*/
public int getBuildSuccessVariantCount() {
return buildSuccessVariantCount;
}

/**
* 引数の要素すべてを次世代のVariantとして追加する
*
Expand Down Expand Up @@ -233,4 +260,19 @@ private Consumer<Variant> newVariantRecorder(final boolean historyRecord) {
public Configuration getConfiguration() {
return config;
}

/**
* variantCount, syntaxValidVariantCount, buildSuccessVariantCountを更新する
*
* @param variants 前回の更新以降新たに生成した個体のリスト
*/
public void updateVariantCounts(final List<Variant> variants) {
variantCount += variants.size();
syntaxValidVariantCount += variants.stream()
.filter(Variant::isSyntaxValid)
.count();
buildSuccessVariantCount += variants.stream()
.filter(Variant::isBuildSucceeded)
.count();
}
}

0 comments on commit 6e40150

Please sign in to comment.