实验一:棋盘覆盖(递归与分治策略)
[align=center][/align]
一、实验目的与要求
1、明确棋盘覆盖的概念
2、明确递归与分治策略的设计思路。
3、利用递归与分治策略解决棋盘覆盖问题。
二、实验题:
问题描述:
递归与分治策略算法,用4种不同形态的L型骨牌覆盖一个给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖。输入数据由程序运行后的界面中的编辑框中输入游戏规模,特殊方格的位置。将覆盖的结果在窗口中显示出来。
三、实验代码
#include
#include
int Board[16][16];
int tile=0,si;
void ChessBoard(int tr, int tc, int dr, int dc, int size)
{
if(size == 1)
return;
int t = ++tile, s = size/2;
//覆盖左上角子棋盘
if(dr=tc+s)
ChessBoard(tr, tc+s, dr, dc, s);
else
{
Board[tr+s-1][tc+s] = t;
ChessBoard(tr, tc+s, tr+s-1, tc+s, s);
}
//覆盖左下角子棋盘
if(dr>=tr+s && dc=tr+s && dc>=tc+s)
ChessBoard(tr+s, tc+s, dr, dc, s);
else
{
Board[tr+s][tc+s] = t;
ChessBoard(tr+s, tc+s, tr+s, tc+s, s);
}
}
void DisplayBoard(int size)
{
for(int i=1; i
void matrix_chain(int * p, int n, int[][100], int[][100]);
void trace_back(int i, int j, int [][100]);
int main()
{
int size[100], total, i=0, m[100][100], s[100][100],j;
printf("请输入矩阵的个数:\n");
scanf("%d", &total);
printf("请输入每个矩阵的规模\n");
while(i
#include
#define MAXSIZE 100 //假设物体总数
#define M 20 //背包的载荷能力
//算法核心,贪心算法
void GREEDY(float w[], float x[], int n)
{
float cu = M;
int i = 0;
for (i = 0; i cu)
{
break;
}
x[i] = 1;//若合适则取出
cu -= w[i];//将容量相应的改变
}
if (i
#include
#define MAXNUM 30//最多10个皇后
int num;
int x[MAXNUM];
bool Place(int k)
{
int i;
i=1;
while(i0)
{
x[k]+=1; // 向右移一列;
while(x[k]
using namespace std;
#define e 0.0001
struct NODE{ //结点数据结构
NODE *Parent; //指向父结点指针
NODE *next; //后继结点指针
int Level; //结点的所在的层数
int Tag; //左右孩子的标志,1为左孩子,0为右孩子
int CW; //目前背包剩余空间
int CV; //目前已装入物品有效益值
int LB; //结点的下界值
float UB; //结点的上界值
};
NODE *head; //活动结点队列队头
NODE *RESULT,*E; //解结点、根结点
int *v,*w; //指向物品的价值、重量数组指针
int W,lb,cw,cv; //背包最大容量、下限、目前剩余容量、目前物品价值之和
int N; //背包中物品数量
float ub; //背包的价值上限
void INIT(int *vv,int *ww,int WW,int NN,int& value); //初始化队列
void LUBOUND(int rw,int cp,int k,int &LBB,float &UBB); //计算上下界限
NODE* INSERTNODE(NODE *parent,int level,int t,int cw,int cv,int lb,float ub); //生成一个新结点
void ENQUEUE(NODE *node); //将结点i加入优先队列
void DEQUEUE(NODE *node); //将结点i从优先队列中删除(杀死结点)
NODE* NEXLIVENODE(); //下一扩展结点(取下限lb最大结点)
void PRINT(NODE* result,int n,int value); //打印结果
void LCBB(NODE* reusult,int n,int W,int lb,float ub,int cv,int cw,int& value); //求解最优解
int main()
{
int VALUE; //目前装入物品价值
int value[]={20,10,15,40};
int weight[]={20,30,18,35};
int BW;
cout> BW;
cout next=NULL;
value=0;
RESULT=new(NODE);
}
void LUBOUND(int rw,int cp,int k,int &LBB,float &UBB) //计算上下界限
{
int i,j,c;
LBB=cp;
c=rw;
for(i=k;i=w[j])
{
c=c-w[j];
LBB+=v[j];
}
return;
}
c=c-w[i];
LBB+=v[i];
}
UBB=(float)LBB;
}
NODE* INSERTNODE(NODE *parent,int level,int t,int cw,int cv,int lb,float ub) //生成一个新结点
{
NODE* node=new(NODE);
node->Parent=parent;
node->next=NULL;
node->Level=level;
node->Tag=t;
node->CW=cw;
node->CV=cv;
node->UB=ub;
node->LB=lb;
return(node);
}
void ENQUEUE(NODE* node) //将结点i加入优先队列
{
node->next=head->next;
head->next=node;
}
void DEQUEUE(NODE* node) //将结点i从优先队列中删除
{
NODE *pre=head,*p=head->next;
while(p!=node)
{
pre=p;
p=p->next;
}
pre->next=p->next;
}
NODE* NEXLIVENODE() //下一扩展结点(取下限lb最大结点)
{
NODE *p=head->next,*choice=p;
int lb=p->LB;
while(p)
{
if(p->LB>lb)
choice=p;
p=p->next;
}
return(choice);
}
void PRINT(NODE* result,int n,int value) //打印结果
{
cout=1;i--)
{
if(RESULT->Tag==1)
coutParent;
}
coutParent=NULL;
node->next=NULL;
node->Level=0;
node->CW=W;
node->CV=0;
node->Tag=0;
LUBOUND(W,0,0,lb,ub); //计算根结点上下界限
value=lb-e;
node->LB=lb;
node->UB=ub;
while(node->UB>value) //当前扩展结点上界Level;
cw=node->CW;
cv=node->CV;
if(i==N)
{
if(cv>value)
{
value=cv;
RESULT=node;
}
}
else //node有两个儿子
{
if(cw>=w[i]) //左孩子结点可行
ENQUEUE(INSERTNODE(node,i+1,1,cw-w[i],cv+v[i],node->LB,node->UB));
LUBOUND(cw,cv,i+1,lb,ub); //重新计算上下界
if(ub>value) //右孩子结点可行
{
ENQUEUE(INSERTNODE(node,i+1,0,cw,cv,lb,ub));
if(valuenext==NULL) //队列空或ub>VALUE结束
break;
else
{
node=NEXLIVENODE(); //下一扩展结点
DEQUEUE(node); //将结点从队列中删除
}
}
PRINT(RESULT,n,value);
}
四、实验结果
[align=center][/align]
一、实验目的与要求
1、明确棋盘覆盖的概念
2、明确递归与分治策略的设计思路。
3、利用递归与分治策略解决棋盘覆盖问题。
二、实验题:
问题描述:
递归与分治策略算法,用4种不同形态的L型骨牌覆盖一个给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖。输入数据由程序运行后的界面中的编辑框中输入游戏规模,特殊方格的位置。将覆盖的结果在窗口中显示出来。
三、实验代码
#include
#include
int Board[16][16];
int tile=0,si;
void ChessBoard(int tr, int tc, int dr, int dc, int size)
{
if(size == 1)
return;
int t = ++tile, s = size/2;
//覆盖左上角子棋盘
if(dr=tc+s)
ChessBoard(tr, tc+s, dr, dc, s);
else
{
Board[tr+s-1][tc+s] = t;
ChessBoard(tr, tc+s, tr+s-1, tc+s, s);
}
//覆盖左下角子棋盘
if(dr>=tr+s && dc=tr+s && dc>=tc+s)
ChessBoard(tr+s, tc+s, dr, dc, s);
else
{
Board[tr+s][tc+s] = t;
ChessBoard(tr+s, tc+s, tr+s, tc+s, s);
}
}
void DisplayBoard(int size)
{
for(int i=1; i
void matrix_chain(int * p, int n, int[][100], int[][100]);
void trace_back(int i, int j, int [][100]);
int main()
{
int size[100], total, i=0, m[100][100], s[100][100],j;
printf("请输入矩阵的个数:\n");
scanf("%d", &total);
printf("请输入每个矩阵的规模\n");
while(i
#include
#define MAXSIZE 100 //假设物体总数
#define M 20 //背包的载荷能力
//算法核心,贪心算法
void GREEDY(float w[], float x[], int n)
{
float cu = M;
int i = 0;
for (i = 0; i cu)
{
break;
}
x[i] = 1;//若合适则取出
cu -= w[i];//将容量相应的改变
}
if (i
#include
#define MAXNUM 30//最多10个皇后
int num;
int x[MAXNUM];
bool Place(int k)
{
int i;
i=1;
while(i0)
{
x[k]+=1; // 向右移一列;
while(x[k]
using namespace std;
#define e 0.0001
struct NODE{ //结点数据结构
NODE *Parent; //指向父结点指针
NODE *next; //后继结点指针
int Level; //结点的所在的层数
int Tag; //左右孩子的标志,1为左孩子,0为右孩子
int CW; //目前背包剩余空间
int CV; //目前已装入物品有效益值
int LB; //结点的下界值
float UB; //结点的上界值
};
NODE *head; //活动结点队列队头
NODE *RESULT,*E; //解结点、根结点
int *v,*w; //指向物品的价值、重量数组指针
int W,lb,cw,cv; //背包最大容量、下限、目前剩余容量、目前物品价值之和
int N; //背包中物品数量
float ub; //背包的价值上限
void INIT(int *vv,int *ww,int WW,int NN,int& value); //初始化队列
void LUBOUND(int rw,int cp,int k,int &LBB,float &UBB); //计算上下界限
NODE* INSERTNODE(NODE *parent,int level,int t,int cw,int cv,int lb,float ub); //生成一个新结点
void ENQUEUE(NODE *node); //将结点i加入优先队列
void DEQUEUE(NODE *node); //将结点i从优先队列中删除(杀死结点)
NODE* NEXLIVENODE(); //下一扩展结点(取下限lb最大结点)
void PRINT(NODE* result,int n,int value); //打印结果
void LCBB(NODE* reusult,int n,int W,int lb,float ub,int cv,int cw,int& value); //求解最优解
int main()
{
int VALUE; //目前装入物品价值
int value[]={20,10,15,40};
int weight[]={20,30,18,35};
int BW;
cout> BW;
cout next=NULL;
value=0;
RESULT=new(NODE);
}
void LUBOUND(int rw,int cp,int k,int &LBB,float &UBB) //计算上下界限
{
int i,j,c;
LBB=cp;
c=rw;
for(i=k;i=w[j])
{
c=c-w[j];
LBB+=v[j];
}
return;
}
c=c-w[i];
LBB+=v[i];
}
UBB=(float)LBB;
}
NODE* INSERTNODE(NODE *parent,int level,int t,int cw,int cv,int lb,float ub) //生成一个新结点
{
NODE* node=new(NODE);
node->Parent=parent;
node->next=NULL;
node->Level=level;
node->Tag=t;
node->CW=cw;
node->CV=cv;
node->UB=ub;
node->LB=lb;
return(node);
}
void ENQUEUE(NODE* node) //将结点i加入优先队列
{
node->next=head->next;
head->next=node;
}
void DEQUEUE(NODE* node) //将结点i从优先队列中删除
{
NODE *pre=head,*p=head->next;
while(p!=node)
{
pre=p;
p=p->next;
}
pre->next=p->next;
}
NODE* NEXLIVENODE() //下一扩展结点(取下限lb最大结点)
{
NODE *p=head->next,*choice=p;
int lb=p->LB;
while(p)
{
if(p->LB>lb)
choice=p;
p=p->next;
}
return(choice);
}
void PRINT(NODE* result,int n,int value) //打印结果
{
cout=1;i--)
{
if(RESULT->Tag==1)
coutParent;
}
coutParent=NULL;
node->next=NULL;
node->Level=0;
node->CW=W;
node->CV=0;
node->Tag=0;
LUBOUND(W,0,0,lb,ub); //计算根结点上下界限
value=lb-e;
node->LB=lb;
node->UB=ub;
while(node->UB>value) //当前扩展结点上界Level;
cw=node->CW;
cv=node->CV;
if(i==N)
{
if(cv>value)
{
value=cv;
RESULT=node;
}
}
else //node有两个儿子
{
if(cw>=w[i]) //左孩子结点可行
ENQUEUE(INSERTNODE(node,i+1,1,cw-w[i],cv+v[i],node->LB,node->UB));
LUBOUND(cw,cv,i+1,lb,ub); //重新计算上下界
if(ub>value) //右孩子结点可行
{
ENQUEUE(INSERTNODE(node,i+1,0,cw,cv,lb,ub));
if(valuenext==NULL) //队列空或ub>VALUE结束
break;
else
{
node=NEXLIVENODE(); //下一扩展结点
DEQUEUE(node); //将结点从队列中删除
}
}
PRINT(RESULT,n,value);
}
四、实验结果