如何让Python选择符合要求的最大随机值?
How do I make Python choose the largest random value which fits the requirements?
所以我正在尝试编写一个程序,选择分子和分母之和等于 n 的最大不可约真分数。这是我目前所拥有的:
import random
def fraction(n):
if n < 3 or n > 10 ** 12:
error_message = 'n must lie in the range (3; 10^12)'
print(error_message)
while True: # cycle for repeated variable checking
if n >= 3 or n <= 10 ** 12:
b = random.randint(2, 100) # generating two random numbers a and b, where a is the nominator and b the denominator
a = random.randint(2, 100) # the range is shortened for testing
if a + b != n: # continue picking random ints until they fit
continue
if a + b == n:
if a != b and a < b: # if a=b the fraction is reducible and doesn't fit, and if a>b it is improper and doesn't fit either
print(str(a) + '/' + str(b)) # printing an appropriate ordinary fraction
else:
continue
break
n = int(input('n: '))
fraction(n)
困难在于:当我开始测试更大的 n 个数字(如 12)时,输出不同,有些分数小于其他分数,而我只需要最大的一个。有什么办法可以让 Python 选择这样的分数吗?
要找到最大的一个,您不需要随机生成分子和分母。只需从(n - 1) // 2
开始向下循环分子a
,使分母b = n - a
,如果math.gcd(a, b) == 1
(读Greated Common Divisor)那么我们找到最大的不可约真分数a / b
.
这是因为任何分数最多可以减少分子和分母的最大公约数(GCD)。如果 GCD 为 1,则它是不可约的。
在我的代码中,如果返回元组 (0, n)
,则表示没有答案,换句话说,给定 n
没有解决方案。您也可以 return None
而不是最后一行的 return 0, n
。
import math
def fraction(n):
for a in range((n - 1) // 2, -1, -1):
b = n - a
if math.gcd(a, b) == 1:
return a, b
return 0, n
# Doing some tests below
for i, n in enumerate(range(100)):
f = fraction(n)
print(f'n {n:>2} frac {f[0]:>2}/{f[1]:>2} | ', end = '')
if (i + 1) % 4 == 0:
print()
输出:
n 0 frac 0/ 0 | n 1 frac 0/ 1 | n 2 frac 0/ 2 | n 3 frac 1/ 2
n 4 frac 1/ 3 | n 5 frac 2/ 3 | n 6 frac 1/ 5 | n 7 frac 3/ 4
n 8 frac 3/ 5 | n 9 frac 4/ 5 | n 10 frac 3/ 7 | n 11 frac 5/ 6
n 12 frac 5/ 7 | n 13 frac 6/ 7 | n 14 frac 5/ 9 | n 15 frac 7/ 8
n 16 frac 7/ 9 | n 17 frac 8/ 9 | n 18 frac 7/11 | n 19 frac 9/10
n 20 frac 9/11 | n 21 frac 10/11 | n 22 frac 9/13 | n 23 frac 11/12
n 24 frac 11/13 | n 25 frac 12/13 | n 26 frac 11/15 | n 27 frac 13/14
n 28 frac 13/15 | n 29 frac 14/15 | n 30 frac 13/17 | n 31 frac 15/16
n 32 frac 15/17 | n 33 frac 16/17 | n 34 frac 15/19 | n 35 frac 17/18
n 36 frac 17/19 | n 37 frac 18/19 | n 38 frac 17/21 | n 39 frac 19/20
n 40 frac 19/21 | n 41 frac 20/21 | n 42 frac 19/23 | n 43 frac 21/22
n 44 frac 21/23 | n 45 frac 22/23 | n 46 frac 21/25 | n 47 frac 23/24
n 48 frac 23/25 | n 49 frac 24/25 | n 50 frac 23/27 | n 51 frac 25/26
n 52 frac 25/27 | n 53 frac 26/27 | n 54 frac 25/29 | n 55 frac 27/28
n 56 frac 27/29 | n 57 frac 28/29 | n 58 frac 27/31 | n 59 frac 29/30
n 60 frac 29/31 | n 61 frac 30/31 | n 62 frac 29/33 | n 63 frac 31/32
n 64 frac 31/33 | n 65 frac 32/33 | n 66 frac 31/35 | n 67 frac 33/34
n 68 frac 33/35 | n 69 frac 34/35 | n 70 frac 33/37 | n 71 frac 35/36
n 72 frac 35/37 | n 73 frac 36/37 | n 74 frac 35/39 | n 75 frac 37/38
n 76 frac 37/39 | n 77 frac 38/39 | n 78 frac 37/41 | n 79 frac 39/40
n 80 frac 39/41 | n 81 frac 40/41 | n 82 frac 39/43 | n 83 frac 41/42
n 84 frac 41/43 | n 85 frac 42/43 | n 86 frac 41/45 | n 87 frac 43/44
n 88 frac 43/45 | n 89 frac 44/45 | n 90 frac 43/47 | n 91 frac 45/46
n 92 frac 45/47 | n 93 frac 46/47 | n 94 frac 45/49 | n 95 frac 47/48
n 96 frac 47/49 | n 97 frac 48/49 | n 98 frac 47/51 | n 99 frac 49/50
您还可以通过记住最大值 a
来稍微修改您的变体,过滤掉 a
小于当前最大值或 gcd(a, b) > 1
的结果。然后,如果给定足够的时间,您的随机解决方案在大多数情况下也可能有效,尽管它当然很慢。
在下面尝试修改后的代码。如果找不到更大的分数,它会反复打印越来越大的分数,直到它冻结很长时间。
import random, math
def fraction(n):
if n < 3 or n > 10 ** 12:
error_message = 'n must lie in the range (3; 10^12)'
print(error_message)
amax = -1
while True: # cycle for repeated variable checking
if n >= 3 or n <= 10 ** 12:
b = random.randint(1, n) # generating two random numbers a and b, where a is the nominator and b the denominator
a = random.randint(1, n) # the range is shortened for testing
if a + b != n: # continue picking random ints until they fit
continue
if a + b == n:
if a != b and a < b and a > amax: # if a=b the fraction is reducible and doesn't fit, and if a>b it is improper and doesn't fit either
if math.gcd(a, b) == 1:
print(str(a) + '/' + str(b)) # printing an appropriate ordinary fraction
amax = a
else:
continue
n = int(input('n: '))
fraction(n)
输出:
n: 456
67/389
127/329
179/277
185/271
211/245
215/241
221/235
223/233
227/229
所以我正在尝试编写一个程序,选择分子和分母之和等于 n 的最大不可约真分数。这是我目前所拥有的:
import random
def fraction(n):
if n < 3 or n > 10 ** 12:
error_message = 'n must lie in the range (3; 10^12)'
print(error_message)
while True: # cycle for repeated variable checking
if n >= 3 or n <= 10 ** 12:
b = random.randint(2, 100) # generating two random numbers a and b, where a is the nominator and b the denominator
a = random.randint(2, 100) # the range is shortened for testing
if a + b != n: # continue picking random ints until they fit
continue
if a + b == n:
if a != b and a < b: # if a=b the fraction is reducible and doesn't fit, and if a>b it is improper and doesn't fit either
print(str(a) + '/' + str(b)) # printing an appropriate ordinary fraction
else:
continue
break
n = int(input('n: '))
fraction(n)
困难在于:当我开始测试更大的 n 个数字(如 12)时,输出不同,有些分数小于其他分数,而我只需要最大的一个。有什么办法可以让 Python 选择这样的分数吗?
要找到最大的一个,您不需要随机生成分子和分母。只需从(n - 1) // 2
开始向下循环分子a
,使分母b = n - a
,如果math.gcd(a, b) == 1
(读Greated Common Divisor)那么我们找到最大的不可约真分数a / b
.
这是因为任何分数最多可以减少分子和分母的最大公约数(GCD)。如果 GCD 为 1,则它是不可约的。
在我的代码中,如果返回元组 (0, n)
,则表示没有答案,换句话说,给定 n
没有解决方案。您也可以 return None
而不是最后一行的 return 0, n
。
import math
def fraction(n):
for a in range((n - 1) // 2, -1, -1):
b = n - a
if math.gcd(a, b) == 1:
return a, b
return 0, n
# Doing some tests below
for i, n in enumerate(range(100)):
f = fraction(n)
print(f'n {n:>2} frac {f[0]:>2}/{f[1]:>2} | ', end = '')
if (i + 1) % 4 == 0:
print()
输出:
n 0 frac 0/ 0 | n 1 frac 0/ 1 | n 2 frac 0/ 2 | n 3 frac 1/ 2
n 4 frac 1/ 3 | n 5 frac 2/ 3 | n 6 frac 1/ 5 | n 7 frac 3/ 4
n 8 frac 3/ 5 | n 9 frac 4/ 5 | n 10 frac 3/ 7 | n 11 frac 5/ 6
n 12 frac 5/ 7 | n 13 frac 6/ 7 | n 14 frac 5/ 9 | n 15 frac 7/ 8
n 16 frac 7/ 9 | n 17 frac 8/ 9 | n 18 frac 7/11 | n 19 frac 9/10
n 20 frac 9/11 | n 21 frac 10/11 | n 22 frac 9/13 | n 23 frac 11/12
n 24 frac 11/13 | n 25 frac 12/13 | n 26 frac 11/15 | n 27 frac 13/14
n 28 frac 13/15 | n 29 frac 14/15 | n 30 frac 13/17 | n 31 frac 15/16
n 32 frac 15/17 | n 33 frac 16/17 | n 34 frac 15/19 | n 35 frac 17/18
n 36 frac 17/19 | n 37 frac 18/19 | n 38 frac 17/21 | n 39 frac 19/20
n 40 frac 19/21 | n 41 frac 20/21 | n 42 frac 19/23 | n 43 frac 21/22
n 44 frac 21/23 | n 45 frac 22/23 | n 46 frac 21/25 | n 47 frac 23/24
n 48 frac 23/25 | n 49 frac 24/25 | n 50 frac 23/27 | n 51 frac 25/26
n 52 frac 25/27 | n 53 frac 26/27 | n 54 frac 25/29 | n 55 frac 27/28
n 56 frac 27/29 | n 57 frac 28/29 | n 58 frac 27/31 | n 59 frac 29/30
n 60 frac 29/31 | n 61 frac 30/31 | n 62 frac 29/33 | n 63 frac 31/32
n 64 frac 31/33 | n 65 frac 32/33 | n 66 frac 31/35 | n 67 frac 33/34
n 68 frac 33/35 | n 69 frac 34/35 | n 70 frac 33/37 | n 71 frac 35/36
n 72 frac 35/37 | n 73 frac 36/37 | n 74 frac 35/39 | n 75 frac 37/38
n 76 frac 37/39 | n 77 frac 38/39 | n 78 frac 37/41 | n 79 frac 39/40
n 80 frac 39/41 | n 81 frac 40/41 | n 82 frac 39/43 | n 83 frac 41/42
n 84 frac 41/43 | n 85 frac 42/43 | n 86 frac 41/45 | n 87 frac 43/44
n 88 frac 43/45 | n 89 frac 44/45 | n 90 frac 43/47 | n 91 frac 45/46
n 92 frac 45/47 | n 93 frac 46/47 | n 94 frac 45/49 | n 95 frac 47/48
n 96 frac 47/49 | n 97 frac 48/49 | n 98 frac 47/51 | n 99 frac 49/50
您还可以通过记住最大值 a
来稍微修改您的变体,过滤掉 a
小于当前最大值或 gcd(a, b) > 1
的结果。然后,如果给定足够的时间,您的随机解决方案在大多数情况下也可能有效,尽管它当然很慢。
在下面尝试修改后的代码。如果找不到更大的分数,它会反复打印越来越大的分数,直到它冻结很长时间。
import random, math
def fraction(n):
if n < 3 or n > 10 ** 12:
error_message = 'n must lie in the range (3; 10^12)'
print(error_message)
amax = -1
while True: # cycle for repeated variable checking
if n >= 3 or n <= 10 ** 12:
b = random.randint(1, n) # generating two random numbers a and b, where a is the nominator and b the denominator
a = random.randint(1, n) # the range is shortened for testing
if a + b != n: # continue picking random ints until they fit
continue
if a + b == n:
if a != b and a < b and a > amax: # if a=b the fraction is reducible and doesn't fit, and if a>b it is improper and doesn't fit either
if math.gcd(a, b) == 1:
print(str(a) + '/' + str(b)) # printing an appropriate ordinary fraction
amax = a
else:
continue
n = int(input('n: '))
fraction(n)
输出:
n: 456
67/389
127/329
179/277
185/271
211/245
215/241
221/235
223/233
227/229