Math 区间图的识别

Math 区间图的识别,math,graph,graph-theory,intervals,Math,Graph,Graph Theory,Intervals,我需要一个识别区间图并生成其区间的算法。 经过一些研究,我发现了徐文莲开发的算法 () 这似乎是一个算法,它解决了我的问题。但是,我不是一个计算机科学家,所以我在理解算法方面有问题 有人能简单明了地向新手解释一下这个算法吗?这不是你想要的完整答案,但我希望它能有所帮助 维基百科把我带到了那个页面,在那个页面上我找到了对该报纸的引用 现在,本文确实给出了使用算法2、3、4和9确定一个图是否为整图的实际算法。算法2和算法3可以在上面的LBS页面上找到替代形式,并且可以通过它进行操作。然而到目前为止,

我需要一个识别区间图并生成其区间的算法。 经过一些研究,我发现了徐文莲开发的算法

()

这似乎是一个算法,它解决了我的问题。但是,我不是一个计算机科学家,所以我在理解算法方面有问题


有人能简单明了地向新手解释一下这个算法吗?

这不是你想要的完整答案,但我希望它能有所帮助

维基百科把我带到了那个页面,在那个页面上我找到了对该报纸的引用

现在,本文确实给出了使用算法2、3、4和9确定一个图是否为整图的实际算法。算法2和算法3可以在上面的LBS页面上找到替代形式,并且可以通过它进行操作。然而到目前为止,在过去的几天里,算法4打败了我。即使使用他们给出的示例图,也不会产生他们所陈述的结果

所以有三种可能

  • 我不够聪明,无法理解它
  • 算法不够详细
  • 算法中有错误
  • 在它的工作是2或3这是真的,我会继续工作,它断断续续,看看我是否可以破解它。然后是要处理的算法9


    也许上面的几页和论文会让你对解决问题有足够的了解。如果我找到一个完整的答案,我会张贴它。祝你好运。

    通过一些示例,我想我知道发生了什么,尽管我仍然不遵循算法4。下面是我确定图是否为区间图的算法,后面是一些实现该算法的Javascript代码。把它放进代码中,我就可以检查它是否工作了。代码可以在这里找到。我已经用这三个图测试了代码。(1和2是区间图,3不是)

    由于我已根据我对先前答案中给出的论文的解释制定了算法,我无法保证它完全正确,但它似乎有效

    该算法将在图1中完成

    当x和y是图的顶点时,当x和y被图的边连接时,x和y是邻居

    区间图的算法

    第1阶段从图中创建按字典顺序排列的顶点列表L。

    Form an arbitrarily ordered list U of vertices of the graph, called a CLASS.
    
    Form US, an ordered list of one element the class U.
    
    While US is not empty
    
    Take the 1st vertex, v,  from the 1st class in US and put it at the front of L.
    
    Set T to be an empty class
    
    For each vertex in each class in US 
    
    If it is a neighbour of v remove it from its class and push to back of T
    
    If T is not empty put T at front of US.
    
    Remove any empty classes from US
    
    L现在是图中按字典顺序排列的顶点列表

    Set RN(x) to be the neighbours of x which come after x in L placed in the same order that they occur in L
    
    Set parent(x) to be the first vertex in RN(x)
    
    Set RNnoP(x) to be the vertices of in RN(x) with parent(x) removed, ie RN(x)/parent(x)
    
    If the graph is an interval graph then for all vertices x if RNnoP(x) has any vertices in it then they will all appear in RN(parent(x)), ie RNnoP(x) is a subset of RN(parent(x)
    
    对于图1

    U=(3,6,1,4,5,8,2,7)

    US=((3,6,1,4,5,8,2,7))

    v=3US=((3,6,1,4,5,8,2,7))L=(3)

    3人的邻居在前面

    US=((6,8)、(1,4,5,2,7))

    v=6us=((8)(1,4,5,2,7))L=(6,3)

    6人的邻居在前面

    US=((8,1,7)、(4,5,2))

    v=8us=((1,7)(4,5,2))L=(8,6,3)

    邻居们从8个向前走

    美国=((7,4,5,2)(1))

    v=7us=((4,5,2)(1))L=(7,8,6,3)

    7号楼的邻居在前面

    美国=((4,5)(2)(1))

    v=4us=((5)(2)(1))L=(4,7,8,6,3)

    邻居们四个到前面去

    美国=((5)(2)(1))

    v=5us=((2)(1))L=(5,4,8,6,3)

    5人的邻居到前线-没有邻居,所以没有变化

    美国=((2)(1))

    v=2 US=((1))L=(2,5,4,8,6,3)

    2到前线的邻居-没有邻居,所以没有变化

    美国=((1))

    v=1us=()L=(1,2,5,4,8,6,3)

    我做完了

    第2阶段–区间图的第一次测试

    当x是图的顶点,L是图的字典序列表时

    Set RN(x) to be the neighbours of x which come after x in L placed in the same order that they occur in L
    
    Set parent(x) to be the first vertex in RN(x)
    
    Set RNnoP(x) to be the vertices of in RN(x) with parent(x) removed, ie RN(x)/parent(x)
    
    If the graph is an interval graph then for all vertices x if RNnoP(x) has any vertices in it then they will all appear in RN(parent(x)), ie RNnoP(x) is a subset of RN(parent(x)
    
    如果任何x未通过该测试,则该图不能是区间图

    下面显示了示例图的结果

    x    RN(x)    Parent(x)    RN(x)/parent(x)    RN(parent(x))    Pass
    
    1   | 6    |     6         |     -    |            3-      |   T
    
    2   | 8    |     8         |     -    |            6-      |   T
    
    5   | 7,8  |     7         |     8    |            8-      |   T
    
    4   | 7,8  |     7         |     8    |            8-      |   T
    
    7   |8     |     8         |     -    |            6-      |   T
    
    8   | 6,3  |     6         |     3    |            3-      |   T
    
    6   | 3    |     3         |     -    |            --      |   T
    
    3   |  -   |     -         |     -    |            --      |   T
    
    第3阶段-对于通过第2阶段的图,为图的每个顶点形成团,并创建一组最大团

    团是图中的一组顶点,使得对于集合x、y中的任何一对不同顶点,x和y是相邻的

    将C(x)设置为包含RN(x)和x中顶点的集合,即RN(x)并集{x}

    现在有必要建立一组最大团。一个团是最大的,如果在团的任何其他顶点上的加法停止它是一个团

    使用阶段2中找到的父关系形成一个树

    Using post-order traverse the tree and form a set, CS, of vertices where for each x in CS C(x) is a maximal clique using the following process on all vertices except for the root. 
    
    If C(parent(x)) is a subset of C(x) 
    
    if parent(x)  in CS remove it
    
    put x at in CS 
    
    下面是示例图的树,显示每个节点的x和C[x]

    x    RN(x)    Parent(x)    C(x)    C(parent(x))
    
    1    |6    |  6          |  1,6      |   3,6
    
    2    Z8    |  8          |  2,8      |   3,6,8
    
    5    |7,8  |  7          |  5,7,8    |   7,8
    
    4    |7,8  |  7          |  4,7,8    |   7,8
    
    7    |8    |  8          |  7,8      |   3,6,8
    
    8    |6,3  |  6          |  3,6,8    |   3,6
    
    6    |3    |  3          |  3,6      |   3
    
    3    | -   |  -          |  3        |   -
    

    上面树上的进程

    x=3是根

    x=6c(6)={3,6}CS=(6)C(3)是C(6)的子集,但不在OC中

    x=1c(1)={1,6}CS=(1,6)C(6)不是放在6中的C(1)的子集

    x=8c(8)={3,6,8)CS=(1,8)C(6)是C(8)的子集。去掉6放入8

    x=7c(7)={7,8})CS=(1,8,7)C(8)不是放在7中的C(7)的子集

    x=4c(4)={4,7,8}CS=(1,8,4)C(7)是C(4)的一个子集。删除7放入4

    x=5c(5)={5,7,8}CS=(1,8,4,5)C(7)是C(5)的子集,但不是7,放在5中

    x=2c(2)={2,8}CS={1,8,4,5,2}C(8)不是放在2中的C(2)的子集

    注意,在代码中,我使用了一个子关系来遍历树,作为排除根的一种方式

    第4阶段尝试对最大派系进行排序,使其连续。

    Form an arbitrarily ordered list U of vertices of the graph, called a CLASS.
    
    Form US, an ordered list of one element the class U.
    
    While US is not empty
    
    Take the 1st vertex, v,  from the 1st class in US and put it at the front of L.
    
    Set T to be an empty class
    
    For each vertex in each class in US 
    
    If it is a neighbour of v remove it from its class and push to back of T
    
    If T is not empty put T at front of US.
    
    Remove any empty classes from US
    
    如果对于任何顶点x,如果x在团n和n+m中,m>0,则x在团n+1,n+2

    如果可能的话,下面的算法将把最大团按连续顺序排列

    Set NC to be the ordered list, or class, of maximal cliques from CS, such that if x is in CS(x) then C(x) is in NC
    
    Set P to be the ordered list containing NC, P=(NC)
    
    Set OC=() and empty ordered list
    
    While P is not empty
    
        Take the last clique, LST, from the last class of P and put at front of OC
    
        For each clique Q in the last class of P partition into two classes 
    
            OUT if Q and LST have no vertices in common (intersection empty)
    
    IN if Q and LST have vertices in common (non empty intersection)
    
    Replace the last class of P with the classes OUT IN if both non empty
    
    Replace the last class of P with the class OUT if OUT non empty and IN empty
    
    Replace the last class of P with the classes IN if IN non empty and OUT  empty
    
    Leave P if both empty
    
    对于示例图p=({3,6,8},{4,7,8},{1,6},{5,7,8},{2,8}))(我混淆了顺序以显示过程如何工作)

    p=({3,6,8},{4,7,8},{1,6},{5,7,8},{2,8}))OC=()

    p=({3,6,8},{4,7,8},{1,6},{5,7,8}))OC=({2,8})

    OUT=({1,6})IN=({3,6,8},{4,7,8},{5,7,8})

    p=({1,6}),({3,6,8},{4,7,8},{5,7,8}))OC=({2,8})

    p=({1,6}),({3,6,8},{4,7,8}))OC=({5,7,8},{2,8})

    OUT=()IN({3,6,8},{4,7,8})

    p=({1,6}),({3,6,8},{4,7,8}))OC=({5,7,8},{2,8})

    p=({1,6}),({3,6,8}))OC=({4,7,8},{5,7,8},{2,8})

    OUT=()IN({3,6,8})

    //Array methods added to carry out interval graph check
    
    if(!Array.indexOf){  //Needed for earlier versions of IE;
        Array.prototype.indexOf = function(obj){
            for(var i=0; i<this.length; i++){
                if(this[i]===obj){
                    return i;
                }
            }
            return -1;
        }
    }
    
    Array.prototype.subsetOf = function(set){ //returns true if Array is a subset of set
        if(this.length==0) {return true;}  //empty set is subset of all sets
        var subset=true;
        for(var i=0; i<this.length; i++){
               subset = subset && (set.indexOf(this[i])>-1); //element of Array not in set forces subset to be false
           }
           return subset;
    }
    
    Array.prototype.intersection = function(set){ //returns the intersection of Array and set
        if(this.length==0) {return [];}  //empty set intersect any set is empty set
        var inter=[];
        for(var i=0; i<this.length; i++){
               if(set.indexOf(this[i])>-1) {//element of Array and set
        inter.push(this[i]);
               } 
        }
        return inter;
    }
    
    Array.prototype.union = function(set){ //returns the union of Array and set
        var union=[];
        for(var i=0; i<this.length; i++){
            union.push(this[i]);
        }
        for(var i=0; i<set.length; i++) {
               if(union.indexOf(set[i])==-1) {//element not yet in union
                  union.push(set[i]);
               } 
        }
        return union;
    }
    
    //A set is an array with no repeating elements
    
    
    function vertex(label,neighbours) {
        this.label=label;
        this.neighbours=neighbours;
    }
    
    //Using the following format for each vertex on the graph [vertex lable, [neighbour lables] ] set up the model of the graph
    //order of vertices does not matter
    
    //graph One - an interval graph
    graph=[
        [3,[6,8]],
        [6,[1,3,7,8]],
        [1,[6]],
        [4,[7,8]],
        [5,[7,8]],
        [8,[2,3,4,5,6,7]],
        [2,[8]],
        [7,[4,5,8]]
    ];
    
    //graph Two - an interval graph
    /*graph=[
        ['A',['B','C','D']],
        ['B',['A','C']],
        ['C',['A','B','D','E','F']],
        ['D',['A','C','E','F']],
        ['E',['C','D']],
        ['F',['D','G']],
        ['G',['F']]
    ];
    
    
    //graph Three - not an interval graph
    graph=[
        ['W',['Y','Z']],
        ['X',['Z']],
        ['Y',['W']],
        ['Z',['W']]
    ];
    
    */
    /*Create a new vertex object U[i] where U is an unordered array.
     *Unordered as at this point the numbering of vertices does not matter.
     *Referencing by name rather than an array index is easier to follow
     */
    
    var U=[];
    
    for(var i=0; i<graph.length; i++) {
        U[i]=new vertex(graph[i][0],graph[i][4]);
    }
    
    var US=[U]; 
    /*US is an array containing the single array U
     * during Lexicographical ordering US will contain other arrays
     */ 
    
    //********************Lexicographical Ordering Start*************************
    
    var L=[]; //L with contain the vertices in Lexicographical order.
    
    while (US.length>0) {    
        F=US[0]; //First array in US    
        vertex=F.shift(); //In Javascript shift removes first element of an array    
        if(F.length==0) { //F is empty
            US.shift();
        }
        L.unshift(vertex); //In Javascript unshift adds to front of array    
        var T=new Array(); //new array to add to front of US
        tus=[]; //tempory stack for US sets    
        while(US.length>0) { //for remaining vertices in the arrays in US check if neighbours of vertex        
            set=US.shift(); //first set of US
            ts=[]; //tempory stack for set elements        
            while(set.length>0){
               v=set.shift();  //v is one of the remaining vertices //
               lbl=v.label;    
               if (vertex.neighbours.indexOf(lbl) != -1) { //is v a neighbour of vertex
                   T.push(v);      //push v to T  
               }
               else {
                  ts.unshift(v);  //not a neighbour store for return
               }
            }
            while(ts.length>0) {    //restore list of v not moved to set           
               set.push(ts.pop());
            }
            if(set.length>0) {//if set not empty store for restoration
                  tus.unshift(set);
            }
        }
        if(T.length>0) {   //if T not empty
            US.push(T); //put T as first set of US
        }
        while(tus.length>0) {
            US.push(tus.pop()); // restore non empty sets
        }
    }
    
    
    //************************End of Lexicographical Ordering*************************
    
    //----------------------Chordality Check and Clique Generation Start----------------------------------------
    RN={}; //RN as an object so that an associative array can be used if labels are letters
    Parent={};  //Parent as an object so that an associative array can be used if labels are letters
    RNnoP={}; //RN with parent removed as an object so that an associative array can be used if labels are letters
    Children={}; //Used in clique generation NOTE this is a deviation from given alogorithm 4 which I do not follow, again object for associative array
    for(var i=0; i<L.length;i++) {
        Children[L[i].label]=[];
    }
    var chordal=true; 
    for(var i=0; i<L.length-1; i++) {
        vertex=L[i];
        RN[vertex.label]=[];
        RNnoP[vertex.label]=[];
        for(j=i+1;j<L.length; j++) {
            v=L[j];
            lbl=v.label;
            if(vertex.neighbours.indexOf(lbl) != -1) {
                RN[vertex.label].push(lbl); //store vertex labels in order they are processed
            }
        }
        Parent[vertex.label]=RN[vertex.label][0]; //Parent is front vertex of RN
        Children[RN[vertex.label][0]].push(vertex.label);//used for Clique generation my method
        for(k=1;k<RN[vertex.label].length;k++) {
            RNnoP[vertex.label][k-1]=RN[vertex.label][k];
        } 
    }
    //**************  chordality check ************
    for(i=0; i<L.length-1; i++) {
        vertex=L[i];
        var x=vertex.label;
        parentx=Parent[x];
        for(j=0;j<RNnoP[x].length;j++) {
            chordal = chordal && (RNnoP[x].subsetOf(RN[parentx]));
        }
    }
    
    if(!chordal) {
        alert('Not an Interval Graph');
    }
    else {
        //Construct maximal clique list from tree formed by parent and child relationships determined above NOTE not algorithm 4    
        var root = Children[L[L.length-1].label]; //last vertex in L which has no parent
        RN[L[L.length-1].label]=[]; //no vertices to right of last vertex
        var clique={}; //clique for each vertex label -- object so associative array using lables
        var cliques=[]; //stores maximal cliques from subtree of vertices processed
        clique[L[L.length-1].label]=[L[L.length-1].label]; //clique for root contains last vertex label
        generateCliques(root);  //cliques becomes a list of labels of vertices with maximal cliques
        var pivots=[];
        for(i=0;i<cliques.length;i++) {    
            pivots=pivots.union(clique[cliques[i]]);    
        }
        /*attempt to place each clique in cliques in consecutive order 
         * ie all cliques containing a given label are all next to each other 
         * if at end of process the cliques are in consecutive order then have an interval graph otherwise not an interval graph
        */
    
        var orderedCliques=[]; //will contain maximal cliques in consecutive order if possible
        var partitions=[cliques]; //holds partitions of cliques during process
        while(partitions.length>0) { 
            inPartition=new Array(); //partition of elements containing pivot
            outPartition=new Array(); //partition of elements not containing pivot
            lastPartition=partitions.pop(); //last partition of cliques        
            orderedCliques.unshift(lastPartition.shift());//first label in partition moved to front of orderedCliques    
            pivotClique=clique[orderedCliques[0]]; //which points to pivot clique    
            for(var i=0; i<lastPartition.length; i++) {         
                if(pivotClique.intersection(clique[lastPartition[i]]).length>0){   //non empty intersection
                   inPartition=inPartition.union([lastPartition[i]]);
                }
                else {
                   outPartition=outPartition.union([lastPartition[i]]);
                }        
            }
            if(outPartition.length>0) {
                partitions.push(outPartition);
            }
            if(inPartition.length>0) {    
                 partitions.push(inPartition);
            }
        }
    
        //----------------------End of Chordality Check and Clique Generation----------------------------------------
        var start={};  //start is an associative array;
        var end={};    //end is an associative array;
        if (consecutive()){
            //draw intervals......................
            var across=20;
            var down=20;
            var colwidth=20;
            var gap=30;
            var coldepth=30;
            var height=20;
            for(v=0;v<pivots.length;v++) {
               var vertex=pivots[v];
               var line=document.createElement('div');
               line.style.top=(down+(coldepth+height)*v)+'px';        
               line.style.height=(coldepth+height)+'px';
               line.style.left=(across+start[vertex]*(colwidth+gap))+'px';
               line.style.width=((end[vertex]-start[vertex])*gap+(1+end[vertex]-start[vertex])*colwidth)+'px';
               line.className='interval';
               document.body.appendChild(line);
               var label=document.createElement('div');
               label.style.left=line.style.left;
               label.style.top=(parseInt(line.style.top)+28)+'px';
               label.style.height='17px';
               label.style.width='30px';
               label.innerHTML=vertex;
               label.className='label';
               document.body.appendChild(label);
            }
        }
        else {
            alert('Not an Interval Graph')
        };  
    }
    
    function generateCliques(node) {    
        for(var i=0; i<node.length;i++) {
            lbl=node[i];
            clique[lbl]=[];
            for(j=0;j<RN[lbl].length;j++) {
                clique[lbl][j]=RN[lbl][j]; //each element of RN[x] becomes an element of clique[x]
            }
            clique[lbl].push(lbl); //RN(x) U {x} is a clique of subgraph processed so far and now   clique[x] = RN[x] as sets
            var parentx=Parent[lbl];
            if(clique[parentx].subsetOf(clique[lbl])) {
                var indx=cliques.indexOf(parentx);
                if(indx>-1) { //if parent of lbl is in cliques list remove it
                    cliques.splice(indx,1);
                }
            }
            cliques.push(lbl); //add lbl to cliques list
            if(Children[lbl].length>0) {  //lbl is not a leaf
                 generateCliques(Children[lbl]);
            }
        }
    }
    
    function consecutive() {
        var p;
        for(v=0;v<pivots.length;v++) {
            var vertex=pivots[v];
            p=0;
            for(cl=0;cl<orderedCliques.length;cl++) {
                if(clique[orderedCliques[cl]].indexOf(vertex)>-1) { //is vertex in maximal clique
                    if(p==0){
                       p=cl+1;
                       start[vertex]=p;
                       if(p==orderedCliques.length) {
                          end[vertex]=p;
                       }
                }
                else {
                       p+=1;        
                       if(p==orderedCliques.length) {
                           end[vertex]=p;
                       }
                       if(p!=cl+1) {
                           return false;
                       }
                   }
               }
               else {
                  if(!end[vertex] && p>0) {
                       end[vertex]=cl;
                  }
               }
            }
        }
        return true;
    }