繁体   English   中英

随机获得随机数

[英]Getting Random Number with probability

尝试制作音频播放器时,当前在播放列表中工作,并且我在随机播放功能方面遇到问题。

首先,我有一个列表,其中包含文件名:

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个值,这些值描述了播放列表项的优先级,因此优先级最低的项将有更好的机会针对优先级较高的项返回,因此我需要根据项目优先级获得具有概率的随机项目。

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

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

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

这应该够了吧!

这个SO问题的公认答案具有易于移植到C#中的伪代码。 它还讨论了如何针对很少变化的权重和/或大型列表进行优化,我希望这两种方法都适用于音频播放器。

列表中为每个项目添加了优先级(整数越大,优先级越高),并且列表中所有优先级的总和也作为参数添加,因为缓存它会很好。

   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;
      }
   }

好的,所以您需要的是加权随机系统。

一种技术是模拟转轮(例如在电视节目游戏中)。 您将每个项目放在该轮子上,每个项目所占用的空间与其重要性成正比。 然后您实际上旋转了那个轮子,因此最重要的项目有更大的机会被选择。

假设您的优先级基于数字P,该数字是歌曲之前播放过的次数。

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

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

  • 生成范围为[0; P]

  • 遍历数组并进行每次迭代:

    • 方向盘上的当前位置:C + = P
    • 测试R> = C
      如果为True,则选择歌曲,否则转到下一首歌曲

这样一来,播放得最多的歌曲就有更多的机会被选择。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM