【问题标题】:Adjacency Matrix In JavaJava中的邻接矩阵
【发布时间】:2013-11-30 04:59:28
【问题描述】:

我对图和邻接矩阵感到很困惑。我正在为一个类做作业,其中我有一个节点的文本文件和一个边的文本文件,我必须阅读它们中的每一个并将它们制作成一个图,然后我可以在其上执行操作,例如确定图是否是连接,寻找最小生成树,遍历和寻找路径。不过,我以前从未使用过图表,我真的对整个事情感到困惑,我想知道是否有人可以帮助向我解释其中的一些内容。

首先,我是否要自己构建一个图(也许有节点和边类?),然后从中构建一个邻接矩阵?还是邻接矩阵本身就是图?

然后我对如何在程序中实现相邻矩阵感到困惑。节点是诸如“ND5”和“NR7”之类的名称,因此我必须设置和读取 [ND5][NR7] 的边缘,但我不知道如何设置一个带有字符串的二维数组外面是数字,里面是数字。

我一直在互联网上进行搜索,并通读了教科书中有关图表的整章,但我真的不了解设置此图表的最初基本步骤。我非常感谢您的帮助。谢谢。

【问题讨论】:

  • 尝试发布每个文件的小样本以及到目前为止您拥有的任何代码以获得更好的帮助。
  • “首先,我是否自己构建一个图(可能包含节点和边类?)然后从中构造一个邻接矩阵?还是邻接矩阵本身就是图形?” 如果没有实际阅读作业说明,任何人都无法肯定地回答这个问题。但是,除非作业特别提到 NodeEdge 类或其他内容,否则我的猜测是您应该使用邻接矩阵来表示您的图形。

标签: java graph adjacency-matrix


【解决方案1】:

首先,我是否要自己构建一个图(也许有节点和边类?),然后从中构建一个邻接矩阵?还是邻接矩阵本身就是图?

如果没有实际阅读作业说明,任何人都无法肯定地回答这个问题。但是,除非作业特别提到 NodeEdge 类或其他内容,否则我的猜测是您应该使用邻接矩阵来表示您的图形。

然后我对如何在程序中实现相邻矩阵感到困惑。节点是诸如“ND5”和“NR7”之类的名称,因此我必须设置和读取[ND5][NR7] 的边缘,但我不确定如何设置一个带有外部字符串和数字的二维数组在里面。

我完全可以理解你在这里的困惑。您真正想要做的是在您的节点名称和矩阵的索引之间创建一个bijection(一对一的关系)。例如,如果您的图中有 n 个节点,那么您需要一个 n×n 矩阵(即new boolean[n][n]),并且每个节点对应一个0 到 n 范围内的单个整数(不包括 n)。

我不确定到目前为止您在课堂上涵盖了哪些数据结构,但最简单的方法可能是使用Map<String, Integer>,它可以让您查找像"ND5" 这样的名称并取回一个整数(索引)。

另一个不错的选择可能是使用数组。您可以将所有节点名称放入一个数组中,使用Arrays.sort 对其进行排序,然后一旦排序,您就可以使用Arrays.binarySearch 在该数组中查找特定节点名称的索引。我认为这个解决方案实际上比使用Map 更好,因为它可以让您以两种方式进行查找。您使用Arrays.binarySearch 进行名称到索引的查找,而您只需对数组进行索引以进行索引到名称的查找。


示例:假设我们有这个图表:

鉴于该图,以下是一些示例代码,说明如何执行此操作:(警告!未经测试)

import java.util.Arrays;

// Add all your node names to an array
String[] nameLookup = new String[4];
nameLookup[0] = "A";
nameLookup[1] = "B";
nameLookup[2] = "C";
nameLookup[3] = "D";

// Our array is already properly sorted,
// but yours might not be, so you should sort it.
// (if it's not sorted then binarySearch won't work)
Arrays.sort(nameLookup);

// I'm assuming your edges are unweighted, so I use boolean.
// If you have weighted edges you should use int or double.
// true => connected, false => not connected
// (entries in boolean arrays default to false)
boolean[][] matrix = new boolean[4];
for (int i=0; i<matrix.length; i++) matrix[i] = new boolean[4];

// I don't want to call Arrays.binarySearch every time I want an index,
// so I'm going to cache the indices here in some named variables.
int nodeA = Arrays.binarySearch(nameLookup, "A");
int nodeB = Arrays.binarySearch(nameLookup, "B");
int nodeC = Arrays.binarySearch(nameLookup, "C");
int nodeD = Arrays.binarySearch(nameLookup, "D");

// I'm assuming your edges are undirected.
// If the edges are directed then the entries needn't be semmetric.
// A is connected to B
matrix[nodeA][nodeB] = true;
matrix[nodeB][nodeA] = true;
// A is connected to D
matrix[nodeA][nodeD] = true;
matrix[nodeD][nodeA] = true;
// B is connected to D
matrix[nodeB][nodeD] = true;
matrix[nodeD][nodeB] = true;
// C is connected to D
matrix[nodeC][nodeD] = true;
matrix[nodeD][nodeC] = true;

// Check if node X is connected to node Y
int nodeX = Arrays.binarySearch(nameLookup, stringNameOfX);
int nodeY = Arrays.binarySearch(nameLookup, stringNameOfY);

if (matrix[nodeX][nodeY]) { /* They're connected */ }

// Print all of node Z's neighbors' names
int nodeZ = Arrays.binarySearch(nameLookup, stringNameOfZ);
for (int i=0; i<matrix.length; i++) {
  if (matrix[nodeZ][i]) {
    System.out.println(nameLookup[nodeZ] + " is connected to " + nameLookup[i]);
  }
}

【讨论】:

  • 啊,这太棒了,谢谢!你真的帮我解决了这个问题:)
  • @Josephine - 我很高兴这是有道理的!请注意,我没有测试上面的任何代码,因此可能存在一些语法错误——但我认为您应该能够大致了解。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-10-13
  • 1970-01-01
  • 2016-04-06
  • 1970-01-01
  • 2012-11-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多