8puzzle codigo

Upload: milton-joel-calcina-yucra

Post on 02-Apr-2018

218 views

Category:

Documents


0 download

TRANSCRIPT

  • 7/27/2019 8puzzle codigo

    1/21

    8puzzle.h

    #define UP 0#define DOWN 1#define RIGHT 2#define LEFT 3

    #define NUM_OPERATORS 4

    typedef struct tState_ {int cells[3][3];int r,c;

    } tState

    8puzzle.c

    #include #include "8puzzle.h"#include "search.h"

    static int initcells[3][3] ={{1,2,3},{4,5,6},{7,8,0}

    };

    static int goalcells[3][3] ={{4,1,3},{7,2,5},

    {0,8,6}};

    /*static int goalcells[3][3] ={{1,2,3},{4,0,6},{7,5,8}

    };*/

    tState *initialState() {tState *s = (tState *)malloc(sizeof(tState));int i,j;for (i=0;ir=2; s->c=2;return s;

    }

    int goalTest(tState *s) {

  • 7/27/2019 8puzzle codigo

    2/21

    int i,j;

    for (i=0;ir>0;case DOWN: return s->rc>0;case RIGHT: return s->cr--; break;case DOWN: result->r++; break;case LEFT: result->c--; break;case RIGHT: result->c++; break;

    }result->cells[result->r][result->c]=0;result->cells[old->r][old->c]=old->cells[result->r][result->c];

    return result;}

    int cost(unsigned op,tState *s) {return 1;

    }

    int stateEqual(tState *s1,tState *s2) {return (memcmp(s1,s2,sizeof(tState))==0);

    }

    /*--- DISPLAY FUNCTIONS -----------------------------------------------*/

    void showState(tState *s) {int i,j;

    for (i=0; i

  • 7/27/2019 8puzzle codigo

    3/21

    case DOWN: printf("DOWN");break;case LEFT: printf("LEFT");break;case RIGHT: printf("RIGHT");break;

    }}

    ////////////queue.h

    /****************************************************************************** QUEUE.h* Pedro Cabalar 15/10/2004

    ** A QUEUE is a single connected round list. The QUEUE itself is apointer* used to point at any moment the last element in the list.

    *****************************************************************************/

    struct qNode {struct qNode *next;int data[0];

    };

    typedef struct qNode *QUEUE;

    /* qEMPTY: returns the empty queue (represented as the NULL pointer) */#define qEMPTY NULL

    /* qIsEmpty(QUEUE q);* Decides whether QUEUE q is empty or not. It is equivalent to* the expression q==qEMPTY*/#define qIsEmpty(q) ((q)==NULL)

    /* qIsNotEmpty(QUEUE q);* The opposite to qIsEMPTY. It is equivalent to the expression q!=qEMPTY*/

    #define qIsNotEmpty(q) ((q)!=NULL)

    /* qFirst(QUEUE q,type);* Returns a pointer to the data of the first element in the list,assuming* that the element type is 'type'.* EXAMPLE:* printf("%d\n",*qFirst(q,int));* will print the first element of q, assuming it is an integer number.* REQUIRES: q must be non-empty.

  • 7/27/2019 8puzzle codigo

    4/21

    */#define qFirst(q,type) ((type *)(q)->next->data)

    /* qNext(QUEUE q,type);* Returns a QUEUE pointer to the next element from q.* Remember that the end of the list is not a NULL pointer, but isconnected

    * instead to the first element (it is a round list).* REQUIRES: q must be non-empty.*/#define qNext(q) ((q)->next)

    /* qInsertAt(QUEUE *pq,QUEUE pos,void *e,unsigned int size);* Inserts an element of size 'size' whose address is pointer 'e' at the* position pointed by QUEUE pointer 'pos'.* REQUIRES: 'pos' must be one of the pointers inside the queue *pq.* MODIFIES: the queue elements and (possibly) the queue pointer *pq.*/#define qInsertAt(pq,pos,e,size)((*pq)==(pos))?qInsertFirst(pq,e,size):qInsertFirst(&p,e,size)

    /* qPUSH(QUEUE *pq,void *e,type)* Pushes element of type 'type' whose address is pointer 'e' at the* top of the queue pointed by 'pq'. Note that 'pq' must be of type(QUEUE *),* since the queue pointer can be modified.* MODIFIES: the queue elements and (possibly) the queue pointer *pq.*/#define qPUSH(pq,e,type) qInsertFirst(pq,(void *)e,sizeof(type))

    /* qPOP(QUEUE *pq,void *e,type)* Retrieves and deletes the top element of queue *pq, storing it ataddress* 'e', assuming that its type is 'type'.

    * REQUIRES: the queue *pq must be non-empty.* MODIFIES: the content of the area pointed by 'e', the queue elements,and* (possibly) the queue pointer *pq.*/#define qPOP(pq,e,type) {memcpy((void *)e,(*(pq))->next->data,sizeof(type)); qDeleteFirst(pq);}

    /* See qOrderedInsert */#define REPEATING 1

    int qInsertFirst(QUEUE *pq, void *e, int size);/* Inserts an element of size 'size' pointed by 'e' as the first element

    of* queue *pq.* MODIFIES: the queue elements and (possibly) the queue pointer *pq.*/

    int qInsertLast(QUEUE *pq, void *e, int size);/* Inserts an element of size 'size' pointed by 'e' as the last elementof* queue *pq.* MODIFIES: the queue elements and (possibly) the queue pointer *pq.

  • 7/27/2019 8puzzle codigo

    5/21

    */

    int qDeleteFirst(QUEUE *pq);/* Deletes the first element of queue *pq* MODIFIES: the queue elements and the queue pointer *pq.*/

    QUEUE qBrowse(QUEUE q, int (*found)(QUEUE , void *),void *data);/* Allows browsing the queue q and performing some arbitrary operationuntil* the end of the queue is reached or some element is found.* Argument 'found' is a pointer to a function of type* int (*found) (QUEUE pos,void *data)* that will be called for each pointer 'pos' to each element in list'q'.* When this function returns 0, the browsing will continue untilreaching* the queue end. Otherwise, it may return 1 (for instance, when somesearched* element is found) and the browsing will stop at that moment.

    * The pointer 'data' is used to pass common data to each call offunction* (*found).* REQUIRES: function (*found) should return 0 or 1 and should not modify* the element pointers (should not delete or insert elements in q).* MODIFIES: It depends on function (*found), which can modify thecontent of* the elements in the queue.* EXAMPLE: We want to add some constant k to all the elements in a listof* integer numbers until we reach some negative number:** int addConstant(QUEUE q,void *data) {* if (*qFirst(q,int) < 0)

    * return 1;* int *pk=(int *)data;* *qFirst(q,int) += *pk;* return 0;* }** ...* int k=10;* qBrowse(q,addConstant,&k);* ...*/

    int qDelete(QUEUE *pq, QUEUE pos);

    /* Deletes the element of queue *pq at position pointed by queue pointer'pos'.* REQUIRES: 'pos' must be one of the valid position pointers insidequeue* *pq.* MODIFIES: the queue elements and possibly the content of *pq.*/

    int qMove(QUEUE *q1, QUEUE *q2, int (*movethis)(void *),int size);/* Moves all the elements in *q1 to *q2 that satisfy a property specified

  • 7/27/2019 8puzzle codigo

    6/21

    * by the generic function (*movethis). The moved elements are removedfrom* *q1 and appended to *q2, that is, they are inserted in the end. Theelements* size is fixed to 'size'.* MODIFIES: the elements of both queues, and possibly *q1 and *q2.*/

    int qFree(QUEUE *q);/* Deletes all the queue elements leaving *q empty. */

    int qOrderedInsert(QUEUE *q, void *e, int size,int (*cmp)(void *, void*),

    char repeating);/* Makes an ordered insertion of element of size 'size' pointed by 'e' in* queue *q. Generic function (*cmp) is used to compare two elements* (passed as void pointers) so that it returns a value 0 if the first element isgreater.* Argument 'repeating' is used to point out whether we allow repeated

    elements* or not (1 means with repeated elements, 0 means no repeated elements).* REQUIRES: the elements in *q should be ordered with respect to (*cmp)* ordering criterion.* MODIFIES: the queue elements and (possibly) the pointer *q.*/

    int qDeleteThoseThat(QUEUE *q,int (*DeleteThis)(QUEUE pos,void*data),void *data);/* Deletes from queue *q all those elements that satisfy proertyspecified* by generic function (*DeleteThis). Argument 'data' is used for passing* additional data to (*DeleteThis) if needed.* REQUIRES: function DeleteThis should return 1 if the first element of

    * pointer 'pos' should be deleted, and 0 otherwise.* MODIFIES: the queue elements and (possibly) the pointer *q.*/

    QUEUE qCopy(QUEUE q,int size);/* Returns a full copy of q. */

    QUEUE qMerge(QUEUE q,QUEUE r,int size,int (*cmp)(void *,void *),charrepeating);/* It returns a list containing the result of merging the two orderedlists q* and r. The new list contains a copy of the elements in the old lists.* The ordering criterion is specified by the generic function (*cmp)

    (see* qOrderedInsert). When 'repeating' is 0, repeated elements are copiedonly* once. The size elements is fixed to 'size'.*/

    QUEUE qIntersect(QUEUE q,QUEUE r,int size,int (*cmp)(void *,void *));/* Returns the common elements of queues q and r. The new list contains a* copy of the elements in the old lists. Generic function (*cmp) returns0

  • 7/27/2019 8puzzle codigo

    7/21

    * when two elements are equal (see qOrderedInsert). The size elements is* fixed to 'size'.*/

    QUEUE qDiff(QUEUE q,QUEUE r,int size,int (*cmp)(void *,void *));/* Returns the elements in q not in r. The new list contains a* copy of the elements in the old lists. Generic function (*cmp) returns

    0* when two elements are equal (see qOrderedInsert). The size elements is* fixed to 'size'.*/

    unsigned int qCount(QUEUE q);/* Returns the number of elements in a list. */

    void *Queue2Array(QUEUE q,unsigned int size,unsigned int *num);/* Returns an array (void *) containing a copy of all the elements in the* queue q. The elements size is fixed to 'size'.* It also returns the number of elements in *num.*/

    QUEUE qCat(QUEUE q,QUEUE r);/* Returns the result of appending queue r in the end of queue q.* The new list contains a copy of the elements in the old lists.*/

    ////////////////queue.c

    #include #include #include #include "queue.h"

    #define BREAKLINK(Q,QOLD,QNEXTOLD) {(QOLD)=(Q); (QNEXTOLD)=(Q)->next;(Q)=(Q)->next; (QOLD)->next=qEMPTY;}

    /* Round queues */

    static QUEUE qAux;

    int qInsertFirst(QUEUE *q, void *e, int size){QUEUE p;

    if ((p=(QUEUE)malloc(sizeof(struct qNode)+size))!=NULL){memcpy((void *)(p->data),e,size);

    if (qIsEmpty(*q))

  • 7/27/2019 8puzzle codigo

    8/21

    { *q=p;(*q)->next=(*q);

    }else{ p->next = (*q)->next;

    (*q)->next = p;}

    return 1;}else return 0;

    }

    int qDeleteFirst(QUEUE *q){QUEUE p;

    if (qIsEmpty(*q)) return 0;

    if (*q == (*q)->next)

    { free(*q);*q=qEMPTY;

    }else{ p=(*q)->next;(*q)->next=p->next;free(p);

    }return 1;

    }

    int qInsertLast(QUEUE *q, void *e, int size){QUEUE p;

    if (!qInsertFirst(q,e,size))return 0;

    *q=(*q)->next;return 1;

    }

    QUEUE qBrowse(QUEUE q, int (*found)(QUEUE, void *),void *data){QUEUE p;int stop;

    if (qIsNotEmpty(q))

    {p=q;while (! (stop=(*found)(p,data) ) &&

    (p=p->next)!=q );if (stop)

    return p;}return NULL;

    }

  • 7/27/2019 8puzzle codigo

    9/21

    int qDelete(QUEUE *q, QUEUE pos){if (qIsEmpty(*q) || qIsEmpty(pos) ) return 0;

    if (pos->next==*q){*q=pos;

    return qDeleteFirst(q);}

    return qDeleteFirst(&pos);}

    int qMove(QUEUE *q1, QUEUE *q2, int (*movethis)(void *elem),int size){QUEUE p;

    p=qEMPTY;while (qIsNotEmpty(*q1)){

    if ((*movethis)((void *)(*q1)->next->data)){ if (!qInsertLast(q2,(void *)((*q1)->next->data),size)) return 0;

    }else

    { if (!qInsertLast(&p,(void *)((*q1)->next->data),size)) return 0;}

    if (!qDeleteFirst(q1)) return 0;}*q1=p;

    return 1;}

    int qFree(QUEUE *q){while ((*q)!=NULL) qDeleteFirst(q);

    }

    struct cmpData{void *elem;int (*cmp)(void *, void *);

    };

    static int FirstIsgeqThan(QUEUE q,void *e){

    struct cmpData *d;d=(struct cmpData*)e;return (d->cmp(q->next->data,d->elem)>=0);

    }

    int qOrderedInsert(QUEUE *q, void *e, int size,int (*cmp)(void *, void*),

    char repeating){QUEUE p;

  • 7/27/2019 8puzzle codigo

    10/21

    struct cmpData d;

    d.cmp=cmp;d.elem=e;p=qBrowse(*q,FirstIsgeqThan,&d);if (p==NULL)qInsertLast(q,e,size);

    else{

    if (!repeating && cmp(p->next->data,e)==0) return 0;qInsertAt(q,p,e,size);

    }return 1;

    }

    int qDeleteThoseThat(QUEUE *q,int (*DeleteThis)(QUEUE,void *),void *data){QUEUE p;char InFirst;int n=0;

    if (qIsNotEmpty(*q)){p=*q;InFirst=1;do{

    if (DeleteThis(p,data)){qDelete(q,p);n++;if (InFirst) InFirst=(p==*q);

    }else

    {p=p->next;InFirst=0;

    }} while(qIsNotEmpty(*q) && (p!=*q || InFirst));

    }return n;

    }

    static int CopyElem(QUEUE q,void *e){qInsertLast(&qAux,q->next->data,*(int *)e);

    return 0;}

    QUEUE qCopy(QUEUE q,int size){qAux=qEMPTY;qBrowse(q,CopyElem,&size);return qAux;

    }

  • 7/27/2019 8puzzle codigo

    11/21

    #define COPY(Q) qInsertLast(&qAux,(Q)->data,size)#define MOVE(Q) (Q)=(Q)->next;

    QUEUE qMerge(QUEUE q,QUEUE r,int size,int (*cmp)(void *,void *),charrepeating){

    QUEUE qOld,rOld,qNextOld,rNextOld;int comp;

    if (qIsEmpty(q))if (qIsEmpty(r)) return qEMPTY;else return qCopy(r,size);

    if (qIsEmpty(r)) return qCopy(q,size);

    /* Momentaneously break the round links */BREAKLINK(q,qOld,qNextOld);BREAKLINK(r,rOld,rNextOld);

    qAux=qEMPTY;while (q!=qEMPTY && r!=qEMPTY){comp=cmp(q->data,r->data);

    if (comp0) {COPY(r); MOVE(r);}else {

    COPY(q);if (repeating) COPY(r);MOVE(q); MOVE(r);}

    }

    while (q!=qEMPTY) {COPY(q); MOVE(q);}while (r!=qEMPTY) {COPY(r); MOVE(r);}

    /* Restore round links */qOld->next=qNextOld;rOld->next=rNextOld;

    return qAux;}

    QUEUE qIntersect(QUEUE q,QUEUE r,int size,int (*cmp)(void *,void *)){QUEUE qOld,rOld,qNextOld,rNextOld;

    int comp;

    if (qIsEmpty(q)||qIsEmpty(r)) return qEMPTY;

    /* Momentaneously break the round links */BREAKLINK(q,qOld,qNextOld);BREAKLINK(r,rOld,rNextOld);

    qAux=qEMPTY;while (q!=qEMPTY && r!=qEMPTY)

  • 7/27/2019 8puzzle codigo

    12/21

    {

    comp=cmp(q->data,r->data);if (comp0) {MOVE(r);}else {COPY(q); MOVE(q); MOVE(r);}

    }

    /* Restore round links */qOld->next=qNextOld;rOld->next=rNextOld;

    return qAux;}

    QUEUE qDiff(QUEUE q,QUEUE r,int size,int (*cmp)(void *,void *)){QUEUE qOld,rOld,qNextOld,rNextOld;int comp;

    if (qIsEmpty(q)) return qEMPTY;if (qIsEmpty(r)) return qCopy(q,size);

    /* Momentaneously break the round links */BREAKLINK(q,qOld,qNextOld);BREAKLINK(r,rOld,rNextOld);

    qAux=qEMPTY;while (q!=qEMPTY && r!=qEMPTY){comp=cmp(q->data,r->data);if (comp0) {MOVE(r);}else {MOVE(q); MOVE(r);}

    }

    while (q!=qEMPTY) {COPY(q); MOVE(q);}

    /* Restore round links */qOld->next=qNextOld;rOld->next=rNextOld;

    return qAux;}

    static int CountElem(QUEUE q,void *e)

    {*(unsigned int *)e+=1;return 0;

    }

    unsigned int qCount(QUEUE q){unsigned int c=0;qBrowse(q,CountElem,(void*)&c);return c;

  • 7/27/2019 8puzzle codigo

    13/21

  • 7/27/2019 8puzzle codigo

    14/21

    typedef struct tHashEntry_ {void *key; /* Pointer to key */void *data; /* Pointer to data */

    } tHashEntry;

    /*----------------------------------------------------------------

    Creates a hash table 'numLists' lists (use a prime number), and'keySize' fixed size for all keysREQUIRES 'numLists' should be a prime number.RETURNS the pointer to the hash table structure.

    */tHashTable *hashCreate(unsigned int numLists,unsigned int keySize);

    /*----------------------------------------------------------------Inserts an element in the hash table. For computing the hash value,it will use h->keySize bytes beginning at the 'key' pointer. The

    'data'will be stored just as a pointer. If 'data' is not used, fix it to

    NULL.

    REQUIRES pointer 'h' must point to a correctly created non-null hashstructure.

    RETURNS 1 if the element is inserted, 0 if the key was already in thetable.*/int hashInsert(tHashTable *h,void *key, void *data);

    /*----------------------------------------------------------------Searchs for entry 'e'.REQUIRES e->key should contain the searched key.

    The value of e->data before calling is irrelevant.RETURNS 0 if key was not found.

    1 if key was found.

    If found, the corresponding data pointer is stored in e->data.*/int hashFind(tHashTable *h,tHashEntry *e);

    /*----------------------------------------------------------------Frees memory assigned to the hash table.It will NOT free the assigned memory to each element key and element

    data,just the structures that exclusively correspond to the hash table

    structure.*/void hashFree(tHashTable *h);

    //////////////hash.c

  • 7/27/2019 8puzzle codigo

    15/21

    #include "queue.h"#include "hash.h"

    /*----------------------------------------------------------------Creates a hash table 'numLists' lists (use a prime number), and'keySize' fixed size for all keysREQUIRES 'numLists' should be a prime number.

    RETURNS the pointer to the hash table structure.*/tHashTable *hashCreate(unsigned int numLists,unsigned int keySize){tHashTable *h=(tHashTable *) malloc(sizeof(tHashTable));h->lists=(QUEUE *)calloc(numLists,sizeof(QUEUE));h->numLists=numLists;h->keySize=keySize;

    return h;}

    /* Compares two hash entries using their keys. The key size ismomentarily

    stored in the static var 'auxKeySize'.*/static unsigned int auxKeySize;static int entryCmp(void *e1, void *e2) {return memcmp(((tHashEntry *)e1)->key,((tHashEntry *)e2)-

    >key,auxKeySize);}

    /* Computes the hash value for a given key */static unsigned int hv(tHashTable *h,void *key) {int n=sizeof(unsigned int);union {

    unsigned int x;char p[n];

    } u;

    unsigned int sum=0;

    int i;char *q=key;

    for (i=0;ikeySize/n;i++,q+=n) {memcpy(u.p,q,n);sum+=u.x;

    }

    for (i=0;ikeySize % n);sum += u.x;

    return sum % h->numLists;}

    /*----------------------------------------------------------------Inserts an element in the hash table. For computing the hash value,

  • 7/27/2019 8puzzle codigo

    16/21

    it will use h->keySize bytes beginning at the 'key' pointer. The'data'

    will be stored just as a pointer. If 'data' is not used, fix it toNULL.

    REQUIRES pointer 'h' must point to a correctly created non-null hashstructure.

    RETURNS 1 if the element is inserted, 0 if the key was already in the

    table.*/int hashInsert(tHashTable *h,void *key, void *data) {tHashEntry e;e.key=key;e.data=data;auxKeySize=h->keySize;return qOrderedInsert(&h-

    >lists[hv(h,key)],&e,sizeof(tHashEntry),entryCmp,0);}

    /* Searchs the first entry which is greater or equal than e */static int geqEntry(QUEUE q, void *e) {

    return entryCmp(qFirst(q,tHashEntry),e)>=0;}

    /*----------------------------------------------------------------Searchs for entry 'e'.REQUIRES e->key should contain the searched key.

    The value of e->data before calling is irrelevant.RETURNS 0 if key was not found.

    1 if key was found.If found, the corresponding data pointer is stored in e-

    >data.*/int hashFind(tHashTable *h,tHashEntry *e) {QUEUE aux;

    /* Ordered search in the corresponding list */auxKeySize=h->keySize;aux=qBrowse(h->lists[hv(h,e->key)],geqEntry,e);

    if (aux!=qEMPTY && entryCmp(qFirst(aux,tHashEntry),e)==0) {e->data=qFirst(aux,tHashEntry)->data;return 1;

    }

    return 0; /* not found */}

    /*----------------------------------------------------------------

    Frees memory assigned to the hash table.It will NOT free the assigned memory to each element key and element

    data,just the structures that exclusively correspond to the hash table

    structure.*/void hashFree(tHashTable *h) {/* Delete all lists */int i;for (i=0;inumLists;i++)

  • 7/27/2019 8puzzle codigo

    17/21

    while (qIsNotEmpty(h->lists[i]))qDeleteFirst(&h->lists[i]);

    free(h->lists); /* Free the lists array */free(h); /* Free the hash table structure */

    }

    ///////////////search.c

    #include #include #include "queue.h"#include "hash.h"#include "domain.h"#include "search.h"#include

    #include

    struct {enum {BREADTH,DEPTH} fringeInsertion;int (*algorithm)();char verbose;

    } options;

    struct {unsigned int expandedNodes;struct rusage resources;

    } statistics;

    int inPath(tSearchNode *node,tState *s) {while (node!=NULL) {if (stateEqual(node->state,s)) return 1;node=node->parent;

    }return 0;

    }

    QUEUE expand(tSearchNode *node) {QUEUE successors=qEMPTY;unsigned op;

    for (op=0;opstate)) {tSearchNode *new;tState *s=successorState(op,node->state);

    if (options.fringeInsertion==DEPTH && inPath(node->parent,s))free(s);

    else {new=(tSearchNode *)malloc(sizeof(tSearchNode));new->state=s;new->parent=node;

  • 7/27/2019 8puzzle codigo

    18/21

    new->action=op;new->pathCost=node->pathCost + cost(op,node->state);new->depth=node->depth+1;

    qInsertLast(&successors,&new,sizeof(tSearchNode *));}

    }

    statistics.expandedNodes++;return successors;

    }

    void printReversePath(tSearchNode *node) {if (node->parent==NULL) return;

    printReversePath(node->parent);showOperator(node->action);if (options.verbose) {printf("\n");

    showState(node->state);printf("\n");

    }else printf("; ");

    }

    void printSolution(tSearchNode *node) {printf("Solution: \n");printReversePath(node);printf("\nDepth=%d\n",node->depth);printf("Cost=%d\n",node->pathCost);

    }

    void insertNode(QUEUE *fringe,tSearchNode **n) {switch(options.fringeInsertion) {case BREADTH:

    qInsertLast(fringe,n,sizeof(tSearchNode *)); break;case DEPTH:

    qInsertFirst(fringe,n,sizeof(tSearchNode *)); break;}

    }

    tSearchNode *rootNode() {/* Create the root node */

    tSearchNode *root=(tSearchNode *)malloc(sizeof(tSearchNode));root->state=initialState();root->parent=NULL;root->pathCost=0;root->depth=0;return root;

    }

    int treeSearch() {tSearchNode *node,*n,*root=rootNode();

  • 7/27/2019 8puzzle codigo

    19/21

    QUEUE fringe=qEMPTY,successors;

    qInsertFirst(&fringe,&root,sizeof(tSearchNode *));while (1) {if (qIsEmpty(fringe)) return 0;qPOP(&fringe,&node,sizeof(tSearchNode *));

    if (goalTest(node->state)) {printSolution(node); return 1;}

    successors = expand(node);while (!qIsEmpty(successors)) {

    qPOP(&successors,&n,sizeof(tSearchNode *));insertNode(&fringe,&n);

    }}

    }

    int graphSearch() {tSearchNode *node,*n,*root=rootNode();

    QUEUE fringe=qEMPTY,successors;tHashTable *closed=hashCreate(10007,sizeof(tState));tHashEntry e;

    qInsertFirst(&fringe,&root,sizeof(tSearchNode *));

    while (1) {if (qIsEmpty(fringe)) return 0;qPOP(&fringe,&node,sizeof(tSearchNode *));

    if (goalTest(node->state)) {printSolution(node); return 1;}

    e.key=node->state;if (hashFind(closed,&e)) { /* already visited state */

    free(node->state);free(node);continue;

    }

    hashInsert(closed,node->state,NULL);

    successors = expand(node);while (!qIsEmpty(successors)) {

    qPOP(&successors,&n,sizeof(tSearchNode *));insertNode(&fringe,&n);

    }}

    }

    extern char *optarg;extern int optind;

    int main (int argc,char *argv[]) {/* Processing options */int c;

  • 7/27/2019 8puzzle codigo

    20/21

    options.algorithm=treeSearch;options.fringeInsertion=BREADTH;options.verbose=0;statistics.expandedNodes=0;

    while ((c = getopt(argc, argv, "a:f:v")) != EOF) {switch (c) {

    case 'a':if (!strcmp(optarg,"tree"))options.algorithm=treeSearch;

    else {if (!strcmp(optarg,"graph"))

    options.algorithm=graphSearch;else {

    printf("Unrecognized algorithm %s.\n",optarg); exit(1);}

    }break;

    case 'f':if (!strcmp(optarg,"breadth"))

    options.fringeInsertion=BREADTH;else {if (!strcmp(optarg,"depth"))

    options.fringeInsertion=DEPTH;else {

    printf("Unrecognized type of fringe insertion%s.\n",optarg); exit(1);

    }}break;

    case 'v': options.verbose=1;break;case 'h':case '?':

    printf("search -a -f ");

    }}

    if (!(options.algorithm()))printf("No solution.\n");

    printf("%d expanded nodes.\n",statistics.expandedNodes);getrusage(RUSAGE_SELF,&statistics.resources);printf("%ld.%03ld seconds.\n",statistics.resources.ru_utime.tv_sec,statistics.resources.ru_utime.tv_usec/1000);

    }

    ////////////////search.h

    tState *initialState();int goalTest(tState *s);int executable(unsigned op,tState *s);tState *successorState(unsigned op,tState *s);int cost(unsigned op,tState *s);

  • 7/27/2019 8puzzle codigo

    21/21

    void showOperator(unsigned op);void showState(tState *s);

    /////////////////////////////////////////////////////////////////////////////////NOSE PARA QUE ES

    SOURCES=queue.c domain.c search.c hash.cINCLUDES=$(SRCS:%.c=%.h)

    search : $(INCLUDES) $(SOURCES)gcc -o search $(SOURCES)

    debug : $(INCLUDES) $(SOURCES)gcc -ggdb -o search $(SOURCES)

    domain :rm -f domain.c domain.hln -s $(DOM).c domain.cln -s $(DOM).h domain.htouch domain.c

    clean :rm -f search *.o