为什么在下面的代码块中需要while循环?摘自R/examics包中提供的dist3练习。
sc <- NULL
while (is.null(sc)) {
p <- c(sample(1:3, 1), sample(1:5, 1))
q <- c(sample(4:5, 1), sample((1:5)[-p[2]], 1))
sol <- sqrt(sum((p - q)^2))
err <- c(sqrt(sum((p + q)^2)), sqrt(sum(abs(p - q))))
err <- err[abs(err - sol) > 0.1]
if (length(err) > 1) err <- sample(err, 1)
sc <- num_to_schoice(sol, wrong = err,
range = c(0.1, 10), delta = 0.3, digits = 3)
}
通常,函数num_to_schoice()
(在本例中负责更新while循环条件所依据的变量sc
(不能保证返回包含$questions
文本和相应逻辑$solutions
的列表。相反,当它无法设置具有指定属性(范围、最小距离等(的问题/解决方案时,它可能会返回NULL
并发出警告。请参阅下面的一些说明。
因此,为了保证依赖于num_to_schoice()
的练习总是产生有效的解决方案,首先用NULL
初始化单选列表sc
,然后重新采样参数并调用num_to_schoice()
,直到sc
不再是NULL
(而是一个包含问题/解决方案的列表((备注:我在自己的练习中经常使用这个设置,通常不检查是否真的会发生任何问题。在这个特定的设置中,NULL值的问题似乎永远不会发生。(
为了说明,考虑以下简单的例子,其中正确的解是10,我们希望正确解和任何错误解之间的delta
至少为1,并且我们对错误解使用不同的范围。
-
首先,让我们使用范围[1,20],它总是找到一些错误的解。
set.seed(2021) num_to_schoice(10, range = c(1, 20), delta = 1, digits = 0) ## $solutions ## [1] FALSE FALSE FALSE TRUE FALSE ## ## $questions ## [1] "$16$" "$17$" "$7$" "$10$" "$13$"
-
相反,对于最小距离为1的四个伪解,区间[9,11]永远不够大。
num_to_schoice(10, range = c(9, 11), delta = 1, digits = 0) ## NULL ## Warning message: ## In num_to_schoice(10, range = c(9, 11), delta = 1, digits = 0) : ## specified 'range' is too small for 'delta'
-
最后,间隔[7,13]可能足够大,也可能不够大。这取决于在
num_to_schoice()
中执行的初始步骤,其中函数首先决定四个错误解中有多少应该在正确解的左侧与右侧。这是内置在函数中的,以避免系统地生成正确解决方案是最小或最大的问题列表。num_to_schoice(10, range = c(7, 13), delta = 1, digits = 0) ## $solutions ## [1] FALSE FALSE TRUE FALSE FALSE ## ## $questions ## [1] "$7$" "$13$" "$10$" "$11$" "$9$" num_to_schoice(10, range = c(7, 13), delta = 1, digits = 0) ## NULL ## Warning message: ## In num_to_schoice(10, range = c(7, 13), delta = 1, digits = 0) : ## specified 'range' is too small for 'delta'
如果预先指定的wrong
解决方案与正确的解决方案过于接近和/或使间隔过小等,则可能会发生更多不可能的设置。有关更多插图,请参阅?num_to_schoice
中的示例。