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

    运行结果:

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

  • 相关阅读:
    姐姐的vue(1)
    LeetCode 64. Minimum Path Sum 20170515
    LeetCode 56. 56. Merge Intervals 20170508
    LeetCode 26. Remove Duplicates from Sorted Array
    LeetCode 24. Swap Nodes in Pairs 20170424
    LeetCode 19. Remove Nth Node From End of List 20170417
    LeetCode No.9 Palindrome Number 20170410
    LeetCode No.8. String to Integer (atoi) 2017/4/10(补上一周)
    LeetCode No.7 Reverse Integer 2017/3/27
    LeetCode No.4 Median of Two Sorted Arrays 20170319
  • 原文地址:https://www.cnblogs.com/AndyJee/p/4463646.html
Copyright © 2011-2022 走看看