Running Racket Code Parallel for N-Queens Problem

I use the following simple code to solve the n-queens problem :

#lang racket

; following returns true if queens are on diagonals:  
(define (check-diagonals bd) 
  (for/or ((r1 (length bd)))
    (for/or ((r2 (range (add1 r1) (length bd))))
      (= (abs (- r1 r2))
         (abs(- (list-ref bd r1)
                (list-ref bd r2)))))))

; set board size: 
(define N 8)
; start searching: 
(for ((brd (in-permutations (range N))))
  (when (not (check-diagonals brd))
    (displayln brd)))

It works fine, but takes longer for large N values. It uses a function in-permutationsto get a stream of permutations. I also see that it uses only 25% of the processor power (1 of 4 cores is used). How can I change this code so that it uses parallel testing of permutations from a flow with permutations and uses all 4 processor cores? Thank you for your help.

Edit: The function has been changed check-diagonals, as suggested in the comments. Older code:

(define (check-diagonals bd) 
  (define res #f)
  (for ((r1 (length bd))
        #:break res)
    (for ((r2 (range (add1 r1) (length bd)))
          #:break res)
      (when (= (abs (- r1 r2))
               (abs(- (list-ref bd r1)
                      (list-ref bd r2))))
        (set! res #t))))
  res)
+8
1

, -, . , :

  • for/or #:break.
  • for*/or , for/or .
  • in-range, , for .
  • , Racketeers ( , , ).

:

#lang racket

; following returns true if queens are on diagonals:  
(define (check-diagonals bd) 
  (for*/or ([r1 (in-range (length bd))]
            [r2 (in-range (add1 r1) (length bd))])
    (= (abs (- r1 r2))
       (abs (- (list-ref bd r1)
               (list-ref bd r2))))))

; set board size: 
(define N 8)
; start searching: 
(for ([brd (in-permutations (range N))])
  (unless (check-diagonals brd)
    (displayln brd)))

. : . , , . , , , .

, , , , . , ( - ) - , . Rackets futures, parallelism. - , Rackets ( , ), , . , Racket Future Visualizer, .

, N = 11 .

$ time racket n-queens.rkt
[program output elided]
       14.44 real        13.92 user         0.32 sys

.

, for for/asnyc, . , :

(for/async ([brd (in-permutations (range N))])
  (unless (check-diagonals brd)
    (displayln brd)))

; , . N = 9 ~ 6.5 ; N = 10, ~ 55.

, , . ( N = 7) , displayln , - . , , , , :

(define results-futures
  (for/list ([brd (in-permutations (range N))])
    (future (λ () (cons (check-diagonals brd) brd)))))

(for ([result-future (in-list results-futures)])
  (let ([result (touch result-future)])
    (unless (car result)
      (displayln (cdr result)))))

for/async, , . , N = 9, ~ 4,58 , N = 10 ~ 44.

( , N = 7), , ( jit_on_demand ). , , , , , !

, , , , .

, , , , , , . , (, N = 10, ) , . , , , , - , in-slice:

(define results-futures
  (for/list ([brds (in-slice 10000 (in-permutations (range N)))])
    (future
     (λ ()
       (for/list ([brd (in-list brds)])
         (cons (check-diagonals brd) brd))))))

(for* ([results-future (in-list results-futures)]
       [result (in-list (touch results-future))])
  (unless (car result)
    (displayln (cdr result))))

, , . ~ 3,9 N = 10, 10 . , , , , 1,4 . N 11 , ~ 44 , , in-slice, 100 000, ~ 55 .

, N = 11 1 000 000, , , , parallelism, :

, , , , , , , .

, , , . , fixnum, - , , parallelism. , , , , , , , , .

, , , . .


, , Haskell, Haskell . Haskell, , Racket.

, , :

import Data.List (permutations)
import Data.Maybe (catMaybes)

checkDiagonals :: [Int] -> Bool
checkDiagonals bd =
  or $ flip map [0 .. length bd - 1] $ \r1 ->
    or $ flip map [r1 + 1 .. length bd - 1] $ \r2 ->
      abs (r1 - r2) == abs ((bd !! r1) - (bd !! r2))

n :: Int
n = 11

main :: IO ()
main =
  let results = flip map (permutations [0 .. n-1]) $ \brd ->
        if checkDiagonals brd then Nothing else Just brd
  in mapM_ print (catMaybes results)

parallelism Control.Parallel.Strategies. , :

import Control.Parallel.Strategies
import Data.List.Split (chunksOf)

main :: IO ()
main =
  let results =
        concat . withStrategy (parBuffer 10 rdeepseq) . chunksOf 100 $
        flip map (permutations [0 .. n-1]) $ \brd ->
          if checkDiagonals brd then Nothing else Just brd
  in mapM_ print (catMaybes results)

, , 30-40% .

, , Haskells , Rackets, . , , , 4 (8 ), 50% . .

, :

parallelism . - CS parallelism . , , " parallelism . , 20 , ( CE, EE, CS, Bio, Econ ..) -/PhDs parallelism . , N - 1 2, , parallelism . .

, parallelism.

, .

+19

All Articles