图算法

152 阅读2分钟

图算法指利用特制的线条算图求得答案的一种简便算法。无向图、有向图和网络能运用很多常用的图算法,这些算法包括:各种遍历算法(这些遍历类似于树的遍历),寻找最短路径的算法,寻找网络中最低代价路径的算法,回答一些简单相关问题(例如,图是否是连通的,图中两个顶点间的最短路径是什么,等等)的算法。图算法可应用到多种场合,例如:优化管道、路由表、快递服务、通信网站等。

所以关于图算法,比较重要的是如何进行建模,将场景使用代码表示出来。

图的表示

从图的定义可以知道,一个图的基本单位是“点”与“边”。有“点”、“边”合成一张图。

从点的属性来看,我们声明一个点,可以记录以下信息:

  • in,一个点的入度
  • out, 一个点的出度
  • value,该点所代表的含义
  • edges,该点所连接的边的集合
  • nexts,从该点出发,可到达的下一个点的集合

代码实现

interface NodeEl {
	in: number,
	out: number,
	value: number,
	edges: Array<Edge>,
	nexts: Array<NodeEl>

	constructor(value: number)
}


class NodeEl {
	constructor(value: number) {
		this.in = 0;
		this.out = 0;
		this.value = value;
		this.nexts = [];
		this.edges = [];
	}
}

线

从线的属性来看,我们声明一个线,可以记录以下信息:

  • from,从哪一个出发
  • to, 指向哪一个点
  • weight,该路径上的权重

代码实现

interface Edge {
	from: NodeEl,
	to: NodeEl,
	weight: number,
	constructor(from: NodeEl, to: NodeEl, weight: number)
}

 class Edge {
	from: NodeEl;
	to: NodeEl;
	weight: number;

	constructor(from, to, weight) {
		this.from = from;
		this.to = to;
		this.weight = weight;
	}
}

图表示点与线的集合。

代码实现

interface Graph {
	nodes: Map<number, NodeEl>,
	edges: Edge[]
}

 class Graph {
	nodes: Map<number, NodeEl>;
	edges: Edge[];

	constructor() {
		this.nodes = new Map();
		this.edges = [];
	}
}

如何从给出的条件转化成其对应的图的表示方法

假设题目给出的图的表示方法为一个二维数组,使用以下函数讲该二维数组转化成图对象。

代码实现

interface GraphGenerator {
	graph: Graph;
	constructor(matrix: Array<Array<number>>);
        getGraph(): Graph;
}

class GraphGenerator {
	constructor(matrix: Array<Array<number>>){
		this.graph = new Graph();

		for(let i = 0; i < matrix.length; i++) {
			let node1 = this.graph.nodes.get(matrix[i][0]) 
			let node2 = this.graph.nodes.get(matrix[i][1]) 
			if (!node1) {
				this.graph.nodes.set(matrix[i][0], new NodeEl(matrix[i][0]));
			}
			if (!node2) {
				this.graph.nodes.set(matrix[i][1], new NodeEl(matrix[i][1]));
			}
			let fromNode = this.graph.nodes.get(matrix[i][0]);
			let toNode = this.graph.nodes.get(matrix[i][1]);
			let edge = new Edge(fromNode, toNode, matrix[i][2]);

			fromNode.edges.push(edge);
			fromNode.nexts.push(toNode);
			fromNode.out++;

			toNode.in++;

			this.graph.edges.push(edge);
		}

		this.graph.edges = this.graph.edges.filter(el => el);
	}

	getGraph(): Graph {
		return this.graph;
	}
}