Php 如何将介于1和10之间的值随机化以获得真实评级?

Php 如何将介于1和10之间的值随机化以获得真实评级?,php,random,numbers,Php,Random,Numbers,我有一个电影数据库,我需要在其中填充数据,以便更容易测试和开发应用程序。有一些表格可以保存电影分级和用户帐户,用户对电影进行分级 我已经开始开发一个脚本,用假数据和一般数据填充数据库,但我不知道如何随机化评级。对于每部电影,我随机选择了100、500、1000等用户。对于这些用户中的每一位,我都随机将评分从1分到10分。但这些评级的结果是相同的平均值,约为5。这意味着一部特定电影的收视率分布(1到10)基本相同。这一点都不“现实”,因为所有像这样生成收视率的电影都有相同的平均收视率,因此来自不同

我有一个电影数据库,我需要在其中填充数据,以便更容易测试和开发应用程序。有一些表格可以保存电影分级和用户帐户,用户对电影进行分级

我已经开始开发一个脚本,用假数据和一般数据填充数据库,但我不知道如何随机化评级。对于每部电影,我随机选择了100、500、1000等用户。对于这些用户中的每一位,我都随机将评分从1分到10分。但这些评级的结果是相同的平均值,约为5。这意味着一部特定电影的收视率分布(1到10)基本相同。这一点都不“现实”,因为所有像这样生成收视率的电影都有相同的平均收视率,因此来自不同用户和不同数量用户的相同收视率并不重要

我希望电影A的平均值为7,电影B的平均值为5,电影C的平均值为8,等等。。。但我只是不希望每部电影的平均值都不一样。我的意思是,制作这样的评级(针对特定数量的用户)会很好: 还是这个

你知道,一些随机的东西可能会产生两种不同的变化,就像上面所说的。我点击refresh,得到第一张图,点击refresh,得到第二张图,再次点击,得到不同或相似的东西,一些“随机”和“现实”的东西

我还将在我的应用程序上显示这样的图形,这样就可以有不同的分布。但我不知道如何用一个简单的脚本来随机完成这一切

我怎样才能解决这个问题?也许工作太多不值得


也许更简单一些,比如选择一个点(介于1和10之间),然后创建一个评分的正态分布,其中所选的点是最高的点,这对我来说是可行的。

我的建议是在randon数生成中花费时间,还可以使用诸如mt_rand之类的函数来改进随机生成。试着做一些复杂的浮点运算和对int的转换,最后应用一个%max_值,使结果符合您的限制

例如:

function x()
{
 return (time() * 7.3333333333 * mt_rand(0.1 , 10.1));
}

$rank = (x() + 3.99999) % 10);

我并不是说这是可行的,而是说明了这个想法。希望有帮助

您希望修正平均值,可能还有方差,并围绕这些值生成随机数

这将帮助您开始:

编辑: 事实上,如果你仔细想想,这个问题很容易解决:你的数字趋向于5的原因是因为你的分数在1到10之间(所以平均值是5)


只要把你的随机数加上8,然后把任何大于10的数四舍五入到10,你就会得到一个以8为中心的数字(但在上面是倾斜的)。对于您的目的来说可能足够好了?

请记住,使用标准RNG(随机数生成器),您将获得非常均匀的值分布。正如您所发现的,给定足够的“随机”值,您将得到平均结果。对于您的数据库的人口,我会考虑这种方法:

选择一个随机数作为电影的平均分数。然后,在该平均值的上界生成一组随机数。例如,如果随机生成7,则生成5到9之间的随机数。然后输入从1到6和8到10的两个值,以给出异常值的外观

编辑:

这可能就是您正在寻找的,用Java代码完成

均匀分布示例:

您的代码可能类似于以下代码:

public class EvenDistribution
{
    private static Random random = new Random();

    public static void main(String[] args)
    {
        int maxValue = 20;

        int[] distribution = new int[maxValue];

        int iterations = 1000;

        for (int i = 0; i < iterations; i++)
        {
            int rand = random.nextInt(maxValue);
            distribution[rand]++;
        }

        for (int i = 0; i < distribution.length; i++)
        {
            System.out.println(i+1+": "+distribution[i]);
        }
    }
}
它产生了以下产出:

1:19
2:27
3:41
4:68
5:110
6:111
7:125
8:138
9:125
10:85
11:64
12:32
13:32
14:14
15:5
16:2
17:1
18:0
19:1
20:0


似乎这个库对于您要完成的任务非常有用。

尝试Mersenne Twister算法以获得高质量的随机数

我认为这些坏蛋有一些php实现:


很好的php实现:D

正如Kenny所暗示的,您希望看到正态分布。如果你看IMDB的收视率,你会发现大多数电影都遵循正态分布。例外情况是排名靠前和靠后。很多人会说他们讨厌或喜欢一部电影——他们夸大了自己的真实感受,因此出现了这些尖峰。因此,要获得准确的数据集,您需要将这些数据添加到。也许让最低排名=(下两个最低排名的总和)*一个常数?

我也支持Kenny的建议,但想补充一点关于实施的说明。虽然这不是我见过的最好的方法,但由于它的易用性,我已经实现过几次了

想象一个数组,十个元素长,每个元素的值为10。如果要生成一个介于1到100之间的随机数,则可以将前进到数组中下一个索引的每个元素加总到数组中,前提是该值大于到目前为止数组值的总和。通过这种方式,您可以将1-100映射到1-10

尽管上面提到的使用这种技术会很糟糕,但是你可以很容易地看到,你可以用一点创造力创建自己的非均匀分布。例如,考虑:

1,2,4,8,16,16,8,4,2,1

以上10个元素的总和为64,因此非常适合将64映射到10(这只是一个示例)。我看到的实现希望分布的总和总是一个特定的数字,但是如果你封装了从1到10的随机数,那么你可以得到不同总和的分布

通过只创建几个这样的分布,您可以通过对概率向量求和潜在地创建许多合理的分布(考虑高度本地化的分布在3左右,高度本地化的分布在8左右,可能是最新的僵尸杀手和僵尸爱好者都投了8票,因为作为僵尸电影
public class RandomDistribution {
    private static MersenneTwisterRNG random = new MersenneTwisterRNG();
    private static GaussianGenerator gen = new GaussianGenerator(7, 3, random);

    public static void main(String[] args)
    {
        int maxValue = 20;

        int[] distribution = new int[maxValue];

        int iterations = 1000;

        for (int i = 0; i < iterations; i++)
        {
            int rand = Math.abs(gen.nextValue().intValue());
            distribution[rand]++;
        }

        for (int i = 0; i < distribution.length; i++)
        {
            System.out.println(i+1+": "+distribution[i]);
        }
    }
}