随机获得概率

时间:2011-11-10 07:59:28

标签: c# generics random

在尝试创建一个音频播放器时,目前在播放列表中工作,我有洗牌功能的问题。

首先我有一个文件名列表:

List<string> myPlaylist = new List<string>();
            myPlaylist.Add("Untitled1.mp3");
            myPlaylist.Add("Untitled2.mp3");
            myPlaylist.Add("Untitled3.mp3");

并且使用此方法即可获得播放列表中的随机项:

public string shuffleme(List<string> playlist)
        { 
            Random random = new Random();
            int playlistitem = random.Next(0,playlist.Count);
            return playlist[playlistitem];
        }

但是我需要以某种概率获得随机元素,假设我有1-10个值来描述播放列表项目优先级,因此具有最低优先级的项目将有更好的机会返回对项目优先级较高,所以我需要根据项目优先级获得随机项目的概率。

4 个答案:

答案 0 :(得分:4)

您可以通过以下方式创建播放列表:

  • 每个高优先级项目,将其放在列表中3倍。
  • 每个中等优先级项目,将其放在列表中2倍。
  • 所有其他项目,将它们放在列表中1个。
  • 随机播放列表。
  • 确认连续两次没有歌曲出现;如果找到一个(例如,在11和12位置),只需将第二个与列表中的下一个交换(即,如本例所示,将交换#12与#13交换)。

然后,当需要选择下一首歌曲时,只需选择列表中的第一首歌曲,将其取出并将其放回列表后半部分的随机位置。

这应该可以做到!

答案 1 :(得分:2)

this SO question的已接受答案包含可轻松移植到C#的伪代码。它还讨论了如何针对极少变化的权重和/或大型列表进行优化,我希望将这两种权重应用于音频播放器。

答案 2 :(得分:1)

列表中为每个项添加优先级(更高优先级的更大整数)以及列表中所有优先级的总和作为参数,因为最好将其缓存。

   public string shuffleme(List<Tuple<string,int> playlist, int prioritiesSum)
   { 
      Random random = new Random();

      foreach(var song in playlist)
      {
         var prob=random.NextDouble(); //0.0-1.0
         if (prob < song.Item2/(double)prioritiesSum)
            return song.Item1;
         else
            prioritiesSum-=song.Item2;
      }
   }

答案 3 :(得分:0)

好的,你需要的是加权随机系统。

一种技术是模拟一个轮子(就像在电视节目游戏中一样)。您将每个项目放在该轮子上,每个项目占用的空间与其重要性成正比。然后你几乎旋转那个轮子,这样最重要的项目有更大的机会被选中。

我们假设您的优先级基于数字P,即之前播放的歌曲的次数。

  • 将所有歌曲放置在类似数组的结构中

  • 计算车轮的周长
    它将是所有P值的总和

  • 生成[0;范围内的随机数R. P]

  • 循环遍历数组并在每次迭代时:

    • 车轮上的当前位置:C + = P
    • 测试R> = C
      如果为True,则选择其他歌曲转到下一首歌曲

通过这样做,播放次数最多的歌曲有更多机会被选中。