简体   繁体   English

从QuickGraph图表中获取连接的组件

[英]Getting connected components from a QuickGraph graph

I'm new to graph theory. 我是图论的新手。

I've created an adjacency graph with the QuickGraph library and ultimately, I'd like to have the connected components from the graph. 我已经使用QuickGraph库创建了一个邻接图,最终,我希望从图中获得连接的组件。

open QuickGraph

let tup = [(1M,1M); (2M, 18M); (3M, 3M); (4M, 5M); (5M, 24M); (24M, 6M); (7M, 6M); (8M, 9M); (10M, 9M)]

type Vertex = {decimal: decimal}

let edges = 
    tup
    |> List.map (fun x -> ({decimal = fst x}, {decimal = snd x}))
    |> List.map (fun x -> Edge<Vertex> x)

//Undirected Graph
let undirGraph = edges.ToUndirectedGraph()

undirGraph.Edges
undirGraph.Vertices

let x = QuickGraph.Algorithms.ConnectedComponents.ConnectedComponentsAlgorithm(undirGraph)

Output from undirGraph.Edges : undirGraph.Edges输出:

val it : Collections.Generic.IEnumerable<Edge<Vertex>> =
seq
[FSI_0227+Vertex->FSI_0227+Vertex {Source = {decimal = 1M;};
                                       Target = {decimal = 1M;};};
 FSI_0227+Vertex->FSI_0227+Vertex {Source = {decimal = 2M;};
                                   Target = {decimal = 18M;};};
 FSI_0227+Vertex->FSI_0227+Vertex {Source = {decimal = 3M;};
                                   Target = {decimal = 3M;};};
 FSI_0227+Vertex->FSI_0227+Vertex {Source = {decimal = 4M;};
                                   Target = {decimal = 5M;};}; ...]

and from undirGraph.Vertices : 并且来自undirGraph.Vertices

val it : Collections.Generic.IEnumerable<Vertex> =
seq
[{decimal = 1M;}; {decimal = 2M;}; {decimal = 18M;}; {decimal = 3M;}; ...]

are as expected. 正如所料。

The undirected graph is created successfully, but now I'm stuck. 无向图已成功创建,但现在我被卡住了。 From here, I don't know how to get the connected components of the graph or, frankly, if I'm using the correct graph structure. 从这里开始,我不知道如何获取图形的连通组件,或者坦率地说,如果我使用正确的图形结构。

I would have expected x to contain the components in the graph but output from x;; 我希望x包含图中的组件但是从x;;输出x;; in FSI looks like this: 在FSI看起来像这样:

FSI中x的输出

The values in the example tuple list represent BillTo and ShipTo customer ID values in a database. 示例tuple list的值表示BillToShipTo客户ID值。

The documentation in the QuickGraph library is sparse, particularly for someone trying to "learn on the fly." QuickGraph库中的文档很少,特别是对于那些试图“即时学习”的人。

This question supplants a previous question I posted . 这个问题取代了我发布上一个问题 I had considered modifying my prior question but, as this is a completely separate question, have decided to leave it as is. 我曾考虑修改我之前的问题,但由于这是一个完全独立的问题,所以决定将其保留原样。

Is this something you are looking for? 这是你要找的东西吗?

图形

I would use use the RProvider to send the code to R and generate this and then wrap it in a dll if necessary. 我会使用RProvider将代码发送到R并生成它,然后在必要时将其包装在dll中。 You can then use components , clusters , groups etc. to extract the connections. 然后,您可以使用componentsclustersgroups等来提取连接。

# In R:
g1 <- graph(  edges=c( "1","1", "2", "18", "3", "3", "4", "5", "5", "24", "24", "6", "7", "6", "8", "9", "10", "9"),n=9,directed=T)
plot(g1)
comp1 <- components(g1)
comp1
groups(comp1)
cl <- clusters(g1)
lapply(seq_along(cl$csize)[cl$csize > 1], function(x) 
  V(g1)$name[cl$membership %in% x]) 

In case you decide to still stick to QuickGraph, what you are seeing in FSI is because you are defining a record type called Vertex that has one member called decimal of type decimal. 如果您决定仍然坚持使用QuickGraph,您在FSI中看到的是因为您正在定义一个名为Vertex的记录类型,其中有一个名为decimal的十进制成员。 This is a tad bit confusing, so initially I would suggest you stick to int and just generate the graph the following way: 这有点让人困惑,所以最初我建议你坚持使用int并按以下方式生成图形:

let tup = [(1,1); (2, 18); (3, 3); (4, 5); (5, 24); (24, 6); (7, 6); (8, 9); (10, 9)]
let edges =
    tup |> List.map (fun x -> SEdge<int>(fst x, snd x))
let graph = edges.ToAdjacencyGraph()
let uniGraph = edges.ToUndirectedGraph()

You could also just write some sort of dictionary like data structure that keeps record/count of the references. 你也可以写一些像数据结构这样的字典来保存引用的记录/数量。

It turns out that you need to call the Compute method on the algorithm to actually get it to run! 事实证明,你需要在算法上调用Compute方法来实际运行它!

I took your sample code and just added call to Compute : 我拿了你的示例代码,只是添加了对Compute调用:

let x = QuickGraph.Algorithms.ConnectedComponents.
          ConnectedComponentsAlgorithm(undirGraph)
x.Compute()

Once you do this, x.Components contains a dictionary that assigns an index of a component to each vertex, so if you want groups of vertices (representing components), you can just group the results by the Value (which is the component index): 一旦你这样做, x.Components包含一个字典,为每个顶点分配一个组件的索引,所以如果你想要顶点组(代表组件),你可以只用Value (它是组件索引)对结果进行分组:

x.Components 
|> Seq.groupBy (fun kv -> kv.Value)
|> Seq.map (fun (comp, vertices) -> 
    comp, vertices |> Seq.map (fun kv -> kv.Key))

This gives the following: 这给出了以下内容:

[ (0, [{decimal = 1M;}]); 
  (1, [{decimal = 2M;}; {decimal = 18M;}]);
  (2, [{decimal = 3M;}]);
  (3, [{decimal = 4M;}; {decimal = 5M;}; {decimal = 24M;}; 
       {decimal = 6M;}; {decimal = 7M;}]);
  (4, [{decimal = 8M;}; {decimal = 9M;}; {decimal = 10M;}]) ]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM