Skip to content

Commit

Permalink
Finshed the final 5 problems
Browse files Browse the repository at this point in the history
  • Loading branch information
Peter Kelly committed Mar 31, 2021
1 parent 08544a5 commit c54a57a
Show file tree
Hide file tree
Showing 5 changed files with 195 additions and 197 deletions.
117 changes: 58 additions & 59 deletions src/clojush/problems/psb2/spin_words.clj
Original file line number Diff line number Diff line change
@@ -1,14 1,31 @@
;; spin-words.clj
;; Peter Kelly, [email protected]
;;
;; Problem inspired by: https://www.codewars.com/kata/5264d2b162488dc400000001

(ns clojush.problems.software.benchmarks-v2.spin-words
(ns clojush.problems.psb2.spin-words
(:use clojush.pushgp.pushgp
[clojush pushstate interpreter random util globals]
clojush.instructions.tag
clojure.math.numeric-tower)
(:require [clojure.string :as str]))

; Atom generators
(def atom-generators
(make-proportional-atom-generators
(concat
(registered-for-stacks [:integer :boolean :string :char :exec]) ; stacks
(list (tag-instruction-erc [:integer :boolean :string :char :exec] 1000) ; tags
(tagged-instruction-erc 1000)))
(list 'in1) ; inputs
(list 4
5
\space ; constants
(fn [] (lrand-nth (map char (range 97 122)))) ; visible character ERC
(fn [] (spin-words-input (lrand-int 21)))) ; string ERC
{:proportion-inputs 0.15
:proportion-constants 0.05}))

(defn word-generator
"Generates words at a nice distribution for Spin Words
80% of the time word will have length in range [1, 8].
Expand All @@ -22,7 39,8 @@
(apply str (repeatedly word-len #(rand-nth chars)))))

(defn spin-words-input
"Makes a Spin Words input of length len."
"Makes a Spin Words input of length len, which is just a string of words, where the
words that are length 5 or greater are reversed"
[len]
(let [words (apply str
(take len ; This looks weird because str isn't lazy, so you
Expand All @@ -33,30 51,12 @@
words
(apply str (butlast words)))))

; Atom generators
(def spin-words-atom-generators
(make-proportional-atom-generators
(concat
(registered-for-stacks [:integer :boolean :string :char :exec])
(list (tag-instruction-erc [:integer :boolean :string :char :exec] 1000) ; tags
(tagged-instruction-erc 1000)))
(list 'in1) ; inputs
(list 4
5
\space
(fn [] (lrand-nth (map char (range 97 122)))) ;Visible character ERC
(fn [] (spin-words-input (lrand-int 21))) ;String ERC
) ; constants
{:proportion-inputs 0.15
:proportion-constants 0.05}))


;; A list of data domains for the problem. Each domain is a vector containing
;; a "set" of inputs and two integers representing how many cases from the set
;; should be used as training and testing cases respectively. Each "set" of
;; inputs is either a list or a function that, when called, will create a
;; random element of the set.
(def spin-words-data-domains
; A list of data domains for the problem. Each domain is a vector containing
; a "set" of inputs and two integers representing how many cases from the set
; should be used as training and testing cases respectively. Each "set" of
; inputs is either a list or a function that, when called, will create a
; random element of the set.
(def data-domains
[[(list ""
"a"
"this is a test"
Expand Down Expand Up @@ -86,14 86,11 @@
"maybe this isgood"
"racecar palindrome"
"ella is a short pali"
"science hi") 30 0] ;; "Special" inputs covering some base cases
"science hi") 30 0] ; "Special" inputs covering some base cases
[(fn [] (spin-words-input (inc (lrand-int 20)))) 170 2000]])

;;Can make Spin Words test data like this:
;(test-and-train-data-from-domains spin-words-data-domains)

; Helper function for error function
(defn spin-words-test-cases
(defn create-test-cases
"Takes a sequence of inputs and gives IO test cases of the form
[input output]."
[inputs]
Expand All @@ -102,23 99,14 @@
(str/join " " (map #(if (>= (count %) 5) (apply str (reverse %)) %) (str/split in #" ")))))
inputs))

(defn get-spin-words-train-and-test
"Returns the train and test cases."
[data-domains]
(map spin-words-test-cases
(test-and-train-data-from-domains data-domains)))

; Define train and test cases
(def spin-words-train-and-test-cases
(get-spin-words-train-and-test spin-words-data-domains))

(defn make-spin-words-error-function-from-cases
(defn make-error-function-from-cases
"Creates and returns the error function based on the train/test cases."
[train-cases test-cases]
(fn the-actual-spin-words-error-function
(fn the-actual-error-function
([individual]
(the-actual-spin-words-error-function individual :train))
([individual data-cases] ;; data-cases should be :train or :test
(the-actual-spin-words-error-function individual data-cases false))
(the-actual-error-function individual :train))
([individual data-cases] ; data-cases should be :train or :test
(the-actual-error-function individual data-cases false))
([individual data-cases print-outputs]
(let [behavior (atom '())
errors (doall
Expand All @@ -145,16 133,26 @@
:behaviors (reverse @behavior)
:errors errors))))))

(defn spin-words-initial-report
(defn get-train-and-test
"Returns the train and test cases."
[data-domains]
(map create-test-cases
(test-and-train-data-from-domains data-domains)))

; Define train and test cases
(def train-and-test-cases
(get-train-and-test data-domains))

(defn initial-report
[argmap]
(println "Train and test cases:")
(doseq [[i case] (map vector (range) (first spin-words-train-and-test-cases))]
(doseq [[i case] (map vector (range) (first train-and-test-cases))]
(println (format "Train Case: = | Input/Output: %s" i (str case))))
(doseq [[i case] (map vector (range) (second spin-words-train-and-test-cases))]
(doseq [[i case] (map vector (range) (second train-and-test-cases))]
(println (format "Test Case: = | Input/Output: %s" i (str case))))
(println ";;******************************"))

(defn spin-words-report
(defn custom-report
"Custom generational report."
[best population generation error-function report-simplifications]
(let [best-test-errors (:test-errors (error-function best :test))
Expand All @@ -171,17 169,18 @@
(println ";;------------------------------")
(println "Outputs of best individual on training cases:")
(error-function best :train true)
(println ";;******************************"))) ;; To do validation, could have this function return an altered best individual
;; with total-error > 0 if it had error of zero on train but not on validation
;; set. Would need a third category of data cases, or a defined split of training cases.
(println ";;******************************")
)) ; To do validation, could have this function return an altered best individual
; with total-error > 0 if it had error of zero on train but not on validation
; set. Would need a third category of data cases, or a defined split of training cases.


; Define the argmap
(def argmap
{:error-function (make-spin-words-error-function-from-cases (first spin-words-train-and-test-cases)
(second spin-words-train-and-test-cases))
:training-cases (first spin-words-train-and-test-cases)
:atom-generators spin-words-atom-generators
{:error-function (make-error-function-from-cases (first train-and-test-cases)
(second train-and-test-cases))
:training-cases (first train-and-test-cases)
:atom-generators atom-generators
:max-points 2000
:max-genome-size-in-initial-program 250
:evalpush-limit 2000
Expand All @@ -195,8 194,8 @@
:alternation-rate 0.01
:alignment-deviation 10
:uniform-mutation-rate 0.01
:problem-specific-report spin-words-report
:problem-specific-initial-report spin-words-initial-report
:problem-specific-report custom-report
:problem-specific-initial-report initial-report
:report-simplifications 0
:final-report-simplifications 5000
:max-error 10000})
38 changes: 19 additions & 19 deletions src/clojush/problems/psb2/square_digits.clj
Original file line number Diff line number Diff line change
@@ -1,10 1,9 @@
;; square_digits.clj
;;
;; Tom Helmuth, [email protected]
;;
;; Problem inspired by: https://www.codewars.com/kata/546e2562b03326a88e000020

(ns clojush.problems.software.benchmarks-v2.square-digits
(ns clojush.problems.psb2.square-digits
(:use clojush.pushgp.pushgp
[clojush pushstate interpreter random util globals]
clojush.instructions.tag)
Expand All @@ -14,15 13,15 @@
(def atom-generators
(make-proportional-atom-generators
(concat
(registered-for-stacks [:string :char :integer :boolean :exec])
(registered-for-stacks [:string :char :integer :boolean :exec]) ; stacks
(list (tag-instruction-erc [:string :char :integer :boolean :exec] 1000) ; tags
(tagged-instruction-erc 1000)))
(list 'in1) ; inputs
(list 0
1
2
(fn [] (- (lrand-int 201) 100)) ;Integer ERC
"") ; constants
"" ; constants
(fn [] (- (lrand-int 201) 100))) ; integer ERC
{:proportion-inputs 0.15
:proportion-constants 0.05}))

Expand All @@ -34,16 33,16 @@
999999
1000000))

;; A list of data domains. Each domain is a vector containing
;; a "set" of inputs and two integers representing how many cases from the set
;; should be used as training and testing cases respectively. Each "set" of
;; inputs is either a list or a function that, when called, will create a
;; random element of the set.
; A list of data domains. Each domain is a vector containing
; a "set" of inputs and two integers representing how many cases from the set
; should be used as training and testing cases respectively. Each "set" of
; inputs is either a list or a function that, when called, will create a
; random element of the set.
(def data-domains
[[hard-coded-inputs 30 0] ; fixed integers
[[hard-coded-inputs 30 0] ; Fixed integers
[(fn []
(first (filter #(not (some #{%} hard-coded-inputs))
(repeatedly #(lrand-int 999999))))) 170 2000] ; random integers, besides those in hard-coded inputs
(repeatedly #(lrand-int 999999))))) 170 2000] ; Random integers, besides those in hard-coded inputs
])

(defn digits
Expand All @@ -66,9 65,9 @@
(digits input))))

; Helper function for error function
(defn test-cases
(defn create-test-cases
"Takes a sequence of inputs and gives IO test cases of the form
[[input1 input2] output]."
[input output]."
[inputs]
(map (fn [in]
(vector in
Expand All @@ -81,7 80,7 @@
(fn the-actual-error-function
([individual]
(the-actual-error-function individual :train))
([individual data-cases] ;; data-cases should be :train or :test
([individual data-cases] ; data-cases should be :train or :test
(the-actual-error-function individual data-cases false))
([individual data-cases print-outputs]
(let [behavior (atom '())
Expand Down Expand Up @@ -112,7 111,7 @@
(defn get-train-and-test
"Returns the train and test cases."
[data-domains]
(map test-cases
(map create-test-cases
(test-and-train-data-from-domains data-domains)))

; Define train and test cases
Expand Down Expand Up @@ -145,9 144,10 @@
(println ";;------------------------------")
(println "Outputs of best individual on training cases:")
(error-function best :train true)
(println ";;******************************"))) ;; To do validation, could have this function return an altered best individual
;; with total-error > 0 if it had error of zero on train but not on validation
;; set. Would need a third category of data cases, or a defined split of training cases.
(println ";;******************************")
)) ; To do validation, could have this function return an altered best individual
; with total-error > 0 if it had error of zero on train but not on validation
; set. Would need a third category of data cases, or a defined split of training cases.


; Define the argmap
Expand Down
Loading

0 comments on commit c54a57a

Please sign in to comment.