【问题标题】:Need your help on running clojure library via leiningen在通过 leiningen 运行 clojure 库时需要您的帮助
【发布时间】:2015-12-29 18:04:07
【问题描述】:

我在 github 上找到了最小命中设置的解决方案:https://github.com/bdesham/hitting-set,然后尝试使用它。解决方案是 clojure 库,所以我下载了 leiningen 尝试运行它。

我从 github 链接阅读了自述文件,但我仍然不知道如何运行 clj 代码以获得最小命中集的结果。我看到 hit_set.clj 文件中有一个名为 minimum-hitting-sets 的函数,但我不知道如何用参数调用它。 例如:获取最小命中集:

{"Australia" #{:white :red :blue},
 "Tanzania" #{:black :blue :green :yellow},
 "Norway" #{:white :red :blue},
 "Uruguay" #{:white :blue :yellow},
 "Saint Vincent and the Grenadines" #{:blue :green :yellow},
 "Ivory Coast" #{:white :orange :green},
 "Sierra Leone" #{:white :blue :green},
 "United States" #{:white :red :blue}}

Project.clj 代码:

(defproject hitting-set "0.9.0"
        :description "Find minimal hitting sets"
        :url "https://github.com/bdesham/hitting-set"
        :license {:name "Eclipse Public License"
                  :url "http://www.eclipse.org/legal/epl-v10.html"
                  :distribution :repo
                  :comments "Same as Clojure"}
        :main hitting-set
        :min-lein-version "2.0.0"
        :dependencies [	[org.clojure/clojure "1.4.0"]
						[hitting-set "0.9.0"]])

hitting_set.clj 代码:

(ns hitting-set
  (:use hitting-set :only [minimal-hitting-sets]))

; Utility functions

(defn- dissoc-elements-containing
  "Given a map in which the keys are sets, removes all keys whose sets contain
  the element el. Adapted from http://stackoverflow.com/a/2753997/371228"
  [el m]
  (apply dissoc m (keep #(-> % val
                           (not-any? #{el})
                           (if nil (key %)))
                        m)))

(defn- map-old-new
  "Returns a sequence of vectors. Each first item is an element of coll and the
  second item is the result of calling f with that item."
  [f coll]
  (map #(vector % (f %)) coll))

(defn- count-vertices
  "Returns the number of vertices in the hypergraph h."
  [h]
  (count (apply union (vals h))))

(defn- sorted-hypergraph
  "Returns a version of the hypergraph h that is sorted so that the edges with
  the fewest vertices come first."
  [h]
  (into (sorted-map-by (fn [key1 key2]
                         (compare [(count (get h key1)) key1]
                                  [(count (get h key2)) key2])))
        h))

(defn- remove-dupes
  "Given a map m, remove all but one of the keys that map to any given value."
  [m]
  (loop [sm (sorted-map),
         m m,
         seen #{}]
    (if-let [head (first m)]
      (if (contains? seen (second head))
        (recur sm
               (rest m)
               seen)
        (recur (assoc sm (first head) (second head))
               (rest m)
               (conj seen (second head))))
      sm)))

(defn- efficient-hypergraph
  "Given a hypergraph h, returns an equivalent hypergraph that will go through
  the hitting set algorithm more quickly. Specifically, redundant edges are
  discarded and then the map is sorted so that the smallest edges come first."
  [h]
  (-> h remove-dupes sorted-hypergraph))

(defn- largest-edge
  "Returns the name of the edge of h that has the greatest number of vertices."
  [h]
  (first (last (sorted-hypergraph h))))

(defn- remove-vertices
  "Given a hypergraph h and a set vv of vertices, remove the vertices from h
  (i.e. remove all of the vertices of vv from each edge in h). If this would
  result in an edge becoming empty, remove that edge entirely."
  [h vv]
  (loop [h h,
         res {}]
    (if (first h)
      (let [edge (difference (second (first h))
                             vv)]
        (if (< 0 (count edge))
          (recur (rest h)
                 (assoc res (first (first h)) edge))
          (recur (rest h)
                 res)))
      res)))

; Auxiliary functions
;
; These functions might be useful if you're working with hitting sets, although
; they're not actually invoked anywhere else in this project.

(defn reverse-map
  "Takes a map from keys to sets of values. Produces a map in which the values
  are mapped to the set of keys in whose sets they originally appeared."
  [m]
  (apply merge-with into
         (for [[k vs] m]
           (apply hash-map (flatten (for [v vs]
                                      [v #{k}]))))))

(defn drop-elements
  "Given a set of N elements, return a set of N sets, each of which is the
  result of removing a different item from the original set."
  [s]
  (set (for [e s] (difference s #{e}))))

; The main functions
;
; These are the functions that users are probably going to be interested in.

; Hitting set

(defn hitting-set?
  "Returns true if t is a hitting set of h. Does not check whether s is
  minimal."
  [h t]
  (not-any? empty? (map #(intersection % t)
                        (vals h))))

(defn hitting-set-exists?
  "Returns true if a hitting set of size k exists for the hypergraph h. See the
  caveat in README.md for odd behavior of this function."
  [h k]
  (cond
    (< (count-vertices h) k) false
    (empty? h) true
    (zero? k) false
    :else (let [hvs (map #(dissoc-elements-containing % h)
                         (first (vals h)))]
            (boolean (some #(hitting-set-exists? % (dec k))
                           hvs)))))

(defn- enumerate-algorithm
  [h k x]
  (cond
     (empty? h) #{x}
     (zero? k) #{}
     :else (let [hvs (map-old-new #(dissoc-elements-containing % h)
                                  (first (vals h)))]
             (apply union (map #(enumerate-algorithm (second %)
                                                     (dec k)
                                                     (union x #{(first %)}))
                               hvs)))))

(defn enumerate-hitting-sets
  "Return a set containing the hitting sets of h. See the caveat in README.md
  for odd behavior of this function. If the parameter k is passed then the
  function will return all hitting sets of size less than or equal to k."
  ([h]
   (enumerate-algorithm (efficient-hypergraph h) (count-vertices h) #{}))
  ([h k]
   (enumerate-algorithm (efficient-hypergraph h) k #{})))

(defn minimal-hitting-sets
  "Returns a set containing the minimal hitting sets of the hypergraph h. If
  you just want one hitting set and don't care whether there are multiple
  minimal hitting sets, use (first (minimal-hitting-sets h))."
  [h]
  (first (filter #(> (count %) 0)
                 (map #(enumerate-hitting-sets h %)
                      (range 1 (inc (count-vertices h)))))))

; Set cover

(defn cover?
  "Returns true if the elements of s form a set cover for the hypergraph h."
  [h s]
  (= (apply union (vals h))
     (apply union (map #(get h %) s))))

(defn greedy-cover
  "Returns a set cover of h using the 'greedy' algorithm."
  [h]
  (loop [hh h,
         edges #{}]
    (if (cover? h edges)
      edges
      (let [e (largest-edge hh)]
        (recur (remove-vertices hh (get hh e))
               (conj edges e))))))

(defn approx-hitting-set
  "Returns a hitting set of h. The set is guaranteed to be a hitting set, but
  may not be minimal."
  [h]
  (greedy-cover (reverse-map h)))

由于我是 leiningen 和 clojure 的新手,所以我真的需要你的帮助。

谢谢, 挂了

【问题讨论】:

  • 您能否更具体地说明问题是什么以及您尝试了什么?
  • 您能否包括 project.clj 的依赖项部分,以及您进行调用的 core.clj 部分(或您进行调用的任何文件和命名空间)以及 ns 声明从需要库的 core.clj 顶部
  • 我已经添加了要发布的代码。实际上,我不知道如何处理已安装的 leiningen 以使用我的输入参数获得最小命中集的结果。请帮我解决这个问题

标签: clojure leiningen


【解决方案1】:

通常使用来自 clojure 的 clojure 库:

  1. lein new app project-name创建一个新项目
  2. 在 project.clj 的依赖部分中包含该库
  3. 要求并在至少一个 .clj 文件中引用该库(core.clj 就是一个示例)
  4. 在您选择的编辑器中加载该文件,并将 REPL 命名空间切换到文件顶部 ns 形式的命名空间。
  5. ...
  6. 利润!!

虽然我希望这足以让您大致了解解决此问题的一种方法,但还有更多细节,如果您解决了第 5 步,请分享您的解决方案 ;-)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-22
    • 2012-04-04
    • 2014-04-28
    • 1970-01-01
    • 2012-01-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多