(defun k-means( myk mydates norm ) (setq dates mydates) (setq k myk) (select-norm norm) (setq sample-length (length dates)) (setq data-dimension (length (nth 0 dates))) (setq old-centers (list)) (initialize k dates) (do (i) (( list-eql old-centers centers) centers ) ;(princ "iterating ") ;(print i) (iterate) ) ) (defun iterate() (setq clusters (list)) (into-cluster) (setq old-centers centers) (setq centers (list)) (update-all-centers) ) (defun initialize(k dates) (setq centers (list)) (setq clusters (list)) (dotimes (i k NIL) (setq centers ( append centers (list (nth i dates) ) ) ) (setq clusters ( append clusters (list (list)))) ) centers ) (defun into-cluster() (dotimes (i sample-length NIL) (put-into-cluster (where-fits-best (nth i dates) centers) (nth i dates ) ) ) ) (defun update-all-centers() (dotimes (i k NIL) (update-center i) ) ) (defun update-center(n) (setq mycluster (nth n clusters)) (setq res (list)) (dotimes (i data-dimension NIL) (setq temp 0) (dotimes (j (length mycluster) NIL) (setq temp (+ temp (nth i (nth j mycluster)) )) ) (cond ( (not (eql (length mycluster) 0 ) ) (setq res (append res (list (/ (* 1.0 temp) (length mycluster)))) ) ) ( (not NIL) (setq res (append res (list 0 ))) ) ) ) ;(print "center vorher") ;(print centers) (put-at-position-centers n res) ;(print "center nachher") ;(print centers) NIL ) (defun where-fits-best(point mycenters) (setq minima-pos 0) (setq minima-val (euklid (nth minima-pos mycenters) point) ) (dotimes (i k NIL) ;(print "iterating_IN-FIT") (setq temp-distance (euklid (nth i mycenters) point) ) ;(print temp-distance) ;(print minima-val) (cond ( (< temp-distance minima-val) (setq minima-val temp-distance) (setq minima-pos i) ) ) ) ;(print "bestfit returns ") ;(print minima-pos) minima-pos ) (defun select-norm(param) (cond ( (eql param 0) (defun euklid(a b) (setq res 0) (dotimes (i (length a) NIL ) (setq res (+ res (* ( - (nth i a) (nth i b) ) ( - (nth i a) (nth i b) ) )) ) ) (sqrt res) ) ) ( (eql param 1) (defun euklid(a b) (setq res 0) (dotimes (i (length a) NIL ) (setq res (+ res (abs (- (nth i a) (nth i b) )))) ) res ) ) ( (not NIL) (print "pass 0 for euklid and 1 for manhatten") (/ 1 0) ) ) ) (defun put-at-position-centers(n point) (setq centers (set-elem-at centers n point) ) ) (defun put-into-cluster(n point) (setq clusters (put-into-list n point clusters)) ) (defun put-into-list(n point l) (setq temp (nth n l )) (setq temp (append temp (list point))) (set-elem-at l n temp) ) (defun remove-at(p l) ;(print l) (cond ( (>= p (length l)) (print "position too big") ) ( (not NIL) (setq temp (nth p l)) (setq l (remove temp l :test 'EQUAL) ) ) ) l ) (defun set-elem-at(l p e) (cond ( (> p (length l)) (print "position too big") ) ( (eql p (length l)) (append l (list e) ) ) ( (not NIL) (set-elem-at-rec l p e) ) ) ) (defun set-elem-at-rec(l p e) (if (eql p 0) (append (list e) (rest l)) (append (list (first l)) (set-elem-at-rec (rest l) (- p 1) e) ) ) ) (defun list-eql(a b) (cond ( (eql (length a) (length b) ) (list-eql-rec a b) ) ( (eql NIL a) NIL) ( (eql NIL b) NIL) ( (not NIL) (print "list size not the same") NIL ) ) ) (defun list-eql-rec(a b) (cond ( (numberp a) (eql a b) ) ( (and (eql a NIL) (numberp b) ) NIL ) ( (and (eql b NIL) (numberp a) ) NIL ) ( (and (eql a NIL) (eql b NIL) ) (not NIL) ) ( (not NIL) (and (list-eql-rec (first a) (first b) ) (list-eql-rec (rest a ) (rest b) ) ) ) ) ) (defun generate-data(a b) (setq range 100) (setq res (list)) (dotimes (i a NIL) (setq temp (list)) (dotimes (j b NIL) (if (eql (random 2) 0) (setq temp (append temp (list (random range)))) (setq temp (append temp (list (* -1 (random range))))) ) ) (setq res (append res (list temp))) ) res ) ; wrapper functions for catala support ; use generate-data to generate random data to cluster (defun Clase_mas_cercana (pixel clases) (where-fits-best pixel clases) ) ; norm := 0 => euklid (default) ; norm := 1 => manhatten (defun Nuvols-dinamics (n_clusters dades_entrada &optional (norm 0) ) (time (k-means n_clusters dades_entrada norm)) ) ; (Nuvols-dinamics 20 (generate-data 200 200)) ; (Nuvols-dinamics 20 (generate-data 200 200) 1 )