[Haskell] 圖的表示方法:鄰接矩陣

1. 圖的表示

import Data.Array
import Data.Ix

-- adjacency matrix representation
type Graph n w = Array (n, n) (Maybe w)

mkGraph :: (Ix n, Num w) => Bool -> (n, n) -> [(n, n, w)] -> (Graph n w)
mkGraph dir bnds@(l, u) es =
    emptyArray // ([((x1, x2), Just w) | (x1, x2, w) <- es] ++ 
                   if dir then []
                   else [((x2, x1), Just w) | (x1, x2, w) <- es, x1 /= x2])
    where emptyArray = 
              array ((l, l), (u, u)) 
              [((x1, x2), Nothing) | x1 <- range bnds, x2 <- range bnds]

adjacent g v1 = [v2 | v2 <- nodes g, (g!(v1, v2)) /= Nothing]

nodes g = range (l, u)
    where ((l, _), (u, _)) = bounds g

edgeIn g (x, y) = (g!(x, y)) /= Nothing

weight x y g = w
    where (Just w) = g!(x, y)

edgesD g = [(v1, v2, unwrap $ g!(v1, v2)) | 
               v1 <- nodes g, 
               v2 <- nodes g, 
               edgeIn g (v1, v2)]
    where unwrap (Just w) = w

edgesU g = [(v1, v2, unwrap $ g!(v1, v2)) | 
               v1 <- nodes g, 
               v2 <- range (v1, u), 
               edgeIn g (v1, v2)]
    where (_, (u, _)) = bounds g
          unwrap (Just w) = w

2. 用例

testGraph = mkGraph False (1, 5) 
                  [(1, 2, 12), (1, 3, 34), (1, 5, 78),
                   (2, 4, 55), (2, 5, 32), (3, 4, 61),
                   (3, 5, 44), (4, 5, 93)]
                   
testAdjacent = adjacent testGraph 1
-- [2,3,5]

testNodes = nodes testGraph 
-- [1,2,3,4,5]

testEdgeIn = edgeIn testGraph (1, 2)
-- True

testWeight = weight 1 2 testGraph
-- 12

testEdgesD = edgesD testGraph
-- [(1,2,12),(1,3,34),(1,5,78),(2,1,12),(2,4,55),(2,5,32),(3,1,34),(3,4,61),(3,5,44),(4,2,55),(4,3,61),(4,5,93),(5,1,78),(5,2,32),(5,3,44),(5,4,93)]

testEdgesU = edgesU testGraph
-- [(1,2,12),(1,3,34),(1,5,78),(2,4,55),(2,5,32),(3,4,61),(3,5,44),(4,5,93)]

參考

Algorithms: A Functional Programming Approach

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末始花,一起剝皮案震驚了整個(gè)濱河市茁彭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌整陌,老刑警劉巖嗤谚,帶你破解...
    沈念sama閱讀 211,265評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件篙程,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡瓮增,警方通過查閱死者的電腦和手機(jī)怎棱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來绷跑,“玉大人拳恋,你說我怎么就攤上這事≡夷螅” “怎么了谬运?”我有些...
    開封第一講書人閱讀 156,852評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)带膜。 經(jīng)常有香客問我吩谦,道長(zhǎng),這世上最難降的妖魔是什么膝藕? 我笑而不...
    開封第一講書人閱讀 56,408評(píng)論 1 283
  • 正文 為了忘掉前任式廷,我火速辦了婚禮,結(jié)果婚禮上芭挽,老公的妹妹穿的比我還像新娘滑废。我一直安慰自己,他們只是感情好袜爪,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評(píng)論 5 384
  • 文/花漫 我一把揭開白布蠕趁。 她就那樣靜靜地躺著,像睡著了一般辛馆。 火紅的嫁衣襯著肌膚如雪俺陋。 梳的紋絲不亂的頭發(fā)上豁延,一...
    開封第一講書人閱讀 49,772評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音腊状,去河邊找鬼诱咏。 笑死,一個(gè)胖子當(dāng)著我的面吹牛缴挖,可吹牛的內(nèi)容都是我干的袋狞。 我是一名探鬼主播,決...
    沈念sama閱讀 38,921評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼映屋,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼苟鸯!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起棚点,我...
    開封第一講書人閱讀 37,688評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤早处,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后乙濒,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體陕赃,經(jīng)...
    沈念sama閱讀 44,130評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡卵蛉,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評(píng)論 2 325
  • 正文 我和宋清朗相戀三年颁股,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片傻丝。...
    茶點(diǎn)故事閱讀 38,617評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡甘有,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出葡缰,到底是詐尸還是另有隱情亏掀,我是刑警寧澤,帶...
    沈念sama閱讀 34,276評(píng)論 4 329
  • 正文 年R本政府宣布泛释,位于F島的核電站滤愕,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏怜校。R本人自食惡果不足惜间影,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望茄茁。 院中可真熱鬧魂贬,春花似錦、人聲如沸裙顽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽愈犹。三九已至键科,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背勋颖。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評(píng)論 1 265
  • 我被黑心中介騙來泰國(guó)打工梆掸, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人牙言。 一個(gè)月前我還...
    沈念sama閱讀 46,315評(píng)論 2 360
  • 正文 我出身青樓酸钦,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親咱枉。 傳聞我的和親對(duì)象是個(gè)殘疾皇子卑硫,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容