Rash thoughts about .NET, C#, F# and Dynamics NAV.


"Every solution will only lead to new problems."

Category Theoretische

Monday, 8. December 2008


Project Euler in F# – Problem 53 – Memoization

Filed under: F#,Theoretische — Steffen Forkmann at 17:16 Uhr

Last time I showed how one can solve the Euler Project – problem 53 with the help of Dynamic Programming and a two-dimensional array. This time I will use another technique called (automatic) memoization.

First of all I need a memoization-function. There are two different approaches, one with a System.Collections.Generic.Dictionary and one with an immutable Map. You can read Don Syme’s blog posting to get more information about the differences.

let memoizeWithMap f =
  let cache = ref Map.empty
  fun x ->
    match (!cache).TryFind(x) with
      | Some res -> res
      | None ->
           let res = f x
           cache := (!cache).Add(x,res)
           res
open System.Collections.Generic

let memoizeWithDictionary f =
  let cache = Dictionary<_, _>()
  fun x ->
    let (found,result) = cache.TryGetValue(x)
    if found then
      result
    else
      let res = f x
      cache.[x] <- res
      res

With the help of one of this generic memoization-functions I can create a recursive function for the binomial coefficients, which memoizes intermediate data:

let rec binomial =
  let f (n,k) =
    if k = 0I || n = k then
      1I
    else
      binomial(n - 1I,k) + binomial(n - 1I,k - 1I)
  f |> memoizeWithDictionary

let answer =
      seq { for n in 2I .. 100I do
              for k in 2I .. n -> n,k }
       |> Seq.filter (fun (a,b) -> binomial (a,b) > 1000000I )
       |> Seq.length

answer |> printf "Answer: %A"

It turns out that memoizeWithDictionary is much faster for this problem. But with 160ms it is still slower than the comparable version with a two-dimensional array (45ms).

Tags: , , ,

Project Euler in F# – Problem 53 – Dynamic Programming

Filed under: English posts,F#,Theoretische — Steffen Forkmann at 12:23 Uhr

Claudio Cherubino (from fsharp.it/) posted his solution to Euler Project – problem 53. As I dealed a lot with Dynamic Programming in the recent time, I tried to solve the problem with a dynamic program in F#.

Project Euler – Problem 53:

How many values of C(n,k), for 1 ‚ȧ n ‚ȧ 100, exceed one-million?

Remark: C(n,k) are the binomial coefficients.

As it turned out, this is not that complicated if one knows the recursive function for the binomial coefficients (see Wikipedia):

Recursive definition for the Binomial coefficient with Recursive definition for the Binomial coefficient

This is easily transformed into a F# program:

let binomials = Array2.create 101 101 1I
let answer = ref 0
for n in [1..100] do
  for k in [1..n - 1] do
    binomials.[n, k] <- binomials.[n - 1,k] + binomials.[n - 1,k - 1]
    if binomials.[n, k] > 1000000I then
      answer := !answer + 1

!answer |> printf "Answer: %A"

Claudio’s program took 1315ms on my computer. The dynamic program needs only 63ms. But we can still do better if we use the symmetry of Pascal’s triangle.

Symmetry of Pascal's triangle

This leads to an algorithm, which calculates only half of the binomial coefficients.

let binomials = Array2.create 101 101 1I
let answer = ref 0
for n in [1..100] do
  for k in [1..n/2] do
    let b = binomials.[n - 1,k] + binomials.[n - 1,k - 1]
    binomials.[n, k] <- b
    binomials.[n, n - k] <- b
    if b > 1000000I then
      if k = n-k then
        answer := !answer + 1
      else
        answer := !answer + 2
!answer |> printf "Answer: %A"

This version needs only 45ms – but we are not ready. I mentioned Pascal’s triangle and its symmetry. But we can use another property. We don’t have to calculate the complete row, if we exceed 100000. All values behind this threshold have to be greater.

let binomials = Array2.create 101 101 1I
let answer = ref 0
for n in [1..100] do
  let threshold_reached = ref false
  let c = ref 0
  for k in [1..n/2] do
    if not !threshold_reached then
      let b = binomials.[n - 1,k] + binomials.[n - 1,k - 1]
      binomials.[n, k] <- b
      binomials.[n, n - k] <- b
      if b > 1000000I then
        threshold_reached := true
      else
        c := !c + 1

  if !threshold_reached then
    answer := !answer + (n - 1) - (2 * !c)
!answer |> printf "Answer: %A"

This final version took only 29 ms.

In the next posting I will show a version using memoization.

Tags: , , , ,

Monday, 10. November 2008


A immutable sorted list in F# – part II

Filed under: .NET 3.0,English posts,F#,Informatik,Theoretische — Steffen Forkmann at 13:55 Uhr

Last time I showed how the immutable set implementation in F# can be used to get a immutable sorted list. As a result of using sets, the shown version doesn’t support repeated items. This lack can be wiped out by using an additional dictionary (immutable "Map" in F#) which stores the count of each item.

At first I define two basic helper functions for the dictionary:

module MapHelper =
  let addToMap map idx = 
    let value = Map.tryfind idx map
    match value with
      | Some(x) -> Map.add idx (x+1) map
      | None -> Map.add idx 1 map
      
  let removeFromMap map idx = 
    let value = Map.tryfind idx map
    match value with
      | Some(x) -> 
         if x > 1 then 
           Map.add idx (x-1) map 
         else 
           Map.remove idx map
      | None -> map
      
open MapHelper

Now I can adjust my sorted list implementation:

// a immutable sorted list - based on F# set
type 'a SortedFList =
 {items: Tagged.Set<'a,Collections.Generic.IComparer<'a>>;
  numbers: Map<'a,int>;
  count: int}
   
  member x.Min = x.items.MinimumElement
  member x.Items = 
    seq {
      for item in x.items do            
        for number in [1..x.GetCount item] do
          yield item}
          
  member x.Length = x.count
  member x.IsEmpty = x.items.IsEmpty
  member x.GetCount item = 
    match Map.tryfind item x.numbers with
      | None -> 0
      | Some(y) -> y
    
  static member FromList(list, sortFunction) = 
    let comparer = FComparer<'a>.Create(sortFunction)        
    let m = list |> List.fold_left addToMap Map.empty
      
    {new 'a SortedFList with 
      items = Tagged.Set<'a>.Create(comparer,list) and
      numbers = m and
      count = list.Length}
      
  static member FromListWithDefaultComparer(list) = 
    SortedFList<'a>.FromList(list,compare)    
      
  static member Empty(sortFunction) = 
    SortedFList<'a>.FromList([],sortFunction)
      
  static member EmptyWithDefaultComparer() = 
    SortedFList<'a>.Empty(compare)            
       
  member x.Add(y) =     
    {x with 
      items = x.items.Add(y);
      numbers = addToMap x.numbers y;
      count = x.count + 1} 
    
  member x.Remove(y) =     
    if x.GetCount y > 0 then
      {x with 
        items = x.items.Remove(y);
        numbers = removeFromMap x.numbers y;
        count = x.count - 1}
    else
      x        
Tags: , , , ,

A immutable sorted list in F# – part I

Filed under: .NET 3.0,English posts,F#,Informatik,Theoretische — Steffen Forkmann at 12:06 Uhr

F# supports a powerful implementation of immutable lists (see Dustin’s introduction). But for my current work I needed a sorted list and of course I wanted it the F#-way, which means immutable. I didn’t want to reinvent the wheel so I asked my question in the hubFS forum.

It turned out (thanks to Robert) that F# uses red-black trees to give a fast implementation for the immutable set. This means that a set in F# stores all elements in a balanced binary tree and searching for an element costs only O(log n). As a side effect all elements can be visited in the underlying order, which means the set implementation gives a possibility for implementing a sorted list. The only limitation is that a set usually don’t store objects more than once.

The next problem I got, was that my sorted list needs a specific ordering function. The standard F# set implementation uses structural comparison to give an order, which is not the order I need. But Laurent mentioned the Set.Make function in the F# PowerPack. This function creates a new set type for the given ordering function. The only problem with Set.Make is that it was only designed for OCaml compatibility. But with this hint I was able to put all information together and got a nice immutable sorted list implementation for F#:

// wrap orderingFunction as Collections.Generic.IComparer
type 'a FComparer =
  {compareF: 'a -> 'a -> int}
  static member Create(compareF) =
    {new 'a FComparer with compareF = compareF}
  interface Collections.Generic.IComparer<'a> with
    member x.Compare(a, b) = x.compareF a b    
// a immutable sorted list - based on F# set
type 'a SortedFList =
 {items: Tagged.Set<'a,Collections.Generic.IComparer<'a>> }
   
  member x.Min = x.items.MinimumElement
  member x.Items = seq {for item in x.items do yield item}
  member x.Length = x.items.Count
  member x.IsEmpty = x.items.IsEmpty
    
  static member FromList(list, sortFunction) = 
    let comparer = FComparer<'a>.Create(sortFunction)
    {new 'a SortedFList with 
      items = Tagged.Set<'a>.Create(comparer,list)}
      
  static member FromListWithDefaultComparer(list) = 
    SortedFList<'a>.FromList(list,compare)    
      
  static member Empty(sortFunction) = 
    SortedFList<'a>.FromList([],sortFunction)
      
  static member EmptyWithDefaultComparer() = 
    SortedFList<'a>.Empty(compare)            
       
  member x.Add(y) =     
    {x with items = x.items.Add(y)}    
  member x.Remove(y) =     
    {x with items = x.items.Remove(y)}    

Please note that this implementation stores every item only once. Next time I will show a version which allows to store repeated items.

Tags: , , ,

Friday, 9. May 2008


Vortrag auf der Student Technology Conference 2008

Filed under: .NET,BioInformatik,Dynamics NAV 2009,Informatik,Theoretische,Veranstaltungen — Steffen Forkmann at 12:52 Uhr

Aufgrund einer Sprecherabsage, habe ich kurzfristig einen Vortrag auf der STC 2008 bekommen. Die Veranstaltung steht dieses Jahr unter dem Motto “GreenIT”. Mein Vortrag wird deshalb auch etwas “grüner” als ein “normaler” Navision-Vortrag:

Die Umwelt schonen und gleichzeitig Kosten sparen
Tourenoptimierung in Dynamics NAV

Die strategische Tourenplanung für große Flotten ist ein so komplexes Problem, dass man keine optimale Lösung in vertretbarer Zeit berechnen kann. Der einzige Ausweg führt über intelligente Heuristiken, die in kurzer Zeit Lösungen liefern, die möglichst nah an der optimalen Lösung liegen und damit helfen die Fahrtkosten und den Benzinverbrauch zu minimieren. Der Vortrag stellt einige dieser Verfahren vor und zeigt wie eine Implementation im ERP-System ‚ÄěMicrosoft Dynamics NAV‚Äú aussehen könnte.

Gleichzeitig bekomme ich auch die Gelegenheit als einer der ersten die neue Navision-Version “Dynamics NAV 2009″ öffentlich zu zeigen.

Weitere Informationen gibt es in der Agenda.

Tags: , , , ,

Wednesday, 22. November 2006


Überflüßige Hochkommata entfernen

Filed under: Navision,Theoretische — Steffen Forkmann at 13:38 Uhr

Oft machen Zollzeichen im Text (z.B. bei¬†Monitor 17″) Probleme beim Import mit Navision-Dataports, da der Dataport diese fälschlicherweise als Trennzeichen interpretiert.¬†Wenn man die ungewollten Zollzeichen im Text weg haben will, kann man diese einfach per RegEx ersetzen lassen.

Dazu kann man z.B.¬†PsPad benutzen,¬†um¬†dann die Fundstellen des Regulären Ausdrucks¬†([^;])(“)([^;]) durch $1′$3 ersetzen zu lassen. Damit werden alle “ungewollten” Hochkommata in umgewandelt.

Tags: , , , ,

Wednesday, 25. January 2006


Ein neuer Compiler in einer Stunde [ein Nightcast]

Filed under: C#,Theoretische,WebCasts — Steffen Forkmann at 8:30 Uhr

In diesem Nightcast möchte Bernd Marquardt ein interessantes Thema aufgreifen. Er will in einer Stunde einen kleinen Sprach-Compiler entwickeln. Geplant sind ein kleine Einführung in Compilerbau und dann natürlich das Praktische also der Code, der notwendig ist, um einen eigenen Sprach-Compiler mit .NET zu entwickeln.

Sunday, 15. January 2006


Empirisches Gesetz der Fehler

Filed under: Theoretische — Steffen Forkmann at 17:10 Uhr

Manchmal denke ich wirklich das folgende “Gesetz” hat uneingeschränkte Gültigkeit:

Daraus folgt, dass wenn das Problem hinreichend komplex ist, kann man zwar die Anzahl der auftretenen Bugs minimieren, aber die schädlichen Auswirkungen der übriggebliebenen bzw. neu entstandenen Bugs werden damit umso größer. Zum Glück gibt es dann aber noch Donald E. Knuth, der einen immer wieder eines Besseren belehren kann: “Beware of bugs in the above code; I have only proved it correct, not tried it.”

Wednesday, 22. June 2005


Webcast von Bernd Marquardt zu regulären Ausdrücken unter .NET

Filed under: .NET,Theoretische,WebCasts — Steffen Forkmann at 17:31 Uhr

Bernd Marquardt hält am 05.07.2005 von 16:00 bis 17:00 Uhr einen Webcast zum Thema reguläre Ausdrücke und Ihre Verwendung unter .NET. Neben der Erläuterung der Syntax sollen viele Beispiele mit der Regex-Klasse des .NET-Frameworks gezeigt werden.

Danach wird der Webcast sicher auch wieder zum Download bereit stehen.

Tags: , , , ,

Monday, 20. June 2005


RegEx Regulärer Ausdruck

Filed under: Theoretische — Steffen Forkmann at 8:46 Uhr

Laut Theorie kann man mit regulären Ausdrücken bekanntlich keine beliebig tiefen Klammerstrukturen analysieren. Mit einem modernen RegEx-Parser geht das trotzdem:

\(
    (?>
        [^()]+
           |    \( (?<number>)
           |    \) (?<-number>)
    )*
    (?(number)(?!))
\)

Das liefert zumindest die größten balancierten Klammerausdrücke in einem Text.

Also aus “blabla () + (3*(5+3)*4) blah” werden die beiden Matches “()” und “(3*(5+3)*4)” gefunden.

Die Folge ist, dass ein RegEx-Parser echt mächtiger ist als ein regulärer Ausdruck.

Tags: