Оптимизация решения n-queens в php

У меня есть рудиментарное решение грубой силы, которое находит одно решение проблемы n-queens, написанное на php. Вот демо. При n=16 сервер начинает выдавать ошибку нехватки памяти.

Исходный код на gitHub.

<?php

function isAttacked($board, $x, $y){
    foreach($board as $key => $value){
        if($value != -1){
            if ($key==$x){
                return true;
            }else if($value==$y){
                return true;
            }else if(($key-$x) / ($value-$y) == 1){
                return true;
            }else if(($key-$x) / ($value-$y) == -1){
                return true;
            }
        }
    }
    return false;
}

function allQueensPlaced($board){
    $done = true;
    for($i=0;$i<sizeof($board);$i++){
        if($board[$i]==-1){
            $done = false;
        }
    }
    return $done;
}

function placeQueens($board, $index){

    if($index==sizeof($board) && allQueensPlaced($board)){  
        return $board;
    }

    $nextPosition = $board[$index] + 1;
    $board[$index] = -1;

    for($i=$nextPosition; $i<sizeof($board);$i++){
        if(!isAttacked($board, $index, $i)){
            $board[$index]=$i;
            return placeQueens($board, $index+1);
        }
    }
    $board[$index] = -1;
    return placeQueens($board, $index-1);
}
?>
<html>
    <head>
        <link rel="stylesheet" type="text/css" href="../css/reset.css">
        <link rel="stylesheet" type="text/css" href="../css/style.css">
        <style>
            div{
                float:left;

            }
            div.black{
                background-color:#B58862;
                width:40px;
                height:40px;
                text-align:center;

            }
            div.white{
                background-color:#F0D9B5;
                width:40px;
                height:40px;
                text-align:center;

            }
        </style>
    </head>
    <body>
        <h1>Recursion: Brute Force N-Queens</h1>
        <form action="nqueens.php" method="GET">
            <p>Number of queens: <input name="queens" type="text" /><input name="submit" type="submit" value="Go" /></p>
        </form>
        <div style='margin:50px;border:1px solid black;'>
<?php

if(isset($_GET['queens']) && is_numeric($_GET['queens'])){
    $queens = $_GET['queens'];
}else{
    $queens=8;
}

if($queens > 25 || $queens < 4){
    $queens = 8;
}

$placements = array($queens);

for($i=0;$i<$queens;$i++){
    $placements[$i]=-1;
}

$placements = placeQueens($placements, 0);

for ($i=0;$i<$queens;$i++){
    echo "<div style='clear:left;'>\n";
    for($j=0;$j<$queens;$j++){
        if(($i+$j)%2==0){
            echo "<div class='black'>";
        }else{
            echo "<div class='white'>";
        }
        if ($placements[$i]==$j){
            echo "<img height='40' src='../images/queen.png'/>";
        }else{
            echo "&nbsp;";
        }
        echo "</div>\n";
    }
    echo"</div>\n";
}

?>
        </div>
    </body>
</html>

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


person Eric Jankowski    schedule 02.12.2012    source источник
comment
может быть, ваше условие выхода из рекурсии неверно: if($index==sizeof($board) && allQueensPlaced($board))? для некоторого N может не быть решения, поэтому вы бесконечно повторяетесь   -  person thumbmunkeys    schedule 02.12.2012
comment
Возможно, мое условие выхода неверно, но я так не думаю. N-ферзей — довольно популярная задача в CS. Я почти уверен, что существует по крайней мере одно решение для всех n при n ›= 4.   -  person Eric Jankowski    schedule 02.12.2012


Ответы (1)


Лучше избегать использования грубой силы. Если вы сможете заставить его работать, время решения все равно будет очень большим по сравнению с другими методами. По крайней мере, если вам нужно только ОДНО решение.

Попробуйте посмотреть на эту страницу: http://yuval.bar-or.org/index.php?item=9

С уважением,

Пер

person Per    schedule 05.06.2013