質問

私は特定のトピックを尋ねるためにここにいます - 私は本当にウェブ上でこれに関する情報をほとんど見つけませんでした。 MinimaxアルゴリズムのF#バージョンを実装しています。私が今抱えている問題は、私の木の葉を比較したいということです(以下のデータ構造)。 VSが私に与えたエロを検索すると、私はこのようなものに到着しました:

私が持っていたツリータイプ:

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

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"

最終的に、leafpのリストの最大値(および最小)をその静的値(他の関数で計算)で取得したいだけです。

上のコードがコンパイルされています。ただし、これでのテスト:

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

gethashcodeのオーバーライドの「|:?treeofposition as y-> compare(x)(y)」ラインでSystem.StackoverFlowExceptionを取得しました。

hubfs.netにスレッドがあります(http://cs.hubfs.net/forums/thread/15891.aspx)私は私のミニマックスについて話し合っています。ここでは、私の最新コードを見つけることができます(http://www.inf.ufrgs.br/~pmdusso/works/functional_implementation_minimax_fsharp.htm)

前もって感謝します、

ペドロデュッソ

まあ、私はそのアイデアを非常にはっきりと理解していましたが、それを機能させることはできません。葉のリストから最大値の葉を取得したいことを思い出してください(「list.max」:p)、実装していると思います CompareTo また Equals list.maxがそれらに動作するようにしますか、正しいですか?私はこのようなものを構成します:

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" 

この方法で機能を整理している問題は、次のとおりです。

1)パターンの識別器「leafp」は定義されていません(leafp red-underlinged)

2)(77,39):エラーFS0039:値またはコンストラクター「mycompare」は定義されていません。位置{77,39}は、MyCompareコールの開始(GethashCode)に対応しています。

私は何が間違っているのですか?私は何がもっといいですか?

どうもありがとう、

ペドロデュッソ

編集3-解決しました

はい!私はあなたの答えを最終的に仕事に管理しています!

最終コードはこちらです:

[<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" 

フィードバックをお寄せいただきありがとうございます!

ペドロデュッソ

役に立ちましたか?

解決

まず第一に、あなたは例外を取得しています compare 関数はを呼び出します CompareTo 比較している値の方法(つまり、 x.ComaperTo(y))。使用している値を使用しています compare のカスタム実装で CompareTo (ランタイムまでに)比較するように求められる値であるため、これによりスタックオーバーフローが発生します。

実装する通常の方法 CompareTo また Equals あなたがあなたのタイプに保存するいくつかの値のみを比較することです。たとえば、次のようなものを書くことができます。

編集: :ヘルパー関数を書くことができます mycopare 比較を行うために(または単に変更することもできます CompareTo 実装)。ただし、関数を使用する場合は、タイプ宣言の内側に移動する必要があります(タイプについて知っているように - F#では、宣言の順序が重要であることに注意してください!)

それを書く1つの方法はこれです:

[<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" 

これは、すべての呼び出しがあるため、機能します compare データの一部しか取っていないので、いくらか進歩しています。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top