zoukankan      html  css  js  c++  java
  • (算法)随机播放歌曲

    题目:

    假设张三的mp3里有1000首歌,现在希望设计一种随机算法来随机播放。与普通随机模式不同的是,张三希望每首歌被随机抽到的概率是与一首歌的豆瓣评分(0~10分)成正比的,如朴树的《平凡之路》评分为8.9分,逃跑计划的《夜空中最亮的星》评分为9.5分,则希望听《平凡之路》的概率与《夜空中最亮的星》的概率比为89:95,。现在我们已知这1000首歌的豆瓣评分:
        (1)请设计一种随机算法来满足张三的需求。
        (2)请写代码实现自己的算法。

    思路:

    将1000首歌的豆瓣评分累加起来,成为一条1000个区间的数轴,每个区间代表一首歌曲,在每个区间内是均匀分布的,而区间与区间之间满足概率与豆瓣评分成正比。

    这样,通过产生一个[0,totalScore]间的随机浮点数,落在哪个区间就播放哪首歌曲。

    代码:

    #include <iostream>
    #include <time.h>
    #include <stdlib.h>
    
    using namespace std;
    
    int findIdx(double songs[],int n,double rnd){
        int left=0;
        int right=n-1;
        int mid;
        while(left<=right){
            mid=(left+right)/2;
            if((songs[mid-1]<=rnd) && (songs[mid]>=rnd))
                return mid;
            if(songs[mid]>rnd)
                right=mid-1;
            else
                left=mid+1;
        }
    //    return mid;
    }
    
    int randomPlaySong(double sum_scores[],int n){
        double mx=sum_scores[n-1];
        double rnd= rand()*mx/(double)(RAND_MAX);
        return findIdx(sum_scores,n,rnd);
    }
    
    int main()
    {
        srand(time(0));
        double scores[]={5.5,6.5,4.5,8.5,9.5,7.5,3.5,5.0,8.0,2.0};
        int n=sizeof(scores)/sizeof(scores[0]);
        double sum_scores[n];
        sum_scores[0]=scores[0];
    
        for(int i=1;i<n;i++)
            sum_scores[i]=sum_scores[i-1]+scores[i];
    
        cout<<"Calculate the probability of each song: "<<endl;
        int totalScore=sum_scores[n-1];
        for(int i=0;i<n;i++)
            cout<<scores[i]/totalScore<<" ";
        cout<<endl;
    
        int counts[n];
        for(int i=0;i<n;i++)
            counts[i]=0;
    
        int i=0;
        int idx;
        int MAX_ITER=100000000;
        while(i<MAX_ITER){
            idx=randomPlaySong(sum_scores,n);
            counts[idx]++;
            i++;
        }
    
        cout<<"After simulation, probability of each song: "<<endl;
        for(int i=0;i<n;i++)
            cout<<1.0*counts[i]/MAX_ITER<<" ";
        cout<<endl;
    
        return 0;
    }

    运行结果:

    基于豆瓣评分的每首歌曲的概率以及一亿次的随机试验结果,可以看出基本一致:

  • 相关阅读:
    【Android】将apk文件安装到Android模拟器中
    【笔试or面试】操作系统的多道编程
    表单附件显示问题
    vs2010部署报错,服务器场功能未激活,未安装在此服务器场中,无法添加到该范围,解决方案
    sharepoint 列表排序
    设置网站匿名访问后无法匿名访问列表内容问题解决
    Moss2010隐藏 用户欢迎下拉框项目
    SharePoint 自定义的MasterPage (母版页结构)
    SharePoint2010搜索的简单设置
    (经验)如何“正确”为SharePoint字段命名
  • 原文地址:https://www.cnblogs.com/AndyJee/p/4463646.html
Copyright © 2011-2022 走看看