예제 #1
0
        public bool IsValidFor(ToyDistributionProblem problem)
        {
            bool b1 = List.Count == ToyDistributionProblem.ListLength;
            bool b2 = List.Keys.Distinct().Count() == ToyDistributionProblem.ListLength;
            bool b3 = List.Values.Distinct().Count() == ToyDistributionProblem.ListLength;
            bool b4 = !problem.Toys.Except(List.Values.Select(y => new Toy(y))).Any();
            bool b5 = !List.Values.Select(y => new Toy(y)).Except(problem.Toys).Any();
            bool b6 = problem.Children.Aggregate(seed: true,
                                                 (result, child) => result &&
                                                 List.ContainsKey(child.Name) &&
                                                 child.WishList.Toys.Contains(new Toy(List[child.Name])));

            return(b1 && b2 && b3 && b4 && b5 && b6);
        }
        public static ToyDistributionProblem Create()
        {
            while (true)
            {
                Toy[] toys = ToyNames.Select(x => new Toy(x)).ToArray();

                Dictionary <string, Toy> toysDictionary = toys.ToDictionary(x => x.Name);

                Child[] children = Names.Shuffle()
                                   .Take(ListLength)
                                   .Select(x => new Child(x, GetRandomWishList(toysDictionary.Select(t => t.Value).ToArray())))
                                   .ToArray();

                bool InternalCreate(out Child[] randomChildren1, out List <Toy> list)
                {
                    randomChildren1 = children;
                    InterestingToy[] byInterest = InterestingToys(randomChildren1);
                    if (byInterest.Take(5).Any(x => x.Counter == 1))
                    {
                        randomChildren1 = null;
                        list            = null;
                        return(false);
                    }

                    List <Toy> interestingToys = byInterest.SkipWhile(x => x.Counter > 2).Select(x => x.Toy).ToList();

                    list = new List <Toy>(ListLength);
                    foreach (Child c in randomChildren1.OrderBy(x => x.WishList.Toys.Count))
                    {
                        Toy first = c.WishList.Toys.FirstOrDefault(interestingToys.Contains);

                        if (first == null)
                        {
                            return(false);
                        }

                        interestingToys.Remove(first);

                        list.Add(first);
                    }

                    return(true);
                }

                if (InternalCreate(out Child[] randomChildren, out List <Toy> toyPool))
                {
                    var problem = new ToyDistributionProblem
                    {
                        Children = randomChildren.Shuffle().ToArray(),
                        Toys     = toyPool.Shuffle().ToArray(),
                    };

                    ToyDistributionProblem originalProblem = problem.DeepClone();

                    ToyDistributionSolution solution = problem.CreateSolution();

                    if (solution != null && solution.IsValidFor(originalProblem))
                    {
                        return(originalProblem);
                    }
                }

                // try again :D
            }
        }