Algorithmus während Laufzeit stoppen



  • Hallo zusammen,

    folgendes Problem:

    Ich bin momentan dabei das nDamen Problem zu lösen.

    Jetzt häng ich daran, den ALgorithmus während der Laufzeit zu stoppen.

    Hier mein Code:

    int board[20];
    
    void printSolution(int iChessBoardLength)
    {
    	int i, j, k , c;
    	int x =25, y=6;
    
    	nQueensStr.iCountOfSolutions++;
    	_clrscr();
    	printMenu();
    	printStatus();
    	if (kbhit())
    	{
    		int iChar = getch();
    		if (iChar == 's')
    		{
    			return EXIT_FAILURE;
    		}
    	}
    
    		if (nQueensStr.AppMode == 0)
    		{
    			nQueensStr.AppMode = 0;
    
    				for (i = 1; i <= iChessBoardLength; ++i)
    				{
    					_gotoxy(x, y);
    					y++;
    					printf("\n");
    
    					for (j = 1; j <= iChessBoardLength; ++j) 
    					{
    						if (board[i] == j)
    							printf("[Q]"); 
    						else
    							printf("[]");
    					}
    				}
    			getch();
    		}
    		else
    		{
    			nQueensStr.AppMode = 1;
    			_gotoxy(x, y);
    			y++;
    			printf("Es wurden %d Loesungen gefunden", nQueensStr.iCountOfSolutions);
    		}
    
    	printf("\n\n");
    }
    
    void queen(int row, int iChessBoardLength)
    {
    	int c;
    	int column;
    
    	for (column = 1; column <= iChessBoardLength; ++column)
    	{
    		if (place(row, column))
    		{
    			board[row] = column; 
    			if (row == iChessBoardLength) 
    				printSolution(iChessBoardLength); 
    			else 
    				queen(row + 1, iChessBoardLength);
    		}
    
    	}
    }
    
    int place(int row, int column)
    {
    	int i;
    
    	for (i = 1; i <= row - 1; ++i)
    	{
    
    		if (board[i] == column)
    			return 0;
    		else
    			if (abs(board[i] - column) == abs(i - row))
    				return 0;
    	}
    
    	return 1; 
    }
    

    Meine Idee war:

    if(_khbit())
    
    int iChar = _getch();
    
    if(iChar == 's')
     {
      break;
     }
    }
    

    Aber egal wo ich den Code einfüge, es läuft nicht.

    pls help.

    Danke euch!



  • was möchtest du denn erreichen? wenn du einfach getchar() aufrufst, wird der code an der stelle angehalten. falls es kein getchar() gibt, geht evtl. auch while(!kbhit()).

    kbhit() liefert jedenfalls, wenn ich das richtig in erinnerung habe, immer false bzw. 0, wenn nicht vorher schon eine taste gedrückt wurde, und computerprogramme laufen verdammt schnell ab, sodass du wohl kaum rechtzeitig eine taste drücken kannst, wenn du nicht while(!kbhit()) verwendest.



  • Danke schon mal für deine Antwort.

    Hab mich leider wirklich zu knapp ausgedrückt.

    Der Algorithmus wird mit "r" gestartet.

    Beim drücken von "r" wird queen(int, int) aufgerufen.

    Abhängig von nQueensStr.AppMode wird ein durchlaufender Modus oder ein step by step Modus gestartet.

    Den Code den ich gepostet habe ist nur der Algorithmus, welchen ich, nachdem er gestartet wurde, mit einer bestimmten Taste (z.B. 's') nicht stoppen, sondern abbrechen möchte.

    Hier den Code nochmal ordentlich:

    #include<stdio.h>
    #include<conio.h>
    #include<stdlib.h>
    #include<math.h>
    #include<utilities.h>
    #include<nQueens.h>
    
    int board[20];
    
    // Prints out the solution
    void printSolution(int iChessBoardLength)
    {
    	int i, j, k , c;
    	int x =25, y=6;
    
    	nQueensStr.iCountOfSolutions++;
    	_clrscr();
    	printMenu();
    	printStatus();
    
    		if (nQueensStr.AppMode == 0)
    		{
    			nQueensStr.AppMode = 0;
    				for (i = 1; i <= iChessBoardLength; ++i)
    				{
    					_gotoxy(x, y);
    					y++;
    					printf("\n");
    
    					for (j = 1; j <= iChessBoardLength; ++j) 
    					{
    						if (board[i] == j)
    							printf("[Q]"); 
    						else
    							printf("[]"); 
    					}
    				}
    			_getch();
    		}
    		else
    		{
    			nQueensStr.AppMode = 1;
    			_gotoxy(x, y);
    			y++;
    			printf("Es wurden %d Loesungen gefunden", nQueensStr.iCountOfSolutions);
    		}
    
    	printf("\n\n");
    }
    
    // Checks for positioning of queen
    void queen(int row, int iChessBoardLength)
    {
    	int c;
    	int column;
    
    	for (column = 1; column <= iChessBoardLength; ++column)
    	{
    		if (place(row, column))
    		{
    			board[row] = column; 
    			if (row == iChessBoardLength) 
    
    				printSolution(iChessBoardLength); 
    			else 
    				queen(row + 1, iChessBoardLength);
    		}
    
    	}
    }
    
    // Checks if position is valid, returns 1 if true
    int place(int row, int column)
    {
    	int i;
    
    			for (i = 1; i <= row - 1; ++i)
    			{
    				// Checking columns and digonals for validility
    				if (board[i] == column)
    					return 0;
    				else
    					if (abs(board[i] - column) == abs(i - row))
    						return 0;
    		}
    	return 1;
    }
    


  • Was passiert, wenn du den Rechner aus dem Fenster schmeißt, während der Algorithmus noch läuft?



  • Dann hätt ich mein Ziel wohl erreicht.



  • Im Augenblick ist die Tastenabfrage am Anfang von printSolution.

    Wie oft wird das ausgeführt?

    Welcher Teil der Berechnung wird am häufigsten durchlaufen, denn da solte die Abfrage sein.

    Bedenke auch, dass break nur die aktuelle Schleife verlässt und ein return nur zur rufenden Funktion zurück kehrt.
    Je nach Anforderung musst du also noch mehr überprüfen oder exit() bemühen.

    Mit setjmp und longjmp könnte es auch klappen. Habe ich aber noch nicht eingesetzt.



  • wie wäre es sonst damit, einen thread zu starten, der die berechnung durchführt und diesen dann evtl. zu terminieren?



  • DirkB schrieb:

    Im Augenblick ist die Tastenabfrage am Anfang von printSolution.

    Wie oft wird das ausgeführt?

    Welcher Teil der Berechnung wird am häufigsten durchlaufen, denn da solte die Abfrage sein.

    Bedenke auch, dass break nur die aktuelle Schleife verlässt und ein return nur zur rufenden Funktion zurück kehrt.
    Je nach Anforderung musst du also noch mehr überprüfen oder exit() bemühen.

    Mit setjmp und longjmp könnte es auch klappen. Habe ich aber noch nicht eingesetzt.

    exit(); war ein guter Ansatz, danke! Funktioniert jetzt spitze!

    Hier mein aktueller Code:

    /**
     * @file solution.c
     * @brief contains algorithm for nQueens problem
     * @author breezy1
     * @date 09.01.2017
     */
    
    #include<stdio.h>
    #include<conio.h>
    #include<stdlib.h>
    #include<math.h>
    #include<time.h>
    #include<utilities.h>
    #include<nQueensWiSe2014.h>
    
    int board[20];
    
    /**
     * @brief function to print out the board configuration after a solution was found
     * @param int
     * @return 0
     * @author breezy1
     * @date 09.01.2017
     */
    
    void printSolution(int iChessBoardLength)
    {
    	int i, j, c;
    	int x =25, y=6;
    
    	// If-else which checks if stepmode is chosen
    		if (nQueensStr.AppMode == 0)
    		{
    			_clrscr();
    			printMenu();
    			printStatus();
    			nQueensStr.AppMode = 0;
    
    				// For-loop which prints the board until maxlength is reached
    				for (i = 1; i <= iChessBoardLength; ++i)
    				{
    					_gotoxy(x, y);
    					y++;
    					printf("\n");
    
    					// For-loop which prints out the solved board configuration
    					for (j = 1; j <= iChessBoardLength; ++j) 
    					{
    						if (board[i] == j)
    							printf("[Q]"); 
    						else
    							printf("[]"); 
    					}
    
    				}
    				// waits for userinput everytime a solution was successfully printed
    				c = _getch();
    
    				// checks if pressed key is a 's' and handles it accordingly
    				if (c == 's')
    				{
    					handleInputStep();
    				}
    		}
    		else // else part which is triggered if continious mode is chosen
    		{
    			printStatus();
    		}
    	printf("\n\n");
    
    	return 0;
    }
    
    /**
     * @brief initiates the algorithm, calls functions to check validility of pos and for printing out the solution
     * @param int row, int iChessBoardLength
     * @return 0
     * @author breezy1
     * @date 09.01.2017
     */
    
    void queen(int row, int iChessBoardLength)
    {
    	int c;
    	int column;
    
    	for (column = 1; column <= iChessBoardLength; ++column)
    	{
    		if (isPositionValid(row, column))
    		{
    
    			if (kbhit())
    			{
    				char c = getch();
    				if (c == 's')
    				{
    					_clrscr();
    					exit(handleInputCont());
    				}
    			}
    			board[row] = column; //no conflicts so place queen
    			if (row == iChessBoardLength) //dead end
    			{
    				nQueensStr.iCountOfSolutions++;
    				printSolution(iChessBoardLength); //printing the board configuration
    			}
    			else //try queen with next position
    			{
    				queen(row + 1, iChessBoardLength);
    			}
    		}	
    		AppTimeStr.lFinishTime = clock();
    		(double)AppTimeStr.dRuntime = AppTimeStr.lFinishTime - AppTimeStr.lStartTime;
    		_gotoxy(11, 22);
    		printf("%.1lf", AppTimeStr.dRuntime);
    	}
    	return 0;
    }
    
    /**
     * @brief Checks if the given position is valid and returns 1 if so
     * @param int row, int column
     * @return 1 if true, 0 if not
     * @author breezy1
     * @date 09.01.2017
     */
    
    int isPositionValid(int row, int column)
    {
    	int i;
    
    		for (i = 1; i <= row - 1; ++i)
    		{
    			// Checking columns and digonals for validility
    			if (board[i] == column)
    				return 0;
    			else
    				if (abs(board[i] - column) == abs(i - row))
    					return 0;
    		}
    
    	return 1;
    }
    

    Habe noch ne Frage, weicht aber bisschen von dieser hier ab, ich mach deshalb einen neues topic auf.

    Danke euch für die Hilfe!



  • Ich hab leider meinen Namen in den Doxytags gelassen, wär mir recht wenn die jemand rausnehmen kann. 😮


  • Administrator

    breezy1 schrieb:

    Ich hab leider meinen Namen in den Doxytags gelassen, wär mir recht wenn die jemand rausnehmen kann. 😮

    Done 🙂



  • Dravere schrieb:

    breezy1 schrieb:

    Ich hab leider meinen Namen in den Doxytags gelassen, wär mir recht wenn die jemand rausnehmen kann. 😮

    Done 🙂

    Danke dir! 🙂


Log in to reply