File: search.l

package info (click to toggle)
euslisp 9.27%2Bdfsg-7
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye
  • size: 55,344 kB
  • sloc: ansic: 41,162; lisp: 3,339; makefile: 256; sh: 208; asm: 138; python: 53
file content (102 lines) | stat: -rw-r--r-- 3,325 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
;;;;
;;;; search.l
;;;;	search functions library
;;;	Copyright (c) 1989, Toshihiro MATSUI, ETL
;;;	depth-first, breadth-first receive three arguments,
;;;	namely start-node, finish-node and the node extension function.
;;;	best-first, hill-climb, branch-and-bound require a cost evaluating
;;;	function as its third argument.

(defmethod edge 
 (:all-wings () (list (send self :nwing)
		      (send self :pwing)
		      (send self :ncwing)
		      (send self :pcwing))))

;; given a list of node, extend the first node and return the list of subnodes.
(defun extend-wing (path)
   (mapcar #'(lambda (new-node) (cons new-node path))
	   (remove-if #'(lambda (neighbor) (member neighbor path))
		      (send (first path) :all-wings))))

(defun depth-first (start finish extend &optional (queue (list (list start))))
   (cond ((endp queue) nil)
	 ((eq finish (first (first queue)))
	  (nreverse (first queue)))
	 (t (depth-first start finish extend
			 (append (funcall extend (first queue)) (rest queue))))))

(defun breadth-first (start finish extend &optional (queue (list (list start))))
   (cond ((endp queue) nil)
	 ((eq finish (first (first queue)))
	  (nreverse (first queue)))
	 (t (breadth-first start finish extend
			 (append  (rest queue) (funcall extend (first queue)))))))

(defun edge-distance-eval (e1 e2)
;    (format t "~s ~s~%" e1 e2)
   (cond ((null e1) nil)
	 ((null e2) t)
	 (t
           (let ((p0 (send (car (last e1)) :point 0.5))
		 p1 p2 d1 d2)
	     (setq p1 (send (car e1) :point 0.5))
	     (setq d1 (distance p0 p1))
	     (setq p1 (send (car e2) :point 0.5))
	     (setq d2 (distance p0 p1))
	     (format t "~s ~s~%" d1 d2)
	     (if (>= d1 d2) t nil) )
     ) ))

(defun best-first (start finish extend evaluator
			 &optional (queue (list (list start))))
   (cond ((endp queue) nil)
	 ((eq finish (first (first queue)))
	  (nreverse (first queue)))
	 (t (best-first start finish extend evaluator 
			 (merge cons
				(sort (funcall extend (first queue)) evaluator)
				(rest queue)
				evaluator)))))

(defun hill-climb (start finish extend evaluator &optional (queue (list (list start))))
   (cond ((endp queue) nil)
	 ((eq finish (first (first queue)))
	  (nreverse (first queue)))
	 (t (hill-climb start finish extend evaluator
			(append  (sort (funcall extend (first queue))
				       evaluator)
				 (rest queue))))))

(defun branch-and-bound (start finish extend evaluator
				      &optional (queue (list (list start))))
   (cond ((endp queue) nil)
	 ((eq finish (first (first queue)))
	  (nreverse (first queue)))
	 (t (branch-and-bound start finish extend evaluator
			(sort (append (funcall extend (first queue))
				      (rest queue))
			      evaluator)))))

;;; example
;;; make a complex body, and search a path from an edge to another.
;;; each face should not have any hole.

(defun make-ex ()
   (let (a b c d)
      (setq a (make-cube 200 200 100)
	    b (make-cylinder 50 200))
      (send b :rotate (/ pi -4) :x)
      (send b :rotate (/ pi -4) :y)
      (send b :translate #f(0 0 80))
      (setq c (body+ a b))
      (setq d (make-cube 50 60 80))
      (send d :translate #f(-170 170 160))
      (setq bod (body+ c d))) )

(make-ex)
(setq e1 (send bod :edge 0)
      e2 (car (last (send bod :edges))))

;; (setq x (breadth-first e1 e2 #'extend-wing))	;infinite loop