我的模型中有功能可以计算用户的分数:
def score
(MULTIPLER * Math::log10(bets.count * summary_value ** accuracy + 1)).floor
end
我的观点是测试它是否以对数方式增长?
答案 0 :(得分:1)
测试的目的不是证明它始终有效(这是静态打字/校样的区域),而是要检查它是否正常工作。这通常足够好。我猜你是在为游戏做这件事,以及确保这个功能不会“快速”增长的原因。
我们可以这样做的方法是尝试一些值,并检查它们是否遵循一般的对数模式。
例如,考虑一个纯对数函数f(x) = log(x)
(任何基数):
如果f(x) = y
,则f(x^n)
= f(x) * n
。
所以,如果f(x^n) == (f(x) * n)
,那么函数是对数的。
将其与线性函数进行比较,例如f(x) == x * 2
。 f(x^n) = x^n * 2
,即x^(n - 1)
倍(更大)。
您可能具有更复杂的对数函数,例如f(x) = log(x + 7) + 3456
。虽然不太准确,但模式仍然存在。所以我做的是:
x = 1
f(x^n) - f(x) * n
。f((x*100)^n) - f(100x) * n
如果(3)/(2)小于10,则几乎肯定不是线性的,并且可能是对数的。 10只是一个任意数字。大多数线性函数的差异将超过十亿。即使像sqrt(x)
这样的函数也会有比10更大的差异。
我的示例代码只需要score
方法获取参数,并对其进行测试(为了保持简单+我没有您的支持代码)。
require 'rspec'
require 'rspec/mocks/standalone'
def score(input)
Math.log2(input * 3 + 1000 * 3) * 3 + 100 + Math.sin(input)
end
describe "score" do
it "grows logarithmacally based on input" do
x = 50
n = 8
c = score(1)
result1 = (score(x ** n) - c) / ((score(x) -c) * n)
x *= 100
result2 = (score(x ** n) - c) / ((score(x) -c) * n)
(result2 / result1).abs.should be < 10
end
end
答案 1 :(得分:0)
虽然我几乎忘记了复杂的数学知识,但事实似乎无法阻止我回答这个问题。
我的建议如下
describe "#score" do
it "grows logarithmically" do
round_1 = FactoryGirl.create_list(:bet, 10, value: 5).score
round_2 = FactoryGirl.create_list(:bet, 11, value: 5).score
# Then expect some math relation between round_1 and round_2,
# calculated by you manually.
end
end
答案 2 :(得分:0)
一般来说,查看函数是否增长的最佳方法是在图表上绘制一些数据。只需使用一些图形绘制宝石并评估结果。
对数函数将始终如下所示:
log func image http://www.sosmath.com/algebra/logs/log4/log004.gif
然后,您可以通过参数调整其增长速度,并重新绘制图表,直到您发现自己对结果感到满意为止。
答案 3 :(得分:0)
如果您需要将此功能视为黑盒子,唯一真正的解决方案是获取一组值,并查看它们的曲线是否通过对数曲线很好地近似,重点关注大n
。如果您可以对其进行合理限制,例如对于某些值a log(n) < score(n) < b log(n)
和a
b
,那么您可以检查一下。