算法设计与分析 实验3

一、     实验目的和要求


  学习编程实现深度优先搜索状态空间树求解实际问题的方法,着重体会求解第一个可行解和求解所有可行解之间的差别。加深理解回溯法通过搜索状态空间树、同时用约束函数剪去不含答案状态子树的算法思想,会用蒙特卡罗方法估计算法实际生成的状态空间树的结点数。


二、实验环境(实验设备)

VsialStudio 2017


三、     实验原理及内容

1.    要求用回溯法求解8-皇后问题,使放置在8*8棋盘上的8个皇后彼此不受攻击,即:任何两个皇后都不在同一行、同一列或同一斜线上。请输出8皇后问题的所有可行解。

源代码:

#include<iostream>

#include<math.h>

 

using namespace std;

bool Place(int k, int i, int *x);  //判定两个皇后是否在同一列或在同一斜线上

void NQueens(int k, int n, int *x);  //递归函数(求解n皇后问题)

void NQueens(int n, int *x);

 

bool Place(int k, int i, int *x)

{

       for (intj = 0; j < k; j++) {

              if((x[j] == i) ||( abs(x[j] - i) == abs(j - k))) {

                     returnfalse;

              }

       }

       returntrue;

}

 

void NQueens(int k, int n, int *x)

{

       for (inti = 0; i < n; i++) {

              if(Place(k, i, x)) {

                     x[k]= i;

                     if(k == n - 1) {

                            for(i = 0; i < n; i++) {

                                   cout<< x[i] << " ";

                            }

                            cout<< endl;

                     }

                     else{

                            NQueens(k+ 1, n, x);

                     }

              }

       }

}

 

void NQueens(int n, int *x)

{

       NQueens(0,n, x);

}

int main()

{

       int x[8];

       for (inti = 0; i < 8; i++) {

              x[i]= -1;

       }

       NQueens(8,x);

       return 0;

}


2.用回溯法编写一个递归程序解决如下装载问题:有n个集装箱要装上2艘载重分别为c1和c2的轮船,其中集装箱i的重量为wi(1≤i ≤ n),且Σ??≤?1+?2??=1。问是否有合理的装载方案可以将这n个集装箱装上这2艘轮船?如果有,给出装载方案。


举例:当n=3,c1=c2=50,且w=[10,40,40]时,可以将集装箱1和2装到第一艘轮船上,集装箱3装到第二艘轮船上;如果w=[20,40,40]时,无法将这3个集装箱都装上轮船。


源代码:

#include<iostream>

#include<string.h>

usingnamespace std;

template<classT>

classLoading

{

private:

       int  n,//集装箱数

           *x,//当前解

           *bestx,//当前最有载重数组

           w[100];//集装箱重量数组

       T   c1,//第一艘轮船的核定载重量

              c2,//第二艘轮船的核定载重量

              cw,//当前第一艘船的载重量

              bestw,//当前第一艘船的最有载重量

              r;//剩余集装箱总重量

public:

       Loading()

       {

              c1= 0;

              c2= 0;

              cw= 0;

              r= 0;

              bestw= 0;

              x= newint[50];

              bestx= newint[50];

              cout<<"请输入这两艘船的载重:"<< endl;

              cin>> c1;

              cin>> c2;

              cout<<"请输入集装箱个数:"<< endl;

              cin>> n;

              cout<<"请分别输入各集装箱的载重:"<< endl;

              for (int i = 0; i < n;i++)

              {

                     cin>> w[i];

                     r+= w[i];

              }

       }

       ~Loading()

       {

              delete[]x;

              delete[]bestx;

       }

 

       void Backtrack(inti);

       void Show();

};

 

template <classT>

voidLoading<T>::Backtrack(inti)

{

       if (i > n)

       {     //到达叶节点

              if (cw > bestw)

              {

                     for (int j = 1; j <=n; j++)  bestx[j] = x[j - 1];

                     bestw= cw;

              }

              return;

       }

       //搜索子树

       r-= w[i - 1];

       if (cw + w[i - 1] <= c1)

       {

              //搜索左子树

              x[i - 1] = 1;

              cw+= w[i - 1];

              Backtrack(i + 1);

              cw-= w[i - 1];

 

       }

       if (cw + r >bestw)

       {

              x[i - 1] = 0;

              Backtrack(i + 1);

       }

       r+= w[i];

}

 

template <classT>

voidLoading<T>::Show()

{

       int i,s = 0;

       for (i = 0; i <n; i++)

       {

              if (bestx[i + 1] ==0)

                     s+= w[i];

       }

       if (s<c2)

       {

              cout<<"最优载重量:";

              cout<< bestw << endl;

              cout<<"最优的方案为:"<< endl;

              cout<<"第一艘船:";

              for(i = 1; i <=n; i++)

              {

                     if (bestx[i] == 1)

                            cout<< i <<"";

              }

              cout<<"的装载"<< endl;

              cout<<"第二艘船:";

              for (i = 1; i <=n; i++)

              {

                     if (bestx[i] == 0)

                            cout<< i <<"";

              }

              cout<<"的装载"<< endl;

       }    

       else

       cout<<"c2超载!"<< endl;

}

void main()

{

       Loading<int> ld;

       ld.Backtrack(1);

       ld.Show();

       system("pause");

}


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值