longlong
路人甲
路人甲
  • 注册日期2004-10-20
  • 发帖数28
  • QQ
  • 铜币212枚
  • 威望0点
  • 贡献值0点
  • 银元0个
阅读:1159回复:0

最短路径算法实现

楼主#
更多 发布于:2005-08-04 10:56
////////////////////////////////////////////////////////////////////////////////<BR>// topo.h - topology of graph<BR>// author: cheungmine <BR>// date: 2004-6-18<BR>// log: 2004-6-18 initially created by cheungmine<BR>//20040-12 modified by cheungmine <BR>#ifndef _topo_h__<BR>#define _topo_h__<BR>//////////////////////////////////////////////////////////////////////////<BR>#define MAXWEIGHT 1000000000<BR>#define DIFFVAL(v1, v2) (((v1) > (v2))? (v1)-(v2) : (v2)-(v1))<BR><BR>#pragma warning(disable:4786)<BR>#include <vector><BR>using namespace std;<BR><BR><BR>struct topo_node<BR>{<BR>union {<BR>struct {<BR>long x;<BR>long y;<BR>};<BR><BR>long nod[2];<BR>};<BR><BR>topo_node(){}<BR><BR>topo_node(long lx, long ly)<BR>{<BR>x = lx;<BR>y = ly;<BR>}<BR>};<BR><BR>struct topo_arc<BR>{<BR>union {<BR>struct {<BR>long id;// arc id links explict attrlist. aid identifies direction of an arc<BR>long wt;// weight of arc<BR>long na;// from node point<BR>long nb;// to node point<BR>};<BR><BR>long arc[4];<BR>};<BR><BR>topo_arc(){}<BR><BR>topo_arc(long arcid, long weight, long from, long to)<BR>{<BR>id = arcid;<BR>wt = weight;<BR>na = from;<BR>nb = to;<BR>}<BR>};<BR><BR>// A topo_path consistes of multiple topo_arc(s)<BR>class topo_path<BR>{<BR>private:<BR>vector<long> ipath;<BR><BR>public:<BR>topo_path(){}<BR><BR>~topo_path(){<BR>ipath.clear();<BR>}<BR><BR>inline long; operator [](int i)<BR>{<BR>return ipath<I>;<BR>}<BR><BR>inline void pushback(long val)<BR>{<BR>ipath.push_back(val);<BR>}<BR><BR>inline static void link(topo_path; pa, topo_path; pb, topo_path; res)<BR>{<BR>int sa = pa.size();<BR>int sb = pb.size();<BR>int size = sa+sb;<BR>res.ipath.resize(size);<BR><BR>for (int i=0; i<sa; i++)<BR>res.ipath<I> = pa.ipath<I>;<BR><BR>int j=0;<BR>for (i=sa; i<size; i++)<BR>res.ipath<I> = pb.ipath[j++];<BR>}<BR><BR>inline int size(){<BR>return ipath.size();<BR>}<BR>};<BR><BR><BR>class topo_network<BR>{<BR>typedef vector<topo_arc> arc_list;<BR>typedef vector<topo_node> node_list;<BR><BR>// Data<BR>unsigned short diff;// Tolerance units of network<BR>arc_list arcs; // A vector of topo_arc(s)<BR>node_list nodes; // A vector of topo_node(s)<BR><BR>// Adjacence matrix<BR>long* arcmat;// Adjacence matrix of arc ids<BR>long* wtmat;// Adjacence matrix of weights of arcs<BR><BR>// Floyd ; Dijkstra<BR>topo_path* pathmat;<BR><BR>// Dijkstra<BR>long* sel;<BR>long* dist;<BR><BR>public:<BR><BR>topo_network(unsigned short difference=1)<BR>{<BR>diff = difference;<BR>arcmat = NULL;<BR>wtmat = NULL;<BR>pathmat = NULL;<BR><BR>sel = NULL;<BR>dist = NULL;<BR>}<BR><BR>~topo_network(){<BR>delete[] arcmat;<BR>delete[] wtmat;<BR>delete[] pathmat;<BR>delete[] sel;<BR>}<BR><BR>void initDiff(unsigned short difference) {<BR>diff = difference;<BR>}<BR><BR>// Add a edge to arcs, if have a reverse edge simultaneously, add it as well.<BR>void addArc(long arcid, long weight, <BR>long xfrom, long yfrom, <BR>long xto, long yto,<BR>bool bHaveRev = false)<BR>{<BR>// traverse nodes firstly<BR>topo_arc arc(arcid, weight, 0, 0);<BR>long nod;<BR>long size = nodes.size();<BR><BR>bool bAddFrom = false;<BR>bool bAddTo = false;<BR>for (long i=0; i<size; i++) {<BR>if ( !bAddFrom ;; DIFFVAL(nodes<I>.x, xfrom) < diff ;; DIFFVAL(nodes<I>.y, yfrom) < diff) {<BR>arc.na = i;<BR>bAddFrom = true;<BR>}<BR><BR>if ( !bAddTo ;; DIFFVAL(nodes<I>.x, xto) < diff ;; DIFFVAL(nodes<I>.y, yto) < diff) {<BR>arc.nb = i;<BR>bAddTo = true;<BR>}<BR>}<BR><BR>if (!bAddFrom) {<BR>topo_node node(xfrom, yfrom);<BR>nodes.push_back(node);<BR>arc.na = nodes.size()-1;<BR>}<BR><BR>if (!bAddTo) {<BR>topo_node node(xto, yto);<BR>nodes.push_back(node);<BR>arc.nb = nodes.size()-1;<BR>}<BR><BR>arcs.push_back(arc);<BR>if (bHaveRev) {<BR>nod = arc.nb;<BR>arc.nb = arc.na;<BR>arc.na = nod;<BR>arc.id = -arc.id;<BR><BR>arcs.push_back(arc);<BR>}<BR>}<BR><BR>long sizeArcs(){<BR>return arcs.size();<BR>}<BR><BR>long sizeNodes(){<BR>return nodes.size();<BR>}<BR><BR>// Create adjacency matrix for storing topo_network.<BR>bool createAdjMatrix() {<BR>long size = nodes.size();<BR>long length = size*size;<BR>try{<BR>if (arcmat)<BR>delete[] arcmat;<BR>if (wtmat)<BR>delete[] wtmat;<BR>if (pathmat)<BR>delete[] pathmat;<BR><BR>arcmat = new long [length];<BR>wtmat = new long [length];<BR>pathmat = new topo_path [length];<BR>}<BR>catch(...){<BR>arcmat = NULL;<BR>wtmat = NULL;<BR>pathmat = NULL;<BR>return false;<BR>}<BR><BR>if (!arcmat || !wtmat || !pathmat)<BR>return false;<BR><BR>// Initialize with sensely value.<BR>for (long row=0; row<size; row++) {<BR>for (long col=0; col<size; col++) {<BR>long q = row*size+col;<BR>arcmat[q] = -1;<BR>if (row == col) <BR>wtmat[q] = 0;<BR>else<BR>wtmat[q] = MAXWEIGHT;<BR>}<BR>}<BR><BR>// Filling weight in it<BR>long count = arcs.size();<BR>for (long k=0; k<count; k++) {<BR>long i = arcs[k].na;<BR>long j = arcs[k].nb;<BR>long q = i*size+j;<BR>arcmat[q] = k;<BR>wtmat[q] = arcs[k].wt;<BR>pathmat[q].pushback(k);<BR>}<BR><BR>return true;<BR>}<BR><BR>void Floyd()<BR>{<BR>long v = 0;<BR>long size = nodes.size();<BR><BR>for (int k=0; k<size; k++) {<BR>for (int i=0; i<size; i++) {<BR>for (int j=0; j<size; j++) {<BR>long ij = i*size+j;<BR>long ik = i*size+k;<BR>long kj = k*size+j;<BR><BR>v = wtmat[i*size+k] + wtmat[k*size+j];<BR><BR>if (v < wtmat[ij]) {<BR>wtmat[ij] = v;<BR>topo_path::link(pathmat[ik], pathmat[kj], pathmat[ij]);<BR>}<BR>}<BR>}<BR>}<BR>}<BR><BR>// Get path from isrc to idst using Dijkstra Algorithm.<BR>void Dijkstra (long isrc)<BR>{<BR>long size = nodes.size();<BR><BR>if (sel)<BR>delete[] sel;<BR>sel = new long [size];<BR><BR>// Dist is a reference to weight matrix, so we NEED NOT allocate and free it.<BR>dist = wtmat + isrc*size;<BR><BR>// Initialize sel<BR>for (int i=0; i<size; i++)<BR>sel<I> = 0;<BR>sel[isrc] = 1;// Select isrc to selection<BR><BR>// Select the min dist j to selection.<BR>for (long k=0; k<size-1; k++) {<BR><BR>long wt = MAXWEIGHT;<BR>long j = isrc;<BR><BR>for (i=0; i<size; i++) {<BR>if (sel<I>!=1 ;; dist<I> < wt) {// (v!=1) is faster than (v==0)<BR>j = i;<BR>wt = dist<I>;<BR>}<BR>}<BR>sel[j] = 1;// Add j to sel which dist[j] is min.<BR>//if (j==isrc)<BR>//break;<BR><BR>// Modify dist[]<BR>for (i=0; i<size; i++) {<BR>long w = dist[j] + wtmat[j*size+i]; // weight from j to i plus from isrc to j.<BR><BR>if (sel<I> != 1 ;; w < dist<I> ) {<BR>dist<I> = w;<BR>// Desc: path[isrc, i] = path[isrc, j] + path[j,i];<BR>topo_path::link(pathmat[isrc*size+j], pathmat[j*size+i], pathmat[isrc*size+i]);<BR>}<BR>}<BR>}<BR>}<BR><BR>topo_path; getPath(long isrc, long idst, long* length=NULL)<BR>{<BR>int q = isrc*sizeNodes() + idst;<BR><BR>if (length)<BR>*length = wtmat[q];<BR><BR>return pathmat[q];<BR>}<BR><BR>// i must be a valid index of arcs<BR>topo_arc getArc(long i) {<BR>topo_arc a = arcs<I>;<BR>return a;<BR>}<BR><BR>// Get index of node in nodes<BR>long getNodeIndex(long lx, long ly) {<BR>long size = nodes.size();<BR><BR>for (long i=0; i<size; i++) {<BR>if ( DIFFVAL(nodes<I>.x, lx) < diff ;; DIFFVAL(nodes<I>.y, ly) < diff)<BR>return i;<BR>}<BR><BR>return -1;// Invalid index<BR>}<BR>};<BR></I></I></I></I></I></I></I></I></I></I></I></I></I></I></I></I></I></I>
喜欢0 评分0
游客

返回顶部