2009-07-17 8 views
4

Je veux trouver le prix d'un nouvel article basé sur les prix moyens d'articles similaires. La fonction get-k-similar utilise k-Nearest Neighbors mais me renvoie cette sortie ((list rating age price) proximity).Comment écrire la fonction Moyenne pour cette structure de données dans Scheme/Lisp?

For example, 2-similar would be: 
(((5.557799748150248 3 117.94262493533647) . 3.6956648993026904) 
((3.0921378389849963 7 75.61492560596851) . 5.117886776721699)) 

J'ai besoin de trouver le prix moyen des articles similaires. Moyenne de 117 et 75. Y a-t-il une meilleure façon de itérer? Ma fonction est trop moche.

(define (get-prices new-item) 

    (define (average-prices a-list) 
    (/ (cdr 
     (foldl (λ(x y) (cons (list 0 0 0) 
          (+ (third (car x)) (third (car y))))) 
       (cons (list 0 0 0) 0) 
       a-list)) 
     (length a-list))) 

    (let ((similar-items (get-k-similar new-item))) 
     (average-prices similar-items))) 
+0

J'ai pris la liberté d'indenter correctement votre code. Je ne peux pas imaginer que cela produit quelque chose de significatif. – Svante

Répondre

3

Vous pouvez faire la chose simple et il suffit de tirer sur chaque troisième valeur:

(define (average-prices a-list) 
    (/ (apply + (map fourth a-list)) (length a-list))) 

Ceci est un peu inefficace car il construit un intermédiaire liste, et je suppose que c'est pourquoi vous avez essayé foldl. Voici la bonne façon de le faire:

(define (average-prices a-list) 
    (/ (foldl (lambda (x acc) (+ (third x) acc)) 0 l) 
    (length a-list))) 

Il y a encore un manque d'efficacité mineure - length fait un deuxième balayage - mais qui est quelque chose que vous ne devriez pas se soucier puisque vous auriez besoin d'vraiment longues listes pour obtenir un ralentissement visible.

+0

Vous avez soulevé un point intéressant. Puis-je accumuler la longueur de la liste à mesure que j'ajoute les éléments? – unj2

+0

Oui, bien sûr - de plusieurs façons, à la fois impératif et fonctionnel. Mais à ce stade, je ne m'en soucierais pas si j'étais vous. –

5

Common Lisp

(/ (reduce '+ a-list :key 'caddar) (length a-list)) 

ou

(loop for ((nil nil e) . nil) in a-list 
     count e into length 
     sum e into sum 
     finally (return (/ sum length))) 
Questions connexes