- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
当repl变量设置为false时,以下函数为什么返回不正确的长度序列?
open MathNet.Numerics.Distributions
open MathNet.Numerics.LinearAlgebra
let sample (data : seq<float>) (size : int) (repl : bool) =
let n = data |> Seq.length
// without replacement
let rec generateIndex idx =
let m = size - Seq.length(idx)
match m > 0 with
| true ->
let newIdx = DiscreteUniform.Samples(0, n-1) |> Seq.take m
let idx = (Seq.append idx newIdx) |> Seq.distinct
generateIndex idx
| false ->
idx
let sample =
match repl with
| true ->
DiscreteUniform.Samples(0, n-1)
|> Seq.take size
|> Seq.map (fun index -> Seq.item index data)
| false ->
generateIndex (seq [])
|> Seq.map (fun index -> Seq.item index data)
sample
let requested = 1000
let dat = Normal.Samples(0., 1.) |> Seq.take 10000
let resultlen = sample dat requested false |> Seq.length
printfn "requested -> %A\nreturned -> %A" requested resultlen
>
requested -> 1000
returned -> 998
>
requested -> 1000
returned -> 1001
>
requested -> 1000
returned -> 997
最佳答案
首先,我想谈一谈编码风格。然后,我将解释为什么您的序列以不同的长度返回。
在评论中,我提到了用简单的match (bool) with true -> ... | false -> ...
表达式替换if ... then ... else
的方法,但是您使用的是另一种编码风格,我认为可以改进。你写了:
let sample (various_parameters) = // This is a function
// Other code ...
let sample = some_calculation // This is a variable
sample // Return the variable
let f (a : float option) =
let a = match a with
| None -> 0.0
| Some value -> value
// Now proceed, knowing that `a` has a real value even if had been None before
defaultArg
的原因:
let f (a : float option) =
let a = defaultArg a 0.0
// This does exactly the same thing as the previous snippet
a
引用的类型不同于名为
a
的参数的类型:参数为
float option
,而函数内的
a
为
float
。但它们属于“相同”类型-也就是说,“调用方可能已指定浮点值或未指定浮点值”与“现在我肯定有浮点值”之间在精神上几乎没有什么区别。 。但是,“
sample
名称是一个带有三个参数的函数”与“
sample
名称是浮点数的序列”之间存在很大的思维鸿沟。我强烈建议您使用诸如
result
之类的名称作为要从函数返回的值,而不是重复使用函数名。
let result =
match repl with
| true ->
DiscreteUniform.Samples(0, n-1)
|> Seq.take size
|> Seq.map (fun index -> Seq.item index data)
| false ->
generateIndex (seq [])
|> Seq.map (fun index -> Seq.item index data)
result
(something)
替换整个代码块。也就是说,以上代码段可能只是:
match repl with
| true ->
DiscreteUniform.Samples(0, n-1)
|> Seq.take size
|> Seq.map (fun index -> Seq.item index data)
| false ->
generateIndex (seq [])
|> Seq.map (fun index -> Seq.item index data)
if...then...else
表达式:
if repl then
DiscreteUniform.Samples(0, n-1)
|> Seq.take size
|> Seq.map (fun index -> Seq.item index data)
else
generateIndex (seq [])
|> Seq.map (fun index -> Seq.item index data)
open MathNet.Numerics.Distributions
open MathNet.Numerics.LinearAlgebra
let sample (data : seq<float>) (size : int) (repl : bool) =
let n = data |> Seq.length
// without replacement
let rec generateIndex idx =
let m = size - Seq.length(idx)
if m > 0 then
let newIdx = DiscreteUniform.Samples(0, n-1) |> Seq.take m
let idx = (Seq.append idx newIdx) |> Seq.distinct
generateIndex idx
else
idx
if repl then
DiscreteUniform.Samples(0, n-1)
|> Seq.take size
|> Seq.map (fun index -> Seq.item index data)
else
generateIndex (seq [])
|> Seq.map (fun index -> Seq.item index data)
generateIndex
函数中发生的事情为您带来了意想不到的结果。有两件事会让您烦恼:一是序列懒惰,另一是随机性。
generateIndex
函数复制到VS Code中,并添加了一些
printfn
语句以查看发生了什么。首先,我运行的代码,然后是结果:
let rec generateIndex n size idx =
let m = size - Seq.length(idx)
printfn "m = %d" m
match m > 0 with
| true ->
let newIdx = DiscreteUniform.Samples(0, n-1) |> Seq.take m
printfn "Generating newIdx as %A" (List.ofSeq newIdx)
let idx = (Seq.append idx newIdx) |> Seq.distinct
printfn "Now idx is %A" (List.ofSeq idx)
generateIndex n size idx
| false ->
printfn "Done, returning %A" (List.ofSeq idx)
idx
List.ofSeq idx
调用都是这样,以便F#Interactive在我打印出seq时会打印多于四个的seq(默认情况下,如果您尝试使用
%A
打印一个seq,它将仅打印出四个值,然后在省略号时打印省略号seq中有更多可用值)。另外,我将
n
和
size
转换为参数(在两次调用之间不必更改),以便可以轻松对其进行测试。然后,我将其称为
generateIndex 100 5 (seq [])
并得到以下结果:
m = 5
Generating newIdx as [74; 76; 97; 78; 31]
Now idx is [68; 28; 65; 58; 82]
m = 0
Done, returning [37; 58; 24; 48; 49]
val it : seq<int> = seq [12; 69; 97; 38; ...]
seq
是
lazy 。他们不评估自己的内容,除非必须这样做。您不应该将
seq
视为数字列表。取而代之的是,将其视为一种生成器,当要求输入数字时,它将根据某些规则生成数字。在您的情况下,规则是“选择0到
n
-1之间的随机整数,然后采用这些数字的
m
”。关于
seq
的另一件事是它们不缓存其内容(尽管有一个
Seq.cache
函数可以缓存其内容)。因此,如果您有一个基于随机数生成器的
seq
,则每次生成的结果都会不同,正如您在我的输出中看到的那样。当我打印出
newIdx
时,它打印为[74; 76; 97; 78; 31],但是当我将其附加到一个空序列时,结果打印为[68; 28; 65; 58; 82]。
Seq.append
会执行
而不是强制评估。它只是创建一个新的
seq
,其规则是“从第一个序列中取出所有项目,然后在第二个序列中消耗完时,从第二个序列中取出所有项目。而当一个耗尽时,结束。
Seq.distinct
也不强制评估;它只是创建一个新的
seq
,其规则是“从递给您的
seq
中取出项目,并在被询问时开始分发。但是请记住它们,如果您以前曾分发过其中一个,请不要再次分发。”因此,在调用
generateIdx
之间传递的是一个对象,该对象在被求值时会选择一组介于0和n-1之间的随机数(在我的简单情况下,介于0和100之间),然后将其减少为一组不同的数字。
seq
时,它都会从头开始:首先调用
DiscreteUniform.Samples(0, n-1)
生成无限的随机数流,然后从该流中选择
m
数字,然后丢弃所有重复项。 (我现在暂时忽略了
Seq.append
,因为它会造成不必要的心理复杂性,而且无论如何它实际上都不是错误的一部分)。现在,在每次执行功能时,您都要检查序列的长度,这确实会导致对其进行求值。这意味着(在我的示例代码中)它选择了0到99之间的5个随机数,然后确保它们都是不同的。如果它们都是不同的,则
m
= 0且函数将退出,返回...不是数字列表,而是
和seq
对象。并且当对该
seq
对象求值时,它将从头开始,选择5个随机数的不同集合,然后丢弃所有重复项。因此,仍然有机会在这5个数字中至少有一个最终成为重复项,因为长度经过测试的序列(我们知道该序列不包含重复项,否则
m
会大于0)不是返回的序列。返回的序列有1.0 * 0.99 * 0.98 * 0.97 * 0.96的机会不包含任何重复项,约为0.9035。因此,即使您检查了
Seq.length
并将其设为5,也有不到10%的机会,毕竟返回的
seq
的长度最终为4-因为它选择的是与您检查的一组不同的随机数。
generateIndex 100 4 (seq [])
运行产生了以下输出:
m = 4
Generating newIdx as [36; 63; 97; 31]
Now idx is [39; 93; 53; 94]
m = 0
Done, returning [47; 94; 34]
val it : seq<int> = seq [48; 24; 14; 68]
idx
的值)”时,它只有3个值吗?即使最终返回了4个值(因为它为实际结果选择了不同的随机数选择,并且该选择没有重复项),也证明了问题所在。
Seq.item
必须从头开始遍历整个序列,以便选择序列中的
n
第一项。最好在函数开始时将数据存储在数组中(
let arrData = data |> Array.ofSeq
),然后替换
|> Seq.map (fun index -> Seq.item index data)
|> Seq.map (fun index -> arrData.[index])
Seq.distinct
,从中获取m
值,该错误将消失。您可以将整个generateIdx
函数替换为简单的DiscreteUniform.Samples(0, n-1) |> Seq.distinct |> Seq.take size
。 (并使用数组进行数据查找,以便您的函数运行更快)。换句话说,这是最终几乎-我将如何重写代码的最终版本:let sample (data : seq<float>) (size : int) (repl : bool) =
let arrData = data |> Array.ofSeq
let n = arrData |> Array.length
if repl then
DiscreteUniform.Samples(0, n-1)
|> Seq.take size
|> Seq.map (fun index -> arrData.[index])
else
DiscreteUniform.Samples(0, n-1)
|> Seq.distinct
|> Seq.take size
|> Seq.map (fun index -> arrData.[index])
Seq.take size |> Seq.map
表达式的两个分支中都重复if
,因此有一种方法可以简化该表达式。我们可以这样做:let randomIndices =
if repl then
DiscreteUniform.Samples(0, n-1)
else
DiscreteUniform.Samples(0, n-1) |> Seq.distinct
randomIndices
|> Seq.take size
|> Seq.map (fun index -> arrData.[index])
let sample (data : seq<float>) (size : int) (repl : bool) =
let arrData = data |> Array.ofSeq
let n = arrData |> Array.length
let randomIndices =
if repl then
DiscreteUniform.Samples(0, n-1)
else
DiscreteUniform.Samples(0, n-1) |> Seq.distinct
randomIndices
|> Seq.take size
|> Seq.map (fun index -> arrData.[index])
关于f# - 函数生成的长度不正确的序列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42149449/
我正在阅读 Python 文档以真正深入了解 Python 语言,并遇到了 filter 和 map 函数。我以前使用过过滤器,但从未使用过映射,尽管我在 SO 上的各种 Python 问题中都见过这
当我尝试打印 BST 的级别顺序时,这个问题提示了我。 这是一个 Pre-Order Sequence: 4, 1, 2, 3, 5, 6, 7, 8 In_order Sequence : 1, 2
我的代码在 main(序列测试;)的第一行出现错误,指出它是对 sequence::sequence() 的 undefined reference 。我无法更改 main 中的代码。有谁知道我该如何
这可能很简单,但我在通常的 latex 指南中找不到任何相关内容。在这句话中: {\em hello\/} “\/”的目的是什么? 最佳答案 这就是所谓的斜体校正。其目的是确保斜体文本后有适当的间距。
当我从 Postgresql 表中删除所有记录,然后尝试重置序列以在插入时开始一个编号为 1 的新记录时,我得到不同的结果: SELECT setval('tblname_id_seq', (SELE
在版本10.0.3中,MariaDB引入了一种称为序列的存储引擎。 其ad hoc为操作生成整数序列,然后终止。 该序列包含正整数,以降序或升序排列,并使用起始,结束和递增值。 它不允许在多个查询中
如何在 Groovy 中获取给定数字的序列,例如: def number = 169 // need a method in groovy to find the consecutive number
基本上,如果这是 .NET,它看起来像这样: ISomething { string A { get; } int B { get; } } var somethings = new List
说以下代码部分(同一块): A <= 1 A <= 2 变量 A 总是被赋值为 2 吗?还是会出现竞争条件并分配 1 或 2? 我对非阻塞赋值的理解是,由硬件在 future 分配变量 A,因此它可能
在运行 WiX 设置时,我正在寻找操作列表及其顺序。不知何故,官方网站似乎没有提供任何信息。 基本问题是我想正确安排我的自定义操作。通常我需要使用 regsvr32.exe 注册一个 DLL,而这只能
F#初学者在这里 我想创建一个类型,它是具有至少一个元素的另一种具体类型(事件)的序列。任何其他元素都可以在以后随时添加。通常在 C# 中,我会创建一个具有私有(private) List 和公共(p
作为构建过程和不断发展的数据库的一部分,我试图创建一个脚本,该脚本将删除用户的所有表和序列。我不想重新创建用户,因为这将需要比所允许的更多的权限。 我的脚本创建了一个过程来删除表/序列,执行该过程,然
我想恢复两个向量的第一个日期和相同向量的第二个日期之间的日期序列,.... 这是一个例子: dates1 = as.Date(c('2015-10-01', '2015-03-27', '2015-0
这个问题已经有答案了: sql ORDER BY multiple values in specific order? (12 个回答) 已关闭 9 年前。 我有一个 sql 语句,我想要ORDER
我想恢复两个向量的第一个日期和相同向量的第二个日期之间的日期序列,.... 这是一个例子: dates1 = as.Date(c('2015-10-01', '2015-03-27', '2015-0
在用java编写代码时,我需要用“],[”分割字符串。下面是我的代码。 try (BufferedReader reader = new BufferedReader(new InputStreamR
这个问题已经有答案了: Project Euler Question 14 (Collatz Problem) (8 个回答) 已关闭 9 年前。 我正在尝试查找数字的 Collatz 序列。以下
我有一个例程函数process_letter_location(const char& c, string &word)。 在我的 main 中,我声明了一系列字符串变量,如下所示: string s
我需要找到最长的多米诺骨牌链,给定一组 12 个随机挑选的多米诺骨牌。我已经递归地生成了多米诺骨牌的所有可能性(使用 0 到 12 的面值有 91 种可能性)。多米诺骨牌由一 block “砖 blo
我有这个数据结构 Seq,它继承了类 vector 但有一些额外的功能。使用这个数据结构 Seq 我有这个预定义的数据结构: typedef Seq > MxInt2d; 我现在想要一个包含多个 Mx
我是一名优秀的程序员,十分优秀!