如何在 Prolog 中表达无穷大?
How to express infinity in Prolog?
我正在尝试使用 random/3
random(+L:int, +U:int, -R:int)
有什么东西可以用来表示无穷大吗?
例如:
random(0, Infinity, Random_Number).
是否可以通过随机实现?或者还有其他简单的选择吗?
P.S. 我在使用 sup ( Supremum ) 的地方制作了 clpfd 程序,但我没有使用 clpfd。
评论区的讨论真有趣。我对无限数和数学的不发达直觉告诉我:
可以使用一致表示法在物理计算机上表示的整数数量有限。所以就会有无穷多个其他整数无法表示。所以,如果你随机挑选任何个数字,你能在你的机器上表示它的概率是0。你不妨定义:
random_between(0, infinite, infinite).
Transfinite numbers 可能是 一个开始阅读的地方,但我能说谁呢。你需要 数学家 来解决这类问题,而不是编程行人。
也许你应该去https://math.stackexchange.com/问问?
关于你的问题:你可以用一个符号来表示无限的概念,例如原子infinite
。然后你需要决定如何在你的代数中处理这个概念,并为它提供规则。上面的 random_between/3
只是一个例子。如需灵感,请查看 how floating point numbers handle infinity。
我认为评论中的讨论已经变得不太有用了。 David 是正确的,没有办法获得没有上限的 uniform 整数,但不清楚这是否是您想要的。绝对有办法从 偏斜 分布中获取无限随机整数,其中接近 0 的数字比远离 0 的数字更有可能,但 没有 整数,即使是 10000 万亿位的整数,也是不可能的。 (只要不超过Prolog的内存即可。)
这是一个简单的生成器。首先,随机长度列表:
random_length(List) :-
random(P),
( P > 0.25
-> List = [_ | Tail],
random_length(Tail)
; List = [] ).
示例:
?- random_length(List).
List = [].
?- random_length(List).
List = [_2004, _2022, _2040, _2058, _2076].
?- random_length(List).
List = [].
?- random_length(List).
List = [_2004, _2022, _2040, _2058].
接下来,随机位的随机长度列表:
random_bit(Bit) :-
random(P),
( P > 0.5
-> Bit = 1
; Bit = 0 ).
random_bits(Bits) :-
random_length(Bits),
maplist(random_bit, Bits).
示例:
?- random_bits(Bits).
Bits = [0].
?- random_bits(Bits).
Bits = [1, 0, 1, 1, 0, 0].
?- random_bits(Bits).
Bits = [].
?- random_bits(Bits).
Bits = [0, 0, 0].
然后我们可以将这个位列表评估为一个数字,假设使用这种方法:
bits_value([], 0).
bits_value([Bit | Bits], Value) :-
bits_value(Bits, TailValue),
Value is TailValue * 2 + Bit.
示例:
?- random_bits(Bits), bits_value(Bits, Value).
Bits = [1, 1, 0],
Value = 3.
?- random_bits(Bits), bits_value(Bits, Value).
Bits = [0, 1, 0],
Value = 2.
?- random_bits(Bits), bits_value(Bits, Value).
Bits = [0, 0, 0, 1, 1, 0],
Value = 24.
?- random_bits(Bits), bits_value(Bits, Value).
Bits = [0, 1],
Value = 2.
?- random_bits(Bits), bits_value(Bits, Value).
Bits = [],
Value = 0.
这些列表的长度没有限制,但往往很短,因此值相当低。我们可以修改 random_length
中的 0.25 因子,使更长的列表更有可能出现。例如,0.01:
?- random_bits(Bits), bits_value(Bits, Value).
Bits = [0, 0, 0, 0, 0, 0, 1, 0],
Value = 64.
?- random_bits(Bits), bits_value(Bits, Value).
Bits = [0, 1, 0, 1, 1, 1, 0, 0, 0|...],
Value = 137345267061686159418.
?- random_bits(Bits), bits_value(Bits, Value).
Bits = [1, 1, 0, 1, 1, 0, 0, 1, 0|...],
Value = 105607189397659.
?- random_bits(Bits), bits_value(Bits, Value).
Bits = [0, 0, 0, 1, 0, 1, 1],
Value = 104.
这里有很多可以修改的地方,例如,只包含零的列表不是很有用。您可以向此类列表添加一个“隐式 1”元素。您还可以将其中一位视为符号位以允许生成负数。您可以通过生成两个随机整数 P
和 Q
并使用 P/Q
作为随机值来生成随机的、完全无界的有理数。等等。
我正在尝试使用 random/3
random(+L:int, +U:int, -R:int)
有什么东西可以用来表示无穷大吗?
例如:
random(0, Infinity, Random_Number).
是否可以通过随机实现?或者还有其他简单的选择吗?
P.S. 我在使用 sup ( Supremum ) 的地方制作了 clpfd 程序,但我没有使用 clpfd。
评论区的讨论真有趣。我对无限数和数学的不发达直觉告诉我:
可以使用一致表示法在物理计算机上表示的整数数量有限。所以就会有无穷多个其他整数无法表示。所以,如果你随机挑选任何个数字,你能在你的机器上表示它的概率是0。你不妨定义:
random_between(0, infinite, infinite).
Transfinite numbers 可能是 一个开始阅读的地方,但我能说谁呢。你需要 数学家 来解决这类问题,而不是编程行人。
也许你应该去https://math.stackexchange.com/问问?
关于你的问题:你可以用一个符号来表示无限的概念,例如原子infinite
。然后你需要决定如何在你的代数中处理这个概念,并为它提供规则。上面的 random_between/3
只是一个例子。如需灵感,请查看 how floating point numbers handle infinity。
我认为评论中的讨论已经变得不太有用了。 David 是正确的,没有办法获得没有上限的 uniform 整数,但不清楚这是否是您想要的。绝对有办法从 偏斜 分布中获取无限随机整数,其中接近 0 的数字比远离 0 的数字更有可能,但 没有 整数,即使是 10000 万亿位的整数,也是不可能的。 (只要不超过Prolog的内存即可。)
这是一个简单的生成器。首先,随机长度列表:
random_length(List) :-
random(P),
( P > 0.25
-> List = [_ | Tail],
random_length(Tail)
; List = [] ).
示例:
?- random_length(List).
List = [].
?- random_length(List).
List = [_2004, _2022, _2040, _2058, _2076].
?- random_length(List).
List = [].
?- random_length(List).
List = [_2004, _2022, _2040, _2058].
接下来,随机位的随机长度列表:
random_bit(Bit) :-
random(P),
( P > 0.5
-> Bit = 1
; Bit = 0 ).
random_bits(Bits) :-
random_length(Bits),
maplist(random_bit, Bits).
示例:
?- random_bits(Bits).
Bits = [0].
?- random_bits(Bits).
Bits = [1, 0, 1, 1, 0, 0].
?- random_bits(Bits).
Bits = [].
?- random_bits(Bits).
Bits = [0, 0, 0].
然后我们可以将这个位列表评估为一个数字,假设使用这种方法:
bits_value([], 0).
bits_value([Bit | Bits], Value) :-
bits_value(Bits, TailValue),
Value is TailValue * 2 + Bit.
示例:
?- random_bits(Bits), bits_value(Bits, Value).
Bits = [1, 1, 0],
Value = 3.
?- random_bits(Bits), bits_value(Bits, Value).
Bits = [0, 1, 0],
Value = 2.
?- random_bits(Bits), bits_value(Bits, Value).
Bits = [0, 0, 0, 1, 1, 0],
Value = 24.
?- random_bits(Bits), bits_value(Bits, Value).
Bits = [0, 1],
Value = 2.
?- random_bits(Bits), bits_value(Bits, Value).
Bits = [],
Value = 0.
这些列表的长度没有限制,但往往很短,因此值相当低。我们可以修改 random_length
中的 0.25 因子,使更长的列表更有可能出现。例如,0.01:
?- random_bits(Bits), bits_value(Bits, Value).
Bits = [0, 0, 0, 0, 0, 0, 1, 0],
Value = 64.
?- random_bits(Bits), bits_value(Bits, Value).
Bits = [0, 1, 0, 1, 1, 1, 0, 0, 0|...],
Value = 137345267061686159418.
?- random_bits(Bits), bits_value(Bits, Value).
Bits = [1, 1, 0, 1, 1, 0, 0, 1, 0|...],
Value = 105607189397659.
?- random_bits(Bits), bits_value(Bits, Value).
Bits = [0, 0, 0, 1, 0, 1, 1],
Value = 104.
这里有很多可以修改的地方,例如,只包含零的列表不是很有用。您可以向此类列表添加一个“隐式 1”元素。您还可以将其中一位视为符号位以允许生成负数。您可以通过生成两个随机整数 P
和 Q
并使用 P/Q
作为随机值来生成随机的、完全无界的有理数。等等。