亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? 零件切割問題.cpp

?? 零件切割問題的另一個版本 可以參考 內附代碼說明
?? CPP
字號:
#include <math.h>
#include <stdio.h>
#include <malloc.h>
#include <windows.h>
#include <GL/glaux.h>

typedef struct MuKuai{   //木塊結構體定義
	float h;             //木塊高度 
	float w;             //木塊寬度
	struct MuKuai *next; //木塊鏈表
}MuKuai;
typedef struct MuBan{ //木板結構體定義
	float x;          //木板的左下腳橫坐標
	float y;          //木板的左下腳縱坐標
	float h;          //木板高度
	float w;          //木板寬度
	struct MuBan *next;//木板鏈表
}MuBan;

MuKuai *headMuKuai = NULL; //木塊鏈表頭指針
MuBan *headMuBan = NULL;   //木板鏈表頭指針
MuBan *A = NULL;           //用于存放最終結果
MuBan *X;                  //用于保存當前找到的路徑
MuBan *bestX;              //用于保存當前找到的最佳路徑

int   n;             //木塊總個數
int   Line;          //用于控制遞歸深度
float W;             //木板寬度
float h = 0;         //當前找到的路徑木板總高度
float besth = 35767; //最佳路徑木板高度
int x = 0;           //用于調整屏幕的相對坐標
int k = 0;           //用于動態顯示木塊變化
float **C = NULL;    //定義顏色數組頭指針

float **CreatFloatArray_2(float **Head,int m,int n)
{//根據輸入的二維數組行和列動態創建二位數組,返回數組指針
	int i,j;
	float *p=NULL;
	if( !(m > 0 && n > 0) )
	{ //判斷維度是否正確
		printf("錯誤的數組維度\n");
		return NULL;
	}
	p = (float *)malloc(sizeof(float) * m * n);//申請總體空間
	Head = (float **)malloc(sizeof(float *)*m);//申請二級指針空間
	for(i = 0;i < m;i++) 
		Head[i]=p + n * i;
	for(i = 0;i < m;i++) 
		for(j = 0;j < n;j++)
			Head[i][j] = 0;
	return Head;
} 

MuKuai *find(int k)
{//在木塊鏈表中查找第k個元素
	MuKuai *p = headMuKuai;
	if(k > n)
	{
		printf("查找木塊鏈元素失敗!\n");
		return NULL;
	}
	for(int i = 1; i < k; i++)
		p = p->next;
	return p;
}

void sortInsert(MuKuai *Q) 
{//在headMuKuai中按照非遞減排序插入木塊節點,Q是一個已有的節點
	MuKuai *p = headMuKuai,*q = headMuKuai;
	if(p == NULL)
	{ //插在鏈表的第一個元素
		headMuKuai = Q;
		return ;
	}
	while(p->h > Q->h && p->next != NULL)
	{q = p;p = p->next;}//尋找合適的插入位置
	if(p == headMuKuai)
	{ //替換第一個元素
		Q->next = p;headMuKuai = Q;
		return ;
	}
	if(p->next == NULL && p->h > Q->h)//插在鏈表末尾
		p->next = Q; 
	else                             
	{Q->next = p;q->next = Q;}        //插在鏈表中間
}

void freeMuBan(MuBan *X)
{//釋放木板鏈表空間,每次在替換最佳路徑是調用
	MuBan *p = X,*Q = NULL;
	while(p != NULL)
	{Q = p->next;free(p);p = Q;}
}

int even(float x,float y)
{//由于浮點數的精度問題,用此種方法檢測兩個浮點數是否相等
	if(fabs(x-y)<0.00001) return 1;
	else return 0;
}

void delMuBan(float x,float y,float w,float h)
{//刪除木板數組中的元素,實現元素回溯
	MuBan *p = X,*q;
	if(even(X->x,x) && even(X->y,y) && even(X->h,h) && even(X->w,w))
	{                  //判斷第一個元素是否相同
		X = X->next;free(p);
		return ;
	}	
	while(p != NULL && (!even(p->x,x) || !even(p->y,y) || !even(p->w,w) || !even(p->h,h)))
	{q = p;p = p->next;}//查找元素	
	if(p == NULL)
	{//如果沒有找到相應的元素
		printf("查找木塊失敗!\n");
		exit(1);
	}
	q->next = p->next;
	free(p);
}

void insertMuBan(float x,float y,float w,float h)
{//把找到的木板插入當前路徑,用于生成結果
	MuBan *p;
	if(X==NULL)
	{            //木板數組中沒有元素
		X = (MuBan *)malloc(sizeof(MuBan) * 1);
		X->h = h; X->w=w; X->x = x;
		X->y = y; X->next = NULL;
		return ;
	} 
	p = (MuBan *)malloc(sizeof(MuBan) * 1);
	p->h = h; p->w = w;p->x = x; p->y = y;p->next=X;X=p;
}

//////////////////以下函數為opengl圖形繪制函數/////////////////
void myinit(void)
{ 
	glClearColor(0.0,0.0,0.0,0.0); 
	glClear(GL_COLOR_BUFFER_BIT);
	glShadeModel(GL_FLAT);
}

void CALLBACK down(void) 
{ 
	if(k < n-1) k++;
	else  return ;
} 

void CALLBACK myReshape(GLsizei w,GLsizei h)
{
	glViewport(0,0,w,h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	if(w<=h)
		glOrtho(-x,x,-x*(GLfloat)h/(GLfloat)w,x*(GLfloat)h/(GLfloat)w,-50.0,50.0);
	else
		glOrtho(-x*(GLfloat)h/(GLfloat)w,x*(GLfloat)h/(GLfloat)w,-x,x,-50.0,50.0);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

void DrawMyObjects(void)
{
	int i = 0;
	MuBan *p = bestX;
	glClear (GL_COLOR_BUFFER_BIT);
	glLoadIdentity();
	glColor3f(1.0,0.0,0.0);
	glTranslatef(-(x * 0.5),-(x-0.1*x),0.0);//移動屏幕坐標到木板左下方
	glBegin(GL_LINE_STRIP); //繪制木板
	glVertex2f(0.0,0.0);
	glVertex2f(0.0,2*x-0.2*x);
	glVertex2f(0.0,0.0);
	glVertex2f(x,0.0);
	glVertex2f(x,0.0);
	glVertex2f(x,2*x-0.2*x);
	glEnd(); 
	while(i <= k)
	{
		glColor3fv(C[i]);
		glBegin(GL_QUADS ); 
		glVertex2f(A[i].x,A[i].y + A[i].h);
		glVertex2f(A[i].x,A[i].y);
		glVertex2f(A[i].x + A[i].w,A[i].y);
		glVertex2f(A[i].x + A[i].w,A[i].y + A[i].h);
		glEnd(); 
		i++;
	}
} 

void CALLBACK display(void)
{
	DrawMyObjects();glFlush();
}

float backtracking(int level,int num)
{//回溯過程實現
	MuBan *k1,*k2,*k3;              //臨時指針
	MuBan *MuBan1,*MuBan2;          //用于存放切割后的兩塊木板
	MuKuai *l;                      //當前正要放置的木塊
	MuBan *pX = NULL,*pbestX = NULL;//px為當前找到的路徑的頭指針,pbestX為最佳路徑的頭指針
	if(num > n)
	{
		if(h < besth)
		{ //當前找到的路徑比程序保存的最佳還要好,替換最佳路徑
			free(bestX); //釋放已有路徑空間
			pX = X;
			pbestX = (MuBan *)malloc(sizeof(MuBan) * 1);
			*pbestX = *pX;       //復制第一個節點
			pbestX->next = NULL;
			bestX = pbestX;
			pX = pX->next;
			while(pX != NULL)
			{                    //復制其余節點
				pbestX->next = (MuBan *)malloc(sizeof(MuBan) * 1);
				*(pbestX->next) = *pX;
				pbestX->next->next = NULL;
				pbestX = pbestX->next;
				pX = pX->next;
			}
			besth=h;            //新的最佳木板高度
		}
		return 0;
	}
	l = find(num);              //需要處理的木塊
	k1 = headMuBan; k2 = k1->next; k3 = k2->next;
	if(level > Line)
	{ //如果遞歸深度已經超過遞歸控制線,采用貪心算法快速得出結果,并找到合適的可以進行切割的木板
		while(!(l->h <= (k2->h + 0.0001) && l->w <= (k2->w + 0.0001)))
		{ k1 = k2; k2 = k2->next; }
		k3 = k2->next;
		level++; num++;
		k1->next=k3;
		MuBan1 = (MuBan *)malloc(sizeof(MuBan) * 1);
		MuBan2 = (MuBan *)malloc(sizeof(MuBan) * 1);
		MuBan1->next = MuBan2;
		MuBan1->x = l->w + k2->x; MuBan1->y = k2->y;
		MuBan1->w = k2->w - l->w; MuBan1->h = l->h;
		MuBan2->x=k2->x; MuBan2->y=k2->y+l->h;
		MuBan2->w=k2->w; MuBan2->h=k2->h-l->h;
		if(k2->h > 4000)
		{ //被選中切割的木板是會增加最終高度的木板,要進行剪枝
			k1->next = MuBan1;   //把剪切后的木板插入木板鏈表
			MuBan2->next = k3;
			h += l->h;           //高度增加
			if(h>=besth)
			{//剪枝部分
				h -= l->h;
				free(MuBan1);free(MuBan2);
				k1->next=k2;    //還原木板
				k2->next=k3;
				level--; num--; //回溯
				return 0;
			}
			insertMuBan(k2->x,k2->y,l->w,l->h);//插入選中的木板,生成結果路徑
			backtracking(level,num);           //繼續搜索
			delMuBan(k2->x,k2->y,l->w,l->h);   //回溯
			h -= l->h;
		}
		else
		{//切割木塊的else,被選中切割的木板不會增加高度
			k1->next=MuBan1;                   //把剪切后的木板插入木板鏈表
			MuBan2->next=k3;
			insertMuBan(k2->x,k2->y,l->w,l->h);//插入選中的木板,生成結果路徑
			backtracking(level,num);           //繼續搜索
			delMuBan(k2->x,k2->y,l->w,l->h);   //回溯
		}
		free(MuBan1); free(MuBan2);
		k1->next=k2;//回溯
		k2->next=k3;
		level--; num--; 
	} //遞歸的if
	else
	{ //如果遞歸的高度不是太深,則繼續深度搜索解空間
		while(k2 != NULL)
		{ //回溯法找到切割的木板K2
			if((l->h <= (k2->h + 0.0001) && l->w <= (k2->w + 0.0001)))
			{
				level++; num++; //深度搜索
				k1->next = k3;
				MuBan1 = (MuBan *)malloc(sizeof(MuBan) * 1);
				MuBan2 = (MuBan *)malloc(sizeof(MuBan) * 1);
				MuBan1->next = MuBan2;
				MuBan1->x = l->w + k2->x; MuBan1->y = k2->y;
				MuBan1->w = k2->w - l->w; MuBan1->h = l->h;
				MuBan2->x=k2->x; MuBan2->y=k2->y+l->h;
				MuBan2->w=k2->w; MuBan2->h=k2->h-l->h;
				if(k2->h < 4000)
				{ //進行剪枝
					k1->next = MuBan1;                 //把剪切后的木板插入木板鏈表
					MuBan2->next = k3;
					insertMuBan(k2->x,k2->y,l->w,l->h);//插入選中的木板,生成結果路徑
					backtracking(level,num);           //繼續搜索
					delMuBan(k2->x,k2->y,l->w,l->h);   //回溯
				}
				else
				{
					k1->next = MuBan1;
					MuBan2->next = k3;
					h += l->h;//高度增加
					if(h >= besth)
					{ //剪枝
						h -= l->h;
						free(MuBan1); free(MuBan2);
						k1->next=k2; k2->next=k3;
						level--; num--;
						return 0;
					}
					insertMuBan(k2->x,k2->y,l->w,l->h);//插入選中的木板,生成結果路徑
					backtracking(level,num);           //繼續搜索
					delMuBan(k2->x,k2->y,l->w,l->h);   //回溯
					h -= l->h;
				}
				free(MuBan1);free(MuBan2);
				k1->next=k2;k2->next=k3;
				level--; num--;
			}//if
			k1=k2; k2=k2->next;
			if(k2 == NULL) break;
			k3 = k2->next;
		}//while
	}
	return besth;
}

int main(void)
{	
	int i = 1;
	char FileName[20]; //數據文件
	float m;
	MuKuai *p = NULL; 	
	FILE *fp;	
	printf("請輸入正確的數據文件:");
	scanf("%s",FileName);
	fflush(stdin);
	while(!(fp = fopen(FileName,"r")))
	{ //打開數據文件
		printf("\n當前目錄不存在輸入文件%s\n",FileName);
		printf("\n請輸入正確的數據文件:");
	    scanf("%s",FileName);
		fflush(stdin);
	}
	fscanf(fp,"%d %f",&n,&W);
	printf("\n稍等,程序正在打開圖形窗口!\n\n");
	printf("請按向下鍵實現整個畫圖過程!\n\n");
	x = (int)W; //用于調整opengl中屏幕的相對坐標
	while(i <= n)
	{
		p = (MuKuai *)malloc(sizeof(MuKuai) * 1);
		fscanf(fp,"%f %f",&(p->h),&(p->w));
		p->next = NULL;
		sortInsert(p);
		i++;
	}
	//根據不同的數據文件,控制遞歸深度
	if(n > 150)      Line = 12;
	else if(n == 16) Line = 16;
	else if(n == 25) Line = 14;
	else if(n == 50) Line = 14;
	else             Line = 15;
	A = (MuBan *)malloc(sizeof(MuBan) * n);
	headMuBan = (MuBan *)malloc(sizeof(MuBan) * 1);
	headMuBan->next = (MuBan *)malloc(sizeof(MuBan) * 1);	
	headMuBan->x = 0; headMuBan->y = 0;
	headMuBan->w = 0; headMuBan->h = 0;
	headMuBan->next->x = 0; headMuBan->next->y = 0;
	headMuBan->next->w = W; headMuBan->next->h = 65767;
	headMuBan->next->next = NULL;
	m=backtracking(1,1);
	MuBan *pA = bestX;
	for(i = n-1; i >=0; i--, pA = pA->next)
		A[i] = *pA;
	C = CreatFloatArray_2(C,n,3); //動態創建二位數組,用于存放顏色
	for(i = 0; i < n; i++)
	{
		C[i][0] = (rand()%3)/3.0 + 0.01;
		C[i][1] = (rand()%6)/6.0 + 0.3;
		C[i][2] = (rand()%9)/7 + 0.05;
	}
	auxInitDisplayMode(AUX_SINGLE|AUX_RGBA); 
	auxInitPosition(250,100,800,800); 
	auxInitWindow("闕壽輝的實驗:回溯算法的運用之零件切割問題"); 
	myinit(); 
	auxKeyFunc(AUX_DOWN,down); 
	auxReshapeFunc(myReshape); 
	auxMainLoop(display); 
	printf("切割所需最佳高度為:H=%4.2f\n\n",besth);
	return 0;
}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
国产精品一区二区三区四区| 99久久精品免费精品国产| 国产一区二区在线观看免费| 99re热视频这里只精品| 91精品国产一区二区三区香蕉 | 国产精品久久久久三级| 欧美日韩激情一区二区| 精品久久国产老人久久综合| 日韩美女视频一区二区| 国产一区二区不卡老阿姨| 欧美日韩一区在线| 国产精品毛片无遮挡高清| 久久黄色级2电影| 欧美日韩二区三区| 一区二区三区成人| voyeur盗摄精品| 久久久午夜精品| 久久99精品国产.久久久久久 | 欧美精品一区二区不卡 | 国产精品视频你懂的| 爽好久久久欧美精品| 精东粉嫩av免费一区二区三区| 在线观看欧美日本| 26uuu国产在线精品一区二区| 午夜欧美2019年伦理| 色视频一区二区| 亚洲视频在线一区| 成人av在线一区二区三区| 久久久久9999亚洲精品| 国产乱人伦偷精品视频免下载| 日韩欧美一级精品久久| 视频一区二区中文字幕| 在线综合视频播放| 日本不卡高清视频| 日韩三级高清在线| 久久精品国产第一区二区三区| 欧美一区二区精品久久911| 午夜精品久久久久久久蜜桃app | 高清不卡在线观看| 国产日韩成人精品| 成人动漫中文字幕| 亚洲啪啪综合av一区二区三区| 99r精品视频| 一区二区三区在线视频观看| 欧美色图在线观看| 日本亚洲三级在线| 久久久久青草大香线综合精品| 国产河南妇女毛片精品久久久| 国产精品日韩成人| 在线观看亚洲a| 美女精品一区二区| 久久久久国产精品麻豆ai换脸 | 久久国产欧美日韩精品| 精品理论电影在线| 成人国产免费视频| 亚洲一线二线三线久久久| 91麻豆精品91久久久久久清纯| 另类综合日韩欧美亚洲| 久久精品一区蜜桃臀影院| 色综合天天天天做夜夜夜夜做| 日韩精品亚洲专区| 日韩三级电影网址| 99久久久精品| 免费av网站大全久久| 中文字幕精品三区| 欧美三级在线播放| 国产精品羞羞答答xxdd| 一区二区三区精品视频| 精品国产sm最大网站免费看| 99精品在线观看视频| 日本欧美韩国一区三区| 国产精品欧美精品| 欧美顶级少妇做爰| youjizz国产精品| 日本不卡免费在线视频| 国产精品久久久久久久久免费桃花 | 国产剧情一区在线| 亚洲尤物在线视频观看| 国产欧美精品一区aⅴ影院| 欧美午夜寂寞影院| 成人不卡免费av| 麻豆精品在线看| 亚洲精品中文在线| 国产丝袜美腿一区二区三区| 欧美日本免费一区二区三区| 成人白浆超碰人人人人| 久久av老司机精品网站导航| 一区二区久久久久| 国产精品美女久久久久久久久| 日韩欧美一级精品久久| 欧美色综合影院| 97se亚洲国产综合在线| 国产一区二区三区香蕉| 日韩高清国产一区在线| 亚洲一区二区三区四区中文字幕| 国产欧美一区二区三区在线老狼| 欧美一级专区免费大片| 欧美性生活一区| 一本大道久久精品懂色aⅴ | 久久精品一区蜜桃臀影院| 欧美一级搡bbbb搡bbbb| 欧美日韩国产首页| 欧美在线观看一区| 91久久久免费一区二区| 91一区一区三区| 欧美一区二区在线观看| 91美女在线视频| 99久久国产综合精品色伊| 国产黑丝在线一区二区三区| 国产一区二区不卡老阿姨| 精品一区二区三区久久久| 美女视频黄久久| 激情综合色播激情啊| 久草这里只有精品视频| 老司机精品视频在线| 裸体歌舞表演一区二区| 九九视频精品免费| 国产一区二区视频在线播放| 精东粉嫩av免费一区二区三区 | 亚洲免费资源在线播放| 亚洲精品午夜久久久| 亚洲三级理论片| 一区二区三区在线观看国产| 一个色在线综合| 婷婷中文字幕综合| 老司机午夜精品99久久| 国精品**一区二区三区在线蜜桃| 国产麻豆精品在线| 成人av在线电影| 在线国产电影不卡| 69av一区二区三区| 2021国产精品久久精品| 欧美激情综合在线| 亚洲综合免费观看高清在线观看| 亚洲韩国精品一区| 老司机免费视频一区二区三区| 国产精品69毛片高清亚洲| 成年人网站91| 欧美在线观看视频在线| 日韩午夜在线播放| 中文字幕在线一区| 亚洲超碰精品一区二区| 九九国产精品视频| 99久久精品免费| 91精品国产综合久久久蜜臀图片| 精品国产麻豆免费人成网站| 中文字幕一区二区在线播放| 亚洲午夜精品久久久久久久久| 久久精品国产一区二区三| 成人午夜av在线| 欧美裸体一区二区三区| 国产亚洲欧美日韩日本| 一区二区三区日韩欧美精品| 久草这里只有精品视频| 91麻豆swag| 2021中文字幕一区亚洲| 亚洲一区二区三区精品在线| 国产又黄又大久久| 欧美日韩亚洲国产综合| 国产免费成人在线视频| 香蕉av福利精品导航| 成人黄色软件下载| 欧美大片在线观看| 亚洲美女视频在线观看| 国产福利精品导航| 日韩亚洲电影在线| 一区二区三区四区国产精品| 国产精品91xxx| 欧美sm极限捆绑bd| 午夜精品123| av不卡一区二区三区| 欧美精品一区二区三区蜜臀| 亚洲国产cao| 91视频你懂的| 亚洲国产精品t66y| 久久电影网站中文字幕| 欧美高清激情brazzers| 亚洲欧美一区二区三区极速播放| 国产馆精品极品| 久久综合视频网| 日本aⅴ亚洲精品中文乱码| 在线精品视频小说1| 国产精品高潮呻吟| 国产成人99久久亚洲综合精品| 欧美美女激情18p| 亚洲第一福利一区| 欧洲在线/亚洲| 亚洲午夜久久久久久久久久久| 9i看片成人免费高清| 中文字幕一区三区| av成人老司机| 日韩美女视频一区二区| 99久精品国产| 亚洲丝袜自拍清纯另类| 99热99精品| 亚洲欧洲www| 日本韩国一区二区三区视频| 亚洲男帅同性gay1069| 色悠久久久久综合欧美99| 亚洲四区在线观看|