Ejemplo n.º 1
0
Automate::~Automate(){

    deleteTableTranstion();
    deleteQ();
    deleteI();
    deleteT();
}
Ejemplo n.º 2
0
bool Automate::ouvrir(const string& nomFichier){

    deleteTableTranstion();
    deleteA();
    deleteQ();
    deleteI();
    deleteT();

    ifstream fichier(nomFichier.c_str(), ios::in);
    if (fichier.is_open()){

        string charA;
        string charQ;
        string charI;
        string charT;
        string charTDT;
        string temp;

        getline(fichier,charA);

        for(unsigned int i = 0; i < charA.size(); i++)
        {
            temp.clear();
            while ((i < charA.size())&&(charA[i] == ' '))
                i++;
            while((i < charA.size())&&(charA[i] != ' ')){
                temp += charA.substr(i,1);
                i++;
            }
            _A.push_back(temp);
        }

        getline(fichier,charQ);

        for(unsigned int i = 0; i < charQ.size(); i++)
        {
            temp.clear();
            while ((i < charQ.size())&&(charQ[i] == ' '))
                i++;
            while((i < charQ.size())&&(charQ[i] != ' ')){
                temp += charQ.substr(i,1);
                i++;
            }
            _Q.push_back(new list<string>);
            (*--_Q.end())->push_back(temp);
        }

        getline(fichier,charI);

        for(unsigned int i = 0; i < charI.size(); i++)
        {
            temp.clear();
            while ((i < charI.size())&&(charI[i] == ' '))
                i++;
            while((i < charI.size())&&(charI[i] != ' ')){
                temp += charI.substr(i,1);
                i++;
            }
            _I.push_back(new list<string>);
            (*--_I.end())->push_back(temp);
        }

        getline(fichier,charT);

        for(unsigned int i = 0; i < charT.size(); i++)
        {
            temp.clear();
            while ((i < charT.size())&&(charT[i] == ' '))
                i++;
            while((i < charT.size())&&(charT[i] != ' ')){
                temp += charT.substr(i,1);
                i++;
            }
            _T.push_back(new list<string>);
            (*--_T.end())->push_back(temp);
        }

        list<list<string>*>::iterator iQ;

        for(iQ=_Q.begin(); iQ!=_Q.end(); iQ++){

            _tab[*iQ]=new list<list<string>*>[_A.size()];
        }

        getline(fichier,charTDT);
        iQ = _Q.begin();

        unsigned int col;
        unsigned int start;
        while ((!fichier.eof())&&(iQ != _Q.end())){

            getline(fichier,charTDT);
            col = 0;
            start = 0;
            while ((start < charTDT.size())&&(charTDT[start] == ' '))
                start++;
            while(charTDT[start] != ' ')
                start++;

            for(unsigned int i=start; i < charTDT.size(); i++){

                temp.clear();
                while ((i < charTDT.size())&&(charTDT[i] == ' '))
                    i++;
                while((i < charTDT.size())&&(charTDT[i] != ',')&&(charTDT[i] != ' ')){
                    temp += charTDT.substr(i,1);
                    i++;
                }

                if (temp != "-"){
                    _tab[*iQ][col].push_back(new list<string>);
                    (*--_tab[*iQ][col].end())->push_back(temp);
                }

                if (charTDT[i] == ','){
                    i++;
                }
                else{
                    col++;
                }
            }
            iQ++;
        }

        return true;
    }

    return false;
}
Ejemplo n.º 3
0
void Automate::determinisation(){

    /* Determinise l'automate
     * */

    list<list<string>*> Qdet;
    list<list<string>*> Tdet;

    // Creation de l'etat initial (= premier etat de la liste des etats)
    Qdet.push_back(new list<string>);
    list<list<string>*>::iterator iQdet = Qdet.begin();
    _tab[*iQdet] = new list<list<string>*>[_A.size()];

    for(list<list<string>*>::iterator iI=_I.begin(); iI!=_I.end(); iI++)
        (*iQdet)->insert((*iQdet)->begin(),(*iI)->begin(),(*iI)->end());


    (*iQdet)->sort();
    (*iQdet)->unique();

    // Remplace les etats initiaux pour le nouvel etat initial
    _I.clear();
    _I.push_back(new list<string>);
    (*_I.begin())->assign((*iQdet)->begin(),(*iQdet)->end());

    // Creer la nouvelle table de transition et la nouvelle liste des etats
    list<list<string>*>::iterator iQ;
    list<string>::iterator iiQdet;
    unsigned int cpt;

    // Tant qu'il y a des etats dans la nouvelle liste des etats
    while(iQdet != Qdet.end()){

        for(cpt=0; cpt<_A.size(); cpt++){
            _tab[*iQdet][cpt].push_back(new list<string>);
        }

        // Creation des nouvelles transitions pour l'etat concerne
        for(iQ=_Q.begin(); iQ!=_Q.end(); iQ++){
            for(iiQdet=(*iQdet)->begin(); iiQdet!=(*iQdet)->end(); iiQdet++){

                if (find((*iQ)->begin(),(*iQ)->end(),*iiQdet) != (*iQ)->end()){

                    for(cpt=0; cpt<_A.size(); cpt++){

                        list<list<string>*>::iterator iiTab;

                        iiTab = _tab[*iQdet][cpt].begin();
                        for(list<list<string>*>::iterator iTab=_tab[*iQ][cpt].begin(); iTab!=_tab[*iQ][cpt].end(); iTab++)
                            (*iiTab)->insert(--(*iiTab)->end(),(*iTab)->begin(),(*iTab)->end());
                    }
                }
            }
        }

        int temp;
        list<list<string>*>::iterator iTab;

        // Tri des nouvelles transitions pour l'etat concerne, et creation d'un nouvel etat a partir des nouvelles transition (s'il n'existait pas deja)
        for(cpt=0; cpt<_A.size(); cpt++){

            iTab=_tab[*iQdet][cpt].begin();
            while((!_tab[*iQdet][cpt].empty())&&(iTab!=_tab[*iQdet][cpt].end())){

                if((*iTab)->empty()){
                    _tab[*iQdet][cpt].erase(iTab);
                    iTab--;
                }
                else{
                    (*iTab)->sort();
                    (*iTab)->unique();
                }

                iTab++;
            }

            temp = 0;
            iTab = _tab[*iQdet][cpt].begin();

            // Creation d'un nouvel etat (s'il n'existait pas deja)
            for(iQ=Qdet.begin(); iQ!=Qdet.end(); iQ++){

                if((_tab[*iQdet][cpt].empty())||(((*iTab)->size() == (*iQ)->size())&&(equal((*iTab)->begin(),(*iTab)->end(),(*iQ)->begin()))))
                    temp = 1;
            }
            if (temp == 0){

                Qdet.push_back(new list<string>);
                _tab[*(--Qdet.end())] = new list<list<string>*>[_A.size()];
                (*(--Qdet.end()))->assign((*iTab)->begin(),(*iTab)->end());
            }
        }

        iQdet++;
    }

    // Suppression de l'ancienne table de transition
    deleteTableTranstion();

    // Remplace l'ancienne liste des etats par la nouvelle
    deleteQ();
    _Q = Qdet;

    // Creation de la nouvelle liste des etats teminaux (tout etat contenant un ancien etat terminal est terminal)
    for(list<list<string>*>::iterator iT=_T.begin(); iT!=_T.end(); iT++){
        for(iQ=_Q.begin(); iQ!=_Q.end(); iQ++){

            if(search((*iQ)->begin(),(*iQ)->end(),(*iT)->begin(),(*iT)->end()) != (*iQ)->end()){

                int temp = 0;
                list<list<string>*>::iterator iTdet;

                iTdet = Tdet.begin();
                while ((iTdet != Tdet.end())&&(temp == 0)){

                    if (((*iQ)->size() == (*iTdet)->size())&&(equal((*iQ)->begin(),(*iQ)->end(),(*iTdet)->begin())))
                        temp = 1;
                    iTdet++;
                }

                if (temp == 0){
                    Tdet.push_back(new list<string>);
                    (*(--Tdet.end()))->assign((*iQ)->begin(),(*iQ)->end());
                }
            }
        }
    }

    // Remplace l'ancienne liste des etats terminaux par la nouvelle
    deleteT();
    _T = Tdet;

}
Ejemplo n.º 4
0
bool Automate::minimiser(){

    /* Minimise l'automate
     * Retourne true si l'automate etait deja minimal <=> Le nombre de groupe cree lors de la minimisation est egal au nombre d'etat de l'automate
     * Retourne false si l'automate n'etait pas minimal
     * */

    list<string> groupes; // La liste des groupes Ex : {NT, T}
    list<string> tempgroupes; // Une liste des groupes temporaires
    string  groupeString; // Le groupe auquel appartient un etat
    map<string, list<list<string>*>*> tabG; // Un tableau indexe par les groupes contenant la liste des etats dans un groupe

    //Initialisation de tempGroupes et de tabG
    tempgroupes.push_back("NT");
    tempgroupes.push_back("T");

    tabG["NT"] = new list<list<string>*>;
    tabG["T"] = new list<list<string>*>;

    for(list<list<string>*>::iterator iQ=_T.begin(); iQ!=_T.end(); iQ++)
        tabG["T"]->push_back(*iQ);

    for(list<list<string>*>::iterator iQ=_Q.begin(); iQ!=_Q.end(); iQ++){

        int temp = 0;

        for(list<list<string>*>::iterator iT=_T.begin(); iT!=_T.end(); iT++){

             if( ((*iT)->size() == (*iQ)->size()) && (equal(  (*iQ)->begin(), (*iQ)->end(), (*iT)->begin())  )){
                 temp = 1;
             }
        }

        if(temp == 0)
           tabG["NT"]->push_back(*iQ);
    }

    list<string>::iterator iG;
    QStringList liste;
    QString tempS;
    int cptG;

    // Tant que le nombre de groupe n'est pas egal a celui de la derniere iteration
    while (groupes.size() != tempgroupes.size()) {

        // Initialisation de groupes et reinitialisation de tempgroupes
        groupes = tempgroupes;
        tempgroupes.clear();

        cptG = 1;

        for(list<string>::iterator i = groupes.begin(); i != groupes.end(); i++){

            tempS.clear();

            tempS += "Group " + QString::number(cptG) + " : ";
            for(list<list<string>*>::iterator ii = tabG[*i]->begin(); ii != tabG[*i]->end(); ii++){

                if (ii != tabG[*i]->begin())
                    tempS += ", ";

                tempS += "{";

                for(list<string>::iterator iii = (*ii)->begin(); iii != (*ii)->end(); iii++){

                    if(iii != (*ii)->begin())
                        tempS += ", ";

                    tempS += QString::fromStdString(*iii);
                }

                tempS += "}";
            }

            liste << tempS;
            cptG++;
        }

        liste << "";


        // Pour chaque etat
        for(list<list<string>*>::iterator iQ=_Q.begin(); iQ!=_Q.end(); iQ++){

            // Reinitialisation de groupeString
            groupeString.clear();

            iG = groupes.begin();

            int temp;

            // Faire tant que nous ne trouvons pas dans quel groupe est cet etat
            temp = 1;
            do {

                for(list<list<string>*>::iterator iiG = tabG[*iG]->begin(); iiG != tabG[*iG]->end(); iiG++){

                    // Si les etats sont egaux
                    if (((*iiG)->size() == (*iQ)->size())&&(equal((*iiG)->begin(), (*iiG)->end(), (*iQ)->begin())))
                        temp = 0;
                }

                iG++;

            }while(temp == 1);

            iG--;

            // Insertion de ce groupe dans groupeString
            groupeString = groupeString + *iG;

            for (unsigned int cpt = 0; cpt != _A.size(); cpt++){

                int temp;
                iG = groupes.begin();

                temp = 1;
                 do{

                     list<list<string>*>::iterator iTab = _tab[*iQ][cpt].begin();

                     for(list<list<string>*>::iterator iiG = tabG[*iG]->begin(); iiG != tabG[*iG]->end(); iiG++){

                         if (((*iiG)->size() == (*iTab)->size())&&(equal((*iiG)->begin(), (*iiG)->end(), (*iTab)->begin()))) // Si les etats ne sont pas egaux
                             temp = 0;
                     }

                     iG++;

                 }while(temp == 1);

                 iG--;

                 // Insertion de ce groupe dans groupeString
                 groupeString = groupeString + *iG;
             }

             if(tabG[groupeString] == NULL){
                 tabG[groupeString] = new list<list<string>*>;
             }

             // Insertion de cet etat dans son groupe
             tabG[groupeString]->push_back(*iQ);

             tempgroupes.push_back(groupeString);

             tempgroupes.sort();
             tempgroupes.unique();
        }

        // Suppression des anciens groupes
        for (list<string>::iterator it=groupes.begin(); it != groupes.end(); it++)
            tabG[*it]->clear();
    }

    Interface::messageMinimiser(&liste);

    groupes = tempgroupes;
    tempgroupes.clear();

    if(groupes.size() == _Q.size())
        return true;

    list<list<string>*> Qmin, Tmin, Imin;

    list<string>::iterator iGG;
    list<list<string>*>::iterator iTabG;
    list<list<string>*>::iterator iTab;

    int temp;

    list<list<string>*>::iterator iI;
    list<list<string>*>::iterator iIm;

    iI = _I.begin();
    iG=groupes.begin();
    temp = 1;
    do {

        for(list<list<string>*>::iterator iiG = tabG[*iG]->begin(); iiG != tabG[*iG]->end(); iiG++){

            if (((*iiG)->size() == (*iI)->size())&&(equal((*iiG)->begin(), (*iiG)->end(), (*iI)->begin()))) // Si les etats ne sont pas egaux
                temp = 0;
        }

        iG++;

    }while(temp == 1);

    iG--;

    Imin.push_back(new list<string>);
    iIm =-- Imin.end();

    for(list<list<string>*>::iterator iTabGG = tabG[*iG]->begin(); iTabGG != tabG[*iG]->end(); iTabGG++)
        (*iIm)->insert(--(*iIm)->end(), (*iTabGG)->begin(), (*iTabGG)->end());

    deleteI();
    _I = Imin;

    list<list<string>*>::iterator iTmin;

    for(list<string>::iterator iG = groupes.begin(); iG != groupes.end(); iG++){

        if ((*iG).at(0) == 'T'){

            Tmin.push_back(new list<string>);
            iTmin =-- Tmin.end();

            for(list<list<string>*>::iterator iTabG = tabG[*iG]->begin(); iTabG != tabG[*iG]->end(); iTabG++){

                (*iTmin)->insert(--(*iTmin)->end(), (*iTabG)->begin(), (*iTabG)->end());
            }
        }
    }

    deleteT();
    _T = Tmin;

    list<list<string>*>::iterator iQmin;
    list<list<string>*>::iterator iTabmin;

    for(list<string>::iterator iG=groupes.begin(); iG != groupes.end(); iG++){

        // Creation des états
        Qmin.push_back(new list<string>);
        iQmin = --Qmin.end();

        for(iTabG = tabG[*iG]->begin(); iTabG != tabG[*iG]->end(); iTabG++){

            (*iQmin)->insert(--(*iQmin)->end(), (*iTabG)->begin(), (*iTabG)->end());
        }

        // Creation des transitions associes a chaque etat
        _tab[*(--Qmin.end())] = new list<list<string>*>[_A.size()];

        // Pour chaque transition
        for(unsigned int cpt = 0; cpt < _A.size(); cpt++){

            // Pour un etat dans le groupe
            iTabG = tabG[*iG]->begin();

            // Pour une transition de de cet etat dans le groupe
            iTab = _tab[*iTabG][cpt].begin();

            int temp;
            iGG = groupes.begin();

            temp = 1;

            // Faire tant que nous ne trouvons pas dans quel groupe est cet etat
            do {

                for(list<list<string>*>::iterator iiG = tabG[*iGG]->begin(); iiG != tabG[*iGG]->end(); iiG++){

                    if (((*iiG)->size() == (*iTab)->size())&&(equal((*iiG)->begin(), (*iiG)->end(), (*iTab)->begin())))
                        temp = 0;
                    }

                    iGG++;

            }while(temp == 1);

            iGG--;

            _tab[*(--Qmin.end())][cpt].push_back(new list<string>);

            iTabmin =-- _tab[*(--Qmin.end())][cpt].end();

            for(list<list<string>*>::iterator iTabGG = tabG[*iGG]->begin(); iTabGG != tabG[*iGG]->end(); iTabGG++)
                (*iTabmin)->insert(--(*iTabmin)->end(), (*iTabGG)->begin(), (*iTabGG)->end());
        }
    }

    deleteQ();
    _Q = Qmin;

    return false;
}
Ejemplo n.º 5
0
/* RubikSq.c | Stephen Krewson | CPSC 223b. USAGE: RubikSq [-r] [HEIGHT WIDTH]
MAXLENGTH INITIAL GOAL. RubikSq solves a Rubik's square puzzle using a trie data
structure and breadth-first search to find the fewest number of moves necessary
to transform INITIAL into GOAL.
*/
int main (int argc, char *argv[])
{									// 1. PARSING COMMAND-LINE ARGS
	bool rFlag = false;
	int maxLength = 0; 
	int pos = 0;					// pos is counter for moving through argv[]
	int height = 3, width = 3;		// default values
	char *initial = NULL;
	char *goal = NULL;
	
	if (argc % 2 != 0)				// "-r" specified				
	{
		if (argc > 3)
		{
			if (strcmp(argv[1], "-r") != 0)
				KILL("ERROR: '-r' flag improperly specified.");
			else
				rFlag = true;
		}
		else
		 KILL("ERROR: Insufficient number of arguments.");
	}
	if (argc == 6 || argc == 7)		// HEIGHT and WIDTH specified
	{								// Indexes depend on -r flag
		pos = (rFlag == true) ? 2 : 1;
		
		initial = strdup(argv[pos+3]);	// use malloc bc we will call free()
		goal = strdup(argv[pos+4]);		// on all the dict nodes
	
		if (!(height = atoi(argv[pos]))  || 
			!(width = atoi(argv[pos+1])) ||
			(height < 2 || height > 5)	 ||
			(width < 2 || width > 5))
			KILL("ERROR: Invalid HEIGHT and WIDTH values.");

		char *endPtr;	
		maxLength = (int) strtol(argv[pos+2], &endPtr, 10);
		
		if (endPtr < argv[pos+2] + strlen(argv[pos+2]))
			KILL("ERROR: MAXLENGTH contains nun-numeric characters.");
		else if (maxLength < 0)
			KILL ("ERROR: MAXLENGTH is negative.");

		if (!checkTray(height, width, initial, goal))
			KILL("ERROR: Invalid tray sequences.");
	
	}								// HEIGHT, WIDTH NOT specified
	else if (argc == 4 || argc == 5)
	{
		pos = (rFlag == true) ? 2 : 1;
		
		initial = strdup(argv[pos+1]);
		goal = strdup(argv[pos+2]);

		char *endPtr;	
		maxLength = (int) strtol(argv[pos], &endPtr, 10);
		
		if (endPtr < argv[pos] + strlen(argv[pos]))
			KILL("ERROR: MAXLENGTH contains nun-numeric characters.");
		else if (maxLength < 0)
			KILL ("ERROR: MAXLENGTH is negative.");

		if (!checkTray(height, width, initial, goal))
			KILL("ERROR: Invalid tray sequences.");
	}
	else
	{
		KILL("ERROR: Invalid number of  arguments.");
	}
	Trie dict;						// Initialize trie data structure
	createT(&dict);
	Stack stk1, stk2;				// Initialize the "queue"
	createS(&stk1);
	createS(&stk2);
		
	char *currentPos = NULL;		// pointer for position being processed
	char *prevPos = NULL;	     	// pointer to "from" attr in the dict
	long lengthPos = 0;				// address to hold "length" attr in the dict
	int permutations = 0;	    	// hold # of permutations getPerms returns

	insertT(&dict, goal, NULL, 0);				// Add GOAL to dictionary
	enqueue(&stk1, &stk2, goal);				// push GOAL onto the queue
	
	while (!isEmptyQ(&stk1, &stk2))				// While the queue is not empty
	{
		dequeue(&stk1, &stk2, &currentPos);		// Remove P from head of queue
		searchT(&dict, currentPos, &prevPos, &lengthPos);
												// lengPos holds length of P
		if (lengthPos + 2 < maxLength)			// +2 because currentPos is 1
		{							// more than the previous distance and each
									// permutation is another distance of 1
			char **perms;			// array of pointers to permutations of P
			perms = getPerms(currentPos, height, width, rFlag, &permutations);
			
			for (int j = 0; j < permutations; j++)	// for each position . . .
			{
				if (strcmp(initial, perms[j]) == 0)	// if P' is the INITIAL
				{									// add it so we can trace
					insertT(&dict, perms[j], currentPos, lengthPos+1);

					printf("%s\n", initial);	// print INITIAL
					printf("%s\n", currentPos);	// reached INITIAL from...
					
					char *holder2;				// follow path of search
					holder2 = currentPos;		// start at currentPos

					while (strcmp(holder2, goal) != 0)
					{
						if(!searchT(&dict, currentPos, &holder2, &lengthPos)) 
						{
							KILL("ERROR: searchT() failed.");
						}
						printf("%s\n", holder2);
						currentPos = holder2;
					}

					destroyS(&stk1);			// get rid of the queue
					destroyS(&stk2);
					deleteT(dict, dict);
					free(dict);					// Remember root node
					
					free(perms[j]);
					free(perms);				// free the pointer array

					exit(0);					// Successful exit!
				}											
				else if (!searchT(&dict, perms[j], &prevPos, &lengthPos))
				{								// Put p' in dict, on queue
					if (!insertT(&dict, perms[j], currentPos, lengthPos+1)) 
					{
						KILL("ERROR: insertT() failed.");
					}
					enqueue(&stk1, &stk2, perms[j]);
				}
				else				// else P' is already in the dictionary
				{
					free(perms[j]);	// don't need it anymore!
				}
			}
			free(perms);			// Free the pointer array
		}
	}
	
	destroyS(&stk1);				// Cleanup in case of no valid sequence
	destroyS(&stk2);
	deleteT(dict, dict);
	free(dict);						// Remember to clean root node of dict

	return EXIT_SUCCESS;
}