/// <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); }
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"); } }