public static void GenerateMaTiInstances()
        {
            // Generate MaTi instances
            RandomizerSimple random = new RandomizerSimple(0);
            // Generate original MaTi set
            Instance tiny   = InstanceGenerator.GenerateMaTiLayoutTiny(random, new SettingConfiguration(), new ControlConfiguration());
            Instance small  = InstanceGenerator.GenerateMaTiLayoutSmall(random, new SettingConfiguration(), new ControlConfiguration());
            Instance medium = InstanceGenerator.GenerateMaTiLayoutMedium(random, new SettingConfiguration(), new ControlConfiguration());
            Instance large  = InstanceGenerator.GenerateMaTiLayoutLarge(random, new SettingConfiguration(), new ControlConfiguration());
            Instance huge   = InstanceGenerator.GenerateMaTiLayoutHuge(random, new SettingConfiguration(), new ControlConfiguration());

            InstanceIO.WriteInstance("MaTiTiny.xinst", tiny);
            InstanceIO.WriteInstance("MaTiSmall.xinst", small);
            InstanceIO.WriteInstance("MaTiMedium.xinst", medium);
            InstanceIO.WriteInstance("MaTiLarge.xinst", large);
            InstanceIO.WriteInstance("MaTiHuge.xinst", huge);
            // Generate alternative MaTi set
            InstanceIO.WriteInstance("MaTiPico.xinst", InstanceGenerator.GenerateMaTiLayoutPico(random, new SettingConfiguration(), new ControlConfiguration()));
            InstanceIO.WriteInstance("MaTiNano.xinst", InstanceGenerator.GenerateMaTiLayoutNano(random, new SettingConfiguration(), new ControlConfiguration()));
            InstanceIO.WriteInstance("MaTiMicro.xinst", InstanceGenerator.GenerateMaTiLayoutMicro(random, new SettingConfiguration(), new ControlConfiguration()));
            InstanceIO.WriteInstance("MaTiMilli.xinst", InstanceGenerator.GenerateMaTiLayoutMilli(random, new SettingConfiguration(), new ControlConfiguration()));
            InstanceIO.WriteInstance("MaTiCenti.xinst", InstanceGenerator.GenerateMaTiLayoutCenti(random, new SettingConfiguration(), new ControlConfiguration()));
            InstanceIO.WriteInstance("MaTiDeca.xinst", InstanceGenerator.GenerateMaTiLayoutDeca(random, new SettingConfiguration(), new ControlConfiguration()));
            InstanceIO.WriteInstance("MaTiHecto.xinst", InstanceGenerator.GenerateMaTiLayoutHecto(random, new SettingConfiguration(), new ControlConfiguration()));
            InstanceIO.WriteInstance("MaTiKilo.xinst", InstanceGenerator.GenerateMaTiLayoutKilo(random, new SettingConfiguration(), new ControlConfiguration()));
            InstanceIO.WriteInstance("MaTiMega.xinst", InstanceGenerator.GenerateMaTiLayoutMega(random, new SettingConfiguration(), new ControlConfiguration()));
            InstanceIO.WriteInstance("MaTiGiga.xinst", InstanceGenerator.GenerateMaTiLayoutGiga(random, new SettingConfiguration(), new ControlConfiguration()));
        }
Exemple #2
0
        /// <summary>
        /// Generates a list of orders and bundles. TODO this has to be adapted to handle simple items too. While doing so use a configuration for all the settings and feed it to the GUI.
        /// </summary>
        /// <param name="wordFile">The word file.</param>
        /// <param name="baseColors">The colors</param>
        /// <param name="baseColorProbabilities"></param>
        /// <param name="seed"></param>
        /// <param name="minTime"></param>
        /// <param name="maxTime"></param>
        /// <param name="orderCount"></param>
        /// <param name="minItemWeight"></param>
        /// <param name="maxItemWeight"></param>
        /// <param name="minPositionCount"></param>
        /// <param name="maxPositionCount"></param>
        /// <param name="minBundleSize"></param>
        /// <param name="maxBundleSize"></param>
        /// <param name="relativeBundleCount"></param>
        /// <returns></returns>
        public static OrderList GenerateOrders(
            string wordFile,
            LetterColors[] baseColors,
            IDictionary <LetterColors, double> baseColorProbabilities,
            int seed,
            double minTime,
            double maxTime,
            int orderCount,
            double minItemWeight,
            double maxItemWeight,
            int minPositionCount,
            int maxPositionCount,
            int minBundleSize,
            int maxBundleSize,
            double relativeBundleCount)
        {
            // Init random
            IRandomizer randomizer = new RandomizerSimple(seed);
            // Read the words that serve as the base for the item types
            List <string> baseWords = new List <string>();

            using (StreamReader sr = new StreamReader(wordFile))
            {
                string line = "";
                while ((line = sr.ReadLine()) != null)
                {
                    baseWords.Add(line.Trim());
                }
            }
            baseWords = baseWords.Distinct().ToList();
            List <char> baseLetters = baseWords.SelectMany(w => w.ToCharArray()).Distinct().ToList();

            // --> Build all necessary item descriptions
            OrderList orderList = new OrderList(ItemType.Letter);
            int       currentItemDescriptionID = 0;

            foreach (var letter in baseLetters)
            {
                foreach (var color in baseColors)
                {
                    orderList.ItemDescriptions.Add(new ColoredLetterDescription(null)
                    {
                        ID = currentItemDescriptionID++, Color = color, Letter = letter, Weight = randomizer.NextDouble(minItemWeight, maxItemWeight)
                    });
                }
            }

            // --> Generate orders randomly
            for (int i = 0; i < orderCount; i++)
            {
                // Choose a random word from the list
                string word  = baseWords[randomizer.NextInt(baseWords.Count)];
                Order  order = new Order()
                {
                    TimeStamp = randomizer.NextDouble(minTime, maxTime)
                };

                // Add each letter to originalLetters
                for (int j = 0; j < word.Length; j++)
                {
                    // Get color based on distribution
                    double r = randomizer.NextDouble();
                    // Choose a default one just incase
                    LetterColors chosenColor = baseColors.First();
                    // Go through and check the range of each color, pulling random number down to the current range
                    foreach (var c in baseColors)
                    {
                        if (baseColorProbabilities[c] > r)
                        {
                            chosenColor = c; break;
                        }
                        r -= baseColorProbabilities[c];
                    }

                    // Add letter to order
                    order.AddPosition(
                        orderList.ItemDescriptions.Single(d => (d as ColoredLetterDescription).Letter == word[j] && (d as ColoredLetterDescription).Color == chosenColor),
                        randomizer.NextInt(minPositionCount, maxPositionCount + 1));
                }

                // Add the order
                orderList.Orders.Add(order);
            }

            // Get probability of item-descriptions
            Dictionary <ItemDescription, int> itemFrequency = orderList.Orders.SelectMany(o => o.Positions).GroupBy(p => p.Key).ToDictionary(i => i.Key, i => i.Sum(e => e.Value));
            double overallCount = itemFrequency.Sum(f => f.Value);
            Dictionary <ItemDescription, double> itemProbability = itemFrequency.ToDictionary(k => k.Key, v => (double)itemFrequency[v.Key] / overallCount);

            // --> Generate appropriate bundles for this list
            int itemsOrdered = (int)(orderList.Orders.Sum(o => o.Positions.Sum(p => p.Value)) * relativeBundleCount); int newItems = 0; int currentBundleID = 0;

            for (int itemsStored = 0; itemsStored < itemsOrdered; itemsStored += newItems)
            {
                // Draw a random item description based on the frequency of the items
                ItemDescription     newBundleDescription = RandomizerHelper.DrawRandomly <ItemDescription>(itemProbability, randomizer);
                int                 bundleSize           = randomizer.NextInt(minBundleSize, maxBundleSize);
                double              timeStamp            = randomizer.NextDouble(minTime, maxTime);
                ColoredLetterBundle bundle = new ColoredLetterBundle(null)
                {
                    ID = currentBundleID++, ItemDescription = newBundleDescription, TimeStamp = timeStamp, ItemCount = bundleSize
                };
                // Add bundle to list
                orderList.Bundles.Add(bundle);
                // Signal new items
                newItems = bundleSize;
            }

            // Order the orders and bundles
            orderList.Sort();

            // Return it
            return(orderList);
        }
Exemple #3
0
        /// <summary>
        /// Generates a complete configuration for the simple item generator.
        /// </summary>
        /// <param name="preConfig">The pre-configuration defining characteristics of the actual configuration.</param>
        /// <returns>The complete configuration.</returns>
        public static SimpleItemGeneratorConfiguration GenerateSimpleItemConfiguration(SimpleItemGeneratorPreConfiguration preConfig)
        {
            // Init
            SimpleItemGeneratorConfiguration config = new SimpleItemGeneratorConfiguration()
            {
                DefaultWeight     = preConfig.DefaultWeight,
                DefaultCoWeight   = preConfig.DefaultCoWeight,
                ProbToUseCoWeight = preConfig.ProbToUseCoWeight
            };
            RandomizerSimple             randomizer       = new RandomizerSimple(0);
            List <SimpleItemDescription> itemDescriptions = new List <SimpleItemDescription>();
            List <Tuple <SimpleItemDescription, double> > itemDescriptionWeights = new List <Tuple <SimpleItemDescription, double> >();
            List <Tuple <SimpleItemDescription, SimpleItemDescription, double> > itemDescriptionCoWeights = new List <Tuple <SimpleItemDescription, SimpleItemDescription, double> >();

            // Add comment
            config.Description = string.Join(",", typeof(SimpleItemGeneratorPreConfiguration).GetFields().Select(f =>
            {
                string fieldValue;
                if (f.GetValue(preConfig) is double)
                {
                    fieldValue = ((double)f.GetValue(preConfig)).ToString(IOConstants.FORMATTER);
                }
                else
                {
                    fieldValue = f.GetValue(preConfig).ToString();
                }
                return(f.Name + "=" + fieldValue);
            }));

            // Generate a set of item-descriptions
            for (int i = 0; i < preConfig.ItemDescriptionCount; i++)
            {
                // Generate next item
                SimpleItemDescription description = new SimpleItemDescription(null)
                {
                    ID = i
                };
                // Randomly weight the item
                double itemDescriptionWeight = 0;
                switch (preConfig.WeightDistributionType)
                {
                case ItemDescriptionWeightDistributionType.Normal:
                    itemDescriptionWeight = randomizer.NextNormalDouble(preConfig.ItemWeightMu, preConfig.ItemWeightSigma, preConfig.ItemWeightLB, preConfig.ItemWeightUB);
                    break;

                case ItemDescriptionWeightDistributionType.Uniform:
                    itemDescriptionWeight = randomizer.NextDouble(preConfig.ItemWeightLB, preConfig.ItemWeightUB);
                    break;

                default: throw new ArgumentException("Unknown distribution: " + preConfig.WeightDistributionType);
                }
                description.Weight = itemDescriptionWeight;
                // Randomly determine bundle size of the item
                if (preConfig.SupplyBundleSize)
                {
                    int itemDescriptionBundleSize = 0;
                    switch (preConfig.BundleSizeDistributionType)
                    {
                    case ItemDescriptionBundleSizeDistributionType.Normal:
                        itemDescriptionBundleSize = randomizer.NextNormalInt(preConfig.BundleSizeMu, preConfig.BundleSizeSigma, preConfig.BundleSizeLB, preConfig.BundleSizeUB);
                        break;

                    case ItemDescriptionBundleSizeDistributionType.Uniform:
                        itemDescriptionBundleSize = randomizer.NextInt(preConfig.BundleSizeLB, preConfig.BundleSizeUB + 1);
                        break;

                    default: throw new ArgumentException("Unknown distribution: " + preConfig.BundleSizeDistributionType);
                    }
                    description.BundleSize = itemDescriptionBundleSize;
                }
                // Add a random hue value to distinguish the item from others
                description.Hue = randomizer.NextDouble(360);
                // Add it
                itemDescriptions.Add(description);
                // Set a weight for the probability of the item
                double weight = 0;
                switch (preConfig.ProbWeightDistributionType)
                {
                case ItemDescriptionProbabilityWeightDistributionType.Constant:
                    weight = preConfig.ProbabilityWeightConstant;
                    break;

                case ItemDescriptionProbabilityWeightDistributionType.Uniform:
                    weight = randomizer.NextDouble(preConfig.ProbabilityWeightUniformMin, preConfig.ProbabilityWeightUniformMax);
                    break;

                case ItemDescriptionProbabilityWeightDistributionType.Normal:
                    weight = randomizer.NextNormalDouble(preConfig.ProbabilityWeightNormalMu, preConfig.ProbabilityWeightNormalSigma, preConfig.ProbabilityWeightLB, preConfig.ProbabilityWeightUB);
                    break;

                case ItemDescriptionProbabilityWeightDistributionType.Exponential:
                    weight = randomizer.NextExponentialDouble(preConfig.ProbabilityWeightExpLambda, preConfig.ProbabilityWeightLB, preConfig.ProbabilityWeightUB);
                    break;

                case ItemDescriptionProbabilityWeightDistributionType.Gamma:
                    weight = randomizer.NextGammaDouble(preConfig.ProbabilityWeightGammaK, preConfig.ProbabilityWeightGammaTheta, preConfig.ProbabilityWeightLB, preConfig.ProbabilityWeightUB);
                    break;

                default: throw new ArgumentException("Unknown distribution: " + preConfig.ProbWeightDistributionType);
                }
                itemDescriptionWeights.Add(new Tuple <SimpleItemDescription, double>(description, weight));
            }

            // Equally distribute items over two-dimensional space
            Dictionary <SimpleItemDescription, Tuple <double, double> > itemDescriptionPosition = new Dictionary <SimpleItemDescription, Tuple <double, double> >();

            foreach (var description in itemDescriptions)
            {
                itemDescriptionPosition[description] = new Tuple <double, double>(randomizer.NextDouble(), randomizer.NextDouble());
            }

            // Plot the distribution for reference
            GnuPlotter.Plot2DPoints(
                "itemdistribution",
                new List <Tuple <string, IEnumerable <Tuple <double, double> > > >()
            {
                new Tuple <string, IEnumerable <Tuple <double, double> > >("Item locations in 2D", itemDescriptionPosition.Values)
            },
                "item distribution for co-probability emulation");

            // Set conditional weights
            double maxDistance = Distances.CalculateEuclid(0, 0, 1, 1);

            foreach (var description in itemDescriptions.OrderBy(d => randomizer.NextDouble()).Take((int)(itemDescriptions.Count * preConfig.GivenCoWeights)))
            {
                foreach (var otherDescription in itemDescriptions.OrderBy(d => randomizer.NextDouble()).Take((int)(itemDescriptions.Count * preConfig.GivenCoWeights)))
                {
                    itemDescriptionCoWeights.Add(new Tuple <SimpleItemDescription, SimpleItemDescription, double>(
                                                     description,
                                                     otherDescription,
                                                     maxDistance - Distances.CalculateEuclid(
                                                         itemDescriptionPosition[description].Item1, itemDescriptionPosition[description].Item2,
                                                         itemDescriptionPosition[otherDescription].Item1, itemDescriptionPosition[otherDescription].Item2)));
                }
            }

            // Submit all
            config.ItemDescriptions = itemDescriptions.Select(d => new Skvp <int, double>()
            {
                Key = d.ID, Value = d.Hue
            }).ToList();
            config.ItemDescriptionWeights = itemDescriptions.Select(d => new Skvp <int, double>()
            {
                Key = d.ID, Value = d.Weight
            }).ToList();
            if (preConfig.SupplyBundleSize)
            {
                config.ItemDescriptionBundleSizes = itemDescriptions.Select(d => new Skvp <int, int>()
                {
                    Key = d.ID, Value = d.BundleSize
                }).ToList();
            }
            config.ItemWeights = itemDescriptionWeights.Select(d => new Skvp <int, double>()
            {
                Key = d.Item1.ID, Value = d.Item2
            }).ToList();
            config.ItemCoWeights = itemDescriptionCoWeights.Select(d => new Skkvt <int, int, double>()
            {
                Key1 = d.Item1.ID, Key2 = d.Item2.ID, Value = d.Item3
            }).ToList();

            // Name it
            config.Name = config.GetMetaInfoBasedName();

            // Return it
            return(config);
        }
Exemple #4
0
        public static void TestInputTranslationTimeDependentPoisson()
        {
            SettingConfiguration config = new SettingConfiguration();

            config.InventoryConfiguration.PoissonInventoryConfiguration = new PoissonInventoryConfiguration(new DefaultConstructorIdentificationClass());
            IRandomizer randomizer    = new RandomizerSimple(0);
            int         oStationCount = 3;
            int         iStationCount = 3;
            // --> Instantiate poisson generator for orders
            // Calculate instance-specific factor to adapt the rates
            List <KeyValuePair <double, double> > relativeOrderWeights = new List <KeyValuePair <double, double> >();

            for (int i = 0; i < config.InventoryConfiguration.PoissonInventoryConfiguration.TimeDependentOrderWeights.Count; i++)
            {
                relativeOrderWeights.Add(new KeyValuePair <double, double>(
                                             i > 0 ?
                                             config.InventoryConfiguration.PoissonInventoryConfiguration.TimeDependentOrderWeights[i].Key - config.InventoryConfiguration.PoissonInventoryConfiguration.TimeDependentOrderWeights[i - 1].Key :
                                             config.InventoryConfiguration.PoissonInventoryConfiguration.TimeDependentOrderWeights[i].Key,
                                             config.InventoryConfiguration.PoissonInventoryConfiguration.TimeDependentOrderWeights[i].Value
                                             ));
            }
            double unadjustedAverageOrderFrequency =
                relativeOrderWeights.Sum(w => w.Key * w.Value) /
                config.InventoryConfiguration.PoissonInventoryConfiguration.MaxTimeForTimeDependentOrderRates;
            double aimedAverageOrderFrequency =
                TimeSpan.FromSeconds(config.InventoryConfiguration.PoissonInventoryConfiguration.MaxTimeForTimeDependentOrderRates).TotalHours *
                config.InventoryConfiguration.PoissonInventoryConfiguration.AverageOrdersPerHourAndStation *oStationCount / config.InventoryConfiguration.PoissonInventoryConfiguration.MaxTimeForTimeDependentOrderRates;
            double orderSteerFactor = aimedAverageOrderFrequency / unadjustedAverageOrderFrequency;
            // Initiate order poisson generator
            PoissonGenerator TimeDependentOrderPoissonGenerator = new PoissonGenerator(
                randomizer,
                config.InventoryConfiguration.PoissonInventoryConfiguration.MaxTimeForTimeDependentOrderRates,
                config.InventoryConfiguration.PoissonInventoryConfiguration.TimeDependentOrderWeights.Select(w =>
                                                                                                             new KeyValuePair <double, double>(w.Key, orderSteerFactor * w.Value)));
            // --> Instantiate poisson generator for bundles
            // Calculate instance-specific factor to adapt the rates
            List <KeyValuePair <double, double> > relativeBundleWeights = new List <KeyValuePair <double, double> >();

            for (int i = 0; i < config.InventoryConfiguration.PoissonInventoryConfiguration.TimeDependentBundleWeights.Count; i++)
            {
                relativeBundleWeights.Add(new KeyValuePair <double, double>(
                                              i > 0 ?
                                              config.InventoryConfiguration.PoissonInventoryConfiguration.TimeDependentBundleWeights[i].Key - config.InventoryConfiguration.PoissonInventoryConfiguration.TimeDependentBundleWeights[i - 1].Key :
                                              config.InventoryConfiguration.PoissonInventoryConfiguration.TimeDependentBundleWeights[i].Key,
                                              config.InventoryConfiguration.PoissonInventoryConfiguration.TimeDependentBundleWeights[i].Value
                                              ));
            }
            double unadjustedAverageBundleFrequency =
                relativeBundleWeights.Sum(w => w.Key * w.Value) /
                config.InventoryConfiguration.PoissonInventoryConfiguration.MaxTimeForTimeDependentBundleRates;
            double aimedAverageBundleFrequency =
                TimeSpan.FromSeconds(config.InventoryConfiguration.PoissonInventoryConfiguration.MaxTimeForTimeDependentBundleRates).TotalHours *
                config.InventoryConfiguration.PoissonInventoryConfiguration.AverageBundlesPerHourAndStation *iStationCount / config.InventoryConfiguration.PoissonInventoryConfiguration.MaxTimeForTimeDependentBundleRates;
            double bundleSteerFactor = aimedAverageBundleFrequency / unadjustedAverageBundleFrequency;
            // Initiate bundle poisson generator
            PoissonGenerator TimeDependentBundlePoissonGenerator = new PoissonGenerator(
                randomizer,
                config.InventoryConfiguration.PoissonInventoryConfiguration.MaxTimeForTimeDependentBundleRates,
                config.InventoryConfiguration.PoissonInventoryConfiguration.TimeDependentBundleWeights.Select(w =>
                                                                                                              new KeyValuePair <double, double>(w.Key, bundleSteerFactor * w.Value)));
            // Initiate time-independent order poisson generator
            double orderRate = PoissonGenerator.TranslateIntoRateParameter(
                TimeSpan.FromHours(1),
                config.InventoryConfiguration.PoissonInventoryConfiguration.AverageOrdersPerHourAndStation * oStationCount);
            PoissonGenerator TimeIndependentOrderPoissonGenerator = new PoissonGenerator(randomizer, orderRate);
            // Initiate time-independent bundle poisson generator
            double bundleRate = PoissonGenerator.TranslateIntoRateParameter(
                TimeSpan.FromHours(1),
                config.InventoryConfiguration.PoissonInventoryConfiguration.AverageBundlesPerHourAndStation * iStationCount);
            PoissonGenerator TimeIndependentBundlePoissonGenerator = new PoissonGenerator(randomizer, bundleRate);

            // --> Test
            int           simulationHours          = 2 * 24;
            double        simulationTime           = simulationHours * 60 * 60;
            double        currentTime              = 0;
            List <double> timeDependentBundleSteps = new List <double>();

            while (currentTime < simulationTime)
            {
                currentTime += TimeDependentBundlePoissonGenerator.Next(currentTime);
                timeDependentBundleSteps.Add(currentTime);
            }
            currentTime = 0;
            List <double> timeDependentOrderSteps = new List <double>();

            while (currentTime < simulationTime)
            {
                currentTime += TimeDependentOrderPoissonGenerator.Next(currentTime);
                timeDependentOrderSteps.Add(currentTime);
            }
            currentTime = 0;
            List <double> timeIndependentBundleSteps = new List <double>();

            while (currentTime < simulationTime)
            {
                currentTime += TimeIndependentBundlePoissonGenerator.Next(currentTime);
                timeIndependentBundleSteps.Add(currentTime);
            }
            currentTime = 0;
            List <double> timeIndependentOrderSteps = new List <double>();

            while (currentTime < simulationTime)
            {
                currentTime += TimeIndependentOrderPoissonGenerator.Next(currentTime);
                timeIndependentOrderSteps.Add(currentTime);
            }

            // Output graph
            WriteHourBasedGraph(
                new List <List <double> >()
            {
                timeDependentBundleSteps, timeDependentOrderSteps, timeIndependentBundleSteps, timeIndependentOrderSteps
            },
                new List <string>()
            {
                "Bundles (time-dependent)", "Orders (time-dependent)", "Bundles (time-independent)", "Orders (time-independent)"
            },
                simulationHours);
        }
Exemple #5
0
        public static void TestGenerateNormalDistribution()
        {
            // Prepare
            RandomizerSimple randomizer = new RandomizerSimple(0);
            int randomNumberCount       = 5000;

            // --> Double related
            List <List <double> > randomNumbers        = new List <List <double> >();
            List <List <int> >    randomNumbersRounded = new List <List <int> >();
            List <Tuple <double, double, double, double> > meanStdTuples = new List <Tuple <double, double, double, double> >()
            {
                new Tuple <double, double, double, double>(1, 2, double.NegativeInfinity, double.PositiveInfinity),
                new Tuple <double, double, double, double>(10, 0.5, double.NegativeInfinity, double.PositiveInfinity),
                new Tuple <double, double, double, double>(-7, 5, double.NegativeInfinity, double.PositiveInfinity),
                new Tuple <double, double, double, double>(15, 5, 14.5, double.PositiveInfinity),
                new Tuple <double, double, double, double>(30, 2, 29, 32),
            };

            // Draw random double numbers
            for (int j = 0; j < meanStdTuples.Count; j++)
            {
                randomNumbers.Add(new List <double>());
                for (int i = 0; i < randomNumberCount; i++)
                {
                    randomNumbers[j].Add(randomizer.NextNormalDouble(meanStdTuples[j].Item1, meanStdTuples[j].Item2, meanStdTuples[j].Item3, meanStdTuples[j].Item4));
                }
            }

            // Round them to get ints
            for (int j = 0; j < meanStdTuples.Count; j++)
            {
                randomNumbersRounded.Add(new List <int>());
                for (int i = 0; i < randomNumbers[j].Count; i++)
                {
                    randomNumbersRounded[j].Add((int)Math.Round(randomNumbers[j][i]));
                }
            }

            // Write them
            string fileNameBase = "normaldistribution";

            for (int i = 0; i < meanStdTuples.Count; i++)
            {
                using (StreamWriter sw = new StreamWriter(fileNameBase + i.ToString() + ".dat"))
                {
                    foreach (var numberGroup in randomNumbersRounded[i].GroupBy(e => e).OrderBy(g => g.Key))
                    {
                        sw.WriteLine(numberGroup.Key.ToString() + " " + numberGroup.Count().ToString());
                    }
                }
            }

            // Write plot script
            using (StreamWriter sw = new StreamWriter(fileNameBase + ".gp"))
            {
                sw.WriteLine("reset");
                sw.WriteLine("# Output definition");
                sw.WriteLine("set terminal postscript clip color eps \"Arial\" 14");
                sw.WriteLine("# Parameters");
                sw.WriteLine("set key left top Left");
                sw.WriteLine("set xlabel \"Value\"");
                sw.WriteLine("set ylabel \"Count\"");
                sw.WriteLine("set grid");
                sw.WriteLine("set style fill solid 0.25");
                sw.WriteLine("# Line-Styles");
                sw.WriteLine("set style line 1 linetype 1 linecolor rgb \"#474749\" linewidth 1");
                sw.WriteLine("set style line 2 linetype 1 linecolor rgb \"#7090c8\" linewidth 1");
                sw.WriteLine("set style line 3 linetype 1 linecolor rgb \"#42b449\" linewidth 1");
                sw.WriteLine("set style line 4 linetype 1 linecolor rgb \"#f7cb38\" linewidth 1");
                sw.WriteLine("set style line 5 linetype 1 linecolor rgb \"#db4a37\" linewidth 1");
                sw.WriteLine("set title \"Normal distribution - Test\"");
                sw.WriteLine("set output \"" + fileNameBase + ".eps\"");
                sw.WriteLine("plot \\");
                for (int i = 0; i < meanStdTuples.Count; i++)
                {
                    if (i < meanStdTuples.Count - 1)
                    {
                        sw.WriteLine("\"" + fileNameBase + i.ToString() + ".dat\" u 1:2 w boxes linestyle " + ((i % 5) + 1) +
                                     " t \"mean: " + meanStdTuples[i].Item1.ToString(IOConstants.FORMATTER) +
                                     " std: " + meanStdTuples[i].Item2.ToString(IOConstants.FORMATTER) +
                                     " lb: " + (double.IsNegativeInfinity(meanStdTuples[i].Item3) ? "na" : meanStdTuples[i].Item3.ToString(IOConstants.FORMATTER)) +
                                     " ub: " + (double.IsPositiveInfinity(meanStdTuples[i].Item4) ? "na" : meanStdTuples[i].Item4.ToString(IOConstants.FORMATTER)) + "\", \\");
                    }
                    else
                    {
                        sw.WriteLine("\"" + fileNameBase + i.ToString() + ".dat\" u 1:2 w boxes linestyle " + ((i % 5) + 1) +
                                     " t \"mean: " + meanStdTuples[i].Item1.ToString(IOConstants.FORMATTER) +
                                     " std: " + meanStdTuples[i].Item2.ToString(IOConstants.FORMATTER) +
                                     " lb: " + (double.IsNegativeInfinity(meanStdTuples[i].Item3) ? "na" : meanStdTuples[i].Item3.ToString(IOConstants.FORMATTER)) +
                                     " ub: " + (double.IsPositiveInfinity(meanStdTuples[i].Item4) ? "na" : meanStdTuples[i].Item4.ToString(IOConstants.FORMATTER)) + "\"");
                    }
                }
                sw.WriteLine("reset");
                sw.WriteLine("exit");
            }
            using (StreamWriter sw = new StreamWriter(fileNameBase + ".cmd"))
            {
                sw.WriteLine("gnuplot " + fileNameBase + ".gp");
            }

            // --> Int related
            int randomNumberCountInt            = 200;
            List <List <int> > randomNumbersInt = new List <List <int> >();
            List <Tuple <double, double, int, int> > meanStdTuplesInt = new List <Tuple <double, double, int, int> >()
            {
                new Tuple <double, double, int, int>(1, 1.5, 1, 4),
                new Tuple <double, double, int, int>(4, 0.5, 0, int.MaxValue),
                new Tuple <double, double, int, int>(-7, 3, int.MinValue, int.MaxValue),
            };

            // Draw random int numbers
            for (int j = 0; j < meanStdTuplesInt.Count; j++)
            {
                randomNumbersInt.Add(new List <int>());
                for (int i = 0; i < randomNumberCountInt; i++)
                {
                    randomNumbersInt[j].Add(randomizer.NextNormalInt(meanStdTuplesInt[j].Item1, meanStdTuplesInt[j].Item2, meanStdTuplesInt[j].Item3, meanStdTuplesInt[j].Item4));
                }
            }

            // Write them
            string fileNameBaseInt = "normaldistributionint";

            for (int i = 0; i < meanStdTuplesInt.Count; i++)
            {
                using (StreamWriter sw = new StreamWriter(fileNameBaseInt + i.ToString() + ".dat"))
                {
                    foreach (var numberGroup in randomNumbersInt[i].GroupBy(e => e).OrderBy(g => g.Key))
                    {
                        sw.WriteLine(numberGroup.Key.ToString() + " " + numberGroup.Count().ToString());
                    }
                }
            }

            // Write plot script
            using (StreamWriter sw = new StreamWriter(fileNameBaseInt + ".gp"))
            {
                sw.WriteLine("reset");
                sw.WriteLine("# Output definition");
                sw.WriteLine("set terminal postscript clip color eps \"Arial\" 14");
                sw.WriteLine("# Parameters");
                sw.WriteLine("set key left top Left");
                sw.WriteLine("set xlabel \"Value\"");
                sw.WriteLine("set ylabel \"Count\"");
                sw.WriteLine("set grid");
                sw.WriteLine("set style fill solid 0.25");
                sw.WriteLine("# Line-Styles");
                sw.WriteLine("set style line 1 linetype 1 linecolor rgb \"#474749\" linewidth 1");
                sw.WriteLine("set style line 2 linetype 1 linecolor rgb \"#7090c8\" linewidth 1");
                sw.WriteLine("set style line 3 linetype 1 linecolor rgb \"#42b449\" linewidth 1");
                sw.WriteLine("set style line 4 linetype 1 linecolor rgb \"#f7cb38\" linewidth 1");
                sw.WriteLine("set style line 5 linetype 1 linecolor rgb \"#db4a37\" linewidth 1");
                sw.WriteLine("set title \"Normal distribution (int) - Test\"");
                sw.WriteLine("set output \"" + fileNameBaseInt + ".eps\"");
                sw.WriteLine("plot \\");
                for (int i = 0; i < meanStdTuplesInt.Count; i++)
                {
                    if (i < meanStdTuplesInt.Count - 1)
                    {
                        sw.WriteLine("\"" + fileNameBaseInt + i.ToString() + ".dat\" u 1:2 w boxes linestyle " + ((i % 5) + 1) +
                                     " t \"mean: " + meanStdTuplesInt[i].Item1.ToString(IOConstants.FORMATTER) +
                                     " std: " + meanStdTuplesInt[i].Item2.ToString(IOConstants.FORMATTER) +
                                     " lb: " + ((int.MinValue == meanStdTuplesInt[i].Item3) ? "na" : meanStdTuplesInt[i].Item3.ToString(IOConstants.FORMATTER)) +
                                     " ub: " + ((int.MaxValue == meanStdTuplesInt[i].Item4) ? "na" : meanStdTuplesInt[i].Item4.ToString(IOConstants.FORMATTER)) + "\", \\");
                    }
                    else
                    {
                        sw.WriteLine("\"" + fileNameBaseInt + i.ToString() + ".dat\" u 1:2 w boxes linestyle " + ((i % 5) + 1) +
                                     " t \"mean: " + meanStdTuplesInt[i].Item1.ToString(IOConstants.FORMATTER) +
                                     " std: " + meanStdTuplesInt[i].Item2.ToString(IOConstants.FORMATTER) +
                                     " lb: " + ((int.MinValue == meanStdTuplesInt[i].Item3) ? "na" : meanStdTuplesInt[i].Item3.ToString(IOConstants.FORMATTER)) +
                                     " ub: " + ((int.MaxValue == meanStdTuplesInt[i].Item4) ? "na" : meanStdTuplesInt[i].Item4.ToString(IOConstants.FORMATTER)) + "\"");
                    }
                }
                sw.WriteLine("reset");
                sw.WriteLine("exit");
            }
            using (StreamWriter sw = new StreamWriter(fileNameBaseInt + ".cmd"))
            {
                sw.WriteLine("gnuplot " + fileNameBaseInt + ".gp");
            }
        }