使用度序列创建图形

时间:2012-10-27 18:02:51

标签: java algorithm language-agnostic graph-theory

这是我第一次分配数据结构课程的一部分,所以如果您只是告诉我错误的地方而不是发布工作代码,我会很高兴。

我们应该编写一个给出度数序列的程序,绘制图形。我为图形编写了数据结构,它可以正确连接两个顶点(graph.addConnection)。但我无法找到一种从程度序列构建图形的方法。

This Wikipedia page提供了一个简单的算法:

  
      
  1. 从没有边缘的图表开始。
  2.   
  3. 维持一个顶点列表,其中的度数要求尚未按剩余度要求的非递增顺序得到满足。
  4.   
  5. 将第一个顶点连接到此列表中的下一个d1顶点,然后将其从列表中删除。重新排序列表并重复直到所有   学位要求得到满足。
  6.   

我用Java实现了它:

public static void populate(Graph graph, int[] degrees) {
    class DegreeMapping {
        int vertice=0;
        int degree=0;
    }

    ArrayList<DegreeMapping> degrees_ = new ArrayList<DegreeMapping>(degrees.length);
    for(int i=0; i<degrees.length; i++) {
        degrees_.add(new DegreeMapping());
        degrees_.get(i).vertice = i;
        degrees_.get(i).degree = degrees[i];
    }

    while(! degrees_.isEmpty()) {
        // Sort by degrees
        Collections.sort(degrees_, new Comparator<DegreeMapping>() {
                                @Override
                                public int compare(DegreeMapping o1, DegreeMapping o2) {
                                    return o2.degree - o1.degree ;
                                }
                            }); 
        for(DegreeMapping i: degrees_) System.out.printf("{%d, #%d} ", i.degree, i.vertice );
        System.out.println();

        for(int i=1; i<degrees_.get(0).degree+1; i++) {
            degrees_.get(i).degree--;
            graph.addConnection(degrees_.get(0).vertice, degrees_.get(i).vertice);
            System.out.printf("#%d <-> #%d \n", degrees_.get(0).vertice, degrees_.get(i).vertice);
        }

        degrees_.remove(0); 
    }
}

它为度序列2 2 2 2 2 2 2 2

提供此输出
{2, #0} {2, #1} {2, #2} {2, #3} {2, #4} {2, #5} {2, #6} {2, #7} 
#0 <-> #1 
#0 <-> #2 
{2, #3} {2, #4} {2, #5} {2, #6} {2, #7} {1, #1} {1, #2} 
#3 <-> #4 
#3 <-> #5 
{2, #6} {2, #7} {1, #4} {1, #5} {1, #1} {1, #2} 
#6 <-> #7 
#6 <-> #4 
{1, #7} {1, #5} {1, #1} {1, #2} {0, #4} 
#7 <-> #5 
{1, #1} {1, #2} {0, #5} {0, #4} 
#1 <-> #2 
{0, #2} {0, #5} {0, #4} 
{0, #5} {0, #4} 
{0, #4} 

如您所见,它创建了两个不同的组,顶点为{0,1,2}和{3,4,5,6,7},它们之间没有任何连接。但它应该只创建一个图形。

我做错了什么?

2 个答案:

答案 0 :(得分:1)

根据维基百科的说法,该算法产生了一个简单的图形,再次根据维基百科,它是一个无向图,在任何两个不同的顶点之间没有环,只有一条边。'

你得到的是一个包含两个不同连通组件的图形,而不是两个图形,因此算法似乎正常工作。

如果你的作业没有明确说明应该连接图表,你就不用担心了。

答案 1 :(得分:0)

如果您还对顶点数字进行排序,它似乎也会更好。

// Sort by degrees and then vertex number
Collections.sort(degrees_, new Comparator<DegreeMapping>() {
    @Override
    public int compare(DegreeMapping o1, DegreeMapping o2) {
        if (o1.degree == o2.degree) return o2.vertice - o1.vertice;
        return o2.degree - o1.degree;
    }
});

<强>结果:

{2, #0}, {2, #1}, {2, #2}, {2, #3}, {2, #4}, {2, #5}, {2, #6}, {2, #7}
#0 <-> #1
#0 <-> #2
{2, #3}, {2, #4}, {2, #5}, {2, #6}, {2, #7}, {1, #1}, {1, #2}
#3 <-> #4
#3 <-> #5
{2, #6}, {2, #7}, {1, #1}, {1, #2}, {1, #4}, {1, #5}
#6 <-> #7
#6 <-> #1
{1, #2}, {1, #4}, {1, #5}, {1, #7}, {0, #1}
#2 <-> #4
{1, #5}, {1, #7}, {0, #1}, {0, #4}
#5 <-> #7
{0, #7}, {0, #1}, {0, #4}
{0, #1}, {0, #4}
{0, #4}

根据Mihail和Vishnoi的论文"On Generating Graphs with Prescribed Degree Sequences for Complex Network Modeling Applications",您可以通过修改算法的结果来创建连通图。

  

如果此图表未连接,则其中一个连接的组件必须包含一个循环。让( u v )成为循环中的任何边,让( s t )成为边在不同的连接组件中。显然,图形在 u s v t 对之间没有边缘。删除边缘( u v )和( s t ),然后插入边缘(< em> u , s )和( v t ),我们合并了这两个组件。注意,结果图仍然满足给定的度序列。以这种方式进行,我们可以获得连接的拓扑结构。