본문 바로가기

아카이브/C

A* 알고리즘 코드(에러있음)

반응형

일정 거리 이상이면 에러 발생하는 버전.


#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include "Puzzle_Structure.c"



#define null '\0'

#define CAPACITY 100000

#define row 4

#define col 4

#define true 1

#define false 0


int TRY = 0;

int Element_Count = 0;

//int Closeded_Count = 0;

int save = 0;

int mn = 0;

state* root;

Tr* TrRoot;


void Push_OPEN(state* OPen[], state*);

state* Pop_OPEN(state* Open[]);

int Compute_Hh(state*); //골

state* Best_First_In_OPEN(state* Open[]);

void Successors_Expand(state* Open[], state* curr); //골

void Insert_Tree(Tr* tree,state* curr);

void Print_Direction(int cases); ////1:move right, 2: move left, 3:move up, 4:move down

void m_init(state* Open[], state* m, state* curr, int DirectionFromParent);

int test1(state* Open[], state* m);

void test2(state* Open[], state* m);

int main()

{

FILE* fp = fopen("output.txt","w");

//start state

int Puzzle_4x4[row][col] = { {0,1,2,3}, {4,5,6,7}, {8,9,10,11}, {12,13,14,15} }; //0은 빈 타일

//goal state   test1 : 정답은 오른쪽 세칸

int Goal[row][col]  = { {1,2,3,0}, {4,5,6,7}, {8,9,10,11} ,{12,13,14,15} };


//우선순위큐방식. stack방식으로 처리 //memset(Open,null,sizeof(state)*CAPACITY);

state* Open[CAPACITY] = {null}; 

state* StartState;

state* curr;

//잡다

int input=0;

int i,j;

int pathflag = false;

int printflag = false;

int oldpath = 0;

StartState = (state*)malloc(sizeof(state));

root = (state*)malloc(sizeof(state));

while(1){


pathflag = false;

save = 0;

memset(Open,null,sizeof(Open));

//입력

printf("탐색을 원하시나요? (yes:1 / no:0)\n");

scanf("%d",&input);

if(input == 1)

{

printf("시작노드 = ");

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

for(j=0;j<col;j++)

scanf("%d",&Puzzle_4x4[i][j]);

printf("목표노드 = ");

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

for(j=0;j<col;j++)

scanf("%d",&Goal[i][j]);

printf("\n");


//state 초기화

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

for(j=0;j<col;j++)

{

StartState->Number[i][j] = Puzzle_4x4[i][j];

root->Number[i][j] = Goal[i][j];

}

StartState->Parent = null;

StartState->Gh = 0;

StartState->Hh = Compute_Hh(StartState);

StartState->Fh = StartState->Gh + StartState->Hh;

StartState->closed = false;

//필요한가? 그냥 스테이트들마다 parent 정보 가지고있으니까

TrRoot = (Tr*)malloc(sizeof(Tr));

TrRoot->Node = StartState;

TrRoot->StateTr = null;


Push_OPEN(&Open[Element_Count], StartState);


curr = null;

do

{

TRY++;

if(TRY>40000){

printf("탐색실패\n");return 0;}

if(curr && Element_Count == 0)

printf("탐색실패\n"); //while 조건문에 걸리기때문에 실행될일은 없음.  제일 처음에 한번 검사함


curr = Best_First_In_OPEN(&Open[0]);

curr->closed = true;

//Open[save] = null;

//Element_Count--; //이걸 할게 아니라 save에 있는걸 지워야지

//Push_Closed(&Closed[0], curr);

Insert_Tree(TrRoot, curr);


//정답 테스트

if(Compute_Hh(curr) == 0)

{

//printf("정답 찾음\n"); //경로 반환해야함

//경로 반환

while(TrRoot !=null)

{

if(TrRoot->Node==StartState && pathflag == false)

{ //한번 밀기위해

pathflag = true;

TrRoot = TrRoot->StateTr;

printf("This is the start state\n");

fprintf(fp,"This is the start state\n");

}

else{

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

{


for(j=0;j<col;j++)

{

printf("%2d ",TrRoot->Node->Number[i][j]);

fprintf(fp,"%3d",TrRoot->Node->Number[i][j]);

}


printf("\n");

fprintf(fp,"\n");

}

oldpath = TrRoot->Node->Fh;

//여기에 방향 출력

Print_Direction(TrRoot->Node->DirectionFromParent);

TrRoot = TrRoot->StateTr;//이거 테스트 어디다 해야하나

printf("\n");

fprintf(fp,"\n");

}

}

printf("%d\n",oldpath);

TrRoot = null;

oldpath = 0;

Element_Count =0;

//Closeded_Count = 0;

break;

}


//석세서들을 오픈에 넣고 다음 스탭에서 제일 좋은애를 curr로 뽑아야함. 

//open closed 고려해야함.

Successors_Expand(&Open[0],curr);


}while(Element_Count != 0);

fflush(fp);

}

else if(input == 0)

{

printf("Program Complete!\n");

fclose(fp);

return 0;

}

else

{

printf("잘못된 입력\n");

fflush(fp);

}

}

return 1; //비정상종료

}


void Push_OPEN(state* Open[], state* m)

{

int count = 0;

int i = 0;

int flag=false;

//이게 없으면 포인터로 연결되어 open에 잘못들어감!!

state* newstate = (state*)malloc(sizeof(state));

memcpy(newstate,m,sizeof(state));

if(++Element_Count >= CAPACITY-1)

{

printf("CAPACITY IS FULL\n");

return;

}

while(i<CAPACITY)

{

if(Open[i] == null)

{

Open[i] = newstate;

break;

}

i++;

}

//주의!!! Element_Count 한개 증가함!!!!

}


int Compute_Hh(state* state)

{

int i,j;

int Unmatched_Count = 0;


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

for(j=0;j<col;j++)\

{

if(state->Number[i][j] != root->Number[i][j])

Unmatched_Count++;

}

return Unmatched_Count;

}


state* Best_First_In_OPEN(state* Open[])

{

int i,j;

state* curr = Open[0];


//printf("%d\n", Element_Count);

for(i =0;i<Element_Count-1; i++)

{

for(j=i+1;j<Element_Count; j++)

if(Open[i]->Fh > Open[j]->Fh)

{

if(Open[j]->closed == true)

{}

else{

curr = Open[j];

save = j;

}

}

}

return curr;

}


void Successors_Expand(state* Open[], state* curr)

{

//0을 찾아서 인접셀과 이동한거를 오픈에 넣음

int i,j,k,l,temp;

int RowOfEmpty;

int ColOfEmpty;


int Number_Copy[row][col];



state* m = (state*)malloc(sizeof(state));

//m = curr;

memcpy(m,curr,sizeof(state));


for(k=0;k<row;k++)

for(l=0;l<col;l++)

Number_Copy[k][l] = curr->Number[k][l];


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

for(j=0;j<col;j++)

if(curr->Number[i][j] == 0 )

{

RowOfEmpty = i;

ColOfEmpty = j;

//i,j주변과 바꿔줘야 함.   m을 구해야돼!!!

if(i-1 > 0)

{

temp = Number_Copy[RowOfEmpty - 1][ColOfEmpty];

Number_Copy[RowOfEmpty - 1][ColOfEmpty] = 0;

Number_Copy[RowOfEmpty][ColOfEmpty] = temp;

memcpy(m->Number,Number_Copy,sizeof(m->Number));

memcpy(Number_Copy,curr->Number,sizeof(Number_Copy));

m_init(&Open[0], m, curr,3);


if(test1(&Open[0],m)){test2(&Open[0],m);}

else

Push_OPEN(&Open[0], m);

memcpy(m,curr,sizeof(state));

}

if(i+1 < row)

{

temp = Number_Copy[RowOfEmpty + 1][ColOfEmpty];

Number_Copy[RowOfEmpty + 1][ColOfEmpty] = 0;

Number_Copy[RowOfEmpty][ColOfEmpty] = temp;

memcpy(m->Number,Number_Copy,sizeof(m->Number));

memcpy(Number_Copy,curr->Number,sizeof(Number_Copy));

m_init(&Open[0], m, curr,4);

/*

if(test1(&Open[0],m)){}

else

Push_OPEN(&Open[0], m);

memcpy(m,curr,sizeof(state));

*/

if(test1(&Open[0],m)){test2(&Open[0],m);}

else

Push_OPEN(&Open[0], m);

memcpy(m,curr,sizeof(state));

}

if(j-1 > 0)

{

temp = Number_Copy[RowOfEmpty][ColOfEmpty-1];

Number_Copy[RowOfEmpty][ColOfEmpty-1] = 0;

Number_Copy[RowOfEmpty][ColOfEmpty] = temp;

memcpy(m->Number,Number_Copy,sizeof(m->Number));

memcpy(Number_Copy,curr->Number,sizeof(Number_Copy));

m_init(&Open[0], m, curr,2);

if(test1(&Open[0],m)){test2(&Open[0],m);}

else

Push_OPEN(&Open[0], m);

memcpy(m,curr,sizeof(state));

}

if(j+1 < col)

{

temp = Number_Copy[RowOfEmpty][ColOfEmpty+1];

Number_Copy[RowOfEmpty][ColOfEmpty+1] = 0;

Number_Copy[RowOfEmpty][ColOfEmpty] = temp;

memcpy(m->Number,Number_Copy,sizeof(m->Number));

memcpy(Number_Copy,curr->Number,sizeof(Number_Copy));

m_init(&Open[0], m, curr,1);

if(test1(&Open[0],m)){test2(&Open[0],m);}

else

Push_OPEN(&Open[0], m);

memcpy(m,curr,sizeof(state));

}

return;

}

}

void test2(state* Open[], state* m)

{

int i,j,n;

int count = 0;

int flag = false;


//open에서 찾어

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

{

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

for(j=0;j<col;j++)

if(Open[n]->Number[i][j] == m->Number[i][j])

count++;


if(count == row*col)

{

//flag = true;

if((Open[n]->Fh) > (m->Fh))

{

Open[n]->Gh = m->Gh;

Open[n]->Fh = m->Fh;

Open[n]->Parent = m->Parent;


if(Open[n]->closed == true)

Open[n]->closed = false;

}

break;

}

count= 0;

}

/*

if(flag == true)

return Open[n]->closed;

else//없는경우

return Open[--n]->closed;*/

}

int test1(state* Open[], state* m)

{

int i,j,n;

int count = 0;

int flag= 0;


//open에서 비교해

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

{

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

for(j=0;j<col;j++)

if(Open[n]->Number[i][j] == m->Number[i][j])

count++;


if(count == row*col)

{

flag = 1;

break;

}

count = 0;

}

if(flag == 0)

return 0;

return 1;

}


//나중에 open지울것

void m_init(state* Open[], state* m, state* curr, int DirectionFromParent)

{

m->closed = false;

m->Parent = curr;

m->Gh = (m->Gh) + 1;

m->Hh = Compute_Hh(m);

m->Fh =(m->Gh) + (m->Hh);

m->DirectionFromParent = DirectionFromParent;

}


void Insert_Tree(Tr* TrRoot, state* curr)

{

Tr* cursor = TrRoot;

Tr* newcurr = (Tr*)malloc(sizeof(Tr));

newcurr->Node = curr;

newcurr->StateTr = null;


while(cursor->StateTr != null)

cursor = cursor->StateTr;


cursor->StateTr = newcurr;

}


void Print_Direction(int cases) ////1:move right, 2: move left, 3:move up, 4:move down

{

//fflush(fp);

if(cases <1 || cases>4){}

else if(cases ==1)printf("==> move right\n");

else if(cases ==2)printf("==> move left\n");

else if(cases==3) printf("==> move up\n");  

else if(cases==4) printf("==> move down\n"); 

else

printf("direction print test\n");

}



반응형

'아카이브 > C' 카테고리의 다른 글

파일 입출력 함수들  (0) 2015.11.01