日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

计算任意一个图生成树的个数——Kirchhoff 的Matrix Tree 方法Java实现

發(fā)布時(shí)間:2024/1/1 java 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 计算任意一个图生成树的个数——Kirchhoff 的Matrix Tree 方法Java实现 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
計(jì)算任意一個(gè)圖的生成樹的個(gè)數(shù),是Kirchhoff提出的理論,通常稱為Matrix Tree Theorem,原理很簡單:

Let G be a graph with V(G)={v1,v2,...,vn},let A={aij}be the adjacentcy matrix of G,and let C={cij}be the n*n matrix, where cij=deg vi if i=j; cij=-aij if i!=j; Then the?number of spanning trees of G is the vlaue of any cofactor(余子式) of C

但是需要計(jì)算行列式的值,這里需要點(diǎn)小技巧,所以這里選擇了LUP分解法來計(jì)算。

package trees;import matrix.DeterminantCalculator;/*** 計(jì)算任意一個(gè)圖的生成樹的個(gè)數(shù),是Kirchhoff提出的理論,通常稱為Matrix Tree Theorem* Let G be a graph with V(G)={v1,v2,...,vn},let A={aij}be the adjacentcy matrix of G,* and let C={cij}be the n*n matrix, where cij=deg vi if i=j; cij=-aij if i!=j; Then the* number of spanning trees of G is the vlaue of any cofactor(余子式) of C* @author xhw**/ public class NumberOfSpanningTree {/*** @param args*/public static void main(String[] args) {double a[][]={{0,1,1,0},{1,0,1,0},{1,1,0,1},{0,0,1,0}};int n=numberOfSpanningTree(a);System.out.println("numberOfSpanningTree:"+n);}public static int numberOfSpanningTree(double[][] a) {double c[][]=generateKirchhoffMatrix(a);double confactor[][]=new double[c.length-1][c.length-1];for(int i=1;i<c.length;i++){for(int j=1;j<c.length;j++){confactor[i-1][j-1]=c[i][j];//System.out.print(c[i][j]+" ");}//System.out.println();}DeterminantCalculator dc=new DeterminantCalculator();int n=(int)dc.det(confactor);return n;}/*** C={cij}be the n*n matrix, where cij=deg vi if i=j; cij=-aij if i!=j* @param a* @return*/public static double[][] generateKirchhoffMatrix(double[][] a) {int length=a.length;double c[][]=new double[length][length];for(int i=0;i<length;i++){int deg=0;for(int j=0;j<length;j++){deg+=a[i][j];c[i][j]=-a[i][j];}c[i][i]=deg;}return c;}} package matrix;/*** 矩陣和可以用來快速地計(jì)算矩陣的行列式,因?yàn)閐et(A) = det(L) det(U),而三角矩陣的行列式就是對(duì)角線元素的乘積。如果要求L 是單位三角矩陣,Uii的乘積* 那么同樣的方法也可以應(yīng)用于LUP分解,只需乘上P的行列式,即相應(yīng)置換的符號(hào)差。* @author xhw**/ public class DeterminantCalculator {private LUPDecomposition lu;/*** @param args*/public static void main(String[] args) {// TODO Auto-generated method stub}public DeterminantCalculator(){this.lu=new LUPDecomposition();}public double det(double a[][]){a=lu.decomposition(a);if(a==null)return 0;double d=1;for(int i=0;i<a.length;i++){d=d*a[i][i];}int n=lu.getExchangeTimes();if(n%2==0)return d;elsereturn -d;}} package matrix;/*** LUP分解* P是置換矩陣,L是下三角矩陣,并且對(duì)角線為1,U是上三角矩陣;P的出現(xiàn)主要是為了選主元,在選取Ade非對(duì)角線元素中選主元避免除數(shù)為0,* 除此以外,除數(shù)的值也不能過小,否則導(dǎo)致計(jì)算中數(shù)值不穩(wěn)定,因此所選的主元是個(gè)較大的值。詳細(xì)參見算法導(dǎo)論P(yáng)461* @author xhw**/ public class LUPDecomposition{private int p[];private int exchangeTimes=0;/*** @param args*/public static void main(String[] args) {// TODO Auto-generated method stub}public double[][] decomposition(double a[][]){int length=a.length;//p是置換矩陣,p[i]=j說明P的第i行第j列為1p=new int [length];for(int i=0;i<length;i++){p[i]=i;}for(int k=0;k<length;k++){double max=0;int maxK=0;for(int i=k;i<length;i++){if(Math.abs(a[i][k])>max){max=Math.abs(a[i][k]);maxK=i;}}if(max==0){System.out.println("singular matrix");return null;}if(k!=maxK){//交換k和maxk行exchange(p,k,maxK);exchangeTimes++;for(int i=0;i<length;i++){double temp=a[k][i];a[k][i]=a[maxK][i];a[maxK][i]=temp;}}//“原地”計(jì)算LU,矩陣a的上半部分為U,下半部分為Lfor(int i=k+1;i<length;i++){a[i][k]=a[i][k]/a[k][k];for(int j=k+1;j<length;j++){a[i][j]=a[i][j]-a[i][k]*a[k][j]; }}}return a;}public void exchange(int p[],int k,int maxK){int temp=p[k];p[k]=p[maxK];p[maxK]=temp;}public int[] getP() {return p;}public void setP(int[] p) {this.p = p;}public int getExchangeTimes() {return exchangeTimes;}public void setExchangeTimes(int exchangeTimes) {this.exchangeTimes = exchangeTimes;}}


總結(jié)

以上是生活随笔為你收集整理的计算任意一个图生成树的个数——Kirchhoff 的Matrix Tree 方法Java实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。