如何生成特定范围内的随机分数

问题描述 投票:0回答:2

在我的项目中,我构建了自己的 Fraction:

public partial struct Fraction
{
    public double Numerator;
    public double Denominator;
    public readonly decimal Quotient
    {
        get 
        {
            decimal quotient;
            try
            {
                quotient = (decimal)Numerator / (decimal)Denominator;
            }
            catch
            {
                quotient = (decimal)(Numerator / Denominator);
            }
            return quotient;
        }
    }
}

我想创建一个函数,它接受一个范围并返回该范围内的随机分数:

    public static Fraction GenerateRandomFraction(Fraction Min, Fraction Max)
    {
    }

我尝试思考,但找不到可以实现我想要的算法。 我尝试在网上搜索,但找不到任何我发现的都是关于十进制的。 我可以使用解决方法使其工作:

  1. 获取范围的商。
  2. 生成一个随机十进制数。
  3. 将其转换回分数。

但我不想使用它,除非我 100% 认为这样的算法不存在。

示例: 最小值 = 0/1,最大值 = 1/1 结果:1/10 或 1/9,或 1/3 但我希望它是随机的。

c# algorithm math random fractions
2个回答
1
投票

一个可以很好地工作的解决方案是,你取两个分数,最小值和最大值,改变它们以使分母相等,(然后确保最小值小于最大值,否则交换它们)。 之后在两个生成的分子之间生成随机数。

假设您有 1/3 和 3/5:

  1. 改变它们以将分母统一化 => 5/15 和 9/15。
  2. 生成分子 5 和 9 之间的随机数。

如果您希望获得更准确的结果,您可以让用户决定一个准确度级别,例如 3,然后执行相同的步骤,但在使分母相等后,还将分数乘以 10^3。

这样 1/3 和 3/5 就变成 5000/15000 和 9000/15000,现在你将生成一个 5000 到 9000 之间的数字。

最后,如果可能的话,最重要的是减少生成的分数,这样就完成了。


0
投票

如果您同意将分子和分母限制为三位数,那么问题就会变得相当简单。

首先创建所有可能的分数并将它们放入列表中。然后对列表进行排序,您将需要对分数进行比较才能完成这项工作。然后使用 BinarySearch 查找最小和最大分数(或可能是下一个较低/较高的分数)的索引。然后,您可以简单地在这些索引之间生成一个随机整数,并用它来找到您的分数。

请注意,两个分数之间存在无穷分数,而计算机不能很好地处理无穷大。因此,如果您不能只列出所有可供选择的数字,您可能需要考虑目标是什么。数字好看吗?还采样?速度?根据您想要实现的目标,将会有所权衡。

© www.soinside.com 2019 - 2024. All rights reserved.