一、实验目的
理解并实践回溯算法。
二、 实验要求
完成教材第5章11个应用范例中的至少4个(任选3个实现即可)。
三、实验步骤与结果
(1)批处理作业调度
代码:
#include<iostream>
using namespace std;
int x[100];
int bestx[100];
int m[100][100];
int f1=0;
int f2=0;
int cf=0;
int bestf=10000;
int n;
void swap(int &a,int &b)
{
int temp=a;
a=b;
b=temp;
}
void Backtrack(int t)
{
int tempf,j;
if(t>n)
{
if(cf<bestf)
{
for(int i=1; i<=n; i++)
bestx[i]=x[i];
bestf=cf;
}
}
else
{
for(j=t; j<=n; j++)
{
f1+=m[x[j]][1];
tempf=f2;
f2=(f1>f2?f1:f2)+m[x[j]][2];
cf+=f2;
if(cf<bestf)
{
swap(x[t],x[j]);
Backtrack(t+1);
swap(x[t],x[j]);
}
f1-=m[x[j]][1];
cf-=f2;
f2=tempf;
}
}
}
int main()
{
int i,j;
cout<<"请输入作业数:";
cin>>n;
cout<<"请输入各机器上的作业时间:"<<endl<<endl;
cout<<"作业: 1 2 3"<<endl;
for(i=1; i<=2; i++)
{
cout<<"机器"<<i<<":";
for(j=1; j<=n; j++)
cin>>m[j][i];
}
for(i=1; i<=n; i++)
x[i]=i;
Backtrack(1);
cout<<endl;
cout<<"最佳调度方案:";
for(i=1; i<=n; i++)
{
if(i==n)
cout<<bestx[i];
else
cout<<bestx[i]<<"-->";
}
cout<<endl;
cout<<"完成时间:";
cout<<bestf<<endl;
return 0;
}
结果:
(2)0-1背包问题
代码:
#include <iostream>
#include <tchar.h>
using namespace std;
typedef int Typew;
typedef int Typep;
class Object{
friend class Knap;
public:
int operator <= (Object a) const{
return (d >= a.d);
}
private:
int ID;
Typew w;
Typep p;
float d;
};
class Knap{
public:
Knap(Typew *w, Typep *p, Typew c, int n);
Typep Knapsack();
void BackTrack(int floor);
void print();
private:
Typep Bound(int i);
Typew c;
int n;
Object *Q;
Typew cw;
Typep cp;
int *cbestx;
int count;
int *bestx[10];
Typep bestp;
Typep oldbestp;
};
Knap::Knap(Typew *w, Typep *p, Typew c, int n)
{
Typew W = 0;
Typep P = 0;
count = 0;
this->c = c;
oldbestp = 0;
this->n = n;
cw = 0;
cp = 0;
Q = new Object[n];
for(int i =0; i<n; i++)
{
Q[i].ID = i+1;
Q[i].d = 1.0*p[i]/w[i];
Q[i].w = w[i];
Q[i].p = p[i];
P += p[i];
W += w[i];
}
if (W <= c)
{
bestp = P;
int *newbestx = new int[n];
for(int i =0; i<n; i++)
{
newbestx[i] = 1;
}
bestx[count++] = newbestx;
}
for(int i = 0; i<n-1; i++)
for(int j = 0; j<n-i-1; j++)
{
if(Q[j].d < Q[j+1].d)
{
Object temp = Q[j];
Q[j] = Q[j+1];
Q[j+1] = temp;
}
}
}
Typep Knap::Knapsack()
{
if(count > 0)
{
print();
return bestp;
}
else
{
cbestx = new int[n];
BackTrack(0);
}
return 1;
}
void Knap::BackTrack(int floor)
{
if(floor > n-1)
{
if( cp == oldbestp )
{
int *newbe = new int[n];
for (int i = 0; i < n; i++)
{
newbe[i] = cbestx[i];
}
bestx[count++] = newbe;
}
if( cp > oldbestp)
{
count = 0;
int *newbe = new int[n];
for (int i = 0; i < n; i++)
{
newbe[i] = cbestx[i];
}
bestx[count++] = newbe;
oldbestp = cp;
}
}
else
{
if (c >= cw + Q[floor].w)
{
cw += Q[floor].w;
cp += Q[floor].p;
if(cp >= bestp)
bestp = cp;
cbestx[floor] = 1;
BackTrack(floor + 1);
cw -= Q[floor].w;
cp -= Q[floor].p;
}
if(cp + Bound(floor + 1) >= bestp)
{
cbestx[floor] = 0;
BackTrack(floor + 1);
}
}
}
void Knap::print()
{
Typep *original = new int[n+1];
cout<<"最优方案:"<<endl;
for (int i = count-1; i >= 0; i--)
{
for (int j = 0; j < n; j++)
{
original[Q[j].ID] = bestx[i][j];
}
for (int k = 1; k <= n; k++)
{
cout<< original[k] <<" ";
}
cout<<endl;
}
cout<<endl;
cout<<"方案个数:"<<count<<endl<<endl;
cout<<"背包最大价值:"<<bestp<<endl;
}
Typep Knap::Bound(int i)
{
Typew cleft = c - cw;
Typep b = cp;
while (i < n && Q[i].w <= cleft)
{
cleft -= Q[i].w;
b += Q[i].p;
i++;
}
if(i < n) b += Q[i].p/Q[i].w * cleft;
return b;
}
int _tmain(int argc, _TCHAR* argv[])
{
const int N=4;
Typew c;
Typew w[N] = {2,2,2,2};
Typep p[N] = {6,4,8,6};
cout<<"物品总数:"<<N<<endl;
cout<<"物品重量:";
for (int i = 0; i < N; i++)
{
cout<<w[i]<<" ";
}
cout<<endl;
cout<<"物品价值:";
for (int i = 0; i < N; i++)
{
cout<<p[i]<<" ";
}
cout<<endl<<endl;
cout<<"请输入背包承重:";
cin>>c;
cout<<endl;
Knap K(w, p, c, N);
K.Knapsack();
K.print();
return 0;
}
结果:
(3)图的m着色问题
代码:
#include <iostream>
#include <fstream>
using namespace std;
ifstream fin("test.txt");
class Color
{
friend int mColoring(int, int, int **);
private:
bool Ok(int k);
void Backtrack(int t);
int n,
m,
**a,
*x;
long sum;
};
bool Color::Ok(int k)
{
for (int j=1;j<=n;j++)
{
if ((a[k][j]==1)&&(x[j]==x[k]))
{
return false;
}
}
return true;
}
void Color::Backtrack(int t)
{
if (t>n)
{
sum++;
for (int i=1; i<=n; i++)
cout << x[i] << " ";
cout << endl;
}
else
{
for (int i=1;i<=m;i++) {
x[t]=i;
if (Ok(t))
Backtrack(t+1);
x[t]=0;
}
}
}
int mColoring(int n,int m,int **a)
{
Color X;
X.n = n;
X.m = m;
X.a = a;
X.sum = 0;
int *p = new int[n+1];
for(int i=0; i<=n; i++)
{
p[i] = 0;
}
X.x = p;
cout<<"图G的着色方案如下:"<<endl;
X.Backtrack(1);
delete []p;
cout<<endl;
cout<<"共有方案:";
return X.sum;
}
int main()
{
int N = 5;
int M ;
int **a = new int *[N+1];
for(int i=1;i<=N;i++)
{
a[i] = new int[N+1];
}
cout<<"图G的邻接矩阵为:"<<endl;
for(int i=1; i<=N; i++)
{
for(int j=1; j<=N; j++)
{
fin>>a[i][j];
cout<<a[i][j]<<" ";
}
cout<<endl;
}
cout<<endl;
cout<<"请输入颜色数:";
cin>>M;
cout<<mColoring(N,M,a)<<endl;
for(int i=1;i<=N;i++)
{
delete[] a[i];
}
delete []a;
}
结果:
(4)旅行销售员问题
代码:
#include <bits/stdc++.h>
#include <iostream>
using namespace std;
const int max_ = 0x3f3f3f;
const int NoEdge = -1;
int citynum;
int edgenum;
int currentcost;
int bestcost;
int Graph[100][100];
int x[100];
int bestx[100];
void InPut()//>>>>
{
int pos1, pos2, len;
cout<<"请输入城市数量:";
cin>>citynum;
cout<<"请输入路线数:";
cin>>edgenum;
memset(Graph, NoEdge, sizeof(Graph));
cout<<endl;
cout<<"\t城市 "<<"城市 "<<"距离 "<<endl;
for(int i = 1; i <= edgenum; ++i)
{
cout<<"路线"<<i<<":";
cin>>pos1>>pos2>>len;
Graph[pos1][pos2] = Graph[pos2][pos1] = len;
}
}
void Initilize()
{
currentcost = 0;
bestcost = max_;
for(int i = 1; i <= citynum; ++i)
{
x[i] = i;
}
}
void Swap(int &a, int &b)
{
int temp;
temp = a;
a = b;
b = temp;
}
void BackTrack(int i) //这里的i代表第i步去的城市而不是代号为i的城市
{
if(i == citynum)
{
if(Graph[x[i - 1]][x[i]] != NoEdge && Graph[x[i]][x[1]] != NoEdge && (currentcost + Graph[x[i - 1]][x[i]] + Graph[x[i]][x[1]] < bestcost || bestcost == max_))
{
bestcost = currentcost + Graph[x[i - 1]][x[i]] + Graph[x[i]][x[1]];
for(int j = 1; j <= citynum; ++j)
bestx[j] = x[j];
}
}
else
{
for(int j = i; j <= citynum; ++j)
{
if(Graph[x[i - 1]][x[j]] != NoEdge && (currentcost + Graph[x[i - 1]][x[j]] < bestcost || bestcost == max_))
{
Swap(x[i], x[j]); //这里i 和 j的位置交换了, 所以下面的是currentcost += Graph[x[i - 1]][x[i]];
currentcost += Graph[x[i - 1]][x[i]];
BackTrack(i + 1);
currentcost -= Graph[x[i - 1]][x[i]];
Swap(x[i], x[j]);
}
}
}
}
void OutPut()
{
cout<<endl;
cout << "最短路线:" <<endl;
for(int i = 1; i <= citynum; ++i)
{
if(i==citynum)
cout <<"城市"<< bestx[i];
else
cout <<"城市"<< bestx[i] << "-->";
}
cout << "-->城市1" << endl;
}
int main()
{
InPut();
Initilize();
BackTrack(2);
OutPut();
}
结果: