public static List <PlaylistSong> CombinationsPlaylist(List <Song> inputList, Playlist playlist, int durationSeconds) { //Set up the environment for the recursive combinatorial algorithm to work. Random rand = new Random(); List <Song> resultList = new List <Song>(); //Shuffling the list of Songs each time means every Playlist will be different, even if they've //got the samew target lengths. List <Song> workingList = Shuffle(inputList); List <PlaylistSong> playlistSongList = new List <PlaylistSong>(); PlaylistSong newPLS = null; int songOrder = 1; resultList = Combinations(workingList, durationSeconds); //A PlaylistSong is not the same as a Song; a PlaylistSong is just a pair of foreign keys (SongID, PlaylistID) //plus an ordinal. In order to complete the Playlist, the PlaylistSongs need to be created from the ListSong<>. foreach (Song s in resultList) { newPLS = new PlaylistSong(); newPLS.PlaylistID = playlist.PlaylistID; newPLS.SongID = s.SongID; newPLS.SongOrder = songOrder; CDCatalogManager.AddPlaylistSong(newPLS); playlistSongList.Add(newPLS); songOrder++; } return(playlistSongList); }
//No longer using this code. public static List <PlaylistSong> RandomPlayList(List <Song> sourceList, int targetSeconds, Playlist playList) { ///Algorithm needs to: ///1) Check playlist length against target--while totalLength less than or equal to targetSeconds + 60? /// ///2) Reduce available songs to those that will fit in the time. ///3) Add a song, add song length to totalLength /// Random rand = new Random(); List <PlaylistSong> playlistSongList = new List <PlaylistSong>(); PlaylistSong newPLS = new PlaylistSong(); bool keepGoing = true; bool isFull = false; bool notEnoughSongs = false; int iterator = 0; int index = 0; int songOrder = 1; int totalLength = 0; List <Song> songList = sourceList.OrderBy(s => s.SongID).ToList(); List <Song> filteredList = songList.Where(s => s.TrackLength <= ((targetSeconds + 60) - totalLength)).ToList(); List <Song> workingList = new List <Song>(); //checking the iterator keeps this from becoming an infinite loop, //but all testing, even with fairly small datasets, has so far found //a solution before the iterator iterates out. while (iterator < 1000000000 && keepGoing == true) { while (totalLength <= (targetSeconds + 60) && isFull == false && notEnoughSongs == false) { //reduce the available songs to only those which will not exceed the specified playlist length plus one minute. filteredList = songList.Where(s => s.TrackLength <= ((targetSeconds + 60) - totalLength)).ToList(); if (filteredList.Count > 0) //If we're out of songs, we can't add any more to the playlist { index = rand.Next(0, filteredList.Count); workingList.Add(songList[index]); totalLength += songList[index].TrackLength; songList.RemoveAt(index); } else { notEnoughSongs = true; keepGoing = false; } if (totalLength >= (targetSeconds - 60)) { isFull = true; } } if (totalLength >= (targetSeconds - 60) && totalLength <= (targetSeconds + 60)) { songOrder = 1; Song s = new Song(); while (workingList.Count > 0) { newPLS = new PlaylistSong(); s = workingList[rand.Next(0, workingList.Count)]; newPLS.PlaylistID = playList.PlaylistID; newPLS.SongID = s.SongID; newPLS.SongOrder = songOrder; CDCatalogManager.AddPlaylistSong(newPLS); playlistSongList.Add(newPLS); workingList.Remove(s); songOrder++; } keepGoing = false; } else { workingList.Clear(); totalLength = 0; isFull = false; songList = sourceList.OrderBy(s => s.SongID).ToList(); filteredList = songList.Where(s => s.TrackLength <= ((targetSeconds + 60) - totalLength)).ToList(); iterator++; } } return(playlistSongList); }