2010-06-22 29 views
8

Belirli bir konu hakkında soru sormak için buradayım - Bu konuda internette çok az bilgi buldum. Minimax algoritmasının F # sürümünü uyguluyorum. Şu an sahip olduğum sorun şu ki, Ağacımın Yapraklarını karşılaştırmak istiyorum (aşağıdaki veri yapısı). VS bana verdi hatalara aranıyor böyle bir şey geldi:F # tuple'da CustomComparison ve CustomEquality ile özel karşılaştırmanın uygulanması

kullandığım ağaç türü olması:

type TreeOfPosition = 
    | LeafP of Position 
    | BranchP of Position * TreeOfPosition list 

ve de IComparable

type staticValue = int 
[<CustomEquality;CustomComparison>] 
type TreeOfPosition = 
    | LeafP of Position * staticValue 
    | BranchP of Position * TreeOfPosition list 

    override x.Equals(yobj) = 
     match yobj with 
     | :? TreeOfPosition as y -> (x = y) 
     | _ -> false 

    override x.GetHashCode() = hash (x) 
    interface System.IComparable with 
     member x.CompareTo yobj = 
      match yobj with 
      | :? TreeOfPosition as y -> compare (x) (y) 
      | _ -> invalidArg "yobj" "cannot compare value of different types" 

uygulanması için temptative Sonunda, StatP'nin bir listesinin maksimum değerini (ve min) statik değeriyle (diğer fonksiyonlarda hesapla) elde etmek istiyorum.

Yukarıdaki kod derleniyor. Ancak bu ile test:

let p = new Position() 
p.Add(1,BLACK) 
let a = LeafP(p,1) 
let b = LeafP(p,2) 

let biger = compare a b 
printf "%d" biger 

Ben bir System.StackOverflowException var "|:? Y olarak TreeOfPosition -> (x) (y) karşılaştırmak" GetHashCode önünün çizgi.

Hubims.net'te (http://cs.hubfs.net/forums/thread/15891.aspx) bir iş parçacığım var, Minimax'ımı görüşüyorum. Burada benim en son kod (http://www.inf.ufrgs.br/~pmdusso/works/Functional_Implementation_Minimax_FSharp.htm) önceden

sayesinde

Pedro Dusso

Eh bulabilirsiniz, ben çok net fikir anlaşılan ama işe yapamazsınız. Yaprakların bir listeden maksimum statik değer elde etmek istediğimi hatırlamak (“List.max”: P), CompareTo veya Equals'u uygulamak, List.max'ın üzerlerinde çalışmasına izin verecek, doğru mu? böyle şeyler oluşturmak: Ben işlevleri bu şekilde düzenlenmesi yaşıyorum

let mycompare x y = 
    match x, y with 
    // Compare values stored as part of your type 
    | LeafP(_, n1), LeafP(_, n2) -> compare n1 n2 
    //| BranchP(_, l1), BranchP(_, l2) -> compare l1 l2 //I do not need Branch lists comparison 
    | _ -> 0 // or 1 depending on which is list... 

[<CustomEquality;CustomComparison>] 
type TreeOfPosition = 
    | LeafP of Position * int 
    | BranchP of Position * TreeOfPosition list 

    override x.Equals(yobj) = 
     match yobj with 
     | :? TreeOfPosition as y -> (x = y) 
     | _ -> false 

    override x.GetHashCode() = hash (x) 
    interface System.IComparable with 
     member x.CompareTo yobj = 
      match yobj with 
      | :? TreeOfPosition as y -> mycompare x y 
      | _ -> invalidArg "yobj" "cannot compare value of different types" 

sorunları:

1) desen ayırt edici 'LeafP' tanımlı değil (ile LeafP-kırmızı altı çizili)

2) (77,39): hata FS0039: Değer veya yapıcı 'mycompare' tanımlanmadı, ALT ENTER tuşuna bastığımda bu mesaj F # Interactive'imde görünür. {77,39} konumu, mycompare çağrısının başlangıcına karşılık gelir (GetHashCode'da).

Neyi yanlış yapıyorum? Daha iyi ne yapabilirim?

Çok teşekkürler,

Pedro Dusso

DÜZENLEME 3 - Çözüldü

Evet! Cevabınızı işin finalinde yönetiyorum!

son kod buradadır: geribildirim için

[<CustomEquality;CustomComparison>] 
type TreeOfPosition = 
    | LeafP of Position * int 
    | BranchP of Position * TreeOfPosition list 

    //Func: compare 
    //Retu: -1: first parameter is less than the second 
    //  0: first parameter is equal to the second 
    //  1: first parameter is greater than the second 
    static member mycompare (x, y) = 
     match x, y with 
     // Compare values stored as part of your type 
     | LeafP(_, n1), LeafP(_, n2) -> compare n1 n2 
     | _ -> 0 // or 1 depending on which is list... 

    override x.Equals(yobj) = 
     match yobj with 
     | :? TreeOfPosition as y -> (x = y) 
     | _ -> false 

    override x.GetHashCode() = hash (x) 
    interface System.IComparable with 
     member x.CompareTo yobj = 
      match yobj with 
      | :? TreeOfPosition as y -> TreeOfPosition.mycompare(x, y) 
      | _ -> invalidArg "yobj" "cannot compare value of different types" 

teşekkürler!compare fonksiyon karşılaştırmakta olduğunuz değerler (yani x.ComaperTo(y) olan) ait CompareTo yöntemi çağrıları için tüm

Pedro Dusso

cevap

6

Öncelikle, istisna alıyoruz. compare'u CompareTo'un özel uygulamasında kullanarak karşılaştırdığınız değerler, karşılaştırmanız istenen (çalışma zamanı) değerlerdir, bu nedenle yığın taşmasına neden olur.

CompareTo veya Equals'u uygulamak için olağan yöntem, yalnızca türünüzde depoladığınız bazı değerleri karşılaştırmaktır.

DÜZENLEME: Örneğin, böyle bir şey yazabilirsiniz Sen karşılaştırma yapmak için bir yardımcı işlevi mycopare yazabilir (veya sadece CompareTo uygulanmasını değiştirebilir). Bununla birlikte, bir işlevi kullanmak istiyorsanız, tür bildirimi içine almanız gerekir (böylelikle bu tür hakkında bilgi sahibi olur - Not F öğesinde, bildirim sırası önemlidir!)

Yazmanın bir yolu, Bu: compare her çağrı verilerin sadece bir kısmını alır, çünkü

[<CustomEquality; CustomComparison >] 
type TreeOfPosition = 
    | LeafP of Position * int 
    | BranchP of Position * TreeOfPosition list 

    override x.Equals(yobj) = 
    match yobj with 
    | :? TreeOfPosition as y -> 
     // TODO: Check whether both y and x are leafs/branches 
     // and compare their content (not them directly) 
    | _ -> false 
    override x.GetHashCode() = // TODO: hash values stored in leaf/branch 

    interface System.IComparable with 
    member x.CompareTo yobj = 

     // Declare helper function inside the 'CompareTo' member 
     let mycompare x y = 
     match x, y with 
     // Compare values stored as part of your type 
     | LeafP(_, n1), LeafP(_, n2) -> compare n1 n2 
     | BranchP(_, l1), BranchP(_, l2) -> compare l1 l2 
     | _ -> -1 // or 1 depending on which is list... 

     // Actual implementation of the member 
     match yobj with 
     | :? TreeOfPosition as y -> mycompare x y 
     | _ -> invalidArg "yobj" "cannot compare value of different types" 

Bu, çalışacak, böylece bazı ilerlemeler yapıyoruz.

+0

Hey, kendi gönderimi düzenledim .. Bunun size geri bildirim vermenin doğru yolu olup olmadığını bilmiyorum ... Eğer değilse, hemen değiştirebilirim! Teşekkürler, Pedro Dusso –

+0

@ Pmdusso: Evet, bence bu soruyu genişletmenin iyi bir yolu. Daha eksiksiz bir örnek vermek için cevabımı güncelledim - yalnızca bir işlevi önceden bildirmek (tip bildirimi öncesinde) işe yaramadı. –