/* * Copyright © 2010 by Ondrej Skalicka. All Rights Reserved */ package cz.cvut.felk.cig.jcop.result.render; import cz.cvut.felk.cig.jcop.problem.ConfigurationMap; import cz.cvut.felk.cig.jcop.problem.OperationHistory; import cz.cvut.felk.cig.jcop.result.Result; import cz.cvut.felk.cig.jcop.result.ResultEntry; import cz.cvut.felk.cig.jcop.util.PreciseTimestamp; import java.io.File; import java.io.FileNotFoundException; import java.io.PrintStream; /** * Renders results into console (or other printStream) in order in which they were added to Result. * <p/> * Example (if {@link #OUTPUT_STANDARD} is supplied): * <p/> * <pre> * === Algorithm MyAlgorithm used on problem Knapsack, settings default === * CPU Time: 16 [ms] * System Time: 0 [ms] * User Time: 15 [ms] * Clock Time: 31 [ms] * Optimize counter: 28 [-] * Optimize/sec (CPU): 1750 [1/s] * Optimize/sec (Clock): 903 [1/s] * Best solution: Configuration{attributes=[0, 0, 0, 0, 0, 0, 0, 0, * 1, 1, 0, 0, 1, 1, 1], operationHistory={23 items}} * Depth: 23 [-] * Fitness: 454,0 [-] * Ended without exception * </pre> * * @author Ondrej Skalicka */ public class SimpleRender implements Render { /** * Prints standard information about every result entry. */ public static final int OUTPUT_STANDARD = 0; /** * Prints only best solution, CPU time, optimize counter and fitness. */ public static final int OUTPUT_MINI = 1; /** * Prints full information about every result entry. * <p/> * This includes all operations in operation history which are not included in {@link #OUTPUT_STANDARD} and also * uses {@link cz.cvut.felk.cig.jcop.problem.ConfigurationMap} of current problem to create human-readable values. */ public static final int OUTPUT_FULL = 2; /** * Output level defined for this render. */ protected int outputLevel; /** * Stream to print result to. * <p/> * Default is System.out, but could be replaced with a file or any other. */ protected PrintStream printStream = System.out; /** * Creates new simple render with given level. * <p/> * Level can be any OUTPUT_* constant of SimpleRender. * * @param outputLevel how output should be formatted * @throws IllegalArgumentException if invalid level is supplied */ public SimpleRender(int outputLevel) throws IllegalArgumentException { switch (outputLevel) { case SimpleRender.OUTPUT_STANDARD: case SimpleRender.OUTPUT_MINI: case SimpleRender.OUTPUT_FULL: this.outputLevel = outputLevel; break; default: throw new IllegalArgumentException("Simple render does not recognize outputLevel " + outputLevel); } } /** * Creates new simple render with level {@link #OUTPUT_STANDARD}. * * @throws IllegalArgumentException if invalid level is supplied */ public SimpleRender() { this(SimpleRender.OUTPUT_STANDARD); } /** * Creates new simple render with output level and print stream specified. * * @param outputLevel how output should be formatted * @param printStream print stream to write to * @throws IllegalArgumentException if invalid level is supplied */ public SimpleRender(int outputLevel, PrintStream printStream) throws IllegalArgumentException { this(outputLevel); this.printStream = printStream; } /** * Creates new simple render with output level and print stream set to a file. * <p/> * Note that SimpleRender will overwrite contents of supplied file. If you create several renders with same File, * their contents will overwrite each other. In such case, create PrintStream beforehand and use {@link * #SimpleRender(int, java.io.PrintStream)} instead. * * @param outputLevel how output should be formatted * @param file file to write to * @throws FileNotFoundException If the given file object does not denote an existing, writable regular file and * a new regular file of that name cannot be created, or if some other error occurs * while opening or creating the file * @throws IllegalArgumentException if invalid level is supplied * @see java.io.PrintStream#PrintStream(java.io.File) print stream from file */ public SimpleRender(int outputLevel, File file) throws FileNotFoundException, IllegalArgumentException { this.outputLevel = outputLevel; this.printStream = new PrintStream(file); } /** * Creates new simple render with output level and print stream set to a file. * <p/> * Note that SimpleRender will overwrite contents of supplied file. If you create several renders with same File, * their contents will overwrite each other. In such case, create PrintStream beforehand and use {@link * #SimpleRender(int, java.io.PrintStream)} instead. * * @param file file to write to * @throws FileNotFoundException If the given file object does not denote an existing, writable regular file and * a new regular file of that name cannot be created, or if some other error occurs * while opening or creating the file * @throws IllegalArgumentException if invalid level is supplied * @see java.io.PrintStream#PrintStream(java.io.File) print stream from file */ public SimpleRender(File file) throws FileNotFoundException, IllegalArgumentException { this.outputLevel = SimpleRender.OUTPUT_STANDARD; this.printStream = new PrintStream(file); } public void render(Result result) { for (ResultEntry resultEntry : result.getResultEntries()) { switch (this.outputLevel) { case SimpleRender.OUTPUT_STANDARD: this.printStandard(resultEntry); break; case SimpleRender.OUTPUT_MINI: this.printMini(resultEntry); break; case SimpleRender.OUTPUT_FULL: this.printFull(resultEntry); break; } } } /** * Prints minimal information about entry. * <p/> * Example: * <p/> * <pre> * === (MyAlgorithm, Knapsack, default) === * CPU Time: 16 ms. Optimizations: 28. Fitness: 454,0. Ended without * exception. Best solution: Configuration{attributes=[0, 0, 0, 0, 0, 0, 0, * 0, 1, 1, 0, 0, 1, 1, 1], operationHistory={23 items}}. * </pre> * * @param resultEntry result entry to be printed */ protected void printMini(ResultEntry resultEntry) { PreciseTimestamp start = resultEntry.getStartTimestamp(); PreciseTimestamp stop = resultEntry.getStopTimestamp(); printStream.println(); printStream.printf("=== (%s, %s) ===\n", resultEntry.getAlgorithm(), resultEntry.getProblem()); printStream.printf(" CPU Time: %7d ms. ", start.getCpuTimeSpent(stop)); printStream.printf("Optimizations: %7d. ", resultEntry.getOptimizeCounter()); if (resultEntry.getBestConfiguration() != null) printStream.printf("Fitness: %7.1f. ", resultEntry.getBestFitness()); else printStream.printf("Fitness: %s. ", "none"); printStream.printf("Best solution: %s. ", resultEntry.getBestConfiguration()); if (resultEntry.getException() == null) printStream.println("Ended without exception."); else printStream.printf("Ended with exception: %s.\n", resultEntry.getException().getClass().getSimpleName()); } /** * Prints all information about entry. * <p/> * Example: * <p/> * <pre> * === Algorithm MyAlgorithm [] used on problem Knapsack, settings default * [file=knap_4.txt] === * CPU Time: 16 [ms] * System Time: 0 [ms] * User Time: 15 [ms] * Clock Time: 31 [ms] * Optimize counter: 28 [-] * Optimize/sec (CPU): 1750 [1/s] * Optimize/sec (Clock): 903 [1/s] * Best solution: Configuration{attributes=[0, 0, 0, 0, 0, 0, 0, * 0, 1, 1, 0, 0, 1, 1, 1], operationHistory={23 items}} * Depth: 23 [-] * Fitness: 454,0 [-] * Operation history: * 0. Empty knapsack created * 1. AddOperation{knapsackItem=KnapsackItem{index=3, weight=3, * price=223}} * 2. AddOperation{knapsackItem=KnapsackItem{index=2, weight=88, * price=192}} * 3. AddOperation{knapsackItem=KnapsackItem{index=1, weight=42, * price=136}} * Ended without exception * </pre> * * @param resultEntry result entry to be printed */ protected void printFull(ResultEntry resultEntry) { PreciseTimestamp start = resultEntry.getStartTimestamp(); PreciseTimestamp stop = resultEntry.getStopTimestamp(); printStream.println(); printStream.printf("=== Algorithm %s used on problem %s ===\n", resultEntry.getAlgorithm(), resultEntry.getProblem()); printStream.printf(" CPU Time: %10d [ms]\n", start.getCpuTimeSpent(stop)); printStream.printf(" System Time: %10d [ms]\n", start.getSystemTimeSpent(stop)); printStream.printf(" User Time: %10d [ms]\n", start.getUserTimeSpent(stop)); printStream.printf(" Clock Time: %10d [ms]\n", start.getClockTimeSpent(stop)); printStream.printf(" Optimize counter: %10d [-]\n", resultEntry.getOptimizeCounter()); printStream.printf(" Optimize/sec (CPU): %10d [1/s]\n", resultEntry.getOptimizeCounter() * 1000L / start.getCpuTimeSpent(stop)); printStream.printf(" Optimize/sec (Clock): %10d [1/s]\n", resultEntry.getOptimizeCounter() * 1000L / start.getClockTimeSpent(stop)); if (resultEntry.getBestConfiguration() != null) { ConfigurationMap map = resultEntry.getProblem().getConfigurationMap(); printStream.print(" Best solution: ["); for (int i = 0; i < resultEntry.getBestConfiguration().getDimension(); ++i) { printStream.printf("%s%s", i == 0 ? "" : ", ", map.map(resultEntry.getBestConfiguration().valueAt(i), i)); } printStream.println("]"); printStream.printf(" Depth: %10d [-]\n", resultEntry.getBestConfiguration().getOperationHistory().getCounter()); printStream.printf(" Fitness: %10.1f [-]\n", resultEntry.getBestFitness()); printStream.println(" Operation history:"); for (OperationHistory operationHistory : resultEntry.getBestConfiguration().getOperationHistory().getChronologicalList()) { printStream.printf(" %4d. %s\n", operationHistory.getCounter(), operationHistory.getOperation().toString()); } } if (resultEntry.getException() == null) printStream.println(" Ended without exception"); else printStream.printf(" Ended with exception: %10s\n", resultEntry.getException()); } /** * Prints standard information about entry. * <p/> * Example: * <p/> * <pre> * === Algorithm MyAlgorithm used on problem Knapsack, settings default === * CPU Time: 16 [ms] * System Time: 0 [ms] * User Time: 15 [ms] * Clock Time: 31 [ms] * Optimize counter: 28 [-] * Optimize/sec (CPU): 1750 [1/s] * Optimize/sec (Clock): 903 [1/s] * Best solution: Configuration{attributes=[0, 0, 0, 0, 0, 0, 0, * 0, 1, 1, 0, 0, 1, 1, 1], operationHistory={23 items}} * Depth: 23 [-] * Fitness: 454,0 [-] * Ended without exception * </pre> * * @param resultEntry result entry to be printed */ protected void printStandard(ResultEntry resultEntry) { PreciseTimestamp start = resultEntry.getStartTimestamp(); PreciseTimestamp stop = resultEntry.getStopTimestamp(); printStream.println(); printStream.printf("=== Algorithm %s used on problem %s ===\n", resultEntry.getAlgorithm(), resultEntry.getProblem()); printStream.printf(" CPU Time: %10d [ms]\n", start.getCpuTimeSpent(stop)); printStream.printf(" System Time: %10d [ms]\n", start.getSystemTimeSpent(stop)); printStream.printf(" User Time: %10d [ms]\n", start.getUserTimeSpent(stop)); printStream.printf(" Clock Time: %10d [ms]\n", start.getClockTimeSpent(stop)); printStream.printf(" Optimize counter: %10d [-]\n", resultEntry.getOptimizeCounter()); printStream.printf(" Optimize/sec (CPU): %10d [1/s]\n", resultEntry.getOptimizeCounter() * 1000 / start.getCpuTimeSpent(stop)); printStream.printf(" Optimize/sec (Clock): %10d [1/s]\n", resultEntry.getOptimizeCounter() * 1000 / start.getClockTimeSpent(stop)); printStream.printf(" Best solution: %10s\n", resultEntry.getBestConfiguration()); if (resultEntry.getBestConfiguration() != null) { printStream.printf(" Depth: %10d [-]\n", resultEntry.getBestConfiguration().getOperationHistory().getCounter()); printStream.printf(" Fitness: %10.1f [-]\n", resultEntry.getBestFitness()); } if (resultEntry.getException() == null) printStream.println(" Ended without exception"); else printStream.printf(" Ended with exception: %10s\n", resultEntry.getException()); } }