com.github.rinde.gpem17.eval.ResultWriter.java Source code

Java tutorial

Introduction

Here is the source code for com.github.rinde.gpem17.eval.ResultWriter.java

Source

/*
 * Copyright (C) 2015-2016 Rinde van Lon, iMinds-DistriNet, KU Leuven
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.github.rinde.gpem17.eval;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Collection;

import com.github.rinde.gpem17.AuctionStats;
import com.github.rinde.rinsim.core.model.time.RealtimeTickInfo;
import com.github.rinde.rinsim.experiment.Experiment.SimArgs;
import com.github.rinde.rinsim.experiment.Experiment.SimulationResult;
import com.github.rinde.rinsim.experiment.ExperimentResults;
import com.github.rinde.rinsim.experiment.MASConfiguration;
import com.github.rinde.rinsim.experiment.PostProcessor.FailureStrategy;
import com.github.rinde.rinsim.experiment.ResultListener;
import com.github.rinde.rinsim.pdptw.common.StatisticsDTO;
import com.github.rinde.rinsim.scenario.Scenario;
import com.github.rinde.rinsim.scenario.gendreau06.Gendreau06ObjectiveFunction;
import com.google.common.base.Charsets;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Multimap;
import com.google.common.io.Files;

abstract class ResultWriter implements ResultListener {
    final File experimentDirectory;
    final File timeDeviationsDirectory;
    final Gendreau06ObjectiveFunction objectiveFunction;
    final boolean realtime;
    private final boolean createFinalFiles;
    private final boolean minimizeIO;

    ResultWriter(File target, Gendreau06ObjectiveFunction objFunc, boolean rt, boolean finalFiles,
            boolean minimizeIOops) {
        experimentDirectory = target;
        objectiveFunction = objFunc;
        realtime = rt;
        createFinalFiles = finalFiles;
        minimizeIO = minimizeIOops;
        if (rt) {
            timeDeviationsDirectory = new File(experimentDirectory, "time-deviations");
            timeDeviationsDirectory.mkdirs();
        } else {
            timeDeviationsDirectory = null;
        }
    }

    public File getExperimentDirectory() {
        return experimentDirectory;
    }

    @Override
    public void startComputing(int numberOfSimulations, ImmutableSet<MASConfiguration> configurations,
            ImmutableSet<Scenario> scenarios, int repetitions, int seedRepetitions) {

        final StringBuilder sb = new StringBuilder("Experiment summary");
        sb.append(System.lineSeparator()).append("Number of simulations: ").append(numberOfSimulations)
                .append(System.lineSeparator()).append("Number of configurations: ").append(configurations.size())
                .append(System.lineSeparator()).append("Number of scenarios: ").append(scenarios.size())
                .append(System.lineSeparator()).append("Number of repetitions: ").append(repetitions)
                .append(System.lineSeparator()).append("Number of seed repetitions: ").append(seedRepetitions)
                .append(System.lineSeparator()).append("Configurations:").append(System.lineSeparator());

        for (final MASConfiguration config : configurations) {
            sb.append(config.getName()).append(System.lineSeparator());
        }

        final File setup = new File(experimentDirectory, "experiment-setup.txt");
        try {
            setup.createNewFile();
            Files.write(sb.toString(), setup, Charsets.UTF_8);
        } catch (final IOException e) {
            throw new IllegalStateException(e);
        }
    }

    @Override
    public void doneComputing(ExperimentResults results) {
        if (createFinalFiles) {

            if (minimizeIO) {
                new Thread(new FinalWriter(this, results)).start();
            } else {
                writeFinal(results);
            }
        }
    }

    void writeFinal(ExperimentResults results) {
        final Multimap<MASConfiguration, SimulationResult> groupedResults = LinkedHashMultimap.create();
        for (final SimulationResult sr : results.sortedResults()) {
            groupedResults.put(sr.getSimArgs().getMasConfig(), sr);
        }

        if (minimizeIO) {
            StringBuilder sb = new StringBuilder("name,").append(createHeader().toString());
            for (final MASConfiguration config : groupedResults.keySet()) {
                final Collection<SimulationResult> group = groupedResults.get(config);
                for (final SimulationResult sr : group) {
                    sb.append(config.getName()).append(",");
                    appendTo(sr, sb);
                }
            }

            final File combinedResult = new File(experimentDirectory, "combined-final.csv");
            try {
                Files.createParentDirs(combinedResult);
                Files.append(sb, combinedResult, Charsets.UTF_8);
            } catch (final IOException e1) {
                throw new IllegalStateException(e1);
            }
        } else {

            for (final MASConfiguration config : groupedResults.keySet()) {
                final Collection<SimulationResult> group = groupedResults.get(config);

                final File configResult = new File(experimentDirectory, config.getName() + "-final.csv");

                // deletes the file in case it already exists
                configResult.delete();

                StringBuilder sb = createHeader();
                for (final SimulationResult sr : group) {
                    appendTo(sr, sb);
                }

                try {
                    Files.createParentDirs(configResult);
                    Files.append(sb, configResult, Charsets.UTF_8);
                } catch (final IOException e1) {
                    throw new IllegalStateException(e1);
                }

            }
        }
    }

    static class FinalWriter implements Runnable {
        private final ExperimentResults data;
        private final ResultWriter instance;

        FinalWriter(ResultWriter rw, ExperimentResults dt) {
            instance = rw;
            data = dt;
        }

        @Override
        public void run() {
            instance.writeFinal(data);
        }
    }

    abstract Iterable<Enum<?>> getFields();

    abstract void appendSimResult(SimulationResult sr, File destFile);

    abstract StringBuilder appendTo(SimulationResult sr, StringBuilder sb);

    StringBuilder createHeader() {
        return Joiner.on(",").appendTo(new StringBuilder(), getFields()).append(System.lineSeparator());
    }

    void createCSVWithHeader(File f) {
        try {
            Files.createParentDirs(f);
            Files.append(createHeader(), f, Charsets.UTF_8);
        } catch (final IOException e1) {
            throw new IllegalStateException(e1);
        }
    }

    static void appendTimeLogSummary(SimulationResult sr, File target) {
        if (sr.getResultObject() instanceof SimResult) {
            final SimResult info = (SimResult) sr.getResultObject();

            final int tickInfoListSize = info.getTickInfoList().size();
            long sumIatNs = 0;
            for (final RealtimeTickInfo md : info.getTickInfoList()) {
                sumIatNs += md.getInterArrivalTime();
            }

            try {
                Files.append(Joiner.on(',').join(sr.getSimArgs().getScenario().getProblemClass().getId(),
                        sr.getSimArgs().getScenario().getProblemInstanceId(),
                        sr.getSimArgs().getMasConfig().getName(), sr.getSimArgs().getRandomSeed(),
                        sr.getSimArgs().getRepetition(), tickInfoListSize,
                        tickInfoListSize == 0 ? 0 : sumIatNs / tickInfoListSize, info.getRtCount(),
                        info.getStCount() + "\n"), target, Charsets.UTF_8);
            } catch (final IOException e) {
                throw new IllegalStateException(e);
            }
        }
    }

    static void createTimeLogSummaryHeader(File target) {
        try {
            Files.append(
                    Joiner.on(',').join("problem-class", "instance", "config", "random-seed", "repetition",
                            "rt-tick-infos", "avg-interarrival-time", "rt-count", "st-count\n"),
                    target, Charsets.UTF_8);
        } catch (final IOException e) {
            throw new IllegalStateException(e);
        }
    }

    static void addSimOutputs(ImmutableMap.Builder<Enum<?>, Object> map, SimulationResult sr,
            Gendreau06ObjectiveFunction objFunc) {
        if (sr.getResultObject() instanceof FailureStrategy) {
            map.put(OutputFields.COST, -1).put(OutputFields.TRAVEL_TIME, -1).put(OutputFields.TARDINESS, -1)
                    .put(OutputFields.OVER_TIME, -1).put(OutputFields.IS_VALID, false)
                    .put(OutputFields.COMP_TIME, -1).put(OutputFields.NUM_REAUCTIONS, -1)
                    .put(OutputFields.NUM_UNSUC_REAUCTIONS, -1).put(OutputFields.NUM_FAILED_REAUCTIONS, -1);
        } else {
            final SimResult ei = (SimResult) sr.getResultObject();
            final StatisticsDTO stats = ei.getStats();
            map.put(OutputFields.COST, objFunc.computeCost(stats))
                    .put(OutputFields.TRAVEL_TIME, objFunc.travelTime(stats))
                    .put(OutputFields.TARDINESS, objFunc.tardiness(stats))
                    .put(OutputFields.OVER_TIME, objFunc.overTime(stats))
                    .put(OutputFields.IS_VALID, objFunc.isValidResult(stats))
                    .put(OutputFields.COMP_TIME, stats.computationTime);

            if (ei.getAuctionStats().isPresent()) {
                final AuctionStats aStats = ei.getAuctionStats().get();
                map.put(OutputFields.NUM_REAUCTIONS, aStats.getNumReauctions())
                        .put(OutputFields.NUM_UNSUC_REAUCTIONS, aStats.getNumUnsuccesfulReauctions())
                        .put(OutputFields.NUM_FAILED_REAUCTIONS, aStats.getNumFailedReauctions());
            } else {
                map.put(OutputFields.NUM_REAUCTIONS, 0).put(OutputFields.NUM_UNSUC_REAUCTIONS, 0)
                        .put(OutputFields.NUM_FAILED_REAUCTIONS, 0);
            }

            // if (!objFunc.isValidResult(stats)) {
            // System.err.println("WARNING: FOUND AN INVALID RESULT: ");
            // System.err.println(map.build());
            // }
        }
    }

    void writeTimeLog(SimulationResult result) {
        final String configName = result.getSimArgs().getMasConfig().getName();
        final File timeLogSummaryFile = new File(experimentDirectory, configName + "-timelog-summary.csv");

        if (!timeLogSummaryFile.exists()) {
            createTimeLogSummaryHeader(timeLogSummaryFile);
        }
        appendTimeLogSummary(result, timeLogSummaryFile);
        createTimeLog(result, timeDeviationsDirectory);
    }

    static void createTimeLog(SimulationResult sr, File experimentDir) {
        if (!(sr.getResultObject() instanceof SimResult)) {
            return;
        }
        final SimArgs simArgs = sr.getSimArgs();
        final Scenario scenario = simArgs.getScenario();

        final String id = Joiner.on("-").join(simArgs.getMasConfig().getName(), scenario.getProblemClass().getId(),
                scenario.getProblemInstanceId(), simArgs.getRandomSeed(), simArgs.getRepetition());

        final File iatFile = new File(experimentDir, id + "-interarrivaltimes.csv");
        final SimResult info = (SimResult) sr.getResultObject();
        try (FileWriter writer = new FileWriter(iatFile)) {
            iatFile.createNewFile();
            for (final RealtimeTickInfo md : info.getTickInfoList()) {
                writer.write(Long.toString(md.getInterArrivalTime()));
                writer.write(System.lineSeparator());
            }
        } catch (final IOException e) {
            throw new IllegalStateException(e);
        }
    }

    enum OutputFields {
        DYNAMISM,

        URGENCY,

        SCALE,

        COST,

        TRAVEL_TIME,

        TARDINESS,

        OVER_TIME,

        IS_VALID,

        SCENARIO_ID,

        RANDOM_SEED,

        REPETITION,

        COMP_TIME,

        NUM_VEHICLES,

        NUM_ORDERS,

        NUM_REAUCTIONS,

        NUM_UNSUC_REAUCTIONS,

        NUM_FAILED_REAUCTIONS;

        @Override
        public String toString() {
            return name().toLowerCase();
        }
    }

}