迷宫问题的双向BFS
2012-11-22 13:51
375 查看
#include <stdio.h> #include <stdlib.h> #include <string.h> #define STARTVALUE 2012 #define ENDVALUE 2013 #define QUEUESIZE (1024*1024) //size of the queue for BFS #define MAXVALUE (65535) typedef enum{START=0,MIDDLE=1,END=2,UNREACHABLE=3}State; typedef enum{ADD=0,MIN=1,MUL=2,DIV=3,DIV2=4,OTHER=5}Opera; typedef struct Node{ int value,path; Node * parent; Node * child[5]; //child[4] is for reverse search when operation is div. State state; }*QuadTree; QuadTree root,root_rev; Node** ExistNode; Node** ExistNode_rev; Node * NewNode(int v, Node* n,int p, State s){ Node *q = (Node *)malloc(sizeof(Node)); q->value = v; q->parent = n; q->path = p; q->child[ADD] = q->child[MIN] = q->child[MUL] = q->child[DIV] = q->child[DIV2] = NULL; q->state = s; return q; } struct Queue{ Node ** data; int size,header,tailer; }NodeQueue, NodeQueue_rev; void InitQueue(){ NodeQueue.data = (Node**)malloc(QUEUESIZE*sizeof(Node *)); NodeQueue_rev.data = (Node**)malloc(QUEUESIZE*sizeof(Node *)); NodeQueue.size = NodeQueue_rev.size = QUEUESIZE; NodeQueue.header = NodeQueue.tailer = NodeQueue_rev.header = NodeQueue_rev.tailer = 0; } void EnQueue(Queue* nodequeue, Node * q){ if((nodequeue->tailer+1)%nodequeue->size == nodequeue->header) {printf("Queue Overflow\n");return;} nodequeue->data[nodequeue->tailer] = q; nodequeue->tailer = (nodequeue->tailer+1)%nodequeue->size; } Node* DeQueue(Queue* nodequeue){ if(nodequeue->header == nodequeue->tailer) return NULL; Node* temp = nodequeue->data[nodequeue->header]; nodequeue->header = (nodequeue->header+1)%nodequeue->size; return temp; } void QueueClear(Queue* nodequeue){ //clear queue nodequeue->tailer = nodequeue->header; } Node* PopStack(Queue* nodequeue){ //queue also can be used as stack for outputing result if(nodequeue->header == nodequeue->tailer) return NULL; nodequeue->tailer = (nodequeue->tailer-1+nodequeue->size)%nodequeue->size; return nodequeue->data[nodequeue->tailer]; } int add(int temp){return temp+7;} int minus(int temp){return temp-5;} int mul(int temp){return (temp<<1)+temp;} int div(int temp){return temp>>1;} int (*fun[5])(int) ={add,minus,mul,div,div}; //function pointer int add_rev(int temp){return temp-7;} int minus_rev(int temp){return temp+5;} int mul_rev(int temp){return temp/3;} int div_rev(int temp){return temp<<1;} int div2_rev(int temp){return (temp<<1)+1;} // int (*fun_rev[5])(int) ={add_rev,minus_rev,mul_rev,div_rev,div2_rev}; //function pointer //three-dimensional matrice: according to [State], [Path], [Next operation] return [Next State] State StateCompute[3][6][5]={ { {UNREACHABLE,UNREACHABLE,UNREACHABLE,MIDDLE,MIDDLE}, {UNREACHABLE,UNREACHABLE,UNREACHABLE,UNREACHABLE,UNREACHABLE}, {UNREACHABLE,UNREACHABLE,UNREACHABLE,UNREACHABLE,UNREACHABLE}, {MIDDLE,UNREACHABLE,UNREACHABLE,UNREACHABLE,UNREACHABLE}, {MIDDLE,UNREACHABLE,UNREACHABLE,UNREACHABLE,UNREACHABLE}, {MIDDLE,UNREACHABLE,UNREACHABLE,MIDDLE,MIDDLE} }, { {UNREACHABLE,END,END,START,START}, {START,UNREACHABLE,END,START,START}, {START,END,UNREACHABLE,START,START}, {START,END,END,UNREACHABLE,UNREACHABLE}, {START,END,END,UNREACHABLE,UNREACHABLE}, {UNREACHABLE,UNREACHABLE,UNREACHABLE,UNREACHABLE,UNREACHABLE} }, { {UNREACHABLE,UNREACHABLE,UNREACHABLE,UNREACHABLE,UNREACHABLE}, {UNREACHABLE,UNREACHABLE,MIDDLE,UNREACHABLE,UNREACHABLE}, {UNREACHABLE,MIDDLE,UNREACHABLE,UNREACHABLE,UNREACHABLE}, {UNREACHABLE,UNREACHABLE,UNREACHABLE,UNREACHABLE,UNREACHABLE}, {UNREACHABLE,UNREACHABLE,UNREACHABLE,UNREACHABLE,UNREACHABLE}, {UNREACHABLE,MIDDLE,MIDDLE,UNREACHABLE,UNREACHABLE} } }; Node* IsExistRevTree(Node** existnode, Node* node); void OutputResult(Node* meet){ char opera[] = "+7-5*3/2/2"; int i = 0; Node* end = meet; while(end->parent!=NULL){ EnQueue(&NodeQueue,end); end = end->parent; } while((end=PopStack(&NodeQueue))!=NULL) printf("%d\t%d%c%c=%d\n",++i,end->parent->value,opera[2*end->path],opera[1+2*end->path],end->value); end = IsExistRevTree(ExistNode_rev,meet); while(end->parent!=NULL){ printf("%d\t%d%c%c=%d\n",++i,end->value,opera[2*end->path],opera[1+2*end->path],end->parent->value); end = end->parent; } } void OutputResult_rev(Node* meet){ char opera[] = "+7-5*3/2"; int i = 0; Node* end = IsExistRevTree(ExistNode, meet); while(end->parent!=NULL){ EnQueue(&NodeQueue,end); end = end->parent; } while((end=PopStack(&NodeQueue))!=NULL) printf("%d\t%d%c%c=%d\n",++i,end->parent->value,opera[2*end->path],opera[1+2*end->path],end->value); end = meet; while(end->parent!=NULL){ printf("%d\t%d%c%c=%d\n",++i,end->value,opera[2*end->path],opera[1+2*end->path],end->parent->value); end = end->parent; } } void InitPruning(){ // allocate memory for storing existing node, using bitmap algorithm ExistNode = (Node**) malloc(3*4*MAXVALUE*sizeof(Node*)); ExistNode_rev = (Node**) malloc(3*4*MAXVALUE*sizeof(Node*)); memset(ExistNode,NULL,3*4*MAXVALUE*sizeof(Node*)); memset(ExistNode_rev,NULL,3*4*MAXVALUE*sizeof(Node*)); } bool Pruning(Node** existnode, Node* node){ if(OTHER == node->path||(unsigned)node->value>MAXVALUE) return true; if(existnode[node->state*4*MAXVALUE+(node->path==DIV2?DIV:node->path)*MAXVALUE+node->value]!=NULL) return false; existnode[node->state*4*MAXVALUE+(node->path==DIV2?DIV:node->path)*MAXVALUE+node->value] = node; return true; } Node* IsExistRevTree(Node** existnode, Node* node){ if(OTHER == node->path||(unsigned)node->value>MAXVALUE) return NULL; for(int i =0; i<4;i++){ if(node->path==i||(node->path==DIV2&&i==DIV)) continue; if(existnode[node->state*4*MAXVALUE+i*MAXVALUE+node->value]!=NULL) return existnode[node->state*4*MAXVALUE+i*MAXVALUE+node->value]; } return NULL; } void Expand(Node * node){ for(int i = 0; i < 4; i++ ){ if(UNREACHABLE ==StateCompute[node->state][node->path][i]) continue; node->child[i] = NewNode(fun[i](node->value),node,i,StateCompute[node->state][node->path][i]); if(Pruning(ExistNode,node->child[i])) EnQueue(&NodeQueue,node->child[i]); if(IsExistRevTree(ExistNode_rev,node->child[i])){ QueueClear(&NodeQueue); QueueClear(&NodeQueue_rev); OutputResult(node->child[i]); break; } } } void Expand_rev(Node * node){ for(int i = 0; i < 5; i++ ){ if(UNREACHABLE ==StateCompute[node->state][node->path][i]||(MUL==i&&node->value%3!=0)||(DIV2==i&&node->value%2==1)) continue; node->child[i] = NewNode(fun_rev[i](node->value),node,i,StateCompute[node->state][node->path][i]); if(Pruning(ExistNode_rev,node->child[i])) EnQueue(&NodeQueue_rev,node->child[i]); if(IsExistRevTree(ExistNode,node->child[i])){ QueueClear(&NodeQueue); QueueClear(&NodeQueue_rev); OutputResult_rev(node->child[i]); break; } } } int main(){ Node * p = root = NewNode(STARTVALUE,NULL,OTHER,START); Node * q = root_rev = NewNode(ENDVALUE,NULL,OTHER,END); InitQueue(); InitPruning(); EnQueue(&NodeQueue_rev,q); EnQueue(&NodeQueue,p); while(true) { if((p=DeQueue(&NodeQueue))==NULL)break; Expand(p); if((q=DeQueue(&NodeQueue_rev))==NULL)break; Expand_rev(q); } printf("Completion!\n"); return 0; }
相关文章推荐
- [POJ](3984)迷宫问题 ---BFS+队列模拟(图+队列模拟)***
- SDUT 1157-小鼠迷宫问题(BFS&DFS)
- 广度优先搜索BFS(迷宫问题)
- hncu1102:迷宫问题(BFS)
- poj 迷宫问题(路径记录)(DFS,BFS)
- POJ-3984-迷宫问题(BFS)
- SDUT1157:小鼠迷宫问题(bfs+dfs)
- 迷宫问题 POJ 3984 【BFS】
- FZU 1205(小鼠迷宫问题)BFS+DFS的基本综合运用(同一题目中体现两种搜索方法的特点)
- 基础迷宫问题-------------(图的BFS 题目取自算法竞赛入门)
- bfs - 迷宫问题
- poj3984 迷宫问题 BFS入门 TWT Tokyo Olympic 2combo-4
- poj 3984 迷宫问题(BFS,记录路径)
- POJ 3984 迷宫问题(BFS)
- BFS - 最简单的迷宫问题
- POJ - 3984 迷宫问题 (BFS+DFS)
- poj3984 迷宫问题(图-BFS)
- 迷宫问题 BFS
- 迷宫问题(广度优先搜索BFS)
- 经典迷宫问题BFS