2016-07-28 8 views
0

最小値を返す関数 'getMin'があります。この関数は、この最小値を決定するために別の関数 'urvalFun'を使用します。最小値を取得

urvalFun 3 ("a","b",0.304) [("a","b",0.304),("a","d",0.52),("a","e",0.824)] 

これは-1.03999と評価されます:ここでは、重要である唯一の事は、私が評価する場合、そのコードのこのchunckを理解する必要はない「urvalFun」

get1:: (String,String,Double) -> String 
get1 (x,_,_) = x 

get2 :: (String,String,Double)-> String 
get2 (_,x,_) = x 

get3:: (String,String,Double)->Double 
get3 (_,_,x) = x 

distDiff:: String-> String->[(String,String,Double)] ->Double 
distDiff a b diMat = sum [z |(x,y,z)<- diMat, (x == a && y /= b) 
|| (y == a && x /= b) ] 

urvalFun:: Int -> (String,String,Double)->[(String,String,Double) ]->Double 
urvalFun size triple diMat = ((fromIntegral size)-2)*(get3 triple) 
     - ((distDiff (get1 triple) (get2 triple) diMat) + (distDiff (get2 triple) 
     (get1 triple) diMat)) 

そののデモです

これは、と評価されます
urvalFun 3 ("a","d",0.52) [("a","b",0.304),("a","d",0.52),("a","e",0.824)] 

から0.60799

urvalFun 3 ("a","e",0.824) [("a","b",0.304),("a","d",0.52),("a","e",0.824)] 

これは今、私たちは「(、( "A"、 "B"、0.304)および[( "A"、 "B"、0.304)とurvalFun呼び出すことを知ってい1.1E^-16

と評価されますa "、" d "、0.52)、(" a "、" e "、0.824)]が最小の値を取得します。上記のように、この最小値(パラメータとして上記の例と同じベクトル)を返す関数 'getMin'を作成します。問題は、それが

getMin:: [(String,String,Double)]->Double 
getMin diMat = inner 0 diMat 2000 
    where 
    inner 3 diMat min = min 
    inner n diMat min 
    |current > min = inner (n + 1) (diMatMinus ++ [(head diMat) ]) min 
    |otherwise = inner (n+1) (diMatMinus ++ [(head diMat) ]) current 
    current = urvalFun (length diMat) (head diMat) diMat 
    diMatMinus = tail diMat 

ではありません

-16 ^例えば-1.1eと評価されます

getMin [("a","e",0.824),("a","d",0.52),("a","b",0.304)] 

を評価しようと、なぜ私は見当がつかない動作しないことです私はこれを返すために私が意図したかった-1.03999

誰かが私を助けてくれますか?

が(このコードは少し広告ホックであるが、それは、私はちょうど今、いくつかのテストをやって建設中である)私はそのようベクトルを再配置している

通知をトリプル(「A」、「B "、0.304)は、ベクトルの最後の要素です。

+0

あなたは最小値を'-1.03999'のリストはどこにもありません。おそらく、あなたは['minimumBy'](http://hackage.haskell.org/package/base-4.9.0.0/docs/Data-Foldable.html#v:minimumBy) – pdexter

+0

のようなものを望みます。ヘッダーは少し誤解を招くリストから最小値を取得したくない場合は、上記のようにurvalFunによって決定される最小値を取得したい –

+1

'minimumBy'とまったく同じように聞こえるので、チェックしてください。 – pdexter

答えて

3

まず、最小要素をurvalFunに渡す方法が必要です。これはminimumByで行うことができます。

λ> let ls = [("a","d",0.52),("a","e",0.824),("a","b",0.304)]                                       
λ> let min = minimumBy (\(_,_,c) (_,_,c') -> compare c c') ls                                      
λ> urvalFun 3 min ls                                                 
-1.0399999999999998 

それとも、この次のことを守って、あなたが意図したものである:

λ> minimum [ urvalFun 3 x ls | x <- ls]                                            
-1.0399999999999998 

あなたも、これはさらに修正することができ、0から3か何かにn個を変更したい場合。私はあなたの機能が欲しいものを英語で述べることをお勧めします。

+0

で何が間違って見ることができることを願って、これは完全に間違っています。最小の数字を見つけた場合、この場合は0.304であるとは言えませんが、それは 'urvalFun 2( "a"、 "b"、0.304)'が最小値になることを意味するものではありません。この場合、これは修正されますが、一般的ではありません。 –

+2

あなたのコードが何をしているのか分かりませんので、私は最高の推測をしました。あなたが英語であなたが何を望んでいるかを説明することができれば、誰かがあなたをより良く助けることができます。私の編集内容を見てください。それはおそらくあなたが達成しようとしているものです。 – pdexter

+0

これは実際に私がやりたかったことです - あなたのポストの "第2のケース"。 –

1

あなたの機能を最小限にする特定のリストの値を探したいとします。

私はあなたよりも簡単な例で作業します:最小の長さの文字列を見つける。 length機能を置き換えることで、これをあなたのケースに適応させることができます。

> import Data.Foldable 
> let list = ["hello", "world!", "here", "is", "fine"] 
> minimumBy (comparing length) list 
"is" 

上記の作品が、それは、リストの長さ、即ち約2倍、それは比較を実行するたびlengthを呼び出します。それを事前計算することで、これを回避し、要素ごとに一度だけlengthを使用することも可能である:私たちは、最初にその長さで各文字列をペア

> snd $ minimumBy (comparing fst) [ (length x, x) | x <- list ] 

は、唯一の長さに応じて最小長さの文字列のペアを取り、最終的にそのようなペアの文字列だけを取ります。

ところで、私はあなたがタプルにアクセスするためにこのようなget1などの機能を避けるためお勧めします:彼らは通常、同じ効果のためにパターンマッチングを利用Haskellコードで慣用的ではありません。例えば

urvalFun:: Int -> (String,String,Double)->[(String,String,Double) ]->Double 
urvalFun size (s1,s2,d) diMat = 
    (fromIntegral size - 2)*d - distDiff s1 s2 diMat + distDiff s2 s1 diMat 

ルックスより読みやすい。

head,tailも部分的であるため、特に危険です。空リストで使用するとプログラムをクラッシュさせますが、あまり説明はありません。

一般に、リストを扱うときは、インデックスの使用やリスト変数の長さまでカウントするカウンター変数は通常は不要であり、慣用的ではありません。パターンマッチングと再帰、あるいは標準的な折り畳み/マップ関数に単純に頼ることができます。大きさ3のリストについては、getMin機能が書き込まれることが

1

注:

rotate (x:xs) = xs ++ [x] 

zip "xyzw" (iterate rotate "xyzw") 
    = [ ('x', "xyzw"), 
     ('y', "yzwx"), 
     ('z', "zwxy"), 
     ('w', "wxyz") ] 
:あなたはジップとして urvalFun機能とヘルパー関数の引数のシーケンスを作成することができます

getMin' [x,y,z] 
    = minimum [ urvalFun 3 x [x,y,z] 
      , urvalFun 3 y [y,z,x] 
      , urvalFun 3 z [z,x,y] 
      ] 

したがって:

関連する問題