【Java】边集转化为邻接矩阵

图的边集是可以转化为邻接矩阵的。

邻接矩阵的定义如下:

邻接矩阵(Adjacency Matrix):是表示顶点之间相邻关系的矩阵。设G=(V,E)是一个图,其中V={v1,v2,…,vn}。G的邻接矩阵是一个具有下列性质的n阶方阵:

①对无向图而言,邻接矩阵一定是对称的,而且对角线一定为零(在此仅讨论无向简单图),有向图则不一定如此。

②在无向图中,任一顶点i的度为第i列所有元素的和,在有向图中顶点i的出度为第i行所有元素的和,而入度为第i列所有元素的和。

③用邻接矩阵法表示图共需要n^2个空间,由于无向图的邻接矩阵一定具有对称关系,所以扣除对角线为零外,仅需要存储上三角形或下三角形的数据即可,因此仅需要n(n-1)/2个空间。

边集就是一个图所有边的集合。

这里使用ArrayList edgeSet一个动态的一维数组表示一个无向图的边集。定义:edgeSet中的顺序为奇数与顺序为偶数的共同表示一条边。如下的测试用例:

		ArrayList<Integer> edgeSet = new ArrayList<Integer>();
		edgeSet.add(1);
		edgeSet.add(2);
		edgeSet.add(1);
		edgeSet.add(3);
		edgeSet.add(2);
		edgeSet.add(3);
		edgeSet.add(2);
		edgeSet.add(4);

就是定义存在边集{(1,2),(1,3),(2,3),(2,4)},现在的任务就是把它转化为这个图的邻接矩阵:

1 2
3 4

1 0 1
1 0

2 1 0
1 1

3 1 1
0 0

4 0 1
0 0

这里 横轴1-4与数组组成1-4的矩阵元素坐标,如果得到的结果是1,则表示,图中存在此边。比如矩阵元素中a[1][2]=1,则边集一定存在边(1,2),如果是0,则图中必定不存在这条边。比如a[1][4]=0,那么在边集中一定找不到(1,4)这条边。

邻接矩阵虽然看起来是二维数组,但是这里还是一维数组表示,只是输出的话以如下的方法输出,那么输出的结果就是矩阵了。

	//输出以一维数组的表示的矩阵
	public static void printAdjacencyMatrix(int adjacencyMatrix[]) {
		//遍历这个一维数据
		for (int i = 0; i < adjacencyMatrix.length; i++) {
			//每输出一个元素则同时输出一个制表符
			System.out.print(adjacencyMatrix[i] + "\t");
			//如果遍历的计数器i+1,刚好是矩阵长度的平方,的倍数,则输出一个换行
			if (((i + 1) % Math.sqrt(adjacencyMatrix.length)) == 0) {
				System.out.println();
			}
		}
		System.out.println();
	}

此方法的关键是换行的输出。比如这个的输出矩阵,i从0开始遇到4,8,12,16则输出一个换行,这个矩阵的长度是25,因此便有了如上的“如果遍历的计数器i+1,刚好是矩阵长度的平方,的倍数,则输出一个换行”:

0 1
2 3 4

1 0 1
1 0

2 1 0
1 1

3 1 1
0 0

4 0 1
0 0

要把边集转化成邻接矩阵,首先要以如下的情况初始化邻接矩阵,布置好横轴、纵轴,当然,那个0只是为了占领那个邻接矩阵a[0][0]这个没有意义的位置。

0 1
2 3 4

1 0 0
0 0

2 0 0
0 0

3 0 0
0 0

4 0 0
0 0

此时应该先根据边集求出点集。根据边集求出点集在《【Java】为ArrayList去重》(点击打开链接)已经介绍过了,这里不再赘述,就是一个边集元素去重的过程。

由于邻接矩阵式由一维数组表示的。因此纵轴的位置是 计数器i x 点集长度+1,比如上面的数组,点集就是{1,2,3,4},长度为4,纵轴1,2,3,4分别在一维数组的5,11,16,21这个位置,因此便有了如下的代码:

		System.out.println("初始化邻接矩阵:");
		ArrayList<Integer> nodeSet = new ArrayList(new HashSet(edgeSet));
		int adjacencyMatrix[] = new int[(nodeSet.size() + 1)
				* (nodeSet.size() + 1)];
		for (int i = 0; i <= nodeSet.size(); i++) {
			if (i == 0) {
				adjacencyMatrix[i] = 0;
			} else {
				adjacencyMatrix[i] = nodeSet.get(i - 1);
				adjacencyMatrix[i * (nodeSet.size() + 1)] = nodeSet.get(i - 1);
			}
		}

接着,是最核心的一步,首先要遍历点集,求出这个点的邻接节点。点的邻接节点根据这个点与边集,如下方法求出:

	//求点的邻接节点
	public static ArrayList<Integer> neighbourNode(ArrayList<Integer> edgeSet,
			int node) {
		//设置一个动态数组ArrayList保存此点的邻接节点
		ArrayList<Integer> neighbourNode = new ArrayList<Integer>();
		//遍历边集,看那条边拥有此点,那么这条边的另一点,就是此点的邻接节点
		for (int i = 0; i < edgeSet.size(); i = i + 2) {
			if (node == edgeSet.get(i)) {
				neighbourNode.add(edgeSet.get(i + 1));
			}
		}
		for (int i = 1; i < edgeSet.size(); i = i + 2) {
			if (node == edgeSet.get(i)) {
				neighbourNode.add(edgeSet.get(i - 1));
			}
		}
		return neighbourNode;
	}

求出点的邻接节点集之后,就开始遍历这个点的邻接节点集,更新邻接矩阵中的元素。找出这点与其邻接节点,组成的一个矩阵元素坐标,把这个这个矩阵元素坐标所对应的值从0改成1,对所有点求出其邻接节点,之后再该上面的方法,更新邻接矩阵,因此便有了如下的代码:

		System.out.println("最终的邻接矩阵:");
		for (int i =1; i <= nodeSet.size(); i++) {
			ArrayList<Integer> neighbourNode=neighbourNode(edgeSet,adjacencyMatrix[i]);
			for(int j=0;j<neighbourNode.size(); j++){
				for(int k=0;k<=nodeSet.size();k++){
					if(neighbourNode.get(j)==adjacencyMatrix[k * (nodeSet.size()+1)]){
						adjacencyMatrix[(nodeSet.size()+1)*k+i]=1;
					}
				}
			}
		}
		printAdjacencyMatrix(adjacencyMatrix);

至此,边集就最终转化成邻接矩阵了。全代码如下:

import java.util.*;

public class edgeSet_AdjacencyMatrix {
	//求点的邻接节点
	public static ArrayList<Integer> neighbourNode(ArrayList<Integer> edgeSet,
			int node) {
		//设置一个动态数组ArrayList保存此点的邻接节点
		ArrayList<Integer> neighbourNode = new ArrayList<Integer>();
		//遍历边集,看那条边拥有此点,那么这条边的另一点,就是此点的邻接节点
		for (int i = 0; i < edgeSet.size(); i = i + 2) {
			if (node == edgeSet.get(i)) {
				neighbourNode.add(edgeSet.get(i + 1));
			}
		}
		for (int i = 1; i < edgeSet.size(); i = i + 2) {
			if (node == edgeSet.get(i)) {
				neighbourNode.add(edgeSet.get(i - 1));
			}
		}
		return neighbourNode;
	}

	//输出以一维数组的表示的矩阵
	public static void printAdjacencyMatrix(int adjacencyMatrix[]) {
		//遍历这个一维数据
		for (int i = 0; i < adjacencyMatrix.length; i++) {
			//每输出一个元素则同时输出一个制表符
			System.out.print(adjacencyMatrix[i] + "\t");
			//如果遍历的计数器i+1,刚好是矩阵长度的平方,的倍数,则输出一个换行
			if (((i + 1) % Math.sqrt(adjacencyMatrix.length)) == 0) {
				System.out.println();
			}
		}
		System.out.println();
	}

	public static void edgeSet_AdjacencyMatrix(ArrayList<Integer> edgeSet) {
		System.out.println("初始化邻接矩阵:");
		ArrayList<Integer> nodeSet = new ArrayList(new HashSet(edgeSet));
		int adjacencyMatrix[] = new int[(nodeSet.size() + 1)
				* (nodeSet.size() + 1)];
		for (int i = 0; i <= nodeSet.size(); i++) {
			if (i == 0) {
				adjacencyMatrix[i] = 0;
			} else {
				adjacencyMatrix[i] = nodeSet.get(i - 1);
				adjacencyMatrix[i * (nodeSet.size() + 1)] = nodeSet.get(i - 1);
			}
		}
		printAdjacencyMatrix(adjacencyMatrix);
		System.out.println("最终的邻接矩阵:");
		for (int i =1; i <= nodeSet.size(); i++) {
			ArrayList<Integer> neighbourNode=neighbourNode(edgeSet,adjacencyMatrix[i]);
			for(int j=0;j<neighbourNode.size(); j++){
				for(int k=0;k<=nodeSet.size();k++){
					if(neighbourNode.get(j)==adjacencyMatrix[k * (nodeSet.size()+1)]){
						adjacencyMatrix[(nodeSet.size()+1)*k+i]=1;
					}
				}
			}
		}
		printAdjacencyMatrix(adjacencyMatrix);

	}

	public static void main(String[] args) {
		ArrayList<Integer> edgeSet = new ArrayList<Integer>();
		edgeSet.add(1);
		edgeSet.add(2);
		edgeSet.add(1);
		edgeSet.add(3);
		edgeSet.add(2);
		edgeSet.add(3);
		edgeSet.add(2);
		edgeSet.add(4);
		edgeSet_AdjacencyMatrix(edgeSet);

	}

}

边集{(1,2),(1,3),(2,3),(2,4)}的运行结果:

时间: 2024-11-03 21:48:43

【Java】边集转化为邻接矩阵的相关文章

JAVA对象转化JSON出现死循环问题

主要是解决JSON因Hibernate映射生成的集合的转化出现的死循环问题. 这个方法很重要 1 public String ajaxJsonByObjectDirecdt(Object obj, String[] filterNames){ 2 JsonConfig jsonConfig = new JsonConfig(); 3 jsonConfig.setIgnoreDefaultExcludes(false); 4 jsonConfig.setCycleDetectionStrategy

JAVA 浮点数转化为百分数,分离整数和小数部分

JAVA 浮点数转化为百分数 public class DoubleToPercentformat { /** * 将double类型数据转换为百分比格式,并保留小数点前IntegerDigits位和小数点后FractionDigits位 * @param d * @param IntegerDigits * @param FractionDigits * @return */ public static String getPercentFormat(double d,int IntegerD

java日期转化

package com.kang.util; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; public class CalendarTest { public static void main(String[] args) throws ParseException { // 获取当前年份.月份.日期 Ca

ason 和 Java 对象转化示例

1.工程 2.代码: JsonUtil.java package com.my.json; import java.util.ArrayList; import java.util.List; import net.sf.json.JSONArray; import net.sf.json.JSONObject; public class JsonUtil { /** * 从一个JSON 对象字符格式中得到一个java对象 * * @param jsonString * json字符串 * *

Jason 和 Java 对象转化示例

1.工程 2.代码: JsonUtil.java package com.my.json; import java.util.ArrayList; import java.util.List; import net.sf.json.JSONArray; import net.sf.json.JSONObject; public class JsonUtil { /** * 从一个JSON 对象字符格式中得到一个java对象 * * @param jsonString * json字符串 * *

java时间戳转化

String aa="1422865572"; long nowTime=System.currentTimeMillis();  //当前时间戳 //以下为时间戳转化 long retime =Integer.valueOf(aa).intValue(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String date = sdf.format(new Date(ret

Java大小写转化

java大写转小写 public String toLowerCase(String str){ char[] chars = str.toCharArray(); for (int i = 0; i < chars.length; i++) { if ('A' <= chars[i] && chars[i]<= 'Z'){ chars[i] += 32; } } return String.valueOf(chars); } java小写转大写 public Strin

java类型转化之Hbase ImmutableBytesWritable类型转String

Hbase 的ImmutableBytesWritable类型一般作为RowKey的类型;但也有时候会把值读出来;故有了转化为string一说. ImmutableBytesWritable RowKey; byte[] Temp = RowKey.get(); String str = Bytes.toString(Temp);

java 类型转化

String 转int s="12345"; int i; 第一种方法:i=Integer.parseInt(s);;//直接使用静态方法,不会产生多余的对象,但会抛出异常 第二种方法:i=Integer.valueOf(s).intValue();//Integer.valueOf(s) 相当于 new Integer(Integer.parseInt(s)),也会抛 异常,但会多产生一个对象 .转double.float类似 int 转String int i=12345; Str