Плохая производительность при поиске nqueens min-confli c - PullRequest
2 голосов
/ 20 апреля 2020

Я выполняю поиск минимальных конфликтов nqueens, как упомянуто

Norvig S., & Peter, JR and. (2014). Искусственный интеллект - современный подход. В Пирсоне (том 58, выпуск 12). enter image description here

Авторы упоминают, что один heuristi c один очень эффективен:

enter image description here

Пока когда я его реализую, я не могу решить более 5000 меньше, чем за минуту. Несмотря на то, что авторы используют скорость в миллион и более за 50 итераций, моя реализация часто превышает 1000 итераций для 5000 итераций. Другой вопрос упоминает аналогичный результат.

Есть идеи, что я делаю не так? Это алгоритми c или я использую все oop, где я не должен? Кстати,

update() - основной метод.





    list<unsigned> rowsInConflict(const unsigned currentState[]) {
        list<unsigned> rowsInConflict; //TODO change to map

        for (unsigned row = 0; row < boardSize; row++) {
            for (unsigned otherRow = 0; otherRow < boardSize; otherRow++) {
                if (isConflict(row, currentState[row], otherRow, currentState[otherRow])) {
                    rowsInConflict.push_front(row);
                    debug("row in conflict " + to_string(row));
                    rowsInConflict.push_front(otherRow);
                    //return rowsInConflict;
                }
            }
        }

        return rowsInConflict;
    }

    bool update(unsigned currentState[]) {
                unsigned randomRow, column;

        list<unsigned> conflictRows = rowsInConflict(currentState);
        if (conflictRows.empty()) {
            return true;
        }

        list<unsigned>::iterator it = conflictRows.begin();
        std::advance(it, rand() % conflictRows.size());
        randomRow = (unsigned) *it;

        column = getMinConflictColumn(currentState, randomRow);
        placeQueen(currentState, randomRow, column);


        return false;

    }



    void solve_nqueen(unsigned size, bool isVerbose) {

        unsigned rowSpace[size];






        while (!update(rowSpace)) {

            if (iterations >= 1000) {
                cout << "Random restart." << endl;
                intialize(rowSpace);
                iterations = 0;
            }
            iterations++;
        }
        printBoard(rowSpace);




    }

};


1 Ответ

1 голос
/ 21 апреля 2020

Как я уже говорил в комментариях, если вы пытаетесь свести к минимуму количество перестановок, важно начать с хорошей начальной конфигурации. В моей реализации nQueens у меня есть 3 различных метода для генерации начальной строки для каждой королевы:

  1. Для каждой королевы выберите случайную строку
  2. Создайте перестановку чисел в 1 ..n, соответствующий номеру строки каждой королевы
  3. Поместите каждую королеву в строку с наименьшим количеством конфликтов, разрывая связи случайным образом

Все эти подходы ограничивают каждую королеву одним столбцом. Третий метод повторно использует функцию поиска новой строки назначения при выполнении перестановок.

Вот некоторые примеры прогонов на 5000 королев для каждой из начальных конфигураций:

# Board initialized by random rows
Number of queens = 5000, 100 reps
Average time per board: 1.57167
Average number of swaps: 3160.87

# Board initialized by shuffle
Number of queens = 5000, 100 reps
Average time per board: 1.17037
Average number of swaps: 2445.96

# Board initialized by min-conflict
Number of queens = 5000, 100 reps
Average time per board: 1.23296
Average number of swaps: 49.97

Как вы можете Видите, метод 3 дает нам целевое количество свопов, в то время как другие требуют гораздо больше. На самом деле, количество перестановок, необходимых для этого метода, соответствует примерно 1000 королевам и более.

Интересно, что общее время, затрачиваемое каждым методом, не меняется почти так же, как количество обменов. (Все время включает в себя как настройку начальной доски, так и перемещение королев.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...