2012-06-29 32 views
0

嗯,我無法弄清楚如何在haskell中做到這一點。例如,我有這樣的矩陣2dm矩陣中的鄰居表示爲列表清單

[[1,2],[3,4]] 

,我想生成列表的與該矩陣的每個元素的所有可能的鄰居列表。

預期的結果是:

[[1,2],[1,3],[1,4],[2,1],[2,3],[2,4],[3,1],[3,2],[3,4],[4,1],[4,2],[4,3]] 

我知道如何使功能,這將創造名單列表與每個小區的鄰居電線:

pos how = [ (0+dx,0+dy) | dx <- [0..(how-2)], dy <- [0..how-1] ] :: [(Int,Int)] 
neighbour (x,y) how = [ (x+dx,y+dy) | dy <- [-1..1], dx <- [-1..1], 
             x+dx >= 0, y+dy >= 0, x+dx<=how-2, y+dy <= how-1, 
             (x,y)/=(x+dx,y+dy) ] :: [(Int,Int)] 
all_n how = [ p | x <- pos how, let p = neighbour x how ] :: [[(Int,Int)]] 

,但我不能將其更改爲像我描述的那樣工作。

+0

現在確實很難弄清楚你在問什麼。你能更清楚一點嗎?例如,你如何定義一個「鄰居」?爲什麼'[1,4]'包含在預期結果列表中? –

+0

如果細胞接觸其他角落甚至是她的鄰居 – whd

+0

那麼爲什麼在您的預期結果列表中有[[1,4]]?它不是'[1,2]'或'[3,4]'的鄰居。 –

回答

5

讓我來描述一個非常不同的方法來描述你所建議的方法。在談到鄰居,我會說一個d -neighbor Ë的是元素ê方向d元素一步。因此,例如,在矩陣[[1,2],[3,4]]中,號碼2是號碼1的右鄰。我們需要使用一些庫代碼。

import Data.List 

我們將從最簡單的事情開始:讓我們找到一維列表的右鄰居。

rightList (x:y:rest) = (x,y) : rightList (y:rest) 
rightList _ = [] 

我們可以通過不確定地選擇矩陣的行和發現行中的所有右的鄰居找到一個矩陣所有的右鄰居。

right m = m >>= rightList 

我們可以採取任何功能的鄰居發現了通過反轉元組發現在其他方向上的鄰居建立功能。例如,左鄰是相同的右的鄰居,但與元組元素交換,所以:

swap (x,y) = (y,x) 
co direction = map swap . direction 
left = co right 

怎麼樣下的鄰居?實際上,下鄰居在轉置矩陣中只是右鄰居:

down = right . transpose 
up = co down 

下一個感興趣的方向是右下鄰居。這一個有點棘手;我們要做的是平行走下兩個列表,但要抵消一個。

downRight (xs:ys:rest) = zip xs (drop 1 ys) ++ downRight (ys:rest) 
downRight _   = [] 
upLeft = co downRight 

有一個最後的方向,即右上鄰居;如果我們顛倒矩陣,這些是右下鄰居。

upRight = downRight . reverse 
downLeft = co upRight 

最後,形成所有的鄰居,我們可以不確定地選擇一個相鄰的方向,然後找到在該方向上的所有鄰居。

allDirections = [right, left, up, down, 
       downRight, upLeft, upRight, downLeft] 
neighbors m = allDirections >>= ($m) 

輸出並不完全按照您指定的順序,但我想這可能並不重要。

1

要糾正你現在的代碼,我爲它周到的回答可以幫助你取得進步的幾個問題:

  • how-2是一件奇怪的事情。爲什麼2要減去正確的數字?
  • all_n的類型很奇怪。爲什麼它是一個功能? (它的參數代表什麼?)爲什麼它會返回一個嵌套列表,而不是一個平面列表?
  • 看來你只追蹤一個尺寸參數,但你的矩陣是一個二維矩陣。爲什麼會有這種差異? (爲什麼你沒有寬度和高度參數?)
  • 一旦你有一個座標,你知道如何從矩陣中獲取該位置的元素? (提示:有一個函數(!!) :: [a] -> Int -> [a]。)如果你有一個座標列表,你知道如何爲列表中的每個元素執行此操作嗎? (提示:有一個功能map :: (a -> b) -> ([a] -> [b])。)

祝你好運!

+0

-1 becouse!從0開始,然後是-1,因爲它的n/n-1矩陣 – whd

+0

@ whd我相信你比我更瞭解這個問題,但是'[[1,2],[3,4]]肯定不會' t *看起來像一個nx(n-1)矩陣。 –

+0

我知道,但它是最簡單的方式來顯示我的意思,你的功能也可以與其他矩陣 – whd