支撑树的插点问题

来源:互联网 发布:淘宝使用的第三方平台 编辑:程序博客网 时间:2024/06/07 06:55

问题描述




支撑树的插点数目问题






支撑树插点数目问题算法描述:




注意:这里的输入还应加上d和B

算法的java实现:


package sy2;import sy1.*;public class TheInsertNodeOfSpanningTree {public final static int Inf=Integer.MAX_VALUE;//表示整型无穷大,用来标识两个顶点是否有边相连public int[][] M;//有向图邻接矩阵public Vnode[] V;//有向图的顶点集public Vnode X[];//反圈中的顶点集public Arc F[];//反圈中的边集合public int ArcNum;public int num=0;//反圈中的边数public int InsertTree[][];public Vnode Insert[];public TheInsertNodeOfSpanningTree(int M[][],Vnode V[],int ArcNum) {// TODO Auto-generated constructor stubthis.M=M;this.V=V;this.ArcNum=ArcNum;X=new Vnode[V.length];X[0]=new Vnode(V[0].getV(),V[0].getVw());V[0].setFlag(true);for(int i=1;i<X.length;i++){X[i]=new Vnode("",i);}F=new Arc[ArcNum];for(int i=0;i<ArcNum;i++){F[i]=new Arc(null,null,Inf);}}public boolean TheMinimalSpanningTree(){boolean flag1=true;boolean flag=false;//用来判断反圈中的顶点集是否等于图的顶点集int min=Inf;//用来求取最小权值弧长int index1=0;//用来表示权值最小的非反圈对应点的位置int index2=0;//用来表示权值最小的反圈对应点的位置while(flag==false){//表示反圈中的顶点集不等于图的顶点集min=Inf;for(int i=0;i<X.length;i++){if(!X[i].getV().equals("")){for(int j=0;j<V.length;j++){if(V[j].isFlag()==false && M[X[i].getVw()][V[j].getVw()]!=Inf){if(M[X[i].getVw()][V[j].getVw()]<min){min=M[X[i].getVw()][V[j].getVw()];//寻找权值最小的边index1=j;index2=i;//System.out.println(index2+" "+index1);}// if}// if}// for}// if}// forif(index1!=-1){//表示反圈不为空X[index1]=new Vnode(V[index1].getV(),index1);//将该点加入反圈的点集合V[index1].setFlag(true);F[num]= new Arc(X[index2],V[index1],M[index2][index1]);//将该边加入反圈集合num++;}else{//表示若反圈为空if(num==V.length-1){flag=true;}else{//System.out.println("此图不连通,不存在最小支撑树!");for(int i=0;i<ArcNum;i++){F[i]=new Arc(null,null,Inf);}for(int i=1;i<X.length;i++){X[i]=new Vnode("",i);}flag1=false;break;}}index1=-1;index2=-1;}//whilereturn flag1;}public boolean InsertTree(int B,int d){boolean flag=true;//判断能否找到支撑树的插点树int sum=0;int Num=0;//表示总的加点数if(!TheMinimalSpanningTree()){flag=false;//表示不存在最小支撑树}int InsertNum[]=new int[num];//记录支撑树每条边上的插点数for(int i=0;i<num;i++){if(F[i].getWeight()!=Inf){sum=sum+F[i].getWeight();}}if(sum>B){flag=false;//表示不存在最小支撑树}else{//System.out.println(num);for(int i=0;i<num;i++){double t;if(F[i].getWeight()!=Inf){t=(double)F[i].getWeight()/d;if(t==(int)t){InsertNum[i]=(int)t-1;}else{InsertNum[i]=(int)t;}//else}//ifNum=Num+InsertNum[i];}//forSystem.out.println("总插点树:"+Num);InsertTree=new int[V.length+Num][V.length+Num];Insert=new Vnode[V.length+Num];for(int i=0;i<V.length+Num;i++){for(int j=0;j<V.length+Num;j++){if(i<V.length && j<V.length){InsertTree[i][j]=M[i][j];}else{InsertTree[i][j]=Inf;}}if(i<V.length){Insert[i]=V[i];}else{Insert[i]=new Vnode("",i);}}int index=V.length;String s;for(int i=0;i<num;i++){if(InsertNum[i]!=0){//表示对应这条边插点InsertTree[F[i].getFirstNode().getVw()][F[i].getLastNode().getVw()]=Inf;InsertTree[F[i].getLastNode().getVw()][F[i].getFirstNode().getVw()]=Inf;InsertTree[F[i].getFirstNode().getVw()][index]=d;InsertTree[index][F[i].getFirstNode().getVw()]=d;s="v"+Integer.toString(index+1);Insert[index]=new Vnode(s,index);for(int j=0;j<InsertNum[i]-1;j++){InsertTree[index][index+1]=InsertTree[index+1][index];index++;s="v"+Integer.toString(index+1);Insert[index]=new Vnode(s,index);}InsertTree[index][F[i].getLastNode().getVw()]=InsertTree[F[i].getLastNode().getVw()][index]=F[i].getWeight()-InsertNum[i]*d;}//if}//for}//ifreturn flag;}public static void main(String args[]) throws Exception{MyGraph G=new MyGraph();G.createGraph();System.out.println("请输出所构建图的邻接矩阵:");for(int i=-1;i<G.getVexNum();i++){if(i<0){System.out.print("          ");for(int j=0;j<G.getVexNum();j++){System.out.print(G.getVex(j)+"         ");}System.out.println();}else{for(int j=-1;j<G.getVexNum();j++){if(j<0){System.out.print(G.getVex(i)+"         ");}else{                         if(G.arcs[i][j]==Inf){                         System.out.print("INF"+"         ");}                         else{                         System.out.print(G.arcs[i][j]+"         ");                         }}//else}// ifSystem.out.println();}// for}//elseTheInsertNodeOfSpanningTree Insert=new TheInsertNodeOfSpanningTree(G.arcs,G.V,G.getArcNum());if(!Insert.InsertTree(10, 1)){System.out.println("不存在最小支撑树!");}else{System.out.println("最小支撑树是:");for(int i=0;i<Insert.num;i++){if(Insert.F[i].getWeight()!=Inf){System.out.println(Insert.F[i].getFirstNode().getV()+"------"+Insert.F[i].getLastNode().getV()+":weight="+Insert.F[i].getWeight());}}System.out.println("其加细树是:");for(int i=-1;i<Insert.InsertTree.length;i++){if(i<0){System.out.print("            ");for(int j=0;j<Insert.InsertTree.length;j++){System.out.print(Insert.Insert[j].getV()+"        ");}System.out.println();}else{for(int j=-1;j<Insert.InsertTree.length;j++){if(j<0){System.out.print(Insert.Insert[i].getV()+"         ");}else{                         if(Insert.InsertTree[i][j]==Inf){                         System.out.print("INF"+"       ");}                         else{                         System.out.print(Insert.InsertTree[i][j]+"         ");                         }}//else}// ifSystem.out.println();}// else}//for}//else}}


程序分析:

本程序共包含1个class,3个method:
class:TheInsertNodeOfSpanningTree
method:
public boolean TheMinimalSpanningTree(): 利用反圈法求最小支撑树
public boolean InsertTree(int B,int d): 对相应的支撑树进行插点
main: 程序的主方法,调用上面的两个方法,找到对应图的最小支撑树,进行插点,并输出插点后的加细树

本实验总的来说难点在构造支撑树的加细树,下面我用一点例子来描述我的构造过程:




从上面的描述就可以找到构造邻接矩阵的规律,具体体现为如下的代码:


for(int i=0;i<num;i++){if(InsertNum[i]!=0){//表示对应这条边插点InsertTree[F[i].getFirstNode().getVw()][F[i].getLastNode().getVw()]=Inf;InsertTree[F[i].getLastNode().getVw()][F[i].getFirstNode().getVw()]=Inf;InsertTree[F[i].getFirstNode().getVw()][index]=d;InsertTree[index][F[i].getFirstNode().getVw()]=d;s="v"+Integer.toString(index+1);Insert[index]=new Vnode(s,index);for(int j=0;j<InsertNum[i]-1;j++){InsertTree[index][index+1]=InsertTree[index+1][index];index++;s="v"+Integer.toString(index+1);Insert[index]=new Vnode(s,index);}InsertTree[index][F[i].getLastNode().getVw()]=F[i].getWeight()-InsertNum[i]*d;InsertTree[F[i].getLastNode().getVw()][index]=F[i].getWeight()-InsertNum[i]*d;}//if}//for


实例演示:

对下面给出的两个图进行插点:



对于第一幅图:




对于第二幅图:



这里的第二幅图是不连通的,因此不存在其最小支撑树,插点也就没有意义了


0 0
原创粉丝点击