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

📄 awd.h

📁 一本全面剖析C++数据结构算法的书籍
💻 H
字号:
// file awd.h// adjacency matrix representation of a directed weighted graph// full version#ifndef AdjacencyWDigraph_#define AdjacencyWDigraph_#include <stdlib.h>#include <iostream.h>#include "fchain.h"#include "network.h"#include "citer.h"#include "wnetwork.h"#include "swap.h"#include "make2db.h"#include "del2d.h"template <class T> class AdjacencyWGraph;template<class T>class AdjacencyWDigraph : virtual public Network,                          virtual public WNetwork<T> {   friend AdjacencyWGraph<T>;   friend class AdjacencyGraph;   public:      AdjacencyWDigraph               (int Vertices = 10, T noEdge = 0);      ~AdjacencyWDigraph() {Delete2DArray(a,n+1);}      bool Exist(int i, int j) const;      int Edges() const {return e;}      int Vertices() const {return n;}      AdjacencyWDigraph<T>& Add                        (int i, int j, const T& w);      AdjacencyWDigraph<T>& Delete(int i, int j);      int OutDegree(int i) const;      int InDegree(int i) const;      void ShortestPaths(int s, T d[], int p[]);      void AllPairs(T **c, int **kay);      void Output() const;      void InitializePos() {pos = new int [n+1];}      void DeactivatePos() {delete [] pos;}      int Begin(int i);      int NextVertex(int i);      void First(int i, int& j, T& c);      void Next(int i, int& j, T& c);      T TSP(int v[]);      T BBTSP(int v[]);   private:      void tSP(int i);      T NoEdge;  // used for absent edge      int n;     // number of vertices      int e;     // number of edges      T **a;     // adjacency matrix      int *pos;      // static members used by backtracking and      // branch-and-bound methods      static int *x,     // path to current node                 *bestx; // best solution so far      static T cc,       // cost at current node               bestc;    // cost of best solution found so far};// define static members for T = int and float// add definitions for additional types as neededint  *AdjacencyWDigraph<int>::x,     *AdjacencyWDigraph<int>::bestx,      AdjacencyWDigraph<int>::bestc,      AdjacencyWDigraph<int>::cc;int  *AdjacencyWDigraph<float>::x,     *AdjacencyWDigraph<float>::bestx;float AdjacencyWDigraph<float>::bestc,      AdjacencyWDigraph<float>::cc;template<class T>AdjacencyWDigraph<T>   ::AdjacencyWDigraph(int Vertices, T noEdge){// Constructor.   n = Vertices;   e = 0;   NoEdge = noEdge;   Make2DArray(a, n+1, n+1);   // initalize to graph with no edges   for (int u = 1; u <= n; u++)      for (int v = 1; v <= n; v++)         a[u][v] = NoEdge;}template<class T>bool AdjacencyWDigraph<T>::Exist(int i, int j) const{// Does edge (i, j) exist?   if (i < 1 || j < 1 || i > n || j > n       || a[i][j] == NoEdge) return false;   return true;}template<class T>AdjacencyWDigraph<T>& AdjacencyWDigraph<T>                  ::Add(int i, int j, const T& w){// Add edge (i,j) to digraph if not present.   if (i < 1 || j < 1 || i > n ||       j > n || i == j || a[i][j] != NoEdge)       throw BadInput();   a[i][j] = w;   e++;   return *this;}template<class T>AdjacencyWDigraph<T>& AdjacencyWDigraph<T>                  ::Delete(int i, int j){// Delete edge (i,j).   if (i < 1 || j < 1 || i > n ||       j > n || a[i][j] == NoEdge)       throw BadInput();   a[i][j] = NoEdge;   e--;   return *this;}template<class T>int AdjacencyWDigraph<T>::OutDegree(int i) const{// Return out degree of vertex i.   if (i < 1 || i > n) throw BadInput();   // count out edges from vertex i   int sum = 0;   for (int j = 1; j <= n; j++)      if (a[i][j] != NoEdge) sum++;   return sum;}template<class T>int AdjacencyWDigraph<T>::InDegree(int i) const{// Return indegree of vertex i.   if (i < 1 || i > n) throw BadInput();   // count in edges at vertex i   int sum = 0;   for (int j = 1; j <= n; j++)      if (a[j][i] != NoEdge) sum++;   return sum;}template <class T>void AdjacencyWDigraph<T>::Output() const{   for (int i = 1; i <= n; i++) {      for (int j = 1; j <= n; j++)         cout << a[i][j] << " ";      cout << endl;}}template<class T>int AdjacencyWDigraph<T>::Begin(int i){// Return first vertex adjacent to vertex i.if (i < 1 || i > n) throw OutOfBounds();   // look for first adjacent vertex   for (int j = 1; j <= n; j++)      if (a[i][j] != NoEdge) {// j is first one         pos[i] = j;         return j;}   pos[i] = n + 1; // no adjacent vertex   return 0;}template<class T>void AdjacencyWDigraph<T>::First(int i, int& j, T& c){// Return first vertex j and weight of (i,j).   if (i < 1 || i > n) throw OutOfBounds();   // look for first adjacent vertex   for (j = 1; j <= n; j++)      if (a[i][j] != NoEdge) {// j is first one         pos[i] = j;         c = a[i][j];         return;}   pos[i] = n + 1; // no adjacent vertex   j = 0;}template<class T>int AdjacencyWDigraph<T>::NextVertex(int i){// Return next vertex adjacent to vertex i.   if (i < 1 || i > n) throw OutOfBounds();   // find next adjacent vertex   for (int j = pos[i] + 1; j <= n; j++)      if (a[i][j] != NoEdge) {// j is next vertex         pos[i] = j; return j;}   pos[i] = n + 1; // no next vertex   return 0;}template<class T>void AdjacencyWDigraph<T>::Next(int i, int& j, T& c){// Return next vertex j and weight of (i,j).   if (i < 1 || i > n) throw OutOfBounds();   // find next adjacent vertex   for (j = pos[i] + 1; j <= n; j++)      if (a[i][j] != NoEdge) {// j is next vertex         pos[i] = j;         c = a[i][j];         return;}   pos[i] = n + 1; // no next vertex   j = 0;}template<class T>void AdjacencyWDigraph<T>::ShortestPaths(int s,                          T d[], int p[]){// Shortest paths from vertex s, return shortest // distances in d and predecessor info in p.   if (s < 1 || s > n) throw OutOfBounds();   Chain<int> L; // list of reachable vertices for                 // which paths have yet to be found   ChainIterator<int> I;   // initialize d, p, and L   for (int i = 1; i <= n; i++){      d[i] = a[s][i];      if (d[i] == NoEdge) p[i] = 0;      else {p[i] = s;             L.Insert(0,i);}      }   // update d and p   while (!L.IsEmpty()) {// more paths exist      // find vertex *v in L with least d      int *v = I.Initialize(L);      int *w = I.Next();      while (w) {         if (d[*w] < d[*v]) v = w;         w = I.Next();}      // next shortest path is to vertex *v      // delete from L and update d      int i = *v;      L.Delete(*v);      for (int j = 1; j <= n; j++) {         if (a[i][j] != NoEdge && (!p[j] ||   	             d[j] > d[i] + a[i][j])) {            // d[j] decreases            d[j] = d[i] + a[i][j];            // add j to L if not already in L            if (!p[j]) L.Insert(0,j);            p[j] = i;}         }      }}    template<class T>void AdjacencyWDigraph<T>::AllPairs(T **c, int **kay){// All pairs shortest paths. // Compute c[i][j] and kay[i][j] for all i and j.   // initialize c[i][j] = c(i,j,0)   for (int i = 1; i <= n; i++)      for (int j = 1; j <= n; j++) {         c[i][j] = a[i][j];         kay[i][j] = 0;         }   for (int i = 1; i <= n; i++)      c[i][i] = 0;      // compute c[i][j] = c(i,j,k)   for (int k = 1; k <= n; k++)      for (int i = 1; i <= n; i++)         for (int j = 1; j <= n; j++) {            T t1 = c[i][k];            T t2 = c[k][j];            T t3 = c[i][j];            if (t1 != NoEdge && t2 != NoEdge &&               (t3 == NoEdge || t1 + t2 < t3)) {                 c[i][j] = t1 + t2;                 kay[i][j] = k;}            }}template<class T>void AdjacencyWDigraph<T>::tSP(int i){// Backtracking code for traveling salesperson.   if (i == n) {// at parent of a leaf      // complete tour by adding last two edges      if (a[x[n-1]][x[n]] != NoEdge &&         a[x[n]][1] != NoEdge &&         (cc + a[x[n-1]][x[n]] + a[x[n]][1] < bestc ||         bestc == NoEdge)) {// better tour found         for (int j = 1; j <= n; j++)            bestx[j] = x[j];         bestc = cc + a[x[n-1]][x[n]] + a[x[n]][1];}      }   else {// try out subtrees      for (int j = i; j <= n; j++)         // is move to subtree labeled x[j] possible?         if (a[x[i-1]][x[j]] != NoEdge &&               (cc + a[x[i-1]][x[i]] < bestc ||                bestc == NoEdge)) {// yes            // search this subtree            Swap(x[i], x[j]);            cc += a[x[i-1]][x[i]];            tSP(i+1);            cc -= a[x[i-1]][x[i]];            Swap(x[i], x[j]);}      }}template<class T>T AdjacencyWDigraph<T>::TSP(int v[]){// Traveling salesperson by backtracking. // Return cost of best tour, return tour in v[1:n].   // initialize for tSP   x = new int [n+1];   // x is identity permutation   for (int i = 1; i <= n; i++)      x[i] = i;   bestc = NoEdge;   bestx = v;  // use array v to store best tour   cc = 0;   // search permutations of x[2:n]   tSP(2);   delete [] x;   return bestc;}#include "minheap.h"template<class T>class MinHeapNode {   friend AdjacencyWDigraph<T>;   public:      operator T () const {return lcost;}   private:      T lcost,  // lower bound on cost of tours in subtree        cc,     // cost of partial tour        rcost;  // min additional cost to complete tour      int s,    // partial tour is x[0:s]          *x;   // vertex array, x[s+1:n-1] gives remaining                // vertices to be added to partial tour x[0:s]};template<class T>T AdjacencyWDigraph<T>::BBTSP(int v[]){// Min cost branch-and-bound // traveling-salesperson code.   // define a max heap for up to   // 1000 live nodes   MinHeap<MinHeapNode<T> > H(1000);   T *MinOut = new T [n+1];   // compute MinOut[i] = cost of min-cost edge   // leaving vertex i   T MinSum = 0;  // sum of min-cost out edges   for (int i = 1; i <= n; i++) {      T Min = NoEdge;      for (int j = 1; j <= n; j++)         if (a[i][j] != NoEdge &&                  (a[i][j] < Min || Min == NoEdge))            Min = a[i][j];      if (Min == NoEdge) return NoEdge; // no route      MinOut[i] = Min;      MinSum += Min;      }   // initial E-node is tree root   MinHeapNode<T> E;   E.x = new int [n];   for (int i = 0; i < n; i++)      E.x[i] = i + 1;   E.s = 0;           // partial tour is x[1:0]   E.cc = 0;          // its cost is zero   E.rcost = MinSum;  // will go up by this or more   T bestc = NoEdge;  // no tour found so far   // search permutation tree   while (E.s < n - 1) {// not at leaf      if (E.s == n - 2) {// parent of leaf         // complete tour by adding 2 edges         // see if new tour is better         if (a[E.x[n-2]][E.x[n-1]] != NoEdge &&             a[E.x[n-1]][1] != NoEdge && (E.cc +             a[E.x[n-2]][E.x[n-1]] + a[E.x[n-1]][1]             < bestc || bestc == NoEdge)) {             // better tour found             bestc = E.cc + a[E.x[n-2]][E.x[n-1]]                          + a[E.x[n-1]][1];             E.cc = bestc;             E.lcost = bestc;             E.s++;             H.Insert(E);}         else delete [] E.x;}  // done with E-node      else {// generate children         for (int i = E.s + 1; i < n; i++)            if (a[E.x[E.s]][E.x[i]] != NoEdge) {               // feasible child, bound path cost               T cc = E.cc + a[E.x[E.s]][E.x[i]];               T rcost = E.rcost - MinOut[E.x[E.s]];               T b = cc + rcost;  // lower bound               if (b < bestc || bestc == NoEdge) {                   // subtree may have better leaf                   // save root in max heap                   MinHeapNode<T> N;                   N.x = new int [n];                   for (int j = 0; j < n; j++)                      N.x[j] = E.x[j];                   N.x[E.s+1] = E.x[i];                   N.x[i] = E.x[E.s+1];                   N.cc = cc;                   N.s = E.s + 1;                   N.lcost = b;                   N.rcost = rcost;                   H.Insert(N);}               }  // end of feasible child         delete [] E.x;}  // done with this node      try {H.DeleteMin(E);}        // get next E-node      catch (OutOfBounds) {break;} // no nodes left      }   if (bestc == NoEdge) return NoEdge; // no route   // copy best route into v[1:n]   for (int i = 0; i < n; i++)      v[i+1] = E.x[i];   while (true) {// free all nodes in min heap      delete [] E.x;      try {H.DeleteMin(E);}      catch (OutOfBounds) {break;}      }   return bestc;}#endif

⌨️ 快捷键说明

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