7.1.2 순열 알고리즘의 경험 정보 구현

초기 경험 정보를 생성하는 함수를 작성합시다.

Heuristic *MakeInitHeuristic(Array *bucket)
{
    Heuristic *heu = 0;

입력 인자로 전달받은 바구니에 있는 공을 순차적으로 접근하기 위해 반복자 변수를 두 개 선언할게요.

    Iterator seek=0, end=0;

Heuristic 크기의 메모리를 할당합니다.

    heu = (Heuristic *)malloc(sizeof(Heuristic));

꺼내지 않은 공을 보관할 동적 배열과 꺼낸 공을 보관할 동적 배열을 생성합니다.

    heu->ori_bucket = New_Array();
    heu->out_bucket = New_Array();

입력 인자로 전달받은 동적 배열의 시작과 끝을 얻어옵니다.

    seek = Array_Begin(bucket);
    end = Array_End(bucket);

순차적으로 이동하면서 바구니에 있는 공을 꺼내지 않은 공을 보관하는 동적 배열에 보관합니다.

    for(seek = seek; seek != end; ++seek)
    {
        Array_PushBack(heu->ori_bucket, *seek);
    }

경험 정보를 반환합니다.

    return heu;
}

동적으로 생성한 경험 정보를 소멸하는 함수를 작성합시다.

void DeleteHeuristic(Heuristic *now)
{

내부에서 동적으로 생성한 배열을 소멸한 후에 자신의 메모리를 소멸합니다.

    Delete_Array(now->ori_bucket);
    Delete_Array(now->out_bucket);
    free(now);
}

현재 경험 정보에서 진행할 수 있는 다음 경험 정보 목록을 구하는 함수를 작성합시다.

void FindNextHeuristics(Heuristic *now, Array *next_heus)
{

현재 경험 정보에서 꺼내지 않은 동적 배열에 있는 공을 하나를 꺼내는 것이 다음 경험 정보입니다. 이를 위해 현재 경험 정보의 꺼내지 않은 동적 배열에서 하나의 공을 꺼내는 것을 순차적으로 반복해야 합니다. 따라서 반복자를 선언합시다.

    Iterator seek=0, end=0;

그리고 다음 경험 정보를 기억할 변수도 선언합시다.

    Heuristic *next = 0;

현재 경험 정보의 꺼내지 않은 동적 배열의 시작과 끝을 구합니다.

    seek = Array_Begin(now->ori_bucket);
    end = Array_End(now->ori_bucket);

경험 정보의 위치를 순차적으로 이동하면서 다음 경험 정보를 생성해야 합니다. for 문을 이용할 때 초기 조건이 비어있는 것을 아무런 변화가 없는 코드(seek=seek)로 채웠습니다. 별 의미가 없는 코드입니다.

    for(seek = seek; seek != end; ++seek)
    {

현재 위치의 공을 꺼내어 다음 경험 정보를 만들고 배열에 보관합니다. 현재 위치의 공을 꺼내어 다음 경험 정보를 만드는 함수는 별도로 작성할게요.

        next = MakeNextHeu(now,(int)*seek);
        Array_PushBack(next_heus,next);
    }
}

현재 경험 정보에서 특정 공을 꺼내어 다음 경험 정보를 만드는 함수를 작성합시다.

Heuristic *MakeNextHeu(Heuristic *now,int ball)
{
    Heuristic *heu = 0;
    Iterator seek=0, end=0;

먼저 Heuristic 크기의 메모리를 할당하고 꺼내지 않은 공과 꺼낸 공을 보관할 동적 배열을 생성합니다.

    heu = (Heuristic *)malloc(sizeof(Heuristic));
    heu->ori_bucket = New_Array();
    heu->out_bucket = New_Array();

입력 인자로 받은 현재 경험의 꺼낸 공을 새로 생성한 다음 경험 정보의 꺼낸 공을 보관할 배열에 보관합니다.

    seek = Array_Begin(now->out_bucket);
    end = Array_End(now->out_bucket);
    for(seek = seek; seek != end; ++seek)
    {
        Array_PushBack(heu->out_bucket, *seek);
    }

현재 경험의 꺼내지 않은 공 중에 입력 인자로 받은 공은 꺼낼 것이므로 꺼낸 공을 보관하는 배열에 넣고 그렇지 않은 공은 꺼내지 않은 공을 보관하는 배열에 넣습니다.

    seek = Array_Begin(now->ori_bucket);
    end = Array_End(now->ori_bucket);
    for(seek = seek; seek != end; ++seek)
    {

참고로 여기에서 사용하는 동적 배열은 동적으로 생성한 자료를 보관하게 설계하였습니다. 즉 동적으로 생성한 자료의 메모리 주소를 보관하는 것이죠. 여기에서는 동적으로 생성한 자료가 아닌 공의 번호인 정수형을 보관하므로 반복자가 가리키는 내용을 정수형으로 강제 형변환을 사용하고 있습니다.

        if((int)(*seek) == ball)
        {
            Array_PushBack(heu->out_bucket,*seek);
        }
         else
        {
            Array_PushBack(heu->ori_bucket,*seek);
        }
    }
    return heu;
}

꺼낸 공의 개수를 반환하는 함수를 작성합시다.

int GetOutCount(Heuristic *now)
{
    return now->out_bucket->usage;
}

꺼낸 공의 목록을 보여주는 함수를 작성합시다.

void ViewHeuristic(Heuristic *now)
{
    Iterator seek=0, end=0;

꺼낸 공을 보관하는 배열의 시작과 끝을 구합니다.

    seek = Array_Begin(now->out_bucket);
    end = Array_End(now->out_bucket);

순차적으로 이동하면서 해당 위치의 공을 출력합니다.

    for(seek = seek; seek != end; ++seek)
    {
        printf("%d ",(int)*seek);
    }

다른 결과 목록과 구분하기 위해 개행 문자를 출력합니다.

    printf("\n");
}