我試圖修改我的代碼,該代碼使用 Graph a 來查找連接到頂點 n 的任何頂點。此處連接的定義是,頂點 m 要么直接連接到頂點 n(通過邊),要么連接到頂點 k,而頂點 k 又連接到頂點 n。
我要修改的代碼:
**code 1**
findPath :: Eq a => Graph a -> a -> [a]
findPath (Graph v w) a
| [x | x<-v, x==a] == [] = []
| otherwise = findPath' (Graph v w) [a]
findPath' :: Eq a => Graph a -> [a] -> [a]
findPath' (Graph [] _) _ = []
findPath' (Graph _ _) [] = []
findPath' (Graph v w) (tp:st)
| [x | x<-v, x==tp] == [] = findPath' (Graph vv w) st
| otherwise = tp : findPath' (Graph vv w) (adjacent st)
where
adjacent = [x | (x,y)<-w, y==tp] [x | (y,x)<-w, y==tp]
vv = [x | x<-v, x/=tp]
connected :: Eq a => Graph a -> a -> a -> Bool
connected g a b = if (a `elem` (findPath g b)) == True then True else False
我嘗試修改它:
**Code 2**
convert :: [a] -> [(a, a)]
convert [] = []
convert (k:v:t) = (k, v) : convert t
-- a is vertex
-- [a] is a list from neighbors
getEdges :: Eq a => a -> [a] -> [a]
getEdges _ [] = []
getEdges a (y:ys) = a : y : getEdges a ys
-- vertices :: Eq a => Graph a -> [a]
-- neighbors :: Eq a => Graph a -> a -> [a]
-- [a] is a list of vertex
mergeEdges :: Eq a => Graph a -> [a] -> [a]
mergeEdges _ [] = []
mergeEdges g (x:xs) = getEdges x (neighbors g x) mergeEdges g xs
removeElements :: Eq a => [(a,a)] -> [(a,a)]
removeElements [] = []
removeElements ((a,b) : (v,w) : xs) = [(a,b)] removeElements xs
--v = vertex, w = edges
findPath :: Eq a => [a] -> [(a,a)] -> a -> [a]
findPath v w a
| [x | x<-v, x==a] == [] = []
| otherwise = findPath' v w [a]
--v = vertex, w = edges
findPath' :: Eq a => [a] -> [(a,a)] -> [a] -> [a]
findPath' [] _ _ = []
findPath' _ _ [] = []
findPath' v w (tp:st)
| [x | x<-v, x==tp] == [] = findPath' vv w st
| otherwise = tp : findPath' vv w (adjacent st)
where
adjacent = [x | (x, y)<-w, y==tp] [x | (y,x)<-w, y==tp]
vv = [x | x<-v, x/=tp]
getParam :: Eq a => Graph a -> [(a,a)]
getParam g = removeElements ((convert(mergeEdges g (vertices g))))
connected :: Eq a => Graph a -> a -> a -> Bool
connected g a b = if (a `elem` (findPath (vertices g) (getParam g) b ) ) == True then True else False
測驗代碼:
這是我的圖表: Graph {vers = [-6,-3,5,3], edgs = [(-6,5),(3,-3),(-3,5)]}
代碼 1:
ghci> connected g 3 5
True
代碼 2:
ghci> connected g 3 5
False
我最好的猜測是,當我將引數從 Graph a 更改為元組串列 [(a,a)] 時,我的代碼在這里停止作業,但我不明白為什么:
| otherwise = tp : findPath' vv w (adjacent st)
where
adjacent = [x | (x, y)<-w, y==tp] [x | (y,x)<-w, y==tp]
我不能使用 Graph a, (..) 中的建構式,因為它是不允許的 :-( 因此我需要修改我的代碼。
添加額外的代碼
data Graph a = Graph {
vers :: [Vertex a],
edgs :: [Edge a]
} deriving (Show, Eq, Read)
neighbors :: Eq a => Graph a -> a -> [a]
neighbors (Graph x []) _ = []
neighbors (Graph x ((v, w) : xs)) a
| a == v = w : neighbors (Graph x xs) a
| a == w = v : neighbors (Graph x xs) a
| (v, w) : xs == [] = []
| otherwise = neighbors (Graph x xs) a
uj5u.com熱心網友回復:
當我getParam在您的示例輸入上運行您的功能時,Graph {vers = [-6,-3,5,3], edgs = [(-6,5),(3,-3),(-3,5)]}我得到:
ghci> getParam g
[(-6,5),(-3,5),(5,-3)]
在這里你可以看到邊 (-3,5) 和 (5,-3) 是重復的,邊 (3,-3) 已經消失了。所以,我覺得你的removeElements功能太簡單了。您也許可以嘗試一個首先對元組進行排序然后洗掉重復項的函式:
import Data.List (nub)
...
sortTuple :: Ord a => (a, a) -> (a, a)
sortTuple (x, y)
| x <= y = (x, y)
| otherwise = (y, x)
removeElements :: Ord a => [(a, a)] -> [(a, a)]
removeElements xs = nub (map sortTuple xs)
-- also change the types of some other functions:
getParam :: Ord a => Graph a -> [(a,a)]
connected :: Ord a => Graph a -> a -> a -> Bool
使用該功能,我確實得到了getParam g == [(-6,5),(-3,3),(-3,5)]和 connected g 3 5 == True。
但我也想知道你為什么不直接使用getParams g = edgs g?
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/389029.html
標籤:哈斯克尔
