Hi,
using sequence expressions (as in the sample from James) makes many constructs like this quite simple, but it definitely takes some time to learn how to use them - and this is quite unique F# feature, so it's unfortunatelly hard to find samples in other languages that you could just rewrite.

Anyway, I implemented a function for calculating permuations here, so it may help:
[link:stackoverflow.com]

T.

By on 12/11/2008 6:00 PM ()

Below is a version using sequence comprehensions. If your input sequences are arrays then writing a nested-loop array specific version may be faster...

1
2
3
4
5
// "Extend" Seq module with a product
module Seq =
    let product xs ys = { for x in xs do for y in ys do yield x,y }

For F# code highlighting mark-up / quotation in hubfs forums, see here:[link:cs.hubfs.net]

By on 12/11/2008 11:55 AM ()

Use of some form of comprehension did occur to me because I do quite a lot of work in Python. The problem is that I do not have input data consisting of two sequences of something. My data looks like an arbitrary number of sequences which need to be CP'd out, e.g.

1
 [[1; 2]; [3; 4; 5]; [6; 13]; [7; 8; 9; 10; 11]] 

Thanks for the code markup hint. I'll go back and tidy mine up.

The permutations example will be useful for getting started - I'll need to modify it to handle k-permutations. The domain I work in is just full of things composed of k-permutations and k-subsets... e.g. quite often I need to generate the cartesian product of three sets of all 3-subsets of three input sets. Is there something like the Python Cookbook website for F# where people contribute snippets and debate them?

By on 12/11/2008 6:48 PM ()

Hello,

In case you just need .net implementation of combinatorics functions you can see to Iridium project
(MathNet.Numerics.Combinatorics class)

By on 12/12/2008 1:06 AM ()

The product of (n+1) sets can be written in terms of the product of n sets. That allows the enumeration to be written recursively.

1
2
3
4
5
6
7
8
9
10
11
/// Given a list of sets (sequences) [x1s;x2s;etcs...]
/// Return the product containing [x1;x2;etc...] for x1 in x1s, x2 in x2s, ...
//
//  The recursive step follows:
//     x1s * x2s * x3s * ... = x1s * (x2s * x3s * ...)
let rec products xss =
    match xss with
    | []                  -> seq { yield [] }
    | x1s :: x2s_x3s_etcs -> seq { for x1 in x1s do
                                   for x23etc in products x2s_x3s_etcs do
                                   yield x1 :: x23etc }
By on 12/12/2008 5:16 AM ()

and here is another version...

1
2
3
4
5
6
7
8
9
let cons (x,xs) = x::xs
let product2 xs ys = seq { for x in xs do for y in ys do yield x,y }
let rec productN xs = 
    match xs with
    | []        -> seq { yield [] }
    | xs :: xss -> product2 xs (productN xss) |> Seq.map cons

productN [[1;2];[3;4];[5;6]] |> Seq.to_array // arrays show more than seqs
By on 12/12/2008 5:18 AM ()

Thanks. I'm certainly going to be better off with your lazy versions given some of my expected input sizes and space considerations.

Iridium looks like a good source for Combinatorics functions although I'll probably want to work through these in F# and post my questions here - because (1) it's educational and (2) it's good to get this kind of thing online where it can be googled by others.

By on 12/12/2008 7:27 PM ()
IntelliFactory Offices Copyright (c) 2011-2012 IntelliFactory. All rights reserved.
Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy
Built with WebSharper