From 37d4320b3774e9cb66179856b5c617b426ef00d8 Mon Sep 17 00:00:00 2001 From: Ryoko Izuta Date: Mon, 31 Aug 2020 18:35:57 +0900 Subject: [PATCH 1/6] round fitness to 3 decimal digits for #735 --- .../jp/kusumotolab/kgenprog/KGenProgMain.java | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/main/java/jp/kusumotolab/kgenprog/KGenProgMain.java b/src/main/java/jp/kusumotolab/kgenprog/KGenProgMain.java index 9e73ae1c7..0c7045967 100644 --- a/src/main/java/jp/kusumotolab/kgenprog/KGenProgMain.java +++ b/src/main/java/jp/kusumotolab/kgenprog/KGenProgMain.java @@ -1,5 +1,6 @@ package jp.kusumotolab.kgenprog; +import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -206,6 +207,7 @@ private void logGenerationSummary(final String timeText, final List var variants.addAll(variantsByMutation); variants.addAll(variantsByCrossover); final StringBuilder sb = new StringBuilder(); + final DecimalFormat df = createDecimalFormat(); sb// .append(System.lineSeparator()) .append("----------------------------------------------------------------") @@ -229,7 +231,7 @@ private void logGenerationSummary(final String timeText, final List var .append(", min ") .append(getMinText(variants)) .append(", ave ") - .append(getAverage(variants)) + .append(df.format(getAverage(variants))) .append(System.lineSeparator()) .append("----------------------------------------------------------------") .append(System.lineSeparator()); @@ -249,7 +251,8 @@ private String getMaxText(final List variants) { } final Map.Entry max = Collections.max(frequencies.entrySet(), Map.Entry.comparingByKey()); - return max.getKey() + "(" + max.getValue() + ")"; + final DecimalFormat df = createDecimalFormat(); + return df.format(max.getKey()) + "(" + max.getValue() + ")"; // ここのmax.getKey() } private String getMinText(final List variants) { @@ -259,7 +262,8 @@ private String getMinText(final List variants) { } final Map.Entry min = Collections.min(frequencies.entrySet(), Map.Entry.comparingByKey()); - return min.getKey() + "(" + min.getValue() + ")"; + final DecimalFormat df = createDecimalFormat(); + return df.format(min.getKey()) + "(" + min.getValue() + ")"; // ここのmin.getKey() } private double getAverage(final List variants) { @@ -267,6 +271,7 @@ private double getAverage(final List variants) { .filter(Variant::isBuildSucceeded) .mapToDouble(this::getNormalizedFitnessValue) .average() + // ここの.average() NaNの時フォーマッタ大丈夫か? .orElse(Double.NaN); } @@ -281,6 +286,10 @@ private double getNormalizedFitnessValue(final Variant variant) { .getNormalizedValue(); } + private DecimalFormat createDecimalFormat(){ + return new DecimalFormat("#.###"); + } + private void logGAStopped(final OrdinalNumber generation) { final StringBuilder sb = new StringBuilder(); sb// From a5694c6fa2a0efe81cc059575eacc00bddb24ab2 Mon Sep 17 00:00:00 2001 From: Ryoko Izuta Date: Tue, 1 Sep 2020 11:56:32 +0900 Subject: [PATCH 2/6] reformat final output message --- .../jp/kusumotolab/kgenprog/KGenProgMain.java | 45 ++++++++++++++----- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/src/main/java/jp/kusumotolab/kgenprog/KGenProgMain.java b/src/main/java/jp/kusumotolab/kgenprog/KGenProgMain.java index 0c7045967..ac4ab3b86 100644 --- a/src/main/java/jp/kusumotolab/kgenprog/KGenProgMain.java +++ b/src/main/java/jp/kusumotolab/kgenprog/KGenProgMain.java @@ -101,6 +101,8 @@ public List run() throws RuntimeException { final StopWatch stopwatch = new StopWatch(config.getTimeLimitSeconds()); stopwatch.start(); + ExitStatus exitStatus; + while (true) { // 新しい世代に入ったことをログ出力 @@ -118,22 +120,22 @@ public List run() throws RuntimeException { // しきい値以上の completedVariants が生成された場合は,GA を抜ける if (areEnoughCompletedVariants(variantStore.getFoundSolutions())) { - log.info("enough solutions have been found."); - logGAStopped(variantStore.getGenerationNumber()); + exitStatus = ExitStatus.SUCCESS; + log.info("GA stopped."); break; } // 制限時間に達した場合には GA を抜ける if (stopwatch.isTimeout()) { - log.info("GA reached the time limit."); - logGAStopped(variantStore.getGenerationNumber()); + exitStatus = ExitStatus.FAIL_TIME; + log.info("GA stopped."); break; } // 最大世代数に到達した場合には GA を抜ける if (reachedMaxGeneration(variantStore.getGenerationNumber())) { - log.info("GA reached the maximum generation."); - logGAStopped(variantStore.getGenerationNumber()); + exitStatus = ExitStatus.FAIL_GEN; + log.info("GA stopped."); break; } @@ -146,7 +148,7 @@ public List run() throws RuntimeException { stopwatch.unsplit(); strategies.finish(); - log.info("execution time: " + stopwatch.toString()); + logGAStopped(variantStore.getGenerationNumber(), stopwatch.toString(), exitStatus); return variantStore.getFoundSolutions(config.getRequiredSolutionsCount()); } @@ -290,12 +292,33 @@ private DecimalFormat createDecimalFormat(){ return new DecimalFormat("#.###"); } - private void logGAStopped(final OrdinalNumber generation) { + private void logGAStopped(final OrdinalNumber generation, 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("Overall") + .append(System.lineSeparator()) + .append("Reached generation = ") + .append(generation.intValue()) + .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"), FAIL_GEN("FAIL(maximum generation)"), FAIL_TIME("FAIL(time limit)"); + private final String code; + + ExitStatus(String code) { + this.code = code; + } + + String getCode() { + return code; + } + } } From 02edf96027311a96cd7dcc90efff5e14606b39c5 Mon Sep 17 00:00:00 2001 From: Ryoko Izuta Date: Tue, 1 Sep 2020 11:56:53 +0900 Subject: [PATCH 3/6] reformat source code --- src/main/java/jp/kusumotolab/kgenprog/KGenProgMain.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/jp/kusumotolab/kgenprog/KGenProgMain.java b/src/main/java/jp/kusumotolab/kgenprog/KGenProgMain.java index ac4ab3b86..01dc56e86 100644 --- a/src/main/java/jp/kusumotolab/kgenprog/KGenProgMain.java +++ b/src/main/java/jp/kusumotolab/kgenprog/KGenProgMain.java @@ -288,7 +288,7 @@ private double getNormalizedFitnessValue(final Variant variant) { .getNormalizedValue(); } - private DecimalFormat createDecimalFormat(){ + private DecimalFormat createDecimalFormat() { return new DecimalFormat("#.###"); } From 6be49dc974876ad2a21b8f9ee6a469cd2d5fab4b Mon Sep 17 00:00:00 2001 From: Ryoko Izuta Date: Tue, 1 Sep 2020 12:00:27 +0900 Subject: [PATCH 4/6] remove useless comment --- src/main/java/jp/kusumotolab/kgenprog/KGenProgMain.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/jp/kusumotolab/kgenprog/KGenProgMain.java b/src/main/java/jp/kusumotolab/kgenprog/KGenProgMain.java index 01dc56e86..7ba6c45a7 100644 --- a/src/main/java/jp/kusumotolab/kgenprog/KGenProgMain.java +++ b/src/main/java/jp/kusumotolab/kgenprog/KGenProgMain.java @@ -254,7 +254,7 @@ private String getMaxText(final List variants) { final Map.Entry max = Collections.max(frequencies.entrySet(), Map.Entry.comparingByKey()); final DecimalFormat df = createDecimalFormat(); - return df.format(max.getKey()) + "(" + max.getValue() + ")"; // ここのmax.getKey() + return df.format(max.getKey()) + "(" + max.getValue() + ")"; } private String getMinText(final List variants) { @@ -265,7 +265,7 @@ private String getMinText(final List variants) { final Map.Entry min = Collections.min(frequencies.entrySet(), Map.Entry.comparingByKey()); final DecimalFormat df = createDecimalFormat(); - return df.format(min.getKey()) + "(" + min.getValue() + ")"; // ここのmin.getKey() + return df.format(min.getKey()) + "(" + min.getValue() + ")"; } private double getAverage(final List variants) { @@ -273,7 +273,6 @@ private double getAverage(final List variants) { .filter(Variant::isBuildSucceeded) .mapToDouble(this::getNormalizedFitnessValue) .average() - // ここの.average() NaNの時フォーマッタ大丈夫か? .orElse(Double.NaN); } From 01a51065225e41bc75646dd1f4a2ed3be985ffa2 Mon Sep 17 00:00:00 2001 From: Ryoko Izuta Date: Tue, 1 Sep 2020 21:44:25 +0900 Subject: [PATCH 5/6] apply review comment --- .../java/jp/kusumotolab/kgenprog/KGenProgMain.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/main/java/jp/kusumotolab/kgenprog/KGenProgMain.java b/src/main/java/jp/kusumotolab/kgenprog/KGenProgMain.java index 7ba6c45a7..81798879b 100644 --- a/src/main/java/jp/kusumotolab/kgenprog/KGenProgMain.java +++ b/src/main/java/jp/kusumotolab/kgenprog/KGenProgMain.java @@ -121,21 +121,18 @@ public List run() throws RuntimeException { // しきい値以上の completedVariants が生成された場合は,GA を抜ける if (areEnoughCompletedVariants(variantStore.getFoundSolutions())) { exitStatus = ExitStatus.SUCCESS; - log.info("GA stopped."); break; } // 制限時間に達した場合には GA を抜ける if (stopwatch.isTimeout()) { - exitStatus = ExitStatus.FAIL_TIME; - log.info("GA stopped."); + exitStatus = ExitStatus.FAILURE_TIME_LIMIT; break; } // 最大世代数に到達した場合には GA を抜ける if (reachedMaxGeneration(variantStore.getGenerationNumber())) { - exitStatus = ExitStatus.FAIL_GEN; - log.info("GA stopped."); + exitStatus = ExitStatus.FAILURE_MAXIMUM_GENERATION; break; } @@ -143,6 +140,7 @@ public List run() throws RuntimeException { variantStore.proceedNextGeneration(); } + log.info("GA stopped."); // 出力処理を行う exporters.exportAll(variantStore); @@ -295,7 +293,7 @@ private void logGAStopped(final OrdinalNumber generation, final String time, final ExitStatus exitStatus) { final StringBuilder sb = new StringBuilder(); sb// - .append("Overall") + .append("Summary") .append(System.lineSeparator()) .append("Reached generation = ") .append(generation.intValue()) @@ -309,7 +307,8 @@ private void logGAStopped(final OrdinalNumber generation, final String time, } private enum ExitStatus { - SUCCESS("SUCCESS"), FAIL_GEN("FAIL(maximum generation)"), FAIL_TIME("FAIL(time limit)"); + SUCCESS("SUCCESS"), FAILURE_MAXIMUM_GENERATION( + "FAILURE (maximum generation)"), FAILURE_TIME_LIMIT("FAILURE (time limit)"); private final String code; ExitStatus(String code) { From 282c31b833ea09406643f431149385c400b931b1 Mon Sep 17 00:00:00 2001 From: Ryoko Izuta Date: Tue, 1 Sep 2020 22:32:11 +0900 Subject: [PATCH 6/6] add information to summary output --- .../jp/kusumotolab/kgenprog/KGenProgMain.java | 20 ++++++++- .../kgenprog/ga/variant/VariantStore.java | 42 +++++++++++++++++++ 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/src/main/java/jp/kusumotolab/kgenprog/KGenProgMain.java b/src/main/java/jp/kusumotolab/kgenprog/KGenProgMain.java index 81798879b..07bed5d7f 100644 --- a/src/main/java/jp/kusumotolab/kgenprog/KGenProgMain.java +++ b/src/main/java/jp/kusumotolab/kgenprog/KGenProgMain.java @@ -7,6 +7,7 @@ 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; @@ -117,6 +118,9 @@ public List 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())) { @@ -146,7 +150,9 @@ public List run() throws RuntimeException { stopwatch.unsplit(); strategies.finish(); - logGAStopped(variantStore.getGenerationNumber(), stopwatch.toString(), exitStatus); + logGAStopped(variantStore.getGenerationNumber(), variantStore.getVariantCount(), + variantStore.getSyntaxValidVariantCount(), variantStore.getBuildSuccessVariantCount(), + stopwatch.toString(), exitStatus); return variantStore.getFoundSolutions(config.getRequiredSolutionsCount()); } @@ -289,7 +295,8 @@ private DecimalFormat createDecimalFormat() { return new DecimalFormat("#.###"); } - private void logGAStopped(final OrdinalNumber generation, final String time, + 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// @@ -298,6 +305,15 @@ private void logGAStopped(final OrdinalNumber generation, final String time, .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()) diff --git a/src/main/java/jp/kusumotolab/kgenprog/ga/variant/VariantStore.java b/src/main/java/jp/kusumotolab/kgenprog/ga/variant/VariantStore.java index b559ae8c1..2441a6d95 100644 --- a/src/main/java/jp/kusumotolab/kgenprog/ga/variant/VariantStore.java +++ b/src/main/java/jp/kusumotolab/kgenprog/ga/variant/VariantStore.java @@ -36,6 +36,9 @@ public class VariantStore { private final AtomicLong variantCounter; private final Function elementReplacer; private final Consumer variantRecorder; + private int variantCount; + private int syntaxValidVariantCount; + private int buildSuccessVariantCount; /** * @param config 設定 @@ -57,6 +60,9 @@ public VariantStore(final Configuration config, final Strategies strategies) { foundSolutions = new ArrayList<>(); // 最後に次の世代番号に進めておく generation.incrementAndGet(); + variantCount = 0; + syntaxValidVariantCount = 0; + buildSuccessVariantCount = 0; } /** @@ -129,6 +135,27 @@ public List 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として追加する * @@ -233,4 +260,19 @@ private Consumer newVariantRecorder(final boolean historyRecord) { public Configuration getConfiguration() { return config; } + + /** + * variantCount, syntaxValidVariantCount, buildSuccessVariantCountを更新する + * + * @param variants 前回の更新以降新たに生成した個体のリスト + */ + public void updateVariantCounts(final List variants) { + variantCount += variants.size(); + syntaxValidVariantCount += variants.stream() + .filter(Variant::isSyntaxValid) + .count(); + buildSuccessVariantCount += variants.stream() + .filter(Variant::isBuildSucceeded) + .count(); + } }