⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 graph.cc

📁 TGFF省城程序
💻 CC
📖 第 1 页 / 共 2 页
字号:
// Copyright 2000 by Robert Dick.// All rights reserved.#include "Graph.h"#include <functional>#include <algorithm>#include <typeinfo>#include <iostream>#include "Epsilon.h"namespace rstd {using namespace std;const RawGraph::vertex_index RawGraph::INVALID_VINDEX = -1;const RawGraph::edge_index RawGraph::INVALID_EINDEX = -1;/*###########################################################################*/RawGraph &RawGraph::operator=(const self & a) {	vertex_ = a.vertex_;	edge_ = a.edge_;	return *this;}/*===========================================================================*/comp_typeRawGraph::vertex_index::comp(const vertex_index & a) const {	return rstd::comp(index_, a.index_);}/*===========================================================================*/RawGraph::vertex_index RawGraph::add_vertex() {	vertex_type new_vertex;	vertex_.push_back(new_vertex);	RDEBUG(self_check());	return vertex_.size() - 1;}/*===========================================================================*/comp_typeRawGraph::edge_index::comp(const edge_index & a) const {	return rstd::comp(index_, a.index_);}/*===========================================================================*/RawGraph::edge_index RawGraph::add_edge(const vertex_index from, const vertex_index to) {	edge_.push_back(edge_type(from, to));	edge_index e = edge_.size() - 1;	vertex(to)->in_.push_back(e);	vertex(from)->out_.push_back(e);	RDEBUG(self_check());	return e;}/*===========================================================================*/doubleRawGraph::vertex_weight(vertex_index /* v */) const {	return 0.0;}/*===========================================================================*/doubleRawGraph::edge_weight(edge_index /* e */) const {	return 1.0;}/*===========================================================================*/void RawGraph::erase_vertex(const vertex_index i) {// Erase all of the connected edges.	vertex_iterator v = vertex(i);	while (! v->in_.empty()) {		erase_edge(v->in_.back());	}	while (! v->out_.empty()) {		erase_edge(v->out_.back());	}// Erase the vertex.	vertex_.erase(v);// Fix all of the other vertex indices.	MAP(x, edge_.size()) {		vertex_index & to = edge_[x].to_;		vertex_index & from = edge_[x].from_;		if (to > i) {			--to;		}		if (from > i) {			--from;		}	}	RDEBUG(self_check());}/*===========================================================================*/void RawGraph::erase_edge(const edge_index i) {	RASSERT(i < size_edge());// Fix connected vertices.	vertex_type & parent = *vertex(edge(i)->from());	vertex_type & child = *vertex(edge(i)->to());	RVector<edge_index>::iterator parent_edge =		find(parent.out_.begin(), parent.out_.end(), i);	RVector<edge_index>::iterator child_edge =		find(child.in_.begin(), child.in_.end(), i);	parent.out_.erase(parent_edge);	child.in_.erase(child_edge);// Erase the edge.	edge_.erase(edge(i));// Fix all the other edge indices.	MAP(x, vertex_.size()) {		RVector<edge_index> & out = vertex_[x].out_;		MAP(y, out.size()) {			RASSERT(out[y] != i);			if (out[y] > i) {				--out[y];			}		}		RVector<edge_index> & in = vertex_[x].in_;		MAP(y, in.size()) {			RASSERT(in[y] != i);			if (in[y] > i) {				--in[y];			}		}	}	RDEBUG(self_check());}/*===========================================================================*/void RawGraph::pack_memory() {	RVector<vertex_type> v(vertex_);	RVector<edge_type> e(edge_);	vertex_.rswap(v);	edge_.rswap(e);}/*===========================================================================*/void RawGraph::clear() {	vertex_.clear();	edge_.clear();	RDEBUG(self_check());}/*===========================================================================*/void RawGraph::rswap(RawGraph & rg) {	vertex_.rswap(rg.vertex_);	edge_.rswap(rg.edge_);	RDEBUG(self_check());	RDEBUG(rg.self_check());}/*===========================================================================*/void RawGraph::print_to(ostream & os) const {	MAP(x, vertex_.size()) {		os << "vertex " << x << " ";		vertex_[x].print_to(os);		os << "\n";	}	MAP(x, edge_.size()) {		os << "edge " << x;		edge_[x].print_to(os);		os << "\n";	}}/*===========================================================================*/bool RawGraph::cyclic() const {	MAP(start, vertex_.size()) {		RVector<big_bool> visited(vertex_.size(), false);		if (cyclic_recurse(visited, start, start))			return true;	}	return false;}/*===========================================================================*/bool RawGraph::connected(const vertex_index start, bool reverse_i) const {	RVector<vertex_index> vec = dfs(start, reverse_i);	return vec.size() == vertex_.size();}/*===========================================================================*/bool RawGraph::nodes_linked (vertex_index a, vertex_index b) const {	MAP (x, vertex(a)->size_out()) {		if (edge(vertex(a)->out(x))->to() == b) {			return true;		}	}	MAP (x, vertex(b)->size_out()) {		if (edge(vertex(b)->out(x))->to() == a) {			return true;		}	}	return false;}/*===========================================================================*/const RVector<RawGraph::vertex_index> RawGraph::dfs(const vertex_index start, bool reverse_i) const {	RVector<vertex_index> vec;	RVector<big_bool> visited(vertex_.size(), false);	dfs_recurse(vec, visited, start, reverse_i);	return vec;}/*===========================================================================*/const RVector<RawGraph::vertex_index>RawGraph::dfs(RVector<vertex_index> start, bool reverse_i) const {	RVector<vertex_index> vec;	RVector<big_bool> visited(vertex_.size(), false);	MAP(x, start.size()) {		dfs_recurse(vec, visited, start[x], reverse_i);	}	return vec;}/*===========================================================================*/const RVector<RawGraph::vertex_index>RawGraph::bfs(const vertex_index start, bool reverse_i) const {	RVector<vertex_index> vec;	RVector<big_bool> visited(vertex_.size(), false);	visited[start] = true;	bfs_recurse(vec, visited, start, reverse_i);	return vec;}/*===========================================================================*/const RVector<RawGraph::vertex_index>RawGraph::bfs(RVector<vertex_index> start, bool reverse_i) const {	RVector<vertex_index> vec;	RVector<big_bool> visited(vertex_.size(), false);	MAP(x, start.size()) {		visited[start[x]] = true;		bfs_recurse(vec, visited, start[x], reverse_i);	}	return vec;}/*===========================================================================*/const RVector<std::pair<RawGraph::vertex_index, double> >RawGraph::shortest_path(vertex_index start) const {Rabort();	RVector<vertex_index> parent;	RVector<double> distance;// Initialize single source	MAP(x, vertex_.size()) {		parent.push_back(RawGraph::INVALID_VINDEX);		if (x == start) {			distance.push_back(0.0);		} else {			distance.push_back(numeric_limits<double>::max());		}	}// relax// recursively do this until no more changes	bool distance_changed = true;	while (distance_changed == true) {		distance_changed = false;		MAP(x, edge_.size()) {			if (distance[edge_[x].to_] > distance[edge_[x].from_] +				edge_weight(x))			{				distance[edge_[x].to_] = distance[edge_[x].from_] + edge_weight(x);				parent[edge_[x].to_] = vertex_index(edge_[x].from_);				distance_changed = true;			}		}	}// check for negative weight	eps_equal_to<double, 10> eq;	MAP(x, edge_.size()) {//#warning THIS CODE IS WRONG		RASSERT(eq(distance[edge_[x].to_], distance[edge_[x].from_] +			edge_weight(x)));	}	RVector<std::pair<vertex_index, double> > shortestpath_result;	MAP (x, parent.size()) {		pair<vertex_index, double> result(parent[x], distance[x]);		shortestpath_result.push_back(result);	}	return shortestpath_result;}/*===========================================================================*/const RVector<RawGraph::vertex_index> RawGraph::top_sort(const vertex_index start, bool reverse_i) const {	RVector<vertex_index> vec;	RVector<big_bool> visited(vertex_.size(), false);// For now, allow only source or sink start nodes.	RASSERT(reverse_i && ! vertex_[start].size_out() ||		! reverse_i && ! vertex_[start].size_in());// Figure out which nodes can be reached.	dfs_recurse(vec, visited, start, reverse_i);// Invert to pre-visit nodes which can't be reached.	transform(visited.begin(), visited.end(), visited.begin(),	  logical_not<big_bool>());	vec.erase(vec.begin(), vec.end());	top_sort_recurse(vec, visited, start, reverse_i);	return vec;}/*===========================================================================*/const RVector<RawGraph::vertex_index> RawGraph::top_sort(const RVector<vertex_index> & start, bool reverse_i) const {	RVector<vertex_index> vec;	RVector<big_bool> visited(vertex_.size(), false);// Figure out which nodes can be reached.	MAP(x, start.size()) {// For now, allow only source or sink start nodes.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -