Here is a functional, tail-recursive implementation of a simple Particle Swarm Optimiser
PSO routines are ideal for tuning the numerical variables of a given function so long as some means can be given for quantifying proximity to the desired solution.
(define (Approach P S) (lambda (x) (cons (map (lambda (a b) (+ a b)) (car x) (cdr x)) (map (lambda (a b c) (+ c (* (- a b) S) )) P (car x) (cdr x)))))
Returns a function that accelerates X towards P proportional to their distance*S and moves X in accord with its velocity. P is an n dimensional point expressed as a list of floats
(define (Swarm F D P H S E) (if (= D 0) E (Swarm F (- D 1) (map (Approach (cdr E) S) P) H S (fold (lambda (a b) (if ((if H > <) (apply F (car a)) (car b)) (cons (apply F (car a)) (car a)) b)) E P))))
The Magic Function: Steps all particles in the direction of the point of the coordinates which applied to F have yeilded the highest or lowest fitness, depending on if H is true or false respectively. The global extrema E is updated if any of the particles correspond with more optimal input variables. The function terminates after recursing to a depth of D.
(define (flist f n) (if (zero? n) '() (cons (f n) (flist f (- n 1))))) (define (replist v n) (if (zero? n) '() (cons v (replist v (- n 1))))) (define (Particle D) (cons (flist (lambda (n) (- 100.0 (random 200.0))) D) (flist (lambda (n) (- 5.0 (random 10.0))) D))) (define (Particles D N) (flist (lambda (x) (particle D)) N)) (define (PSO F C H) (Swarm F 100 (particles C 100) H .1 (cons (if H -99999 99999) (replist 0 C)))) (PSO (lambda (a b) (abs (- (* a b) (+ a (* b 3))))) 2 #f)
Here’s a couple functions to make life easier, flist makes a list of a function called with the number of elements left in the list (i.e. 0 is last); equivalent to (map f (range n)).
Rep list creates a list of length n where each element is the the argument v
After that are the particle and particle-list definitions, followed by a function simplifying the usage of the swarm (PSO), and lastly an example of calculating a solution to ab=a+3b, note that (abs (- a b)) is the fuzzy definition of equal as long as H is set to false (decreasing), because zero is the lowest possible value and if a-b=0 then a=b.
The output of the demo is (0.00187 2.7274569116453007 -10.01).
The first element (the car) is the fitness, or in this case the distance from equality.
The tail elements are the corresponding input variables.