旅行商问题的n种解法

时间:2025-03-15 09:09:12
  • //------------------------------------- 文件--------------------------------------------------  
  • #ifndef AdjTWGraph_H  
  • #define AdjTWGraph_H  
  • #include <vector>  
  • #include <iostream>  
  • using namespace std;  
  • const int MaxV=100;  
  • struct Edge  
  •  {  
  •     int dest;  
  •     int weight;  
  •     Edge * next;  
  •      Edge(){}  
  •      Edge(int d,int w):dest(d),weight(w),next(NULL){}  
  • };  
  • struct item  
  •  {    int data;  
  •     Edge * adj;  
  • };  
  • class AdjTWGraph  
  •  {  
  • private:  
  •     item vertices[MaxV];  
  •     int numV,numE;  
  • public :  
  •     AdjTWGraph();  
  •     ~AdjTWGraph();  
  •      int NumV(){return numV;}  
  •      int NumE(){return numE;}  
  •     int GetValue(const int i);  
  •     int GetWeight(const int v1,const int v2);  
  •     void InsertV(const int & vertex);  
  •     void InsertE(const int v1,const int v2,int weight);  
  •     friend ostream& operator<<(ostream& os,  AdjTWGraph & m)  
  •      {     for (int i = 0; i <  ; i++)     {  
  •             for (int j = 0; j < ; j++)  
  •                 os << right << (i,j) << " ";  
  •             os << endl;  
  •         }  
  •         return os;  
  •     }  
  •     friend istream& operator>>(istream& is, AdjTWGraph & m)  
  •      {    int t;  
  •         for (int i = 0; i < (); i++)  
  •             for (int j = 0; j < (); j++)  
  •              {  
  •                 is >> t;     (i,j,t);  
  •             }  
  •         return is;  
  •     }  
  • };  
  • AdjTWGraph::AdjTWGraph()  
  •  {  
  •     for(int i=0;i<MaxV;i++)     vertices[i].adj=NULL;  
  •     numV=0;numE=0;  
  • }  
  • AdjTWGraph::~AdjTWGraph()  
  •  {  
  •     for(int i=0;i<numV;i++)  
  •      {  
  •         Edge * p=vertices[i].adj,*q;  
  •         while(p!=NULL)  
  •          {  
  •             q=p->next;delete p;p=q;  
  •         }  
  •     }  
  • }  
  •  int AdjTWGraph::GetValue(const int i){    return vertices[i].data;  }  
  • int AdjTWGraph::GetWeight(const int v1,const int v2)  
  •  {  
  •     Edge *p=vertices[v1].adj;  
  •     while(p!=NULL && p->dest<v2) p=p->next;  
  •      if(v2!=p->dest)    {    return 0;    }  
  •     return p->weight;  
  • }  
  •  void AdjTWGraph::InsertV(const int & v) { vertices[numV].data=v; numV++;  }  
  • void AdjTWGraph::InsertE(const int v1,const int v2,int weight)  
  •  {  
  •     Edge * q=new Edge(v2,weight);  
  •     if(vertices[v1].adj==NULL) vertices[v1].adj=q;  
  •     else  
  •      {  
  •         Edge *curr=vertices[v1].adj,*pre=NULL;  
  •          while(curr!=NULL && curr->dest<v2)    {    pre=curr;curr=curr->next;    }  
  •          if(pre==NULL){    q->next=vertices[v1].adj;vertices[v1].adj=q;        }  
  •          else    {    q->next=pre->next;pre->next=q;    }  
  •     }  
  •     numE++;  
  • }  
  • #endif  
  •   
  • //------------------------------------- 文件--------------------------------------------------  
  • #include ""  
  • #include <fstream>  
  • #include <vector>  
  • #include <algorithm>  
  • #include <ctime>  
  • #include <queue>  
  • using namespace std;  
  • ofstream fout("");  
  • int N;  
  • AdjTWGraph g;  
  • struct Node      
  •  {   int currentIndex;  
  •     int level;  
  •     Node * previous;  
  •      Node(int L = 0, int V = 0, Node *p = NULL):level(L),currentIndex(V), previous(p) {}  
  • };  
  • class TspBase  
  •  {  
  • protected:      
  •     vector<int> currentPath;  
  •     vector<int> bestPath;  
  •     int cv;  
  •     int bestV;  
  •     Node * root;  
  •   
  •     int SumV();     
  •     void EnumImplicit(int k);  
  •     void BackTrackImplicit(int k);  
  •   
  •     void EnumExplicit(Node * r);  
  •     void BackTrackExplicit(Node * r);  
  •     void FIFOBB();  
  •   
  •     bool Valid(Node *p,int v)  //  
  •          {    bool flag = true;  
  •             for(Node *r = p; r->level > 0 && V; r = r->previous)  flag = r->currentIndex !=v;  
  •             return flag;  
  •         }  
  •     void StoreX(Node * p) //  
  •          {for(Node *r = p; r->level >0 ; r = r->previous )  
  •  {    currentPath[r->level-1] = r->currentIndex;    }  
  •         }  
  •     void Print();  
  • public:  
  •      TspBase(){(N);    (N);    }  
  •  ~TspBase(){(0);(0);}  
  •   
  •     void TspEnumImplicit();  
  •     void TspBackTrackImplicit();  
  •   
  •     void TspEnumExplicit();          
  •     void TspBackTrackExplicit();  
  •     
  •     void TspBB();  
  •   
  •     void TspGreedy();       
  •       
  •     void DataClear(bool flag)  
  •      {   (N);        (N);  
  •          if(flag)        { Node * p=root,*q;  
  •                       while(p!=NULL) {q=p->previous; delete p; p=q;}      
  •         }  
  •     }  
  • };  
  • void TspBase::TspEnumImplicit()  //         枚举隐式  
  •  {    fout<<"TspEnumImplicit ..."<<endl;  
  • cv=0; bestV=10000;  
  •     for(int i=0;i<N;i++)    currentPath[i]=i;  
  •     EnumImplicit(1);  
  •     Print();  
  • }  
  • void TspBase::EnumImplicit(int k)  
  •  {    if(k == N)  
  •      {    if((cv + (currentPath[N-1],0)) < bestV)  
  •          {  
  •             bestV = cv + (currentPath[N-1],0);  
  •             for(int i = 0; i < N; i++)  
  •               bestPath[i] = currentPath[i];  
  •         }          
  •     }  
  •     else  
  •         for(int j = k; j < N; j++)  
  •          {    swap(currentPath[k],currentPath[j]);  
  •             cv += (currentPath[k-1],currentPath[k]);  
  •             EnumImplicit(k+1);  
  •             cv -= (currentPath[k-1],currentPath[k]);  
  •             swap(currentPath[k],currentPath[j]);  
  •         }  
  • }  
  • void TspBase::TspEnumExplicit()    //  枚举显式  
  •  {   fout<<"TspEnumExplicit  ..."<<endl;  
  • cv=0;     bestV=10000;  
  •      for(int i=0;i<N;i++)     currentPath[i]=i;  
  •      root=new Node(0,-1,NULL);  
  •      EnumExplicit(root);  
  •      Print();  
  • }  
  •   
  • void TspBase::EnumExplicit(Node * r)  
  •  {    if(r->level == N)  
  •      {    StoreX(r);    cv = SumV();  
  •         if(cv  < bestV)      
  •          {    bestV = cv  ;  
  •             for(int i = 0; i < N; i++)  
  •               bestPath[i] = currentPath[i];  
  •         }  
  •     }  
  •     else  
  •         for(int i = 0; i < N; i ++)  
  •          { if(Valid(r,i))   
  •              {  Node *q = new Node(r->level+1,i,r);    EnumExplicit(q);    }  
  •         }  
  • }  
  • void TspBase::TspBackTrackImplicit()     //回溯隐式  
  •  {    fout<<"TspBackTrackImplicit ..."<<endl;  
  • cv=0;  bestV=10000;  
  •     for(int i=0;i<N;i++)    currentPath[i]=i;  
  •     BackTrackImplicit(1);  
  •     Print();  
  • }  
  • void TspBase::BackTrackImplicit(int k)  
  •  {    if(k == N)  
  •      {    if((cv + (currentPath[N-1],0)) < bestV)  
  •          {  
  •             bestV = cv + (currentPath[N-1],0);  
  •             for(int i = 0; i < N; i++)  
  •               bestPath[i] = currentPath[i];  
  •         }          
  •     }  
  •     else  
  •         for(int j = k; j < N; j++)  
  •          { if((cv + (currentPath[k-1],currentPath[j])) < bestV)  
  •            {    swap(currentPath[k],currentPath[j]);  
  •                cv += (currentPath[k-1],currentPath[k]);  
  •             BackTrackImplicit(k+1);  
  •             cv -= (currentPath[k-1],currentPath[k]);  
  •             swap(currentPath[k],currentPath[j]);  
  •           }  
  •         }  
  • }  
  • void TspBase::TspBackTrackExplicit()      // 回溯显式  
  •  {    fout<<"TspBackTrackExplicit  ..."<<endl;   
  • cv=0;     bestV=10000;  
  •      for(int i=0;i<N;i++)     currentPath[i]=i;  
  •      root=new Node(0,-1,NULL);  
  •      BackTrackExplicit(root);  
  •      Print();  
  • }  
  • void TspBase::BackTrackExplicit(Node * r)  
  •  {    int w=0;  //初值  
  •     if(r->level == N)  
  •      {    StoreX(r);  
  •         cv = SumV();  
  •         if(cv  < bestV)      
  •          {   bestV = cv  ;  
  •             for(int i = 0; i < N; i++)        bestPath[i] = currentPath[i];  
  •         }  
  •     }  
  •     else  
  •         for(int i = 0; i < N; i ++)  
  •          {  if(Valid(r,i))   
  •              {    Node *q = new Node(r->level+1,i,r);  
  •                 w += (q->currentIndex,i);  
  •                 if(w < bestV)       BackTrackExplicit(q);  
  •                 w -= (q->currentIndex,i);      
  •             }  
  •         }  
  • }  
  •   
  •   
  • void TspBase::Print() //  
  •  {       fout<<"the shortest path is  ";  
  •        for(unsigned i = 0; i < N; i++)  
  •              fout<<bestPath[i] + 1<<"--";  
  •        fout<<"1"<<endl;  
  •        fout<<"minimum distance is  "<<bestV<<endl;         
  • }  
  •   
  • void TspBase::TspBB()       // 分支限界法  
  •  {        fout<<"TspBB(FIFOBB)  ........"<<endl;  
  • cv = 0;        bestV = 100000;  
  •         for(unsigned i = 0; i < N; i++)    currentPath[i] = i;  
  •         root=new Node(0,-1,NULL);  
  •         FIFOBB();  
  •         Print();  
  • }  
  • void TspBase::FIFOBB()  
  •  { queue<Node*> q;   Node *r;  
  •   (root);  
  •   int w=0;  //初值  
  •   while(!())  
  •    {      r = ();      ();  
  •       if(r->level == N)  
  •        { StoreX(r);  
  •         cv = SumV();  
  •         if(cv  < bestV)      
  •          {   bestV = cv  ;  
  •             for(int i = 0; i < N; i++)     bestPath[i] = currentPath[i];  
  •         }  
  •       }  
  •       else  
  •         for(int i = 0; i < N; i ++)  
  •          {    if(Valid(r,i))   
  •              {   Node *s = new Node(r->level+1,i,r);  
  •                 w += (s->currentIndex,i);  
  •                 if(w < bestV)       (s);  
  •                 w -=  (s->currentIndex,i);  
  •             }  
  •         }  
  •   }  
  • }  
  • int TspBase::SumV()           //用于FIFOBB  
  •  {    int s = 0;  
  •     for(int i = 0; i < N; i++)  
  •         s += (currentPath[i],currentPath[(i + 1)%N]);  
  •     return s;  
  • }  
  • void TspBase::TspGreedy()  //TSP贪心算法  
  •  {     fout<<"TspGreedy ........"<<endl;  
  • bestV = 0;       
  •     vector<int> NEAR(N); //   
  •     NEAR[0] = -1;  
  •     for (int i = 1; i < N; i++)  
  •        NEAR[i] = 0;  
  •     bestPath[0] = 1;  
  •     int t;  
  •     for (int s = 1; s < N; s++)  
  •      {  
  •       int j = 1;  
  •       while (j < N && NEAR[j] < 0) /   
  •           j++;  
  •       int K = j;  
  •       for (int k = j + 1; k < N; k++)  
  •          if (NEAR[k] >= 0 &&  (k,NEAR[k]) < (j,NEAR[j]))  
  •                j = k;  
  •       bestPath[s] = j + 1;  
  •       bestV +=(j,NEAR[j]);  
  •       NEAR[j] = -1;  
  •       for (k = K; k < N; k++) //调整NEAR值  
  •          if (NEAR[k] >= 0)  
  •              NEAR[k] = j;  
  •       t = j;  
  •     }  
  •     bestV += (t,0);  
  •     fout<<"the shortest path is  ";  
  •     for(unsigned w = 0; w < N; w++)  
  •        fout<<bestPath[w] <<"--";  
  •     fout<<"1"<<endl;  
  •     fout<<"minimum distance is  "<<bestV<<endl;     
  • }  
  •   
  • int main(int argc, char* argv[])  
  •  {   int m,n;  
  •     ifstream fin("");  
  •     if(()) return 1;  
  •     fin >> m >> n;  
  •     N = n;  
  •     for(int i=0;i<N;i++)  (i);  
  •     fin >> g;  
  •     TspBase it;  
  •     ();    (false);  
  •   
  •     ();    (false);  
  •   
  •     ();    (true);  
  •   
  •     ();    (true);  
  •   
  •     ();    (true);  
  •   
  •     ();    (false);  
  •     return 0;  
  • }