如何在Clojure中提取距离最大的两个Map元素及对应距离
解决Clojure中提取Map里距离最大元素对的问题
你的核心需求是遍历Map中所有不重复的两两元素对,计算它们的欧氏距离,再找出距离最大的那一组。现有代码只处理了第一个元素与其他元素的配对,缺少后续元素间的组合计算,且没有正确累积最大值。
步骤1:生成所有唯一两两元素对
要避免重复计算(比如p1-p2和p2-p1距离相同),可以借助clojure.math.combinatorics库的combinations函数,直接生成所有长度为2的不重复元素组合;如果不想引入外部库,也可以手动通过索引遍历生成。
步骤2:计算每对距离并保存完整信息
对每个元素对,计算距离后将元素键(如:p1、:p2)和距离绑定保存,方便后续筛选最大值。
完整实现代码
;; 保留你已定义的欧氏距离函数 (defn eclid-dist [u v] (Math/sqrt (apply + (map #(* % %) (mapv - u v))))) (def error {:p1 [1 2 3] :p2 [4 5 6] :p3 [7 8 9] :p4 [1 2 3] :p5 [6 5 4]}) ;; 引入组合库(需确保项目依赖clojure.math.combinatorics) (require '[clojure.math.combinatorics :as combo]) ;; 生成所有不重复的元素键对 (def all-pairs (combo/combinations (keys error) 2)) ;; 计算每对的距离,生成包含键对和距离的序列 (def pair-distances (map (fn [[k1 k2]] {:pair [k1 k2] :distance (eclid-dist (error k1) (error k2))}) all-pairs)) ;; 找出距离最大的那一组 (def max-distance-pair (apply max-key :distance pair-distances)) ;; 输出结果 (println max-distance-pair)
无外部库的替代实现(手动生成元素对)
如果不想引入外部库,可手动遍历索引生成唯一对:
(defn get-all-unique-pairs [m] (let [keys (vec (keys m)) n (count keys)] (for [i (range n) j (range (inc i) n)] [(keys i) (keys j)]))) ;; 后续步骤与上方一致 (def all-pairs (get-all-unique-pairs error)) (def pair-distances (map (fn [[k1 k2]] {:pair [k1 k2] :distance (eclid-dist (error k1) (error k2))}) all-pairs)) (def max-distance-pair (apply max-key :distance pair-distances))
结果说明
运行代码后,max-distance-pair会返回类似{:pair [:p1 :p3], :distance 10.392304845413264}的结构,其中:pair是距离最大的两个元素的键,:distance是对应的欧氏距离。
内容的提问来源于stack exchange,提问作者ZGI
相关产品推荐
相关产品推荐

