clojure.lang.LazySeq 无法转换为 class clojure.lang.Associative
clojure.lang.LazySeq cannot be cast to class clojure.lang.Associative
我是 Clojure 的新手,我试图实现一个遗传算法。因此,我遇到了一个问题,实现不断抛出以下错误:
class clojure.lang.LazySeq cannot be cast to class clojure.lang.Associative (clojure.lang.LazySeq and clojure.lang.Associative are in unnamed module
of loader 'app')
需要说明的是,每个函数都是在REPL中单独测试的,returns结果是正确的,但是把它们放在一起后,就报错了,我不明白,因为它似乎不指定行号。
clojure 的版本来自 master 分支,使用 maven 构建,Windows。
完整代码:
(ns ga)
(defn new-individual
[genome-length]
{:genome (vec (repeatedly genome-length #(rand-int 2))) :fitness 0}
)
(defn fitness-function
[genome, target]
(Math/abs (- (reduce + genome) target))
)
(defn calculate-fitness
[population, target]
(defn fitness-function-helper
[individual, target]
(assoc individual :fitness (fitness-function (individual :genome) target))
)
(map (fn [individual] (#(fitness-function-helper individual target))) population)
)
(defn crossover
[first-individual, second-individual, crossover-rate, target]
(let [new-genome (map (fn [i1,i2] (let [crossover-probability (rand)]
(cond
(<= crossover-probability crossover-rate) i1
:else i2
)
)
)
(first-individual :genome) (second-individual :genome)
)]
{:genome new-genome :fitness (fitness-function new-genome target)}
)
)
(defn mutate
[individual, genome-length, target]
(let [new-genome (assoc (individual :genome) (rand-int genome-length) (rand-int 2))]
{:genome new-genome :fitness (fitness-function new-genome target)}
)
)
(defn better
[i1 i2]
(< (i1 :fitness) (i2 :fitness)))
(defn tournament-selection
[population, population-size, steps, tournament-size, new-population, target]
(if (< steps tournament-size)
(recur population population-size (inc steps) tournament-size (conj new-population (nth population ((comp rand-int -) population-size 2))) target
)
;(println new-population)
(first (sort better (calculate-fitness new-population target)))
)
)
(defn new-generation [population, population-size, crossover-rate, target, tournament-size]
(loop [steps 0 new-population ()]
(if (< steps population-size)
(let [i1 (tournament-selection population population-size 0 tournament-size () target)]
(let [i2 (tournament-selection population population-size 0 tournament-size () target)]
(let [offs (crossover i1 i2 crossover-rate target)]
(recur (inc steps) (conj new-population offs))
)
)
)
new-population
)
)
)
(defn new-mutated-generation [population, population-size, genome-length, target]
(loop [steps 0 new-population ()]
(if (< steps population-size)
(recur (inc steps) (conj new-population (mutate (nth population steps) genome-length target)))
new-population
)
)
)
(defn evolve [population-size, genome-length, target]
(let [population (calculate-fitness (repeatedly population-size #(new-individual genome-length)) target)]
(let [offsprings (new-generation population population-size 0.5 target 5)]
(println (new-mutated-generation offsprings population-size genome-length target))
)
)
)
(evolve 10 5 5)
函数mutate
发生错误。它有这个来源:
(defn mutate
[individual, genome-length, target]
(let [new-genome (assoc (individual :genome) (rand-int genome-length) (rand-int 2))]
{:genome new-genome :fitness (fitness-function new-genome target)}))
在一个步骤中,您使用这些参数调用它:{:genome (0 1 1 1 1), :fitness 1} 5 5
(基因组可以有不同的值,但它始终是数字序列)。
(individual :genome)
returns (0 1 1 1 1)
(序列)然后你使用了 assoc
,它是哈希映射或向量的函数。
Genome一开始是向量,但在crossover
函数中被转换成序列-这里用mapv
代替map
:
(defn crossover
[first-individual, second-individual, crossover-rate, target]
(let [new-genome (mapv (fn [i1, i2] (let [crossover-probability (rand)]
(if (<= crossover-probability crossover-rate) i1 i2)))
(first-individual :genome) (second-individual :genome))]
{:genome new-genome :fitness (fitness-function new-genome target)}))
顺便说一下,定义末尾的所有括号都在同一行。
堆栈跟踪显示有问题的代码是行
(let [new-genome (assoc (vec (individual :genome)) (rand-int genome-length) (rand-int 2))]
更具体地说,是对 assoc
的调用。如果我们通过在上面插入以下行来编辑代码:
(println "Individual: " (individual :genome) ", " (class (individual :genome)))
它打印出来
Individual: (0 1 1 0 1) , clojure.lang.LazySeq
问题是 assoc
不能与惰性序列 (clojure.lang.LazySeq
) 一起使用,因为它没有实现 clojure.lang.Associative interface which is needed by assoc.
这个惰性序列是通过在这一行调用 map
构造的:
(let [new-genome (map (fn [i1,i2] (let [crossover-probability (rand)]
(let [new-genome (mapv (fn [i1,i2] (let [crossover-probability (rand)]
代码将起作用。
我是 Clojure 的新手,我试图实现一个遗传算法。因此,我遇到了一个问题,实现不断抛出以下错误:
class clojure.lang.LazySeq cannot be cast to class clojure.lang.Associative (clojure.lang.LazySeq and clojure.lang.Associative are in unnamed module
of loader 'app')
需要说明的是,每个函数都是在REPL中单独测试的,returns结果是正确的,但是把它们放在一起后,就报错了,我不明白,因为它似乎不指定行号。
clojure 的版本来自 master 分支,使用 maven 构建,Windows。
完整代码:
(ns ga)
(defn new-individual
[genome-length]
{:genome (vec (repeatedly genome-length #(rand-int 2))) :fitness 0}
)
(defn fitness-function
[genome, target]
(Math/abs (- (reduce + genome) target))
)
(defn calculate-fitness
[population, target]
(defn fitness-function-helper
[individual, target]
(assoc individual :fitness (fitness-function (individual :genome) target))
)
(map (fn [individual] (#(fitness-function-helper individual target))) population)
)
(defn crossover
[first-individual, second-individual, crossover-rate, target]
(let [new-genome (map (fn [i1,i2] (let [crossover-probability (rand)]
(cond
(<= crossover-probability crossover-rate) i1
:else i2
)
)
)
(first-individual :genome) (second-individual :genome)
)]
{:genome new-genome :fitness (fitness-function new-genome target)}
)
)
(defn mutate
[individual, genome-length, target]
(let [new-genome (assoc (individual :genome) (rand-int genome-length) (rand-int 2))]
{:genome new-genome :fitness (fitness-function new-genome target)}
)
)
(defn better
[i1 i2]
(< (i1 :fitness) (i2 :fitness)))
(defn tournament-selection
[population, population-size, steps, tournament-size, new-population, target]
(if (< steps tournament-size)
(recur population population-size (inc steps) tournament-size (conj new-population (nth population ((comp rand-int -) population-size 2))) target
)
;(println new-population)
(first (sort better (calculate-fitness new-population target)))
)
)
(defn new-generation [population, population-size, crossover-rate, target, tournament-size]
(loop [steps 0 new-population ()]
(if (< steps population-size)
(let [i1 (tournament-selection population population-size 0 tournament-size () target)]
(let [i2 (tournament-selection population population-size 0 tournament-size () target)]
(let [offs (crossover i1 i2 crossover-rate target)]
(recur (inc steps) (conj new-population offs))
)
)
)
new-population
)
)
)
(defn new-mutated-generation [population, population-size, genome-length, target]
(loop [steps 0 new-population ()]
(if (< steps population-size)
(recur (inc steps) (conj new-population (mutate (nth population steps) genome-length target)))
new-population
)
)
)
(defn evolve [population-size, genome-length, target]
(let [population (calculate-fitness (repeatedly population-size #(new-individual genome-length)) target)]
(let [offsprings (new-generation population population-size 0.5 target 5)]
(println (new-mutated-generation offsprings population-size genome-length target))
)
)
)
(evolve 10 5 5)
函数mutate
发生错误。它有这个来源:
(defn mutate
[individual, genome-length, target]
(let [new-genome (assoc (individual :genome) (rand-int genome-length) (rand-int 2))]
{:genome new-genome :fitness (fitness-function new-genome target)}))
在一个步骤中,您使用这些参数调用它:{:genome (0 1 1 1 1), :fitness 1} 5 5
(基因组可以有不同的值,但它始终是数字序列)。
(individual :genome)
returns (0 1 1 1 1)
(序列)然后你使用了 assoc
,它是哈希映射或向量的函数。
Genome一开始是向量,但在crossover
函数中被转换成序列-这里用mapv
代替map
:
(defn crossover
[first-individual, second-individual, crossover-rate, target]
(let [new-genome (mapv (fn [i1, i2] (let [crossover-probability (rand)]
(if (<= crossover-probability crossover-rate) i1 i2)))
(first-individual :genome) (second-individual :genome))]
{:genome new-genome :fitness (fitness-function new-genome target)}))
顺便说一下,定义末尾的所有括号都在同一行。
堆栈跟踪显示有问题的代码是行
(let [new-genome (assoc (vec (individual :genome)) (rand-int genome-length) (rand-int 2))]
更具体地说,是对 assoc
的调用。如果我们通过在上面插入以下行来编辑代码:
(println "Individual: " (individual :genome) ", " (class (individual :genome)))
它打印出来
Individual: (0 1 1 0 1) , clojure.lang.LazySeq
问题是 assoc
不能与惰性序列 (clojure.lang.LazySeq
) 一起使用,因为它没有实现 clojure.lang.Associative interface which is needed by assoc.
这个惰性序列是通过在这一行调用 map
构造的:
(let [new-genome (map (fn [i1,i2] (let [crossover-probability (rand)]
(let [new-genome (mapv (fn [i1,i2] (let [crossover-probability (rand)]
代码将起作用。