Exemplo n.º 1
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);
        }
Exemplo n.º 2
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);
        }