- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在查看 jgraphT,但我经验不足,而且它缺乏一些文档。
我有一些节点,我想创建一个连接的拓扑以提供一些冗余。示例:
我从 n1,n2,n3,n4 开始
我希望能够与每个节点通信,但仍然有多个可能的路径,这样如果一个节点失败,其他节点仍然可以通信。
jgraphT 能为我创建一个好的拓扑吗?也许给予一些权重,以便它比其他节点更重视某些节点?
或者您知道其他一些图书馆也能获得相同的成就吗?此外,如果我可以生成某种网页来记录我创建的拓扑,那就太好了......
最佳答案
评论有点太长了:
我认为您正在寻找的内容的形式特征没有明确指定。显然,您正在寻找具有一定连接性的图表 ( http://en.wikipedia.org/wiki/Connectivity_%28graph_theory%29 ),但根据当前问题,我们可能建议使用 CompleteGraphGenerator
。
关键点可能是您提到的“一些冗余”和“一些权重”(以及记录拓扑的“一些网页”)。
大概,您想要最小的冗余。也就是说,您可能想要插入最小数量的附加边,以便在删除k
个任意顶点后图仍然是连接的。
我不知道有哪个库可以开箱即用地执行此操作。
基于 JGraphT 提供的两个粗略想法:
可以计算最小割,并在割两侧的顶点之间插入附加边。 http://jgrapht.org/javadoc/org/jgrapht/alg/StoerWagnerMinimumCut.html可能是这里的一个起点。
人们可以计算强连接的组件,并在这些组件之间插入额外的边。强连通分量可以使用 http://jgrapht.org/javadoc/org/jgrapht/alg/StrongConnectivityInspector.html 来计算
编辑:
<小时/>添加了基于上述第一个想法的实现。 ensureConnectivity
方法将确保给定图具有一定的连通性,如下所示:它使用 StoerWagnerMinimumCut
类计算最小割。此类的输出是顶点列表,这些顶点是将由切割创建的组件之一。 computeCutVertices 方法将计算实际需要删除的顶点,以便将图划分为多个组件。对于每个顶点,将计算邻居集合。这些邻居中的任何两个(尚未连接的)都将与新边连接。这整个过程将被重复,直到“切割顶点”的数量大于所需的连通性。
请注意,这还没有经过广泛的测试,并且可能有更优雅或更有效的解决方案,但是......一般来说它应该有效
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import org.jgrapht.Graph;
import org.jgrapht.UndirectedGraph;
import org.jgrapht.alg.StoerWagnerMinimumCut;
import org.jgrapht.graph.DefaultEdge;
import org.jgrapht.graph.SimpleGraph;
public class GraphConnectivityTest
{
public static void main(String[] args)
{
UndirectedGraph<String, DefaultEdge> graph =
new SimpleGraph<String, DefaultEdge>(DefaultEdge.class);
String v0 = "0";
String v1 = "1";
String v2 = "2";
String v3 = "3";
String v4 = "4";
String v5 = "5";
String v6 = "6";
String v7 = "7";
graph.addVertex(v0);
graph.addVertex(v1);
graph.addVertex(v2);
graph.addVertex(v3);
graph.addVertex(v4);
graph.addVertex(v5);
graph.addVertex(v6);
graph.addVertex(v7);
graph.addEdge(v0, v1);
graph.addEdge(v0, v2);
graph.addEdge(v0, v3);
graph.addEdge(v1, v2);
graph.addEdge(v1, v3);
graph.addEdge(v2, v3);
graph.addEdge(v4, v5);
graph.addEdge(v4, v6);
graph.addEdge(v4, v7);
graph.addEdge(v5, v6);
graph.addEdge(v5, v7);
graph.addEdge(v6, v7);
graph.addEdge(v1, v4);
//graph.addEdge(v3, v6);
ensureConnectivity(graph, 2);
}
/**
* Make sure that the given graph has the specified connectivity.
* That is: Make sure that more than the given number of vertices
* have to be removed in order to split the graph into two
* components.
*
* @param graph The graph
* @param connectivity The desired connectivity
*/
private static <V, E> void ensureConnectivity(
UndirectedGraph<V, E> graph, int connectivity)
{
System.out.println("Desired connectivity is "+connectivity);
while (true)
{
StoerWagnerMinimumCut<V, E> m =
new StoerWagnerMinimumCut<V, E>(graph);
Set<V> minCut = m.minCut();
Set<V> cutVertices =
computeCutVertices(graph, minCut);
System.out.println("Removing "+cutVertices+" will create two components");
if (cutVertices.size() > connectivity)
{
System.out.println("Reached desired connectivity");
return;
}
for (V cutVertex : cutVertices)
{
E edge = addBridgeEdge(graph, cutVertex);
System.out.println("Added edge "+edge);
}
}
}
/**
* Creates an edge between two arbitrary neighbors of the
* given vertex in the given graph that have not yet
* been connected.
*
* @param graph The graph
* @param v The vertex
*/
private static <V, E> E addBridgeEdge(Graph<V, E> graph, V v)
{
Set<E> edges = graph.edgesOf(v);
Set<V> neighbors = new LinkedHashSet<V>();
for (E edge : edges)
{
V v0 = graph.getEdgeSource(edge);
V v1 = graph.getEdgeTarget(edge);
neighbors.add(v0);
neighbors.add(v1);
}
neighbors.remove(v);
List<V> neighborsList = new ArrayList<V>(neighbors);
for (int i=0; i<neighborsList.size(); i++)
{
for (int j=i+1; j<neighborsList.size(); j++)
{
V n0 = neighborsList.get(i);
V n1 = neighborsList.get(j);
E present = graph.getEdge(n0, n1);
if (present == null)
{
return graph.addEdge(n0, n1);
}
}
}
return null;
}
/**
* Compute the vertices in the given graph that have to be
* removed from the graph in order to split it into two
* components (of which one only contains the given
* "minCut" vertices)
*
* @param graph The graph
* @param minCut The set of vertices on one side of the cut
* @return The vertices that have to be removed
*/
private static <V, E> Set<V> computeCutVertices(
Graph<V, E> graph, Set<V> minCut)
{
Set<V> cutVertices = new LinkedHashSet<V>();
for (V v : minCut)
{
Set<E> edges = graph.edgesOf(v);
for (E edge : edges)
{
V v0 = graph.getEdgeSource(edge);
V v1 = graph.getEdgeTarget(edge);
if (minCut.contains(v0) && !minCut.contains(v1))
{
cutVertices.add(v1);
}
if (!minCut.contains(v0) && minCut.contains(v1))
{
cutVertices.add(v0);
}
}
}
return cutVertices;
}
}
关于java - 是否可以创建具有一定冗余级别的连通图?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22673792/
我有下面提供的“示例代码”,我觉得这很多余,并且想请您与我一起解释是否有任何更少冗余的方法来处理以下代码。 public interface Bars { FOO1 FOO1 = (FOO1)
我们刚刚测试了一个由 2 个服务器组成的 AppFabric 集群,我们在其中删除了“领导”服务器。第二个服务器对它的任何请求超时并出现错误: Microsoft.ApplicationServer.
我正在设计一个关系数据库 - 底层是 MySQL - DBDesigner 4 . 我有 3 个表:module、page 和 lang。每个模块属于一个页面,每个页面都有特定的语言: 外键 pag
我的 Fraction 程序运行流畅,但 NetBeans IDE 告诉我以下 if 是多余的: public boolean equals(Object other) { Fraction bo
下面的代码显然是多余的,但根据我的经验,我经常使用这种模式。有没有更好的方法在 python 中执行此操作? if re.search("at (\d{1,2}):\d{2}", p): a=
我有一个用具体示例说明的一般性问题。当所有组件对象都已测试时,您建议对复合对象进行多少测试? 作为具体示例,请考虑下面的 NullTerminatedStringReader。它从字节缓冲区中读取一个
if ( a > b) { return true; } return false; 对于上面的代码,Netbeans 给出了 “Redundant if statement” 警告并建议将其更改
当我添加一些约束时,例如: create table Test( IDTest int primary key, Credit int not null constraint Credit
此代码适用于 Microchip 的 PIC32MX 微处理器。他们的编译器本质上是 GCC 3.4。 我倾向于使用 GCC 的 __packed__ attribute将位域打包到一个 union
已关闭。这个问题是 not reproducible or was caused by typos 。目前不接受答案。 这个问题是由拼写错误或无法再重现的问题引起的。虽然类似的问题可能是 on-top
我正在为我的应用程序使用apns通知,为此,我将apns设备 token 存储在我的sql数据库中。 问题在于,每次用户删除或安装该应用程序时,它都会生成一个新的设备 token ,并将其存储在数据库
Action Keyname Type Unique Packed Column Cardinality Collation Null Comment Edit Dro
我正在开发一个使用 ARM Cortex-M0 处理器的项目。在这个项目中,我需要提供计时器支持(CMSDK (SSE-200)计时器)。 因此,在 vector 表中,在 TIMER0_IRQn 表
有没有写的理由 corsFilter.setAllowedOrigins(new HashSet(Arrays.asList("*"))); 其中allowedOrigins在ReSTLet框架中的定
我正在创建一个包含 4 个链接的 HTML/CSS 页面, Home.html Details.html ContactMe.html AboutUs.html 我想在所有关联的 HTML 页面中将其
我试图理解并使用其他人编写的代码,但由于我对 typedef 经验不多。 , 我有时会感到困惑。 有两个不同的头文件,一个继承另一个,并且在两个文件上声明相同的typedef。 为什么会出现冗余,如何
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我有一个用于改造的 POJO 类。 public class AppData(){ String a; String b; String c;
我想知道: 编写这段代码: DataRow[] g = new DataRow[1] ; var t=new StringBuilder().AppendFormat("{0}", g[0]["a
只是一个性能问题...... 假设我有 5 个类,每个类都引用了 System.Data 和一个自己开发的库。这 5 个类是类库的一部分,最终将被构建并发布到一些 Web 应用程序作为引用。 通过将引
我是一名优秀的程序员,十分优秀!