// Generates first solution on random basis public Solution ConfigSolution(List <Photo> photos) { Solution s = new Solution(); //TODO //Add Heuristic for initial solution // Number of photos int noPhotos = photos.Count; List <Slide> slides = new List <Slide>(); List <Photo> slidePhotos; int photoToSkipId = -1; int slideID = 1; // Iterate into photos and put them in list for (int i = 0; i < noPhotos; i++) { // If we have selected this photo before // Continue if (photos[i].ID == photoToSkipId) { continue; } slidePhotos = new List <Photo>(); // If current photo has horizontal orientation // Put that photo into one slide if (photos[i].Orientation == Orientation.H) { slidePhotos.Add(photos[i]); } // If current photo has vertical orientation else { // Add that photo slidePhotos.Add(photos[i]); // Try to get the next one with vertical orientation Photo nextVerticalPhoto = GetNextVerticalPhoto(photos, i + 1); // If there is one // Add that on the list // And mark that one as visited if (nextVerticalPhoto != null) { slidePhotos.Add(nextVerticalPhoto); photoToSkipId = nextVerticalPhoto.ID; } } Slide oneSlide = new Slide(slidePhotos, slideID++); slides.Add(oneSlide); } // Calculate fitness and save it int InterestFactor = CalculateInterestFactor(slides); s.Slides = slides; s.InterestFactor = InterestFactor; return(s); }
private int Quality(Solution s) { return(s.InterestFactor); }
// Main work public void Start() { Solution FirstSolution = ConfigSolution(_photos); // Components var C = GenerateComponents(FirstSolution.Slides); // Total Time var totalTime = TimeSpan.FromSeconds(20); // List of Times used for local optimum List <int> T = new List <int> { 20, 30, 15, 25, 8, 7 }; //List of component penalties, Initially Zero List <int> p = InitializePenalties(C.Count); // Initial Solution Solution S = CopySolution(FirstSolution); // Mark this solution as Best Solution Best = CopySolution(S); var watch = Stopwatch.StartNew(); watch.Start(); // Start while (watch.Elapsed < totalTime) { // Select random time int randomTimeIndex = _random.Next(0, T.Count); int time = T[randomTimeIndex]; var localWatch = Stopwatch.StartNew(); localWatch.Start(); // Start local optimum while (localWatch.Elapsed < TimeSpan.FromSeconds(time)) { // Copy S var copy = CopySolution(S); var R = Tweak(copy); //Quality if (Quality(R) > Quality(Best)) { Best = CopySolution(R); } //Adjusted Quality if (AdjustedQuality(R, C, p) > AdjustedQuality(S, C, p)) { S = CopySolution(R); } } localWatch.Stop(); // List to save index of items to penalize List <int> C_prim = new List <int>(); List <Slide> currentSlides = S.Slides; for (int i = 0; i < currentSlides.Count - 1; i++) { // Form component 1 as a combination between each pair of Slide ID-s string firstComponent = currentSlides[i].ID + " - " + currentSlides[i + 1].ID; // Calculate value of this pair int firstComponentValue = ComponentValue(currentSlides[i], currentSlides[i + 1]); // Get index in list int firstComponnentIndex = ComponentIndex(C, firstComponent); //Get component penalty int firstComponentP = p[firstComponnentIndex]; //Get penalizability double firstComponentPenalizability = Penalizability(firstComponentValue, firstComponentP); // Indicator to check if current component is more penalizible or eqaul than/with all others bool isMorePenalizible = true; for (int j = 0; j < currentSlides.Count - 1; j++) { if (i != j) { // Form component 1 as a combination between each pair of Slide ID-s string secondComponent = currentSlides[j].ID + " - " + currentSlides[j + 1].ID; // Calculate value of this pair int secondComponentValue = ComponentValue(currentSlides[j], currentSlides[j + 1]); // Get index in list int secondComponnentIndex = ComponentIndex(C, secondComponent); //Get component penalty int secondComponentP = p[secondComponnentIndex]; //Get penalizability double secondComponentPenalizability = Penalizability(secondComponentValue, secondComponentP); //If there is only one component that is more penalizible than the one we are comparing //Than break and go look others if (firstComponentPenalizability < secondComponentPenalizability) { isMorePenalizible = false; break; } } } //If component[i] is the most penalizible, add it to list if (isMorePenalizible) { C_prim.Add(firstComponnentIndex); } } // Foreach component that we have seleceted as the most penalizibles // Increase penalty for one for (int i = 0; i < C_prim.Count; i++) { p[C_prim[i]] = p[C_prim[i]] + 1; } } watch.Stop(); }