如何相对于图中的距离创建从单个节点传播的边

Posted

技术标签:

【中文标题】如何相对于图中的距离创建从单个节点传播的边【英文标题】:How to create edges propagating from a single node with respect to distance in a Graph 【发布时间】:2019-04-24 18:31:36 【问题描述】:

我有一个图,我需要在其中创建从单个节点到距该节点一定距离内的所有节点的有向边,从初始节点指向距离内的节点。然后它从距离初始节点的节点到距离这些节点的距离内的节点创建边,并一直持续到每个节点至少有一条边。

我在代码中将其概念化并将其付诸实践时遇到了问题。我目前有以下代码,哪种工作但不够好,因为有时远离初始节点的节点没有边缘:

//create patient zero
    graphVer.get(0).getValue().setInfected(true);
    graphVer.get(0).getValue().setRecentlyInfected(true);
    graphVer.get(0).getValue().setLevel(0);
    for(int i = 0; i < graphVer.size();i++) 
        for(int j = 0; j < graphVer.size();j++) 
            //checks each vertex against every other vertex, and if their distance is within limits and they aren't equal to each other, then create an edge between them
            if(distance(graphVer.get(i).getValue().getX(), graphVer.get(i).getValue().getY(),graphVer.get(j).getValue().getX(),graphVer.get(j).getValue().getY()) < dis.getRange()) 
                if(i != j) 
                    //makes sure that there is only one edge between two nodes and directs it based on where patient zero is
                    if(graphVer.get(i).getValue().getLevel() <= i && graphVer.get(j).getValue().getLevel() > graphVer.get(i).getValue().getLevel()) 
                        graphEdge.add(new Edge<>(0,graphVer.get(i),graphVer.get(j)));
                        graphVer.get(j).getValue().setLevel(i+1);
                    
                
            
        
    

我没有包含顶点创建的代码,它只是在正方形范围内随机创建顶点,确保没有重叠。 graphVer是图中所有顶点的arraylist,graphEdge是图中所有边的arraylist。

有什么更好的方法可以让它每次都能正常工作?

【问题讨论】:

您的问题规范有问题。输出图应该是什么样子?它可以有循环吗?它应该是一棵以起始顶点为根的树吗?最后,您暗示在所有情况下,每个节点最终都会在图中连接。这不是真的。如果一个节点与所有其他节点的距离超过“一定距离”,它怎么能连接起来? 【参考方案1】:

您的措辞有点混乱,您不是仅尝试到达距原始节点设定距离内的节点吗?如果是这种情况,那么“有时距初始节点较远的节点不会得到边”将是您想要发生的事情。

【讨论】:

我最初查看的是第一个节点,然后我查看的是靠近第一个节点的所有节点,并寻找靠近这些节点的节点,而不是初始节点,一直持续到所有节点都被访问过【参考方案2】:

我在 cmets 中指出了您的问题规范中的缺点。

认为你想要的,从概念上讲,是从 所有 边 (v,w) 的图 G 开始,其中 dist(v,w)

要实现这一点,您不需要构造 G。正如您所推断的,您可以遍历所有顶点对并使用 dist(v,w)

BFS 使用队列。你最终会得到这个算法:

Let x be the start vertex
Let N be a set initially containing all vertices (not yet infected)
Let Q be a queue for vertices
Let T be the initially empty set of tree edges
Add x to Q and remove it from N // Infect x.
while Q is not empty
  Pop vertex v from the head of Q
  for each vertex w in N // Iterate through all non-infected vertices
    if dist(v, w) < DIST
      Add edge v->w to T // w is now infected
      add w to the tail of Q
      remove w from N
return T

这几乎可以逐行转换为 Java。

请注意,输出必须是一棵树,因为每个顶点 w 只能从 N 中删除一次。因此在 T 中只能有一个形式为 v->w 的边。这意味着每个顶点最多有一个父节点,这就是有向树的定义。

正如我在 cmets 中所说,如果它们之间的间隙太大,则无法保证这将包括树中的所有顶点。

只是为了好玩,这里是随机定位顶点的示例输出。起始顶点是朝向左上角的两倍大小的顶点。

请注意未包括在内的顶点,因为它们距离任何感染源都太远。这是正确的。

【讨论】:

以上是关于如何相对于图中的距离创建从单个节点传播的边的主要内容,如果未能解决你的问题,请参考以下文章

如何选择最小化到图中其他节点的最大最短距离的节点?

九度oj 题目1495:关键点

格式布局

margin和padding

修改图中的边权

Educational Codeforces Round 54 (Rated for Div. 2) D Edge Deletion (SPFA + bfs)