//----==== PRIVATE ====----------------------------------------------------------------------

        private void AddToTopList(IMovieList sample)
        {
            if (_topLists != null)
            {
                if (!_topListFull)
                {
                    _topLists.Add(sample.Clone());

                    _topMin      = _topLists.Min(list => list.TotalEarnings);
                    _topListFull = _topLists.Count >= _topCount;
                }
                else
                {
                    // Is the sample greater than the top min?
                    // Don't add it if it's already in the list.

                    if (sample.TotalEarnings > _topMin &&
                        !_topLists.Any(list => list.GetHashCode() == sample.GetHashCode()))
                    {
                        // Remove the min and add a clone of the sample.

                        _topLists.Remove(_topLists.First(list => list.TotalEarnings == _topMin));
                        _topLists.Add(sample.Clone());

                        _topMin = _topLists.Min(list => list.TotalEarnings);
                    }
                }
            }
        }
        private void AddToListAlreadyGenerated(List <IMovie> movies)
        {
            var movieList = _movieListPrototype.Clone();

            movieList.Add(movies);

            _listGenerated.Add(movieList.GetHashCode());
        }
        /// <summary>
        /// The recursive call to find the best of the sample.
        /// </summary>
        /// <param name="best">The BEST earnings so far.</param>
        /// <param name="movieToAdd">The movie to be added to the list.</param>
        /// <param name="sample">Current movie list</param>
        /// <param name="movies">Sending in a smaller set each time reduces the scan on the full movie list.</param>
        /// <param name="remainingBudget"></param>
        /// <returns></returns>
        private IMovieList ChooseBest(IMovieList best, IMovie movieToAdd, IMovieList sample, IEnumerable <IMovie> movies, decimal remainingBudget)
        {
            if (sample == null)
            {
                sample = _movieListPrototype.Clone();
            }

            if (sample.CanAdd(movieToAdd))
            {
                // Add the movie to the clone that was passed in.
                sample.Add(movieToAdd);

                TotalComparisons++;

                var sampleHashCode = sample.GetHashCode();

                var beenProcessed = _processedHashes.Contains(sampleHashCode);

                // DON'T PROCESS the sample:
                //		If the sample is already full
                //		Already been processed.

                if (_topLists != null && !beenProcessed)
                {
                    AddToTopList(sample);
                }
                else if (best.TotalEarnings < sample.TotalEarnings)
                {
                    best = sample.Clone();
                }

                if (!sample.IsFull && !beenProcessed)
                {
                    remainingBudget -= movieToAdd.Cost;

                    var availableMovies = AvailableMovies(movies, remainingBudget).ToList();

                    foreach (var movie in availableMovies)
                    {
                        // Cloning is now cheaper than adding and removing.
                        best = ChooseBest(best, movie, sample.Clone(), availableMovies, remainingBudget);

                        //best = ChooseBest(best, movie, sample, availableMovies, remainingBudget);
                    }

                    // When finished processing this sub-list, store the list in the saved hashes.

                    _processedHashes.Add(sampleHashCode);
                }

                //sample.Remove(movieToAdd);
            }

            return(best);
        }
        public IMovieList ChooseBest()
        {
            IMovieList best = _movieListPrototype.Clone();

            var availableMovies = AvailableMovies(_movies, TotalCost).ToList();

            TotalComparisons = 0;
            _processedHashes.Clear();

            foreach (var movie in availableMovies)
            {
                best = ChooseBest(best, movie, null, availableMovies, TotalCost);
            }

            return(best);
        }
Beispiel #5
0
        public IMovieList ChooseBest2()
        {
            IMovieList best      = _movieListPrototype.Clone();
            var        idx       = 0;
            var        maxMovies = _movies.Count;

            TotalComparisons = 0;

            foreach (var movie in _movies)
            {
                _movieArray[idx++] = movie;
            }

            // Create all 15 ^ 8 possibilities. (Kinda brute force, but it's worth a try.)
            // Recursive calls COULD be slow, but investigate that later.
            // Trying to also minimize the memory footprint.
            // Figure out how to use Dominance Relations to clip out some of the noise.

            _topCineplexes   = new int[_topCount == 0 ? 1 : _topCount, ScreenCount + 1];                // Store the top cineplexes (add 1 for the total BO)
            _currentCineplex = new int[ScreenCount + 1];

            for (int cineIdx = 0; cineIdx < _currentCineplex.Length; cineIdx++)
            {
                _currentCineplex[cineIdx] = -1;
            }

            for (int dim1 = 0; dim1 < maxMovies; dim1++)
            {
                _currentCineplex[0] = dim1;
                _currentCineplex[8] = (int)(_movieArray[dim1]?.Earnings ?? 0m);

                // Only adding one movie shouldn't break the bank,
                // so you shouldn't have to check to see if it is over the TotalCost

                for (int dim2 = 0; dim2 < maxMovies; dim2++)
                {
                    var totalCost2 = _movieArray[dim1]?.Cost + _movieArray[dim2]?.Cost;

                    _currentCineplex[1]  = dim2;
                    _currentCineplex[8] += (int)(_movieArray[dim2]?.Earnings ?? 0m);

                    if (totalCost2 < TotalCost)
                    {
                        for (int dim3 = 0; dim3 < maxMovies; dim3++)
                        {
                            var totalCost3 = totalCost2 + _movieArray[dim3]?.Cost;

                            if (totalCost3 < TotalCost)
                            {
                                // Keep adding dimensions... 8 screens

                                if (_movieArray[dim1]?.Earnings + _movieArray[dim2]?.Earnings + _movieArray[dim3]?.Earnings > _topMin)
                                {
                                }
                            }
                            else
                            {
                                // Can't add any more.
                            }
                        }
                    }
                    else if (_currentCineplex[8] > _topMin)
                    {
                        ReplaceTopMinWithCurrent();
                    }

                    TotalComparisons++;
                }
            }

            // Add the top cineplex to the result.

            for (int cineIdx = 0; cineIdx < _currentCineplex.Length - 1; cineIdx++)
            {
                var movie = _topCineplexes[0, cineIdx] >= 0 ? _movieArray[_topCineplexes[0, cineIdx]] : null;

                if (movie != null)
                {
                    best.Add(movie);
                }
            }

            return(best);
        }