【问题标题】:Getting Random Number with probability以概率获取随机数
【发布时间】:2011-12-25 23:01:44
【问题描述】:

在尝试制作音频播放器时,目前在播放列表工作,但我遇到了随机播放功能的问题。

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

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

【问题讨论】:

    标签: c# generics random


    【解决方案1】:

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

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

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

    这应该可以解决问题!

    【讨论】:

    • 如果您要确保在原始随机播放中没有两个相邻位置是同一首歌曲,您可能也希望在将歌曲插入列表的后半部分时这样做。除了那个很小的洞,这不是一个坏主意。
    • @paxdiablo 没错,我忘了提。另一种选择是将歌曲放回列表的末尾;这不需要再次检查,但当然它会保留可能不是您想要的顺序......
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        【解决方案4】:

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

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

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

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

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

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

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

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-04-10
          • 1970-01-01
          • 2017-11-26
          • 1970-01-01
          • 2021-01-08
          • 2017-10-01
          • 2016-01-26
          • 2013-12-18
          相关资源
          最近更新 更多