我想写一个表示马尔可夫链的类(姑且命名为MC
)。它有一个构造函数,它取状态转移矩阵(即vector<vector<double>>
)。我想,这是一个好主意,检查它是一个真正的矩阵(具有相同的行数和列数),是一个真正的转移矩阵:其中所有的数字都是概率,即不小于0.0
,不大于1.0
,并且对于每一行,它的元素的和是1.0
。然而,有一个问题是由浮点限制引起的:例如,和0.3 + 0.3 + 0.3 + 0.1
将不等于1.0
,因此检查将不那么容易。所以我看到了这个问题的两种可能的解决方案:
- 选择某个epsilon并与epsilon误差进行比较。当然,它现在将接受一些违反转换矩阵属性的矩阵,但一般来说,如果有人偶尔传递一些错误的数据到构造函数,他将得到一个异常。
- 不要检查任何东西,依靠类的用户,如果他传递了一些不好的东西,那完全是他的错,类的行为将是意想不到的。
哪种方法更好,更"真实"?我喜欢第一个,但还是不确定我应该如何选择
做第二个。
你的类不是在总结浮点数列表,并决定什么是"足够接近"1,什么不是。您的用户是。你的类代表马尔可夫链。你将无法选择一个值,使你的类以一种有用的方式表示马尔可夫链。
想想你要实现的操作。也许你会有一个函数它符合链的状态和链的转移矩阵的概率分布。这个函数应该检查输入的概率分布是否在某个范围内的概率分布吗?
你的函数几乎肯定不会保持"是概率分布"的属性;当你通过马尔可夫链反复撞击概率分布时,你会得到一些漂移,这是由于舍入误差造成的。您可以稍后通过规范化来纠正这一点,但这会导致更多的不准确性。
现在考虑"给定一个马尔可夫链和一个整数k,返回由输入链迭代k次形成的马尔可夫链"操作。您可以看到,这将累积舍入,并遭受与"马尔可夫链命中概率分布"相同的问题。
如果你只能在使用12小时后就坏掉的东西和不必要的不准确的东西之间做出选择,那不是很糟糕吗?
(当然,检查方阵参数的方正性和矩阵性是完全合理的。)