Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/visual-studio/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Visual studio 如何使用序列创建F#中无限集的幂集(组合)?_Visual Studio_Math_F#_Functional Programming - Fatal编程技术网

Visual studio 如何使用序列创建F#中无限集的幂集(组合)?

Visual studio 如何使用序列创建F#中无限集的幂集(组合)?,visual-studio,math,f#,functional-programming,Visual Studio,Math,F#,Functional Programming,这是我在这个问题上失败的尝试,任何帮助都将不胜感激 我试着为在渴望列表上工作的电源组想出最好的算法。这部分似乎工作得很好。我遇到的问题是将它转换为序列,这样它就可以在流\无限列表上运行。我真的不喜欢yield语法,可能是因为我不太理解它,但我宁愿不使用yield语法 //All Combinations of items in a list //i.e. the Powerset given each item is unique //Note: lists are eager so can't

这是我在这个问题上失败的尝试,任何帮助都将不胜感激

我试着为在渴望列表上工作的电源组想出最好的算法。这部分似乎工作得很好。我遇到的问题是将它转换为序列,这样它就可以在流\无限列表上运行。我真的不喜欢yield语法,可能是因为我不太理解它,但我宁愿不使用yield语法

//All Combinations of items in a list
//i.e. the Powerset given each item is unique
//Note: lists are eager so can't be used for infinite
let listCombinations xs =
    List.fold (fun acc x ->
        List.collect (fun ys -> ys::[x::ys]) acc) [[]] xs

//This works fine (Still interested if it could be faster)
listCombinations [1;2;3;4;5] |> Seq.iter (fun x -> printfn "%A" x)

//All Combinations of items in a sequence
//i.e. the Powerset given each item is unique
//Note: Not working
let seqCombinations xs =
    Seq.fold (fun acc x ->
        Seq.collect (fun ys -> 
            seq { yield ys
                  yield seq { yield x
                              yield! ys} }) acc) Seq.empty xs

//All Combinations of items in a sequence
//i.e. the Powerset given each item is unique
//Note: Not working (even wrong type signature)
let seqCombinations2 xs =
    Seq.fold (fun acc x ->
        Seq.collect (fun ys ->
            Seq.append ys (Seq.append x ys)) acc) Seq.empty xs

//Sequences to test on
let infiniteSequence = Seq.initInfinite (fun i -> i + 1)
let finiteSequence = Seq.take 5 infiniteSequence

//This should work easy since its in a finite sequence
//But it does not, so their must be a bug in 'seqCombinations' above
for xs in seqCombinations finiteSequence do
    for y in xs do
        printfn "%A" y

//This one is much more difficult to get to work
//since its the powerset on the infinate sequence
//None the less If someone could help me find a way to make this work
//This is my ultimate goal
let firstFew = Seq.take 20 (seqCombinations infiniteSequence)
for xs in firstFew do
    for y in xs do
        printfn "%A" y

您的
seqCombinations
几乎是正确的,但您没有正确地将其从列表转换为序列。
[[]]
的等价物不是
Seq.empty
,而是
Seq.singleton Seq.empty

let seqCombinations xs =
    Seq.fold (fun acc x ->
        Seq.collect (fun ys -> 
            seq { yield ys
                  yield seq { yield x
                              yield! ys} }) acc) (Seq.singleton Seq.empty) xs
上面的代码适用于有限序列。但对于无限序列,它不起作用,因为它首先尝试到达终点,而对于无限序列,它显然永远不会达到终点

如果你想要一个能处理无限序列的函数,我设法想出了两种方法,但这两种方法都不是特别好。其中一个使用可变状态:

let seqCombinations xs =
    let combs = ref [[]]
    seq {
        yield! !combs
        for x in xs do
            let added = List.map (fun ys -> x::ys) !combs
            yield! added
            combs := !combs @ added
    }
另一个是关于处理
seq
的细节太多了:

open System.Collections.Generic
let-seq组合(xs:seq)=
let rec combs acc(e:IEnumerator)=
序号{
如果(e.MoveNext()),则
let added=List.map(fun ys->(e.Current)::ys)acc
“屈服!”他补充道
收益率!combs(acc@added)e}
使用枚举器=xs.GetEnumerator()
序号{
收益率[]
yield!combs[[]枚举器
}

我认为,如果你能将无限序列视为首尾序列,就像F#中的有限列表或Haskell中的任何序列一样,这会容易得多。但是很有可能有一种很好的方法可以用F#来表达,我只是没有找到它。

我最近在上问了一个类似的问题,得到了一些很好的答案

对于有限集的powerset,上面链接中@Daniel的答案是一个有效的解决方案,可能适合您的目的。您可以拿出一个测试用例来比较他的方法和您的方法

关于无穷集的幂集,这里有一些数学知识。根据,可数无穷集的幂集是不可数无穷的。这意味着即使是以惰性方式,也无法枚举所有整数(可数无限)的幂集。直觉对于实数也是一样的;由于实数是不可数无限的,我们不能用无限序列来模拟它们


因此,没有算法枚举可数无穷集的幂集。或者这种算法根本没有意义。

这有点像一个笑话,但实际上会为无限序列生成正确的结果(只是它无法被证明——从经验上,而不是数学上)


在一组大小为N的功率集中有2^N个元素,因此即使是一组只有60个元素的功率集中,您也会看到约10^18个元素的功率集,您永远无法完全枚举这些元素。通过使用序列而不是列表,您可能会使用更少的内存,但如果您能够更好地解释您的目标,这将是非常有帮助的。我的目标是看看我可以将f#中的惰性求值序列推到多大程度,这似乎是一个简单但足够复杂的问题。我想以绝对最懒惰的方式制作无穷集的幂集,同时保持代码的优雅和良好的性能。这很好,但考虑到幂集中的元素数量多得无法计数,即使是一个中等大小的集,如果您想对结果执行任何操作,但尚未指定顺序,则条目的生成顺序将非常重要。您建议按什么顺序返回值。它们能否以可转位的方式返回?实际上,是否可以根据输入计算索引?谢谢。我想不出一个具体的例子,但也许你正在寻找一个服从某些性质的最小集(你知道存在一个)。当然,对于无穷集的幂集,你不能严格按递增顺序进行(或者你只需要复制Daniel对一个元素子集枚举的开玩笑的解决方案),但是你可能会找到一些你知道会影响你所关心的实例的顺序。非常感谢,这解决了我在有限序列方面的问题。你有什么建议让它支持无限序列吗?或者如何在不使用屈服语法的情况下实现它?谢谢。非常感谢。这正是我要找的。如果有更干净的东西出现,我会感兴趣的。谢谢。@AaronStainback请看一看Fibonnaci数的无限序列的要点,它不使用列表,因为这样可能效率低下,因为在列表末尾追加需要重建整个列表:。出于效率原因,Seq.cache很重要。let rec绑定将生成一个警告,因为这不是一个函数。所有解决方案似乎都适用于
list
,而不是
seq
,因此您不能使用它们来处理无限序列(至少不能直接使用)。您是对的。依我看,找到无限序列的动力集有点奇怪。将powerset建模为列表的惰性序列(或有限序列)似乎更合理。我同意这很奇怪,但这就是问题所在。这很好,这就是我想要的。试着看看必须编写每个函数来处理无限输入的情况。谢谢你的帮助。哇,这真的让我无法用语言表达,它是无限的。谢谢你提供的信息。这是用什么方法计算值的?当我尝试将代码更新为您的定义时,以下seqCombinations infiniteSequence失败,类型为seq@AaronStainback如我所说,这是个玩笑。因为powerset(S)包括空集,而S本身就是结果——只要您愿意观察
open System.Collections.Generic

let seqCombinations (xs : seq<_>) =
    let rec combs acc (e : IEnumerator<_>) =
        seq {
            if (e.MoveNext()) then
                let added = List.map (fun ys -> (e.Current)::ys) acc
                yield! added
                yield! combs (acc @ added) e }

    use enumerator = xs.GetEnumerator()
    seq {
        yield []
        yield! combs [[]] enumerator
    }
let powerset s =
  seq {
    yield Seq.empty
    for x in s -> seq [x]
  }