示例#1
0
        /// <summary>
        /// Writes the output of the simulations to a file.
        /// </summary>
        /// <param name="tasks"></param>
        private void WriteOutput(Task <Simulation>[] tasks, string description, string outputDirectory)
        {
            Directory.CreateDirectory(outputDirectory);

            //used to get row info.
            DataTable measureTableInformation = tasks[0].Result.MeasureTable; //TODO: getting measurement info is a bit hacky.

            //this assumes all tasks have the same measurements, which should be true since they are created by the same function.
            MeasurementSuite measurementSuite = tasks[0].Result.MeasurementSuite;

            foreach (var kvp in measurementSuite.Measurements)
            {
                IMeasurement <IMeasurable> measurement = kvp.Value;
                string measureName = kvp.Key;
                string filename    = $"{description}-{measureName}.csv";

                using (TextWriter writer = new StreamWriter(Path.Combine(outputDirectory, filename)))
                {
                    writer.Write($"Iteration, {string.Join(", ", Enumerable.Range(1, tasks.Length).Select(x => $"Run {x}"))}");
                    //cycle through each captured iteration, which should be consistent for all simulations
                    for (int i = 0; i < measureTableInformation.Rows.Count; i++)
                    {
                        writer.WriteLine();                               //write a new line before each record
                        writer.Write(measureTableInformation.Rows[i][0]); //write the iteration number
                        for (int j = 0; j < tasks.Length; j++)
                        {
                            writer.Write($", {tasks[j].Result.MeasureTable.Rows[i][measureName]}");
                        }
                    }
                }
            }
        }
示例#2
0
        /// <summary>
        /// Create the table of measurements and execute the algorithm.
        /// </summary>
        /// <param name="recordInitialMeasurements">A value indicating whether measurements should be recorded after initialization, but before the first iteration.</param>
        public void Run(bool recordInitialMeasurements = true)
        {
            MeasureTable = new DataTable("Measurements");

            DataColumn column = new DataColumn()
            {
                ColumnName = "Iteration",
                DataType   = typeof(int)
            };

            MeasureTable.Columns.Add(column);

            foreach (var kvp in MeasurementSuite.Measurements)
            {
                //TODO: a bit hacky, but it works
                column = new DataColumn
                {
                    ColumnName = kvp.Key,
                    DataType   = MeasurementSuite.GetDataType(kvp.Key)
                };

                MeasureTable.Columns.Add(column);
            }

            if (recordInitialMeasurements)
            {
                Algorithm.InitializationComplete += RecordMeasurements;
            }
            Algorithm.IterationComplete += RecordMeasurements;
            Algorithm.PerformInitialization();
            Algorithm.Run();
        }
示例#3
0
        /// <summary>
        /// Execute a <see cref="Simulation"/> a set number of times. The output files will be placed in '{outputDirectory}/{description}-{measurement}.csv.
        /// </summary>
        /// <param name="algorithmGenerator">A function producing an instance of the algorithm to be run.</param>
        /// <param name="measurements">A collection of measurements to be recorded during the simulations.</param>
        /// <param name="runs">The number of times the simulation will be executed.</param>
        /// <param name="description">A description used for naming the output file.</param>
        /// <param name="outputDirectory">The directory to store output.</param>
        public void Execute(Func <IAlgorithm> algorithmGenerator, MeasurementSuite measurements, int runs, string description, string outputDirectory)
        {
            Task <Simulation>[] tasks = new Task <Simulation> [runs];

            int completed = 0;

            Console.Write($"Starting {runs} instances of {description}: ");
            ProgressBar progress = new ProgressBar();

            progress.Report(0);
            for (int i = 0; i < runs; i++)
            {
                //use LongRunning to get dedicated threads for each simulation, which are needed for the Instance
                tasks[i] = Task <Simulation> .Factory.StartNew(() => CreateSimulation(algorithmGenerator, measurements), TaskCreationOptions.LongRunning);

                //report progress as completed/runs
                tasks[i].ContinueWith(x => progress.Report((double)Interlocked.Increment(ref completed) / runs));
            }

            Task.WaitAll(tasks);
            progress.Report(1);  //force the progress bar to read 100%
            Console.WriteLine(); //force a new line after the simulation completes.

            WriteOutput(tasks, description, outputDirectory);
        }
示例#4
0
        /// <summary>
        /// Creates a <see cref="Simulation"/> object using the provided algorithm generator function and list of measurements.
        /// </summary>
        /// <returns>A <see cref="Simulation"/> object that is to be executed.</returns>
        private Simulation CreateSimulation(Func <IAlgorithm> algorithmGenerator, MeasurementSuite measurements)
        {
            IAlgorithm algorithm  = algorithmGenerator();
            Simulation simulation = new Simulation(algorithm, measurements);

            simulation.Run();

            return(simulation);
        }
示例#5
0
 /// <summary>
 /// Create a new simulation given a function producing an algorithm and list of measurements.
 /// </summary>
 /// <param name="algorithmGenerator">A function that produces an <see cref="IAlgorithm"/></param>
 /// <param name="measurements">A List of <see cref="IMeasurement{T}"/> to be recorded.</param>
 /// <returns></returns>
 public static Simulation Create(Func <IAlgorithm> algorithmGenerator, MeasurementSuite measurements)
 {
     return(new Simulation(algorithmGenerator(), measurements));
 }
示例#6
0
 /// <summary>
 /// Create a new simulation consisting of an algorithm and a list of measurements.
 /// </summary>
 /// <param name="algorithm">The algorithm to execute.</param>
 /// <param name="measurements">A collection of measurements to record on the provided algorithm.</param>
 public Simulation(IAlgorithm algorithm, MeasurementSuite measurements)
 {
     Algorithm        = algorithm;
     MeasurementSuite = measurements;
 }
示例#7
0
 /// <summary>
 /// Execute a <see cref="Simulation"/> a set number of times for each <see cref="IProblem"/> in the provided <see cref="ProblemSuite"/>.
 /// The output files will be placed in '{outputDirectory}/{description}-{measurement}.csv.
 /// </summary>
 /// <param name="algorithmGenerator">A function that accepts and <see cref="IProblem"/> and produces an instance of the algorithm to be run.</param>
 /// <param name="problemSuite">A collection of <see cref="IProblem"/> builders that will be built and executed.</param>
 /// <param name="measurements">A collection of measurements to be recorded during the simulations.</param>
 /// <param name="runs">The number of times the simulation will be executed.</param>
 /// <param name="description">A description used for naming the output file.</param>
 /// <param name="outputDirectory">The directory to store output.</param>
 public void Execute(Func <IProblem, IAlgorithm> algorithmGenerator, ProblemSuite problemSuite, MeasurementSuite suite, int runs, string description, string outputDirectory)
 {
     foreach (var kvp in problemSuite.Problems)
     {
         Execute(() => algorithmGenerator(kvp.Value()), suite, runs, description, Path.Combine(outputDirectory, kvp.Key));
     }
 }