gpt4 book ai didi

haskell - 在 Haskell 中阅读 GraphML

转载 作者:行者123 更新时间:2023-12-04 20:08:58 26 4
gpt4 key购买 nike

我正在尝试将包含单个有向图的 GraphML 文件读入 Haskell Data.Graph 为了使用 Math.Combinatorics.Graph 运行分析模块。

但是,我找不到任何允许我读取 GraphML 文件的模块,生成 Data.Graph .我发现的一个相关模块是 ForSyDe.Backend.GraphML .但是,这似乎是 ForSyDe 所特有的。 DSL 和我目前想不出一种方法来使用它来阅读普通的 Data.Graph .

你能给我指一个允许我阅读 GraphML 的库吗,最好有一些关于如何使用它的示例代码?

最佳答案

经过一个多星期的搜索,我认为目前不存在 GraphML 解析器库。因此,我编写了自己的最小解析器。

假设我们有这个 GraphML:

<?xml version="1.0" encoding="UTF-8"?>
<graphml xmlns="http://graphml.graphdrawing.org/xmlns"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns
http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
<graph id="G" edgedefault="undirected">
<node id="n0"/>
<node id="n1"/>
<node id="n2"/>
<node id="n3"/>
<edge id="e1" source="n0" target="n1"/>
<edge id="e1" source="n1" target="n2"/>
<edge id="e1" source="n1" target="n3"/>
<edge id="e1" source="n3" target="n0"/>
</graph>
</graphml>

我创建了这个基于 HXT 的解析器,它能够解析 GraphML 的最小子集(足以创建上述 GraphML 的 Data.Graph )。 main以下文件的函数代表了如何使用它的示例:它打印图中的节点列表(另见 this related question )。
{-# LANGUAGE Arrows, NoMonomorphismRestriction #-}
import Text.XML.HXT.Core
import qualified Data.Graph as DataGraph

data Graph = Graph
{ graphId :: String,
nodes :: [String],
edges :: [(String, String)] -- (Source, target)
}
deriving (Show, Eq)

atTag tag = deep (isElem >>> hasName tag)

parseEdges = atTag "edge" >>>
proc e -> do
source <- getAttrValue "source" -< e
target <- getAttrValue "target" -< e
returnA -< (source, target)

parseNodes = atTag "node" >>>
proc n -> do
nodeId <- getAttrValue "id" -< n
returnA -< nodeId

parseGraph = atTag "graph" >>>
proc g -> do
graphId <- getAttrValue "id" -< g
nodes <- listA parseNodes -< g
edges <- listA parseEdges -< g
returnA -< Graph{graphId=graphId, nodes=nodes, edges=edges}

getEdges = atTag "edge" >>> getAttrValue "source"

-- Get targets for a single node in a Graph
getTargets :: String -> Graph -> [String]
getTargets source graph = map snd $ filter ((==source).fst) $ edges graph

-- Convert a graph node into a Data.Graph-usable
getDataGraphNode :: Graph -> String -> (String, String, [String])
getDataGraphNode graph node = (node, node, getTargets node graph)

-- Convert a Graph instance into a Data.Graph list of (node, nodeid, edge) tuples
getDataGraphNodeList :: Graph -> [(String, String, [String])]
getDataGraphNodeList graph = map (getDataGraphNode graph) (nodes graph)

main :: IO()
main = do
graphs <- runX (readDocument [withValidate no] "foo.graphml" >>> parseGraph)
-- Convert Graph structure to Data.Graph-importable tuple list
let graphEdges = getDataGraphNodeList $ head graphs
-- Convert to a Data.Graph
let (graph, vertexMap) = DataGraph.graphFromEdges' graphEdges
-- Example of what to do with the Graph: Print vertices
print $ map ((\ (vid, _, _) -> vid) . vertexMap) (DataGraph.vertices graph)

关于haskell - 在 Haskell 中阅读 GraphML,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21035103/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com