Ejemplo n.º 1
0
        public Solution CreateInitSolution(Problem problem, Random rnd)
        {
            var cacheLoads = new CacheLoad[problem.C];

            for (var c = 0; c < problem.C; c++)
            {
                var videos = new HashSet <int>();
                var size   = 0ul;

                while (true)
                {
                    var video = problem.Videos.Where(v => v.Size <= problem.X - size).RandomElement(rnd, false);
                    if (video == null)
                    {
                        break;
                    }
                    videos.Add(video.VideoId);
                    size += video.Size;
                }

                cacheLoads[c] = new CacheLoad
                {
                    CacheId  = c,
                    VideoIds = videos
                };
            }

            return(new Solution
            {
                CacheLoads = cacheLoads
            });
        }
Ejemplo n.º 2
0
        public Solution GetNeighboor(Problem problem, Solution solution, Random rnd)
        {
            var cacheLoads = solution.CacheLoads;

            while (true)
            {
                var p = rnd.NextDouble();

                if (p < 0.25)
                {
                    // Add video
                    var cacheLoadIndex = cacheLoads.RandomIndex(rnd);
                    var cacheLoad      = cacheLoads[cacheLoadIndex];

                    var size  = cacheLoad.VideoIds.Select(v => problem.Videos[v].Size).Sum();
                    var video = problem.Videos.Where(v => v.Size <= problem.X - size).RandomElement(rnd, false);
                    if (video != null)
                    {
                        var newLoads = cacheLoads.ShallowClone();
                        newLoads[cacheLoadIndex] = new CacheLoad
                        {
                            CacheId  = cacheLoad.CacheId,
                            VideoIds = cacheLoad.VideoIds.ToHashSet(),
                        };
                        newLoads[cacheLoadIndex].VideoIds.Add(video.VideoId);
                        return(new Solution {
                            CacheLoads = newLoads
                        });
                    }
                }
                else if (p < 0.5)
                {
                    // Swap video between server and pool
                    var cacheLoadIndex = cacheLoads.RandomIndex(rnd);
                    var cacheLoad      = cacheLoads[cacheLoadIndex];

                    if (cacheLoad.VideoIds.Count == 0)
                    {
                        continue;
                    }

                    var solVideoId = cacheLoad.VideoIds.RandomElement(rnd);
                    var size       = cacheLoad.VideoIds.Select(v => problem.Videos[v].Size).Sum() - problem.Videos[solVideoId].Size;

                    var poolVideo = problem.Videos.Where(v => v.Size <= problem.X - size).RandomElement(rnd, false);
                    if (poolVideo == null)
                    {
                        continue;
                    }

                    var newLoads = cacheLoads.ShallowClone();
                    newLoads[cacheLoadIndex] = new CacheLoad
                    {
                        CacheId  = cacheLoad.CacheId,
                        VideoIds = cacheLoad.VideoIds.ToHashSet(),
                    };
                    newLoads[cacheLoadIndex].VideoIds.Remove(solVideoId);
                    newLoads[cacheLoadIndex].VideoIds.Add(poolVideo.VideoId);
                    return(new Solution {
                        CacheLoads = newLoads
                    });
                }
                else if (p < 0.85)
                {
                    // Swap video between servers
                    var cacheLoadIndexOne = cacheLoads.IndicesWhere(c => c.VideoIds.Count > 0).RandomElement(rnd, false);
                    var cacheLoadIndexTwo = cacheLoads.IndicesWhere(c => c.VideoIds.Count > 0).RandomElement(rnd, false);

                    if (cacheLoadIndexOne == cacheLoadIndexTwo ||
                        cacheLoads[cacheLoadIndexOne].VideoIds.Count == 0 ||
                        cacheLoads[cacheLoadIndexTwo].VideoIds.Count == 0)
                    {
                        continue;
                    }

                    var cacheLoadOne = cacheLoads[cacheLoadIndexOne];
                    var cacheLoadTwo = cacheLoads[cacheLoadIndexTwo];

                    var videoOneId   = cacheLoadOne.VideoIds.RandomElement(rnd);
                    var videoOneSize = problem.Videos[videoOneId].Size;
                    var sizeOne      = cacheLoadOne.VideoIds.Select(v => problem.Videos[v].Size).Sum() - videoOneSize;

                    var sizeTwoAll = cacheLoadTwo.VideoIds.Select(v => problem.Videos[v].Size).Sum();

                    var videoTwo = cacheLoadTwo.VideoIds.Select(v => problem.Videos[v]).Where(v => sizeTwoAll - v.Size + videoOneSize <= problem.X).RandomElement(rnd, false);

                    if (videoTwo == null)
                    {
                        continue;
                    }
                    if (sizeOne + videoTwo.Size > problem.X)
                    {
                        continue;
                    }

                    var newLoads = cacheLoads.ShallowClone();
                    newLoads[cacheLoadIndexOne] = new CacheLoad
                    {
                        CacheId  = cacheLoadOne.CacheId,
                        VideoIds = cacheLoadOne.VideoIds.ToHashSet(),
                    };
                    newLoads[cacheLoadIndexTwo] = new CacheLoad
                    {
                        CacheId  = cacheLoadTwo.CacheId,
                        VideoIds = cacheLoadTwo.VideoIds.ToHashSet(),
                    };
                    newLoads[cacheLoadIndexOne].VideoIds.Remove(videoOneId);
                    newLoads[cacheLoadIndexOne].VideoIds.Add(videoTwo.VideoId);
                    newLoads[cacheLoadIndexTwo].VideoIds.Remove(videoTwo.VideoId);
                    newLoads[cacheLoadIndexTwo].VideoIds.Add(videoOneId);
                    return(new Solution {
                        CacheLoads = newLoads
                    });
                }
                else
                {
                    // Remove video
                    var cacheLoadIndex = cacheLoads.RandomIndex(rnd);
                    var cacheLoad      = cacheLoads[cacheLoadIndex];

                    if (cacheLoad.VideoIds.Count > 0)
                    {
                        var removeVideoId = cacheLoad.VideoIds.RandomElement(rnd);

                        var newLoads = cacheLoads.ShallowClone();
                        newLoads[cacheLoadIndex] = new CacheLoad
                        {
                            CacheId  = cacheLoad.CacheId,
                            VideoIds = cacheLoad.VideoIds.ToHashSet(),
                        };
                        newLoads[cacheLoadIndex].VideoIds.Remove(removeVideoId);
                        return(new Solution {
                            CacheLoads = newLoads
                        });
                    }
                }
            }
        }