Backtracking kann nicht mit Kreuzungen umgehen



  • Das hier ist keine Hausaufgabe, sondern ein Problem aus der Mittagspause. 🙄 Folgende Aufgabe war gestellt: 4 Leute sollen sich ein Land teilen. Jeder soll auf seinem Stück Land ein Haus und ein Brunnen haben. Außerdem sollen die Länder jeweils kongruent sein, also die gleiche Form haben. Die Brunnen und Häuser sind folgendermaßen verteilt:

    Brun = Brunnen
    +------+------+------+------+------+------+
    | Leer | Leer | Haus | Haus | Leer | Leer |
    +------+------+------+------+------+------+
    | Leer | Leer | Leer | Leer | Brun | Leer |
    +------+------+------+------+------+------+
    | Leer | Leer | Haus | Leer | Brun | Leer |
    +------+------+------+------+------+------+
    | Leer | Leer | Leer | Leer | Leer | Leer |
    +------+------+------+------+------+------+
    | Leer | Leer | Leer | Leer | Leer | Leer |
    +------+------+------+------+------+------+
    | Leer | Brun | Leer | Leer | Brun | Haus |
    +------+------+------+------+------+------+
    

    Jetzt habe ich ein Programm geschrieben, was das Problem löst und das Land aufteilt. Das Problem ist jedoch, daß es nicht mit Kreuzungen umgehen kann, sondern eine unverzweigte Lösung sucht. Die Lösung des Problems hat aber leider eine Kreuzung in der Aufteilung. So muß ich in meinem Lösungsarray die Kreuzung manuell eintragen, damit er die Lösung findet. Ich hab im Moment keine Ahnung, wie ich das Problem ohne das manuelle Eintragen der Kreuzung lösen kann.

    Wäre also nett, wenn ihr mir ein Hinweis gebt, wie ich Kreuzungen in meinen Algorithmus kriege. Alternativ könnt ihr natürlich auch komplett andere Lösungsansätze posten.

    Hier das Programm: (die Kreuzungen sind jeweils eingetragen in solution[1][1], solution[1][4], solution[4][1] und solution[4][4]. Es soll die Lösung finden auch wenn in diesen Zellen 0 eingetragen ist.)

    #include <stdio.h>
    #include <conio.h>
    
    #define LEER        '0'
    #define HAUS        'H'
    #define BRUNNEN     'B'
    
    static char spielfeld[6][6] = {
        {'0', '0', 'H', 'H', '0', '0'},
        {'0', '0', '0', '0', 'B', '0'},
        {'0', '0', 'H', '0', 'B', '0'},
        {'0', '0', '0', '0', '0', '0'},
        {'0', '0', '0', '0', '0', '0'},
        {'0', 'B', '0', '0', 'B', 'H'}
    };
    
    static int solution[6][6] = {           // Solution array
        {0, 0, 0, 0, 0, 0},                 // records the steps taken
        {0, 9, 0, 0,-1, 0},                 // and the order of the steps
        {0, 0, 1,-1, 0, 0},                 // by numbers from 1 - 9
        {0, 0,-3,-2, 0, 0},                 // 1 marks the starting sport
        {0,-3, 0, 0,-2, 0},                 // -1..-3 marks the land of the
        {0, 0, 0, 0, 0, 0}                  // "others"
    };
    
    static int stepX[4] = { 0, 1, 0,-1};         // First search up, then right,
    static int stepY[4] = {-1, 0, 1, 0};         // then down and then left
    
    void PrintSolution(void)
    {
        int i, j;
        for(i = 0; i < 6; i++)
        {
            for(j = 0; j < 6; j++)
            {
                printf(" %2d", solution[i][j]);
            }
            printf("\n");
        }
    }
    
    int isSolution(int who)
    {
        int i, j;
        int hasBrunnen = 0, hasHaus = 0;
    
        if(who > 0)
        {
            for(i = 0; i < 6; i++)
                for(j = 0; j < 6; j++)
                    if(spielfeld[i][j] == BRUNNEN && solution[i][j] > 0)
                        return 1;
        }
        else
        {
            for(i = 0; i < 6; i++)
                for(j = 0; j < 6; j++)
                {
                    if(spielfeld[i][j] == BRUNNEN && solution[i][j] == who)
                        hasBrunnen = 1;
                    else if(spielfeld[i][j] == HAUS && solution[i][j] == who)
                        hasHaus = 1;
                    if(hasBrunnen && hasHaus)
                        return 1;
                }
        }
        return 0;
    }
    
    int FindSolution(int index, int iX, int iY)
    {
        int step = -1;
        int newX = 0, newY = 0;
        int isOk = 1;
    
        while(step < 4)     // There are still directions left
        {
            step++;
            newX = iX + stepX[step];        // New x direction
            newY = iY + stepY[step];        // New y direction
    
            isOk = 1;
            if(newX < 0 || newX > 5) isOk = 0;              // Out of bounds
            if(newY < 0 || newY > 5) isOk = 0;              // Out of bounds
            if(index > 9) isOk = 0;                         // Max is 9 steps
            if(spielfeld[newY][newX] == HAUS) isOk = 0;     // Blocked?
    
            if(solution[newY][newX] != 0) isOk = 0;         // Blocked?
            if(solution[newX][5-newY] != 0) isOk = 0;       // Blocked?
            if(solution[5-newY][5-newX] != 0) isOk = 0;     // Blocked?
            if(solution[5-newX][newY] != 0) isOk = 0;       // Blocked?
    
            if(isOk)
            {
                solution[newY][newX] = index;
                solution[newX][5-newY] = -1;        // Rotate 90° and set occupied
                solution[5-newY][5-newX] = -2;      // Rotate 180° and set occupied
                solution[5-newX][newY] = -3;        // Rotate 270° and set occupied
    
                PrintSolution();        // For debugging only
                printf("\n");           // For debugging only
    
                if(!isSolution(index) || !isSolution(-1) || !isSolution(-2) || !isSolution(-3))
                {
                    if(FindSolution(index + 1, newX, newY))
                    {
                        return 1;       // Found a solution
                    }
                    else
                    {
                        solution[newY][newX] = 0;       // Take back move
                        solution[newX][5-newY] = 0;     // Rotate 90° and set unoccupied
                        solution[5-newY][5-newX] = 0;   // Rotate 180° and set unoccupied
                        solution[5-newX][newY] = 0;     // Rotate 270° and set unoccupied
                    }
                }
                else
                {
                    return 1;           // Found a solution
                }
            }
        }
        return 0;
    }
    
    int main(void)
    {
        // Start at the house at spielfeld[2][2]. The starting spot is
        // already set, so begin with index 2.
        FindSolution(2, 2, 2);
        PrintSolution();
        getch();
        return 0;
    }
    

    Danke!



  • Ich befürchte mal, daß dir das keiner wird lösen können. 😞



  • ^^frag' doch mal im mathe-forum.
    🙂



  • Javaner schrieb:

    Ich befürchte mal, daß dir das keiner wird lösen können. 😞

    du meinst wohl eher, es wird keiner lust haben sich mit son sch... die zeit um die ohren zu schlagen. 😃



  • LOL!!

    Naja, wenn du es so deutlich schreibst! 🕶



  • Passt schon. Keine Hilfe mehr nötig ...


Anmelden zum Antworten