1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

並列で8Queensを解いた話(1)

Last updated at Posted at 2024-09-01

デバッグを兼ねて

Easy-ISLispはver5.30をもって一応の完成をみました。バグ発見のテストを兼ねて8Queensを並列で解くことに挑戦してみました。

ベースはM.Hiroiさんのコード

M.HiroiさんのISLisp入門の記事中のQueens問題のコードを使わせていただきました。これをベースにして逐次のものにプラス、マルチプロセス並列での8queensを書き加えました。コードは下記の通りです。

;;; originally written by M.Hiroi

(defun 8queens ()
    (mp-exec (81queens)
             (82queens)
             (83queens)
             (84queens)
             (85queens)
             (86queens)
             (87queens)
             (88queens)))


(defun 81queens ()
    (pqueens '(2 3 4 5 6 7 8) nil 1))

(defun 82queens ()
    (pqueens '(1 3 4 5 6 7 8) nil 2))

(defun 83queens ()
    (pqueens '(1 2 4 5 6 7 8) nil 3))

(defun 84queens ()
    (pqueens '(1 2 3 5 6 7 8) nil 4))

(defun 85queens ()
    (pqueens '(1 2 3 4 6 7 8) nil 5))

(defun 86queens ()
    (pqueens '(1 2 3 4 5 7 8) nil 6))

(defun 87queens ()
    (pqueens '(1 2 3 4 5 6 8) nil 7))

(defun 88queens ()
    (pqueens '(1 2 3 4 5 6 7) nil 8))



;; 衝突の検出
(defun attack (x xs)
    (labels ((attack-sub (x n ys)
                         (cond ((null ys) t)
                               ((or (= (+ (car ys) n) x)
                                    (= (- (car ys) n) x))
                                nil)
                               (t (attack-sub x (+ n 1) (cdr ys))))))
            (attack-sub x 1 xs)))


;; 解法(逐次 オリジナル)
(defun nqueens (nums board)
  (if (null nums)
      (format (standard-output) "~A~%" board)
    (for ((xs nums (cdr xs)))
         ((null xs))
         (if (attack (car xs) board)
             (nqueens (remove (car xs) nums)
                      (cons (car xs) board))))))


;; 解法(並列)
(defun pqueens (nums board n)
    (if (null nums)
        (pqueens1 board n)
        (for ((xs nums (cdr xs)))
             ((null xs))
             (if (attack (car xs) board)
                 (pqueens (remove (car xs) nums)
                          (cons (car xs) board)
                          n)))))


(defun pqueens1 (board n)
    (cond ((attack n board)
           (let ((stm (create-string-output-stream)))
               (format stm "~A~%" (cons n board))
               (mp-report  (get-output-stream-string stm))))
          (t nil)))


(defun remove (x ls)
    (cond ((null ls) nil)
          ((eq x (car ls)) (remove x (cdr ls)))
          (t (cons (car ls) (remove x (cdr ls))))))


mp-exec というのはEasy-ISLispの拡張関数です。マルチプロセス並列で各関数を実行します。

並列の計算においてはわざと1つ数が少ないものについて解を計算して、そこに抜けておいた数を当てはめてみてセーフならば解とするという方法をとっています。これにより8queensを8つの計算に分割しています。

(mp-create 8)により8個の子Lispを起動させるのですが、メモリ不足のようです。セルの数を半減させたら動作しました。

計測

逐次
bandicam 2024-09-01 11-01-52-161.jpg

並列
bandicam 2024-09-01 11-02-09-510.jpg

う~ん、おかしいですね。並列の方が遅いですね。なぜでしょう? 解の表示をしている部分が遅いのかもしれません。mp-reportという関数を使って子Lispからメインプロセスの端末に表示させているからです。改良の余地ありです。解を表示しないパターンで計測をしてみようと思います。(続く)

参考

M.HiroiさんのISLisp入門記事 http://www.nct9.ne.jp/m_hiroi/clisp/islisp02.html#chap10
Easy-ISLisp https://github.com/sasagawa888/eisl

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?