Compare commits

..

317 Commits

Author SHA1 Message Date
982da9dcd1 start of fitness function, coming back once I know more
Some checks failed
CI / test-clj (push) Has been cancelled
CI / test-cljs (push) Has been cancelled
2025-03-16 02:19:51 -05:00
9a465ab566 data loading done
Some checks are pending
CI / test-clj (push) Waiting to run
CI / test-cljs (push) Waiting to run
2025-03-15 01:49:00 -05:00
def7c1e965 change of imports
Some checks are pending
CI / test-clj (push) Waiting to run
CI / test-cljs (push) Waiting to run
2025-03-14 19:57:50 -05:00
acdc1ed18a utility for loading data from a csv 2025-03-14 19:56:47 -05:00
cabf5bc376 fix clj-konda errors 2025-03-14 19:46:08 -05:00
8f2ba3579b add GLD data 2025-03-14 17:09:01 -05:00
0cb349ddb1 move stock regression 2025-03-14 16:49:10 -05:00
cd39c62c22 make visible to get-stack-instructions
Some checks are pending
CI / test-clj (push) Waiting to run
CI / test-cljs (push) Waiting to run
2025-03-14 02:33:15 -05:00
c8510755e0 more functions !!!!!
Some checks are pending
CI / test-clj (push) Waiting to run
CI / test-cljs (push) Waiting to run
2025-03-14 02:06:55 -05:00
c1255c5a88 more numeric instructions
Some checks are pending
CI / test-clj (push) Waiting to run
CI / test-cljs (push) Waiting to run
2025-03-14 01:41:50 -05:00
90ff1c49de load signal file 2025-03-14 01:41:41 -05:00
239f3cb4c1 signal file init
Some checks are pending
CI / test-clj (push) Waiting to run
CI / test-cljs (push) Waiting to run
2025-03-14 00:54:31 -05:00
d59c175629 generic signal instructions 2025-03-14 00:54:22 -05:00
616b33fe20 buy/hold keyword exec stack handling 2025-03-14 00:54:13 -05:00
617b03aeb6 start of stock regression 2025-03-14 00:48:43 -05:00
2ad54d8189 buy,hold,sell comparison functions 2025-03-12 17:43:03 -05:00
4ff98629f9 add instructions, is breaking things tho? 2025-03-12 16:42:28 -05:00
a4703d60a8 more comparisons
Some checks failed
CI / test-clj (push) Has been cancelled
CI / test-cljs (push) Has been cancelled
2025-03-11 17:18:40 -05:00
265d9f8c17 jdk8
Some checks are pending
CI / test-clj (push) Waiting to run
CI / test-cljs (push) Waiting to run
2025-03-11 16:01:40 -05:00
33ccf6cad3 add java for shadow-cljs 2025-03-11 16:00:11 -05:00
7bd451b4aa add nodejs 2025-03-11 15:56:30 -05:00
c920cdaade add clojure-lsp back 2025-03-11 15:49:07 -05:00
7487d8a5b2 calva uses their own clojure-lsp
Some checks are pending
CI / test-clj (push) Waiting to run
CI / test-cljs (push) Waiting to run
2025-03-11 15:45:46 -05:00
cc0a32eeb3 update flake.lock 2025-03-11 14:40:52 -05:00
c107363d40 option to sort by max rather than min
Some checks are pending
CI / test-clj (push) Waiting to run
CI / test-cljs (push) Waiting to run
2025-03-11 14:06:22 -05:00
2261b57445 update calva version
Some checks are pending
CI / test-clj (push) Waiting to run
CI / test-cljs (push) Waiting to run
2025-03-11 13:06:37 -05:00
1144a15181 change version file
Some checks are pending
CI / test-clj (push) Waiting to run
CI / test-cljs (push) Waiting to run
2025-03-11 12:57:41 -05:00
b7939f0bfb try exporting shell
Some checks failed
CI / test-clj (push) Has been cancelled
CI / test-cljs (push) Has been cancelled
2025-03-07 13:51:03 -06:00
4c38979e20 try build inputs 2025-03-07 13:47:49 -06:00
9c671afc4a more testing
Some checks failed
CI / test-clj (push) Has been cancelled
CI / test-cljs (push) Has been cancelled
2025-03-02 00:45:57 -06:00
83cc26593a add test-argmap
Some checks failed
CI / test-clj (push) Has been cancelled
CI / test-cljs (push) Has been cancelled
2025-02-27 02:51:46 -06:00
758f2eb740 more testing with session
Some checks are pending
CI / test-clj (push) Waiting to run
CI / test-cljs (push) Waiting to run
2025-02-26 23:54:42 -06:00
b166bacfb5 more imports, play analysis tools
Some checks are pending
CI / test-clj (push) Waiting to run
CI / test-cljs (push) Waiting to run
2025-02-25 23:51:35 -06:00
b698faae08 separate argmap from -main 2025-02-25 23:51:14 -06:00
960b561e3e about this fork
Some checks are pending
CI / test-clj (push) Waiting to run
CI / test-cljs (push) Waiting to run
2025-02-25 13:58:21 -06:00
f700934f5d add default back to the flake
Some checks are pending
CI / test-clj (push) Waiting to run
CI / test-cljs (push) Waiting to run
2025-02-25 13:41:33 -06:00
406b867dfe put shellHook in mkShell call 2025-02-25 13:40:38 -06:00
c9d26d832a more attempting 2025-02-25 13:38:10 -06:00
31de7b0e0c reorganize 2025-02-25 13:36:42 -06:00
ed11d8de6c shellHook and remove standalone codium 2025-02-25 13:33:13 -06:00
c119407dec try with a v 2025-02-25 13:27:47 -06:00
747ae82cea sha256 modification
Some checks are pending
CI / test-clj (push) Waiting to run
CI / test-cljs (push) Waiting to run
2025-02-25 04:04:05 -06:00
8645aac0fd update with proper checksum 2025-02-25 04:03:18 -06:00
970b360b5b fix typo 2025-02-25 04:02:21 -06:00
eea932383d add flake.lock 2025-02-25 04:01:56 -06:00
15b1071938 flake init 2025-02-25 04:01:11 -06:00
3c900613da mention flake in readme 2025-02-25 04:01:01 -06:00
Lee Spector
97a1d381fd
Update README.md
Fix path for regression problem
2024-06-26 16:30:36 -04:00
Lee Spector
847341e4d8 Add and reorganize regression problem files 2024-01-17 15:32:12 -05:00
Lee Spector
6812f5e28c Remove problem file with issues including incorrect constants and obsolete gp arguments 2024-01-16 19:14:33 -05:00
Lee Spector
971f10941e GIT MESSAGE CORRECTION: recently added argument is :closes, not :close 2024-01-12 17:11:03 -05:00
Lee Spector
e6361ec1c0 Allow empty argmap 2024-01-12 16:31:46 -05:00
Lee Spector
70e9f81f84 Implement :close options :specified (default until recently, and now again), :balanced (default just prior to this commit), :none (which also removes instructions that open multiple code blocks) 2024-01-12 16:25:59 -05:00
Lee Spector
ddb788ad84 Clean up movement of opens ; add :closes argument 2024-01-12 15:24:13 -05:00
Lee Spector
131be83328 Flush output stream after each generation report 2024-01-10 13:06:50 -05:00
Lee Spector
71d378f49f Break just before an instruction that opens code blocks or just after a close, unless can't 2024-01-09 16:40:40 -05:00
Lee Spector
b0aee912bf Update docs 2024-01-07 12:53:34 -05:00
Lee Spector
cd73c73aa0 Specify and comment on more (all?) options for gp argmap 2024-01-07 12:47:12 -05:00
Lee Spector
3ae7123cd8 Note that informed downsampling is now enabled by default; add comments to gp argument defaults 2024-01-07 12:11:08 -05:00
Lee Spector
81ef86d4ee Rework handling of defaults to top-level gp function 2024-01-07 11:49:35 -05:00
Lee Spector
f0424979b5 Always make probability of close equal to probability that instruction set adds an open 2024-01-06 16:39:11 -05:00
Lee Spector
126b358643
Update README.md 2024-01-05 17:16:46 -05:00
Lee Spector
163bd92b7a
Update README.md 2024-01-05 17:15:38 -05:00
Lee Spector
a467dcb3f4
Update README.md 2024-01-05 17:07:02 -05:00
Lee Spector
360b943ee6 Fix test 2023-12-31 21:43:38 -05:00
Lee Spector
a10addcc9e Move opens into instructions/parentheses; implement :auto-close to set probability of adding a close from opens produced by instructions 2023-12-31 21:38:49 -05:00
Lee Spector
5eb34a811a Pass argmap to random-instruction 2023-12-31 16:02:49 -05:00
Lee Spector
d8402962f1 Remove rather than filling empty genes. 2023-12-26 17:27:41 -05:00
Lee Spector
feb5a52d25 Explicitly require clojure.set 2023-12-26 15:40:25 -05:00
Lee Spector
77b160e454 Replace :bmx-gap-probability with :bmx-gene-length-limit 2023-12-26 15:32:06 -05:00
Lee Spector
c3a748e5cc Move more bmx utility functions to utils namespace 2023-12-26 14:33:12 -05:00
Lee Spector
1eafd17b5f Fill empty genes after :bmx and :bmx-umad 2023-12-24 15:34:28 -05:00
Lee Spector
d9e5523c99 Implement :bmx-same-gene-count to select only second parents with same number of genes as first 2023-12-21 19:08:11 -05:00
Lee Spector
1e29f88405 Add :ssx-not-bmx as a temporary way to experiment with sequential segment crossover 2023-12-14 19:18:43 -08:00
Lee Spector
d318d702ed Pass argmap to bmx 2023-12-14 19:11:26 -08:00
Lee Spector
b2bcab59de Add argument for :bmx-maximum-distance; don't merge adjacent gaps 2023-12-11 15:30:55 -05:00
Lee Spector
3ce672c022 Reimpose maximum difference for bmx exchange, hardcoded to 3 2023-12-11 00:49:01 -05:00
Lee Spector
0b2024ec6e Merge adjacent gaps 2023-12-10 23:11:08 -05:00
Lee Spector
435eb59371 Reformulate bmx distance and remove distance limit 2023-12-10 20:18:05 -05:00
Lee Spector
a706babff1 Only exchange in bmx with distance <= a limit, hardcoded to 4 for now 2023-12-10 14:37:45 -05:00
Lee Spector
49f6f6de72 Add multiset-distance and unigram-bigram-distance, and use the latter in bmx 2023-12-10 12:37:23 -05:00
Lee Spector
39edec3865 Fix formatting 2023-12-10 12:13:48 -05:00
Lee Spector
0a32938c2b Add and delete gaps in :bmx, not just :bmx-umad 2023-12-08 18:39:13 -05:00
Lee Spector
9fa35c4562 Rework bmx-umad gap addition and deletion 2023-12-07 18:32:11 -05:00
Lee Spector
82657abf32 Do not consider adding at a :gap 2023-12-07 16:47:50 -05:00
Lee Spector
f6a9426751 Clarify docstring 2023-12-07 16:45:03 -05:00
Lee Spector
648c7b866a Implement :gap mutation in :bmx-umad according to :bmx-gap-change-probability 2023-12-07 11:28:21 -05:00
Lee Spector
b40aff3d6d Don't allow uniform-deletion to delete :gap 2023-12-06 20:26:04 -05:00
Lee Spector
28ab925601 For bmx, add instances of :gap in initial plushy genomes according to :bmx-gap-probability 2023-12-06 17:35:00 -05:00
Lee Spector
27857faf85 Rely on :bmx? in argmap to know when using bmx 2023-12-06 15:01:59 -05:00
Lee Spector
85a59cdbe5 Eliminate :bmx-enrichment, and because of that, argmap preprocessing for gp 2023-12-06 14:56:02 -05:00
Lee Spector
2fa6eb5671 Rename :bmx-rate to :bmx-exchange-rate, which is more descriptive 2023-12-06 14:39:30 -05:00
Lee Spector
de5aeabd5e Add question mark, so complementary mate selection for bmx is invoked with :bmx-complementary? true 2023-12-06 14:32:40 -05:00
Lee Spector
2970632c26 Implement complementary mate selection for :bmx and :bmx-umad, activated via ':bmx-complementary true' 2023-12-02 23:11:54 -05:00
Lee Spector
a0bd993281 Rename :gene to :gap 2023-12-02 23:02:07 -05:00
Lee Spector
30a87a2688 Make lexicase-selection use provided :initial-cases and return :selection-cases, both via argmap 2023-12-02 17:35:14 -05:00
Lee Spector
d0d0427dcf Fix typo that spoiled behavioral diversity calculations 2023-11-30 19:06:04 -05:00
Lee Spector
b6e506f4bd Remove autoconstructive hypervariability mutation (ah-umad) 2023-11-30 18:37:33 -05:00
Lee Spector
5c127ef21b Add and strip :gene for bmx-umad 2023-11-25 11:33:36 -05:00
Lee Spector
770dfe74b1 Report on gene counts when using bmx-umad 2023-11-25 10:16:31 -05:00
Lee Spector
98206458d8 Print solution and simplified plushies and programs 2023-11-24 18:41:39 -05:00
Lee Spector
91adcbf089 Clean up and reformat 2023-11-24 18:09:25 -05:00
Lee Spector
48658f455c Print ERC instructions as strings to avoid tripping up read-string on logs; previously (set! *default-data-reader-fn* tagged-literal) required to avoid exception 2023-11-21 22:56:04 -05:00
Lee Spector
ad20e43516 Implement bmx-umad operator; allow collection for bmx-rate 2023-11-21 16:23:26 -05:00
Lee Spector
c61934e50b Report on :best-gene-count and :average-gene-count in bmx; move gene utilities to utils 2023-11-20 21:09:06 -05:00
Lee Spector
5ce452b6ff Add bmx-rate 2023-11-20 20:48:06 -05:00
Lee Spector
d81a9ae3b6 Rename autoconstructive-crossover bmx, for best match crossover 2023-11-20 20:25:42 -05:00
Lee Spector
30daac848a Print instruction list correctly 2023-11-19 10:28:20 -05:00
Lee Spector
177f3ad1eb Print {:run-completed true} at end of run 2023-11-12 14:43:26 -05:00
Lee Spector
6c38a87460 Fix reference to example file, the name of which had changed 2023-11-12 14:42:49 -05:00
Lee Spector
8931f3d372
Merge pull request #67 from thelmuth/fix/solve-boolean
Fixed Solve Boolean problem so that it works.
2023-11-10 13:19:20 -05:00
Tom Helmuth
bf1128ad4b Fixed Solve Boolean problem so that it works. 2023-11-10 13:09:08 -05:00
Lee Spector
98d9c1f13e Clean up boolean mul problems, still experimental and not consistent with one another 2023-11-09 12:24:43 -05:00
Lee Spector
037baf9b2e Add :vary and :protect when using ah-umad 2023-11-08 19:17:16 -05:00
Lee Spector
3ccd5542ea Separate plushy pre-processing from plushy to push translation 2023-11-08 19:09:43 -05:00
Lee Spector
25e8efe255 Handle argmap adjustments outside of gp loop; add :gene when using autoconstructive crossover 2023-11-08 18:53:58 -05:00
Lee Spector
be1e2aae78 Merge remote-tracking branch 'origin/master' into autox-similarity 2023-11-08 14:00:51 -05:00
Lee Spector
ee3045128a
Merge pull request #66 from ryanboldi/remove-hyperselection
remove hacky hyperselection code
2023-11-08 01:29:57 -05:00
Ryan Boldi
7ca3767b02 remove hacky hyperselection code 2023-11-07 22:33:58 -05:00
Lee Spector
98d7126dee
Merge pull request #65 from thelmuth/fix/float-and-better-logging
Added float_div, and made logging print each value on one line instead of pretty-printed across many lines.
2023-11-07 21:37:50 -05:00
Tom Helmuth
a7ce4152a2 Updated readme 2023-11-07 20:52:52 -05:00
Tom Helmuth
e00e34402c Added float_div instruction 2023-11-07 20:43:24 -05:00
Tom Helmuth
739e975111 Merge branch 'master' into fix/float-and-better-logging 2023-11-07 20:25:10 -05:00
Tom Helmuth
1a1f442858 Tom's opinionated better logging 2023-11-07 20:23:49 -05:00
Lee Spector
fac7b03b0c
Fix definition of E 2023-11-07 20:05:01 -05:00
Lee Spector
bc7b4467c1 Allow autoconstructive crossover between any pair, swap genes based on similarity 2023-11-05 10:27:59 -05:00
Lee Spector
e488bbf9da Add EXPERIMENTAL flags 2023-11-04 16:51:20 -04:00
Lee Spector
54b9897803 Remove diploidy 2023-11-04 16:30:50 -04:00
Lee Spector
5fd533c24f Correctly handle leadin/trailing :gene 2023-11-03 12:30:14 -04:00
Lee Spector
c0bc7bc191 Select mates with same number of genes in autoconstructive crossover 2023-11-02 23:16:10 -04:00
Lee Spector
ac3690837d Add autoconstructive-crossover 2023-11-01 18:28:37 -04:00
Lee Spector
f9f1a9e22b Strip :gene when using :autoconstructive-crossover 2023-11-01 14:27:00 -04:00
Lee Spector
84be0de491 Configure mul3 for autox experiments 2023-11-01 14:22:40 -04:00
Lee Spector
f18dbeeafc Resolve merge conflicts 2023-10-29 00:41:23 -04:00
Lee Spector
a8045357fd Reformulate rate normalization for autoconstruction hypervariability 2023-10-29 00:25:20 -04:00
Lee Spector
cfbba8cbc4 Remove unused requires to data-creation 2023-10-23 10:22:08 -04:00
Lee Spector
878caa9ae4 Require org.clojure/data.csv in deps.edn 2023-10-23 10:16:01 -04:00
Lee Spector
92fd220961 Add cleanup to move shutdown-agents into tail position 2023-10-19 10:58:22 -04:00
Lee Spector
b6e7b0e86f Call shutdown-agents at end of run; reformat 2023-10-19 10:53:13 -04:00
Lee Spector
e3ba58587a Make boundaries of hypervariable segments hypervariable 2023-10-19 10:44:30 -04:00
Lee Spector
37df3432fb Switch to normalized autoconstructive hypervariation; reformat 2023-10-18 17:05:38 -04:00
Lee Spector
adf039195c
Merge pull request #63 from ryanboldi/main
pmapallv multi-collection implementation
2023-10-16 18:34:17 -04:00
Ryan Boldi
71f5b9d8de pmapallv always returns vector 2023-10-16 18:38:17 -04:00
Ryan Boldi
a315482302 implements multi collection pmapallv, and uses it in down-sampling and in hyperselection 2023-10-16 18:32:38 -04:00
Ryan Boldi
64e35d320c Update gp.cljc 2023-10-15 23:17:33 -04:00
Ryan Boldi
e9a2fe9a5b made variation operators user pmapallv 2023-10-15 23:10:12 -04:00
Ryan Boldi
ce71c6d49f Merge branch 'master' of https://github.com/lspector/propeller 2023-10-15 22:55:02 -04:00
Ryan Boldi
288faadedf Update downsample.cljc 2023-10-15 22:54:22 -04:00
Lee Spector
6bd060a189 Experiment 2023-10-15 22:54:01 -04:00
Lee Spector
eb467a33b3 Remove mapper arg that is now handled in propeller.utils/pmapallv 2023-10-15 11:10:31 -04:00
Lee Spector
e7130da06f
Merge pull request #60 from ryanboldi/main
down-sampling code, autosimplification code
2023-10-15 10:51:51 -04:00
Ryan Boldi
63ff79e1e4 Update variation.cljc 2023-10-14 21:55:58 -04:00
Ryan Boldi
d427e3a9bd move docs to right place 2023-10-14 21:46:18 -04:00
Ryan Boldi
fbf77cdb90 Merge branch 'master' 2023-10-14 21:39:44 -04:00
Lee Spector
139e395f60 Print average hypervariability when using autoconstructive hypervariability 2023-10-14 17:37:16 -04:00
Lee Spector
5103463cd8 Add doc string and clean up names 2023-10-14 17:08:20 -04:00
Lee Spector
a8d046e52e Add autoconstructive hypervariability tournaments 2023-10-14 16:43:14 -04:00
Lee Spector
9f3c6f46ff Implement autoconstructive hypervariation umad (ah-umad) 2023-10-12 14:39:26 -04:00
Lee Spector
c4070c6f43 Set up mul3 defaults for :ah-umad; note hack to :instructions 2023-10-11 19:37:10 -04:00
Lee Spector
b88ff01526 Strip :vary and :protect if using :ah-umad 2023-10-11 19:27:26 -04:00
Lee Spector
0dc286610a Remove incorrect comment 2023-10-11 18:19:08 -04:00
Lee Spector
7dcf75c433 Allow collection for :max-batch-size 2023-09-05 10:44:50 -04:00
Lee Spector
65c7f2a3fe Experiment 2023-09-04 13:07:23 -04:00
Lee Spector
ced767960c Prevent reader conditional from violating syntax outside of :clj 2023-09-03 21:43:23 -04:00
Lee Spector
a27c7f8477 Allow collections for genetic operator hyperparameters 2023-09-03 21:40:02 -04:00
Lee Spector
875c0b8e73 Rename rate to onenum, since it can be used for non-rate hyperparameters too 2023-09-03 20:54:44 -04:00
Lee Spector
fad10a85b5 Add rate function to support rate collections 2023-09-03 20:48:51 -04:00
Lee Spector
1facb741e6 Improve efficiency of motley-batch-lexicase-selection 2023-09-03 10:06:42 -04:00
Lee Spector
06e9f9445d Add motley batch lexicase selection 2023-09-02 16:38:15 -04:00
Lee Spector
a95e1ea872 Add alternation genetic operator; mul3 enhancements 2023-09-02 14:43:36 -04:00
Lee Spector
3ca6d4175f Initialize diploid genomes to pairs of same; implement diploid vumad; mess around with mul3 2023-08-31 17:17:33 -04:00
Lee Spector
aeae30d0d4 Add variable umad (vumad) genetic operator; mul3 parameter experiments 2023-08-30 16:43:49 -04:00
Lee Spector
b49ced0567 Mess with defaults 2023-08-30 15:19:00 -04:00
Lee Spector
1733ffd42e Merge branch 'master' into boolean-multipliers 2023-08-30 14:47:58 -04:00
Lee Spector
7797fc1def Document concurrency and :single-thread-mode in README 2023-08-30 13:14:32 -04:00
Lee Spector
87ba635f4f Use pmapallv for variation, which includes selection 2023-08-30 12:52:34 -04:00
Lee Spector
a2192ca37d Use pmapallv for evaluation in GP, after debugging and adding shutdown-agents 2023-08-30 12:36:47 -04:00
Lee Spector
4faf2300ee Remove most of GP function's docstring 2023-08-30 12:14:24 -04:00
Lee Spector
0aa8af7993 Add pmapallv utility function 2023-08-30 12:02:46 -04:00
Lee Spector
ee3f8372c8 Add boolean multiplier problems, with temporary default settings 2023-08-28 19:49:49 -04:00
Lee Spector
6eccd21ece
Include CLI tools version of example command lines 2023-04-16 09:11:54 -04:00
Lee Spector
fa9d0a3740 Update docs and bump version 2023-03-29 15:14:56 -04:00
Lee Spector
cb2aad6c17 Add word space 2023-03-29 14:18:10 -04:00
Lee Spector
d6283328db Remove old, incomplete fizz-buzz problem file 2023-03-29 14:14:43 -04:00
Lee Spector
42285ded02 Remove calls to shutdown-agents 2023-03-29 14:10:55 -04:00
Lee Spector
99d3e2ff0b Update docs 2023-03-28 23:14:49 -04:00
Lee Spector
47e7fdc885 Bump version 2023-03-28 23:02:32 -04:00
Lee Spector
d63044ea47 Update docs 2023-03-28 23:00:35 -04:00
Lee Spector
452de0a25a Add doc html files 2023-03-28 22:56:46 -04:00
Lee Spector
395ceac019 Update depricated clj --main to -M -m 2023-03-28 22:53:31 -04:00
Lee Spector
565ae1e79b
Merge pull request #59 from FluffyChipmunk/master
updated documentation to generate docs
2023-03-28 09:05:24 -04:00
Ashley Bao
341a5820ab updated documentation 2023-03-28 09:02:28 -04:00
Lee Spector
65af250d55
Comment out test until issue resolved 2023-03-26 21:34:00 -04:00
Lee Spector
bba21625a0
Improve wording 2023-03-26 21:29:47 -04:00
Lee Spector
83d5820c41
Add note about loading problem files 2023-03-26 21:28:04 -04:00
Lee Spector
23eb926482
Update psb2 dependency, for clj runs on PSB problems 2023-03-26 21:25:15 -04:00
Ryan Boldi
d226c82074 Merge remote-tracking branch 'upstream/master' 2023-03-24 08:50:28 -04:00
Lee Spector
9053be5a5a
Add link to GitHub Pages documentation 2023-03-23 12:47:05 -04:00
Lee Spector
26b6643ed6
Add note about loading problem file separately 2023-03-23 12:27:08 -04:00
Lee Spector
2784998196
Remove require of propeller.problems.data-creation 2023-03-23 00:38:59 -04:00
Lee Spector
98526b0e49
Remove require of propeller.problems.data-creation 2023-03-23 00:38:24 -04:00
Lee Spector
a5156b3747
Remove require of propeller.problems.data-creation 2023-03-23 00:37:59 -04:00
Lee Spector
61f2df857f
Remove require of propeller.problems.data-creation 2023-03-23 00:37:24 -04:00
Ryan Boldi
1c0805169f Merge remote-tracking branch 'upstream/master' 2023-03-17 10:45:37 -04:00
Lee Spector
9ec0ff890f
Fix -main documentation string 2023-03-16 13:09:33 -04:00
Lee Spector
63fcb33ca9
Fix -main documentation string 2023-03-16 13:08:52 -04:00
Lee Spector
c02f64dd68
Fix -main documentation string 2023-03-16 13:07:57 -04:00
Lee Spector
37020697a8
Fix -main documentation string 2023-03-16 13:07:28 -04:00
Lee Spector
87e99306f8
Fix -main documentation string 2023-03-16 13:06:07 -04:00
Lee Spector
c1c5b2ff1a
Fix -main documentation string 2023-03-16 13:05:37 -04:00
Lee Spector
8313af4eec
Fix -main documentation string 2023-03-16 13:05:14 -04:00
Lee Spector
b2f9ee1fb2
Fix -main documentation string 2023-03-16 13:04:44 -04:00
Lee Spector
bd8628695b
Fix -main documentation string 2023-03-16 13:04:04 -04:00
Lee Spector
7162d8c049
Fix -main documentation string 2023-03-16 13:03:42 -04:00
Lee Spector
78a83fe798
Fix -main documentation string 2023-03-16 13:03:21 -04:00
Lee Spector
c49a722306
Fix -main documentation string 2023-03-16 13:02:47 -04:00
Lee Spector
5a9cf36840
Fix -main documentation string 2023-03-16 13:02:17 -04:00
Lee Spector
789b624555
Fix -main documentation string 2023-03-16 13:01:50 -04:00
Lee Spector
4cc087eaa9
Fix -main documentation string 2023-03-16 12:57:09 -04:00
Lee Spector
e8a84745c8
Fix -main documentation string 2023-03-16 12:54:02 -04:00
Lee Spector
8fc7305573
Fix -main documentation string 2023-03-16 12:50:39 -04:00
Lee Spector
8b5009ccdb
Fix -main documentation string 2023-03-16 12:46:23 -04:00
Lee Spector
bcae0e4a36
Fix -main documentation string 2023-03-16 12:43:03 -04:00
Lee Spector
0d0068cd31
Fix -main documentation string 2023-03-16 12:36:58 -04:00
Lee Spector
f442a59c7d
Fix -main documentation string 2023-03-16 12:35:39 -04:00
Lee Spector
7f93ae0bf1
Fix -main documentation string 2023-03-16 12:33:33 -04:00
Lee Spector
f4a8d55b4c
Fix -main documentation string 2023-03-16 12:29:49 -04:00
Lee Spector
0622547a8c
Fix -main documentation string 2023-03-16 12:27:38 -04:00
Lee Spector
9209fa2975
Fix -main documentation string 2023-03-16 12:27:01 -04:00
Lee Spector
116eb9d625
Fix -main documentation string 2023-03-16 12:26:24 -04:00
Lee Spector
aca79750b5
Fix -main documentation string 2023-03-16 12:25:43 -04:00
Lee Spector
a076223a6e
Fix -main documentation string 2023-03-16 12:22:52 -04:00
Lee Spector
3666f51d97
Fix -main documentation string 2023-03-16 12:22:05 -04:00
Lee Spector
c0d5e4e819
Fix -main documentation string 2023-03-16 12:21:25 -04:00
Lee Spector
339857f955
Fix -main documentation string 2023-03-16 12:20:51 -04:00
Lee Spector
86e0f6e3ef
Add examples of calls to -main, documentation 2023-03-15 23:11:32 -04:00
Lee Spector
313a4d5b2f
Update README.md
Fix typos
2023-03-15 22:51:42 -04:00
Lee Spector
a68f1bdfbc
Update README.md
Add instructions for using CLI tools. Remove instructions for working at REPL, which are superseded by the instructions for using `session.cljc`.
2023-03-15 22:48:45 -04:00
Lee Spector
4eb5e93112
Update float_regression.cljc
Use float constants, no exec or boolean instructions, and epsilon lexicase selection
2023-03-07 18:30:06 -05:00
Lee Spector
340715c6e1
Update README.md 2023-03-07 11:13:11 -05:00
Ryan Boldi
23a8b0648a Merge remote-tracking branch 'upstream/master' 2023-02-17 10:21:26 -05:00
Ryan Boldi
00b82ef7b3 remove dependency on datasets 2023-02-17 10:19:39 -05:00
Ryan Boldi
da90f2de8e removing datasets. using psb2.core 2023-02-17 09:57:22 -05:00
Ryan Boldi
a8e42475b5 Update selection_test.cljc 2023-01-10 10:57:20 +01:00
Ryan Boldi
cc9e250a1b Create UBall5D.cljc 2023-01-10 10:30:14 +01:00
Ryan Boldi
2d5bc49d86 Update float_regression.cljc 2023-01-10 09:01:05 +01:00
Ryan Boldi
ed37be0720 Update downsample.cljc 2023-01-09 16:28:36 +01:00
Ryan Boldi
68bab20143 prepped for integer and float regression runs 2023-01-08 15:08:29 +01:00
Ryan Boldi
d9e16aa028 implemented soft ids, where being a threshold away from solved still counts as being solved. 2023-01-08 14:26:36 +01:00
Ryan Boldi
43752ed6e0 Merge branch 'master' 2023-01-07 22:54:37 +01:00
Ryan Boldi
c40f1f70f4 added fitness proportionate selection + tests 2023-01-05 12:40:15 +01:00
Ryan Boldi
2a76d32479 Update .gitignore 2023-01-04 21:38:39 +01:00
Ryan Boldi
4625475e90 Update grade.cljc 2022-12-21 21:03:51 -05:00
Ryan Boldi
77ec7b121e Update gp.cljc 2022-12-21 21:03:49 -05:00
Ryan Boldi
e3ef43e95a overhaul to down-sampling. Separated selection from the down-sampling type.
Also, added to the docs to help startup faster
2022-12-12 11:53:14 -05:00
Ryan Boldi
b4e4552acb implemented elite/not elite vector tracking, moved tests 2022-11-17 20:23:46 -05:00
Ryan Boldi
e011fa7892 added armins function and tests 2022-11-17 20:22:51 -05:00
Ryan Boldi
1cdf6f5640 account for generation interval in eval counting 2022-11-08 15:48:12 -05:00
Ryan Boldi
f6a412d605 added evaluation tracking, automatically stopping at a consistent number of evals 2022-11-07 18:43:36 -05:00
Ryan Boldi
1f62d9ca41 fixed autods errors 2022-10-25 13:00:50 -04:00
Ryan Boldi
fc738e2154 tested and fixed auto-ds size 2022-10-18 15:45:31 -04:00
Ryan Boldi
7467f638a7 Merge branch 'biased-downsampling-exp' into auto-ds-size 2022-10-13 09:27:25 -04:00
Ryan Boldi
28b76e14ab fixed find-pair bug 2022-08-19 11:23:35 -04:00
Ryan Boldi
0ffed2b56c fix find-pair (maybe) 2022-08-16 11:13:25 -04:00
Ryan Boldi
239de881ce fixed scrabble score test-data bugs. (might revert) 2022-08-14 09:36:56 -04:00
Ryan Boldi
6ffd3bea59 grade is now easier, more aligned with comparison. Doesn't use whole string, just output letter. 2022-08-14 09:34:31 -04:00
Ryan Boldi
75fd08e1dc fixed scrabble score bug 2022-08-02 09:33:05 -04:00
Ryan Boldi
560a614afa Update find_pair.cljc 2022-07-31 09:53:38 -04:00
Ryan Boldi
27e64b2362 grade prints, scrabble score doesn't 2022-07-31 09:10:20 -04:00
Ryan Boldi
dd1fc99205 Update find_pair.cljc 2022-07-29 10:50:08 -04:00
Ryan Boldi
98d6881d68 Create find_pair.cljc 2022-07-29 10:48:50 -04:00
Ryan Boldi
98474297fb Update small_or_large.cljc 2022-06-20 22:30:08 -04:00
Ryan Boldi
39aa7a8cf3 implemented all problems but find-pair 2022-06-16 11:14:43 -04:00
Ryan Boldi
039769eaf6 gcd problem implemented 2022-06-11 10:30:51 -04:00
Ryan Boldi
cddb60c63f data parsing works for data with strings now 2022-06-11 10:24:45 -04:00
Ryan Boldi
6bc31e2d9c implemented auto downsample size 2022-06-08 08:51:16 -04:00
Ryan Boldi
72d325a609 stopped creating data 2022-06-07 10:44:50 -04:00
Ryan Boldi
b5763dcc5a added boolean flag to not end runs on success 2022-06-07 09:42:55 -04:00
Ryan Boldi
b5953d3779 Update fuel_cost.cljc 2022-06-05 21:15:23 -04:00
Ryan Boldi
6f152a0357 fixed multiple in/out problems 2022-06-05 21:15:20 -04:00
Ryan Boldi
1cc584ca44 fixed erroneous test 2022-06-05 10:27:30 -04:00
Ryan Boldi
f39d5e76cd logging indices now 2022-06-05 10:17:23 -04:00
Ryan Boldi
b591403fe8 hyperselection implementation and tests
really hacky implementation that only works with UMAD for now.
2022-06-05 10:09:05 -04:00
Ryan Boldi
17f2676a47 Delete down-sampling-data.zip 2022-06-05 10:08:07 -04:00
Ryan Boldi
3ced7bd0fd Update count-odds-test.csv 2022-06-05 10:07:20 -04:00
Ryan Boldi
032a9cc1ab added data and data-creation file, fixed issues 2022-06-05 10:07:11 -04:00
Ryan Boldi
639d08b405 added picked datasets 2022-06-03 22:09:38 -04:00
Ryan Boldi
0cc5cec53a Update data_creation.cljc 2022-06-03 22:06:38 -04:00
Ryan Boldi
42def900d6 data-creation script 2022-06-03 11:16:32 -04:00
Ryan Boldi
fa681bef44 Update simple_classification.cljc 2022-05-15 14:47:29 -04:00
Ryan Boldi
667b04312b added ability to evaluate individuals every k generations 2022-05-14 19:49:51 -04:00
Ryan Boldi
d9171bcb51 argmax NOW tiebreaks randomly 2022-05-05 14:58:15 -04:00
Ryan Boldi
4fffe9e8f3 fixed some printing errors resulting from different input representations 2022-05-05 13:58:26 -04:00
Ryan Boldi
2b234a988b breaks ties randomly 2022-05-05 13:57:59 -04:00
Ryan Boldi
49d1287335 New param, ds-parent-rate, that changes how many parents become the representative population. At 1, this is just full information. 2022-04-27 13:22:57 -04:00
Ryan Boldi
816b443658 retested max-min, and added some new logging to judge case proportions 2022-04-13 22:54:33 -04:00
Ryan Boldi
e3dfcfd58e Create simple_classification.cljc 2022-04-09 15:42:43 -04:00
Ryan Boldi
cebdd1aa20 Update complex_regression.cljc 2022-04-05 15:34:38 -04:00
Ryan Boldi
4f9ed1f267 Update complex_regression.cljc 2022-04-05 15:21:55 -04:00
Ryan Boldi
11b09c9be0 Update complex_regression.cljc 2022-04-03 23:08:49 -04:00
Ryan Boldi
336710144d Create complex_regression.cljc 2022-04-02 14:49:27 -04:00
Ryan Boldi
217f195047 Implemented max-min, which takes the maximum minimum distance into account instead of average distances 2022-03-29 15:32:34 -04:00
Ryan Boldi
bff8f0673c evals the whole population to be used for distance calculations 2022-03-28 22:08:22 -04:00
Ryan Boldi
b33ac7c0a4 evaluate all distances every k generations 2022-03-16 11:07:08 -04:00
Ryan Boldi
9b81e345df Update downsample.md 2022-03-14 19:04:37 -04:00
Ryan Boldi
43fde4c7ad Implements first case subsampling function. 2022-03-14 19:04:32 -04:00
Ryan Boldi
22b7067f10 add and test helper functions 2022-03-14 19:02:47 -04:00
Ryan Boldi
f763db91a2 only do distance calculations if parent-selection is ds-lexicase 2022-03-12 14:05:55 -05:00
Ryan Boldi
287799f194 implemented downsampling and distance measuring/updating
Features:

- Tests!
- maintain index of all training-cases
- update distance of training-cases after every evaluation (only update cases that are in the downsample)
- when an individual passes all of the DS cases, the population is re-evaluated on all training-cases to see if they pass all of them. If so, evolution is completed and training is complete. (they are then tested on held out test set and performance is reported)
2022-03-12 13:59:47 -05:00
Ryan Boldi
83c7e440f6 added step function to math utils 2022-03-12 13:55:47 -05:00
Ryan Boldi
72e31b5c4d made defaults use UMAD 100% of the time 2022-03-12 13:55:31 -05:00
Ryan Boldi
d1044f1ab4 Update simplification.cljc 2022-03-07 14:04:58 -05:00
Ryan Boldi
32f374635a Update utils_test.cljc 2022-03-06 23:33:50 -05:00
Ryan Boldi
4a03a19190 Merge branch 'master' of https://www.github.com/lspector/propeller into downsample 2022-03-06 23:27:00 -05:00
Ryan Boldi
527f115168 downsample takes training-data as arg 2022-03-06 23:24:13 -05:00
Ryan Boldi
45b19fbd3e implement assign-indices-to-data and select-downsample-random and tests 2022-03-03 21:43:44 -05:00
Ryan Boldi
8c074a4ba8 update documentation to include simplification 2022-03-03 21:29:42 -05:00
146 changed files with 5159 additions and 857 deletions

2
.gitignore vendored
View File

@ -23,6 +23,7 @@ notes
/temp /temp
*~ *~
q q
scratch.clj
# Clojure Script # Clojure Script
.shadow-cljs/ .shadow-cljs/
@ -33,4 +34,5 @@ node_modules/
# https://github.com/thelmuth/program-synthesis-benchmark-datasets # https://github.com/thelmuth/program-synthesis-benchmark-datasets
/data /data
**/.DS_Store **/.DS_Store
*.edn
/.cpcache/ /.cpcache/

View File

@ -2,37 +2,86 @@
Yet another Push-based genetic programming system in Clojure. Yet another Push-based genetic programming system in Clojure.
Full documentation is on the GitHub pages link. Propeller is a component of several active research projects and it is subject to change as a part of these activities.
See the git commit comments for guidance with respect to recent changes.
Some documentation is available at [https://lspector.github.io/propeller/](https://lspector.github.io/propeller/), but this should be evaluated in the context of the commit messages and current source code.
## About this fork
This is mainly for personal use to develop inside of Nix environment. Check out the original on package on [github](https://github.com/lspector/propeller).
### How to jack into the project
Once you've ran `nix develop` and vscodium has appeared, click the REPL
button in the bottom left of the screen. Click
`Start your project with a REPL and connect (a.k.a Jack-in)`, select
`Leiningen`, and don't select a profile, instead click `OK`. A window should appear to the right with Calva's REPL.
Head over to `src/propeller/session.cljc` as described below and click
`ctrl + alt + c` then `Enter` to source the session file.
## Usage ## Usage
If you have installed [leiningen](https://leiningen.org), which is a tool If you are working in a Clojure IDE with an integrated REPL, the first
for running Clojure programs, then you can run Propeller on a genetic thing you may want to do is to open `src/propeller/session.cljc` and
programming problem that is defined within this project from the command evaluate the namespace declaration and the commented-out expressions
line with the command `lein run -m <namespace>`, replacing `<namespace>` therein. These demonstrate core components of Propeller including
complete genetic programming runs. When conducting complete genetic
programming runs this way (using `gp/gp`), depending on your IDE you
may need to explicitly open and load the problem file before evaluating
the calls to `require` and `gp/gp`.
To run Propeller from the command line, on a genetic programming problem
that is defined within this project, you will probably want to use either
the Clojure [CLI tools](https://clojure.org/guides/deps_and_cli) or
[leiningen](https://leiningen.org). In the examples below, the leiningen
and CLI commands are identical except that the former begin with
`lein run -m`, while the latter begin with `clj -M -m`.
To start a run use `clj -M -m <namespace>` or
`lein run -m <namespace>`, replacing `<namespace>`
with the actual namespace that you will find at the top of the problem file. with the actual namespace that you will find at the top of the problem file.
For example, you can run the simple-regression genetic programming problem with: For example, you can run the integer-regression genetic programming problem with:
``` ```
lein run -m propeller.problems.simple-regression clj -M -m propeller.problems.regression.integer-regression
```
or
```
lein run -m propeller.problems.regression.integer-regression
``` ```
Additional command-line arguments may Additional command-line arguments may
be provided to override the default key/value pairs specified in the be provided to override the default key/value pairs specified in the
problem file, for example: problem file, for example:
```
clj -M -m propeller.problems.regression.integer-regression :population-size 100
```
or
``` ```
lein run -m propeller.problems.simple-regression :population-size 100 lein run -m propeller.problems.regression.integer-regression :population-size 100
``` ```
On Unix operating systems, including MacOS, you can use something On Unix operating systems, including MacOS, you can use something
like the following to send output both to the terminal like the following to send output both to the terminal
and to a text file (called `outfile` in this example): and to a text file (called `outfile` in this example):
``` ```
lein run -m propeller.problems.simple-regression | tee outfile clj -M -m propeller.problems.regression.integer-regression | tee outfile
```
or
```
lein run -m propeller.problems.regression.integer-regression | tee outfile
``` ```
If you want to provide command line arguments that include If you want to provide command line arguments that include
@ -43,24 +92,22 @@ value for the `:variation` argument, which is a clojure map
containing curly brackets that may confuse your shell: containing curly brackets that may confuse your shell:
``` ```
lein run -m propeller.problems.simple-regression :variation "{:umad 1.0}" clj -M -m propeller.problems.regression.integer-regression :variation "{:umad 1.0}"
``` ```
To run a genetic programming problem from a REPL, start or
your REPL for the project (e.g. with `lein repl` at the
command line when in the project directory, or through your
IDE) and then do something like the following (which in
this case runs the simple-regression problem with
`:population-size` 100):
``` ```
(require 'propeller.problems.simple-regression) lein run -m propeller.problems.regression.integer-regression :variation "{:umad 1.0}"
(in-ns 'propeller.problems.simple-regression)
(-main :population-size 100 :variation {:umad 1.0})
``` ```
If you want to run the problem with the default parameters, For many genetic operator hyperparameters, collections may be provided in place of single values. When this is done, a random element of the collection will be chosen (with each being equally likely) each time the operator is used. When specied at the command line, these collections will also have to be quoted, for example with `:umad-rate "[0.01 0.05 0.1]"` to mean that UMAD rates of 0.01, 0.05, and 0.1 can be used.
then you should call `-main` without arguments, as `(-main)`.
By default, Propeller will conduct many processes concurrently on multiple
cores using threads. If you want to disable this behavior (for example, during
debugging) then provide the argument `:single-thread-mode` with the value `true`.
Threads are not available in Javascript, so no processes are run concurrnetly
when Propeller is run in Clojurescript.
## CLJS Usage ## CLJS Usage
@ -96,8 +143,9 @@ Calling `(-main)` will run the default genetic programming problem.
## Description ## Description
Propel is an implementation of the Push programming Propeller is an implementation of the Push programming
language and the PushGP genetic programming system in Clojure. language and the PushGP genetic programming system in Clojure, based
on Tom Helmuth's little PushGP implementation [propel](https://github.com/thelmuth/propel).
For more information on Push and PushGP see For more information on Push and PushGP see
[http://pushlanguage.org](http://pushlanguage.org). [http://pushlanguage.org](http://pushlanguage.org).

View File

@ -3,7 +3,8 @@
{org.clojure/clojure #:mvn{:version "1.10.0"}, {org.clojure/clojure #:mvn{:version "1.10.0"},
org.clojure/clojurescript #:mvn{:version "1.9.946"}, org.clojure/clojurescript #:mvn{:version "1.9.946"},
org.clojure/test.check #:mvn{:version "1.1.0"}, org.clojure/test.check #:mvn{:version "1.1.0"},
net.clojars.schneau/psb2 #:mvn{:version "1.1.0"}}, net.clojars.schneau/psb2 #:mvn{:version "1.1.1"}
org.clojure/data.csv #:mvn{:version "1.0.1"}},
:mvn/repos {} :mvn/repos {}
:codox {:extra-deps {codox/codox {:mvn/version "0.10.8"}} :codox {:extra-deps {codox/codox {:mvn/version "0.10.8"}}
:exec-fn codox.main/generate-docs :exec-fn codox.main/generate-docs

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

27
flake.lock generated Normal file
View File

@ -0,0 +1,27 @@
{
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1741600792,
"narHash": "sha256-yfDy6chHcM7pXpMF4wycuuV+ILSTG486Z/vLx/Bdi6Y=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "ebe2788eafd539477f83775ef93c3c7e244421d3",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-24.11",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"nixpkgs": "nixpkgs"
}
}
},
"root": "root",
"version": 7
}

42
flake.nix Normal file
View File

@ -0,0 +1,42 @@
{
description = "A flake for developing in a clojure environment with vscode";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-24.11";
};
outputs = { nixpkgs, ... }:
let system = "x86_64-linux"; in
{
devShells."${system}".default =
let
pkgs = nixpkgs.legacyPackages."${system}";
in
pkgs.mkShellNoCC {
buildInputs = [ pkgs.bashInteractive ];
packages = with pkgs; [
clojure
clojure-lsp
leiningen
nodejs
jdk8
(vscode-with-extensions.override {
vscode = vscodium;
vscodeExtensions = pkgs.vscode-utils.extensionsFromVscodeMarketplace [
{
name = "calva";
publisher = "betterthantomorrow";
version = "2.0.490";
sha256 = "sha256-PCEzSWahrTHXeGFrFShvbXrnoq3AtuVkoohKLxBGDRA=";
}
];
})
];
shellHook = ''
export SHELL=${pkgs.lib.getExe pkgs.bashInteractive}
echo "starting codium"
codium .
'';
};
};
}

17
package-lock.json generated
View File

@ -723,13 +723,10 @@
"dev": true "dev": true
}, },
"node_modules/minimist": { "node_modules/minimist": {
"version": "1.2.8", "version": "1.2.5",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
"dev": true, "dev": true
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
}, },
"node_modules/mkdirp": { "node_modules/mkdirp": {
"version": "0.5.5", "version": "0.5.5",
@ -1934,9 +1931,9 @@
"dev": true "dev": true
}, },
"minimist": { "minimist": {
"version": "1.2.8", "version": "1.2.5",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
"dev": true "dev": true
}, },
"mkdirp": { "mkdirp": {

View File

@ -1,4 +1,4 @@
(defproject net.clojars.lspector/propeller "0.3.0" (defproject net.clojars.lspector/propeller "0.3.2"
:description "Yet another Push-based genetic programming system in Clojure." :description "Yet another Push-based genetic programming system in Clojure."
:url "https://github.com/lspector/propeller" :url "https://github.com/lspector/propeller"
:license {:name "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0" :license {:name "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0"
@ -6,7 +6,8 @@
:dependencies [[org.clojure/clojure "1.10.0"] :dependencies [[org.clojure/clojure "1.10.0"]
[org.clojure/clojurescript "1.9.946"] [org.clojure/clojurescript "1.9.946"]
[org.clojure/test.check "1.1.0"] [org.clojure/test.check "1.1.0"]
[net.clojars.schneau/psb2 "1.1.1"]] [net.clojars.schneau/psb2 "1.1.1"]
[org.clojure/data.csv "1.0.1"]]
:profiles {:profiling {:dependencies [[com.clojure-goes-fast/clj-async-profiler "0.5.1"]]}} :profiles {:profiling {:dependencies [[com.clojure-goes-fast/clj-async-profiler "0.5.1"]]}}
:main ^:skip-aot propeller.core :main ^:skip-aot propeller.core
:repl-options {:init-ns propeller.core} :repl-options {:init-ns propeller.core}

1
scripts/GenerateDocs.sh Normal file → Executable file
View File

@ -1,5 +1,6 @@
#!/bin/sh #!/bin/sh
pip install mdutils
lein codox lein codox
python3 FunctionsToMD.py python3 FunctionsToMD.py
python3 HTMLFix.py python3 HTMLFix.py

View File

@ -39,9 +39,9 @@ line with the command `lein run -m <namespace>`, replacing `<namespace>`
with the actual namespace that you will find at the top of the problem file. with the actual namespace that you will find at the top of the problem file.
If you have installed [Clojure](https://clojure.org/guides/install_clojure#java), you can run Propeller on a genetic programming If you have installed [Clojure](https://clojure.org/guides/install_clojure#java), you can run Propeller on a genetic programming
problem with the command `clj --main <namespace>`, replacing `<namespace>` with problem with the command `clj -M -m <namespace>`, replacing `<namespace>` with
the actual namespace that you will find at the top of the problem file. the actual namespace that you will find at the top of the problem file.
The examples below use leiningen, but you can replace `lein run -m` with `clj --main` to run the same problem. The examples below use leiningen, but you can replace `lein run -m` with `clj -M -m` to run the same problem.
A specific example is provided later below. A specific example is provided later below.

View File

@ -116,7 +116,6 @@ instructions from `push/instructions`, input instructions, close, and constants
:umad-rate 0.1 :umad-rate 0.1
:variation {:umad 1.0 :crossover 0.0} :variation {:umad 1.0 :crossover 0.0}
:elitism false} :elitism false}
(apply hash-map (map #(if (string? %) (read-string %) %) args)))) (apply hash-map (map #(if (string? %) (read-string %) %) args)))))
(#?(:clj shutdown-agents)))
``` ```

View File

@ -7,8 +7,10 @@ Table of contents
* [Additional Instructions](#additional-instructions) * [Additional Instructions](#additional-instructions)
* [input_output.cljc](#input_outputcljc) * [input_output.cljc](#input_outputcljc)
* [.DS_Store](#ds_store)
* [numeric.cljc](#numericcljc) * [numeric.cljc](#numericcljc)
* [string.cljc](#stringcljc) * [string.cljc](#stringcljc)
* [parentheses.cljc](#parenthesescljc)
* [character.cljc](#charactercljc) * [character.cljc](#charactercljc)
* [bool.cljc](#boolcljc) * [bool.cljc](#boolcljc)
* [code.cljc](#codecljc) * [code.cljc](#codecljc)
@ -19,8 +21,12 @@ Table of contents
## :print_newline ## :print_newline
Prints new line Prints new line
# .DS_Store
# numeric.cljc # numeric.cljc
## :float_div
Divides the top two items on the float stack If denominator is 0, returns 1.0
## :float_cos ## :float_cos
Pushes the cosine of the top FLOAT Pushes the cosine of the top FLOAT
## :float_sin ## :float_sin
@ -93,6 +99,8 @@ Splits the top STRING on whitespace, and pushes back the resulting components in
Pushes the substring of the top STRING, with beginning and end indices determined by the second topmost and topmost INTEGERs respectively. If an index is out of bounds, the beginning/end of the string is used instead Pushes the substring of the top STRING, with beginning and end indices determined by the second topmost and topmost INTEGERs respectively. If an index is out of bounds, the beginning/end of the string is used instead
## :string_take ## :string_take
Pushes the substring of the top STRING consisting of its first n letters, where n is determined by the top INTEGER Pushes the substring of the top STRING consisting of its first n letters, where n is determined by the top INTEGER
# parentheses.cljc
# character.cljc # character.cljc
## :char_is_letter ## :char_is_letter

View File

@ -0,0 +1,56 @@
Downsampling the Training Data
=
Downsampling is a very simple way to improve the efficiency of your evolutionary runs. It might allow for deeper evolutionary searches and a greater success rate.
Using Downsampled selection with propeller is easy:
Set the :parent-selection argument to whichever selection strategy you would like, and set the :downsample? argument to true as follows:
```clojure
lein run -m propeller.problems.simple-regression :parent-selection :lexicase :downsample? true <required downsampling args here>
```
The number of evaluations is held constant when comparing to a full training set run, so set the :max-generations to a number of generations that you would have gone to using a **full** sample.
## Downsample Functions
In this repository, you have access to 3 different downsampling functions. These are the methods used to take a down-sample from the entire training set.
To use them, add the argument ```:ds-function``` followed by which function you would like to us
The list is
- ```:case-maxmin``` - This is the method used for informed down-sampled lexicase selection
- ```:case-maxmin-auto``` - This method automatically determines the downsample size
- ```:case-rand```- Random Sampling
### Using ```:case-maxmin```:
In order to use regular informed down-sampled selection, you must specify a few things:
- ```:downsample-rate```- This is the $r$ parameter: what proportion of the full sample should be in the down-sample $\in [0,1]$
- ```:ds-parent-rate``` - This is the $\rho$ parameter: what proportion of parents are used to evaluate case distances $\in [0,1]$
- ```:ds-parent-gens``` - This is the $k$ parameter: How many generations in between parent evaluations for distances $\in \{1,2,3, \dots\}$
### Using ```:case-maxmin-auto```:
In order to use automatic informed down-sampled selection, you must specify a few things:
- ```:case-delta ```- This is the $\Delta$ parameter: How close can the farthest case be from its closest case before we stop adding to the down-sample
- ```:ids-type``` - Either ```:elite``` or ```:solved ``` - Specifies whether we are using elite/not-elite or solved/not-solved as our binary-fication of case solve vectors.
- ```:ds-parent-rate``` - This is the $\rho$ parameter: what proportion of parents are used to evaluate case distances $\in [0,1]$
- ```:ds-parent-gens``` - This is the $k$ parameter: How many generations in between parent evaluations for distances $\in \{1,2,3, \dots\}$
### Using ```:case-rand```:
In order to use regular randomly down-sampled selection, you must specify a few things:
- ```:downsample-rate```- This is the $r$ parameter: what proportion of the full sample should be in the down-sample $\in [0,1]$
Here's an example of running informed downsampled lexicase selection with $r=0.1$, $\rho=0.01$ and $k=100$ on the simple classification problem:
```clojure
lein run -m propeller.problems.simple-classification :parent-selection :lexicase :downsample? true :ds-function :case-maxmin :downsample-rate 0.1 :max-generations 300 :ds-parent-rate 0.01 :ds-parent-gens 100
```

View File

@ -1,6 +1,9 @@
# Generating Documentation for Propeller # Generating Documentation for Propeller
To generate documentation with [codox](https://github.com/weavejester/codox), run `scripts/GenerateDocs.sh`in the command line. In order to generate documentation, you'll need Python and `pip` installed.
To generate documentation with [codox](https://github.com/weavejester/codox), run `scripts/GenerateDocs.sh` in the command line from the `scripts` directory.
To make the script executable, you may need to first run `chmod +x GenerateDocs.sh`.
This will run "lein codox" on the command line to generate first batch of HTMl files. This will run "lein codox" on the command line to generate first batch of HTMl files.
Then, it runs FunctionsToMD to take Push instructions generated by `def-instruction` and spit it out to a Markdown file. Then, it runs FunctionsToMD to take Push instructions generated by `def-instruction` and spit it out to a Markdown file.
Then, it runs HTMLFix to fix the ordered lists in `Adding_Genetic_Operators.md`, `Adding_Problem.md`, and Then, it runs HTMLFix to fix the ordered lists in `Adding_Genetic_Operators.md`, `Adding_Problem.md`, and

View File

@ -0,0 +1,132 @@
(ns propeller.downsample
(:require [propeller.tools.math :as math]
[propeller.tools.metrics :as metrics]
[propeller.utils :as utils]))
(defn assign-indices-to-data
"assigns an index to each training case in order to differentiate them when downsampling"
[training-data argmap]
(utils/pmapallv (fn [data-map index]
(let [data-m (if (map? data-map) data-map (assoc {} :data data-map))] ;if data is not in a map, make it one
(assoc data-m :index index)))
training-data (range (count training-data)) argmap))
(defn initialize-case-distances
[{:keys [training-data population-size] :as argmap}]
(utils/pmapallv #(assoc % :distances (vec (repeat (count training-data) population-size))) training-data argmap))
(defn select-downsample-random
"Selects a downsample from the training cases and returns it"
[training-data {:keys [downsample-rate]}]
(take (int (* downsample-rate (count training-data))) (shuffle training-data)))
(defn select-downsample-maxmin
"selects a downsample that has it's cases maximally far away by sequentially
adding cases to the downsample that have their closest case maximally far away"
[training-data {:keys [downsample-rate]}]
(let [shuffled-cases (shuffle training-data)
goal-size (int (* downsample-rate (count training-data)))]
(loop [new-downsample (conj [] (first shuffled-cases))
cases-to-pick-from (rest shuffled-cases)]
(if (>= (count new-downsample) goal-size)
new-downsample
(let [tournament cases-to-pick-from
min-case-distances (metrics/min-of-colls
(map (fn [distance-list]
(utils/filter-by-index distance-list (map #(:index %) tournament)))
(map #(:distances %) new-downsample)))
selected-case-index (metrics/argmax min-case-distances)]
(recur (conj new-downsample (nth tournament selected-case-index))
(shuffle (utils/drop-nth selected-case-index tournament))))))))
(defn select-downsample-maxmin-adaptive
"selects a downsample that has it's cases maximally far away by sequentially
adding cases to the downsample that have their closest case maximally far away
automatically stops when the maximum minimum distance is below delta"
[training-data {:keys [case-delta]}]
(let [shuffled-cases (shuffle training-data)]
(loop [new-downsample (conj [] (first shuffled-cases))
cases-to-pick-from (rest shuffled-cases)]
(let [tournament cases-to-pick-from
min-case-distances (metrics/min-of-colls
(map (fn [distance-list]
(utils/filter-by-index distance-list (map #(:index %) tournament)))
(map #(:distances %) new-downsample)))
selected-case-index (metrics/argmax min-case-distances)]
(if (or (= 0 (count tournament)) (<= (apply max min-case-distances) case-delta))
new-downsample
(recur (conj new-downsample (nth tournament selected-case-index))
(shuffle (utils/drop-nth selected-case-index tournament))))))))
(defn get-distance-between-cases
"returns the distance between two cases given a list of individual error vectors, and the index these
cases exist in the error vector. Only makes the distinction between zero and nonzero errors"
[error-lists case-index-1 case-index-2]
(if (or (< (count (first error-lists)) case-index-1)
(< (count (first error-lists)) case-index-2)
(neg? case-index-1) (neg? case-index-2))
(count error-lists) ;return the max distance
(let [errors-1 (map #(nth % case-index-1) error-lists)
errors-2 (map #(nth % case-index-2) error-lists)]
;compute distance between errors-1 and errors-2
(reduce + (map (fn [e1 e2] (math/abs (- (math/step e1) (math/step e2)))) errors-1 errors-2)))))
(defn update-at-indices
"merges two vectors at the indices provided by a third vector"
[big-vec small-vec indices]
(->> big-vec
(map-indexed (fn [idx itm] (let [index (.indexOf indices idx)]
(if (not= -1 index) (nth small-vec index) itm))))
vec))
(defn merge-map-lists-at-index
"merges two lists of maps, replacing the maps in the big
list with their corresponding (based on index) maps in the small list"
[big-list small-list]
(map
#(let [corresponding-small (some (fn [c] (when (= (:index %) (:index c)) c)) small-list)]
(if (nil? corresponding-small) % corresponding-small))
big-list))
(defn replace-mins-with-zero
"replaces the minimum value(s) in a list with zero"
[coll]
(if (empty? coll)
'()
(let [m (apply min coll)]
(map #(if (= m %) 0 %) coll))))
(defn replace-close-zero-with-zero
"replaces values within a delta of zero with zero, used for regression problems"
[coll delta]
(map #(if (>= delta %) 0 %) coll))
(defn convert-to-elite-error
"converts a set of errors into a list where all the elite errors are replaced with 0s so that we can use
it in the selection of down-samples with elite/not-elite selection"
[errors]
(map #(replace-mins-with-zero %) errors))
(defn convert-to-soft-error
[errors delta]
(map #(replace-close-zero-with-zero % delta) errors))
(defn update-case-distances
"updates the case distance field of training-data list, should be called after evaluation of individuals
evaluated-pop should be a list of individuals that all have the :errors field with a list of this
individuals performance on the each case in the training-data, in order. ids-type is :elite to use elite/not-elite, :soft to consider near solves, and :solved to use solve/not-solved"
([evaluated-pop ds-data training-data ids-type]
(update-case-distances evaluated-pop ds-data training-data ids-type 0)) ; default solution threshold is 0, only used if ids-type is :soft
([evaluated-pop ds-data training-data ids-type solution-threshold]
(let [ds-indices (map #(:index %) ds-data)
errors (map #(:errors %) evaluated-pop)
corr-errors (case ids-type
:elite (convert-to-elite-error errors)
:soft (convert-to-soft-error errors solution-threshold)
errors)] ;errors, including elite/not-elite distinction
(merge-map-lists-at-index
training-data (map-indexed
(fn [idx d-case] (update-in d-case
[:distances] #(update-at-indices
% (map (fn [other] (get-distance-between-cases corr-errors idx other))
(range (count ds-indices))) ds-indices))) ds-data)))))

View File

@ -2,29 +2,26 @@
"The genetic material in Propeller. A `plushy` is a list of Push instructions that represent a Push program. "The genetic material in Propeller. A `plushy` is a list of Push instructions that represent a Push program.
They hold the genetic material for an `individual`. In the initial population, we create random plushys." They hold the genetic material for an `individual`. In the initial population, we create random plushys."
{:doc/format :markdown} {:doc/format :markdown}
(:require [propeller.push.instructions :as instructions] (:require [propeller.push.instructions.parentheses :as parentheses]
[propeller.utils :as utils])) [propeller.utils :as utils]))
(defn make-random-plushy (defn make-random-plushy
"Creates and returns a new plushy made of random instructions and of a maximum size of max-initial-plushy-size." "Creates and returns a new plushy made of random instructions."
[instructions max-initial-plushy-size] [{:keys [instructions max-initial-plushy-size bmx? bmx-gene-length-limit]
(repeatedly :as argmap}]
(rand-int max-initial-plushy-size) (let [plushy (repeatedly (rand-int max-initial-plushy-size)
#(utils/random-instruction instructions))) #(utils/random-instruction instructions argmap))]
(if bmx?
(-> plushy
(utils/remove-empty-genes)
(utils/enforce-gene-length-limit bmx-gene-length-limit))
plushy)))
(defn plushy->push (defn plushy->push-internal
"Returns the Push program expressed by the given plushy representation. [plushy argmap]
(let [opener? #(and (vector? %) (= (first %) 'open))] ;; [open <n>] marks opens
The function takes in a plushy representation as input and converts it into a Push program by iteratively processing
the plushy elements and adding instructions to the push program.
It also handles the case where there are open instructions that need to be closed before the end of the program.
"
([plushy] (plushy->push plushy {}))
([plushy argmap]
(let [plushy (if (:diploid argmap) (map first (partition 2 plushy)) plushy)
opener? #(and (vector? %) (= (first %) 'open))] ;; [open <n>] marks opens
(loop [push () ;; iteratively build the Push program from the plushy (loop [push () ;; iteratively build the Push program from the plushy
plushy (mapcat #(let [n (get instructions/opens %)] plushy (mapcat #(let [n (get parentheses/opens %)]
(if (and n (if (and n
(> n 0)) (> n 0))
[% ['open n]] [% ['open n]]
@ -47,4 +44,16 @@ They hold the genetic material for an `individual`. In the initial population, w
(concat pre-open [post-open ['open (dec num-open)]]))) (concat pre-open [post-open ['open (dec num-open)]])))
(rest plushy)) (rest plushy))
(recur push (rest plushy))) ;; unmatched close, ignore (recur push (rest plushy))) ;; unmatched close, ignore
(recur (concat push [i]) (rest plushy))))))))) ;; anything else (recur (concat push [i]) (rest plushy)))))))) ;; anything else
(defn plushy->push
"Returns the Push program expressed by the given plushy representation."
;; use an empty argmap if none provided
([plushy]
(plushy->push plushy {}))
;; call plushy->push-internal with possibly-preprocessed plushy
([plushy argmap]
(plushy->push-internal (if (:bmx? argmap)
(filter (complement #{:gap}) plushy)
plushy)
argmap)))

View File

@ -1,10 +1,10 @@
(ns propeller.gp (ns propeller.gp
"Main genetic programming loop." "Main genetic programming loop."
(:require [clojure.string] (:require [clojure.string]
[clojure.pprint]
[propeller.genome :as genome] [propeller.genome :as genome]
[propeller.simplification :as simplification] [propeller.simplification :as simplification]
[propeller.variation :as variation] [propeller.variation :as variation]
[propeller.downsample :as downsample]
[propeller.push.instructions.bool] [propeller.push.instructions.bool]
[propeller.push.instructions.character] [propeller.push.instructions.character]
[propeller.push.instructions.code] [propeller.push.instructions.code]
@ -13,88 +13,210 @@
[propeller.push.instructions.polymorphic] [propeller.push.instructions.polymorphic]
[propeller.push.instructions.string] [propeller.push.instructions.string]
[propeller.push.instructions.vector] [propeller.push.instructions.vector]
[propeller.selection :as selection])) [propeller.push.instructions.signal]
[propeller.selection :as selection]
[propeller.utils :as utils]))
(defn report (defn report
"Reports information for each generation." "Reports information each generation."
[pop generation argmap] [evaluations pop generation argmap training-data]
(let [best (first pop)] (let [best (first pop)]
(clojure.pprint/pprint {:generation generation (utils/pretty-map-println
(merge
{:generation generation
:best-plushy (:plushy best) :best-plushy (:plushy best)
:best-program (genome/plushy->push (:plushy best) argmap) :best-program (genome/plushy->push (:plushy best) argmap)
:best-total-error (:total-error best) :best-total-error (:total-error best)
:evaluations evaluations
:ds-indices (if (:downsample? argmap)
(map #(:index %) training-data)
nil)
:best-errors (:errors best) :best-errors (:errors best)
:best-behaviors (:behaviors best) :best-behaviors (:behaviors best)
:genotypic-diversity (float (/ (count (distinct (map :plushy pop))) (count pop))) :genotypic-diversity (float (/ (count (distinct (map :plushy pop))) (count pop)))
:behavioral-diversity (float (/ (count (distinct (map :behaviors pop))) (count pop))) :behavioral-diversity (float (/ (count (distinct (map :behaviors pop))) (count pop)))
:average-genome-length (float (/ (reduce + (map count (map :plushy pop))) (count pop))) :average-genome-length (float (/ (reduce + (map count (map :plushy pop))) (count pop)))
:average-total-error (float (/ (reduce + (map :total-error pop)) (count pop)))}) :average-total-error (float (/ (reduce + (map :total-error pop)) (count pop)))}
(println))) (if (:bmx? argmap)
{:best-gene-count (utils/count-genes (:plushy best))
:average-gene-count (float (/ (reduce + (map utils/count-genes (map :plushy pop)))
(count pop)))}
{})))
(flush)))
(defn cleanup
[]
#?(:clj (shutdown-agents))
(prn {:run-completed true})
nil)
(defn fill-defaults
"Returns argmap with any unspecified values filled with defaults."
[argmap]
(let [defaults
{:alignment-deviation 2 ; for alternation, the standard deviation of deviation of index when alternating
:alternation-rate 0.1 ; for alternation, the probability of switching parents at each location
:bmx-exchange-rate 0.5 ; for bmx, the rate at which genes will be exchanged
:bmx-gene-length-limit 10 ; for bmx, the maximum length of a gene
:bmx-gap-change-probability 0.001 ; for bmx, the mutation rate for gaps
:bmx-complementary? false ; for bmx, whether mates selected using reverse case sequence of first parent
:bmx-maximum-distance 1000000 ; for bmx, don't exchange if distance is greater than this
:bmx-same-gene-count false ; for bmx, only allow exchanges between individuals with same number of genes
:closes :specified ; :specified, :balanced, :none
:custom-report false ; if provided, should be a function that takes an argmap
:dont-end false ; if true, keep running until limit regardless of success
:downsample? true ; wether to use downsampling
:ds-function :case-maxmin ; :case-rand, case-maxmin, case-maxmin-auto
:downsample-rate 0.05 ; proportion of data used in downsample
:ds-parent-rate 0.01 ; proportion of parents used to evaluate case distances
:ds-parent-gens 10 ; generations between computation of parent distances
:elitism false ; whether always to add the lowest-error individual to the next generation
:error-function (fn [& args] (println "ERROR FUNCTION NOT PROVIDED")) ; must provide
:ids-type :solved ; type of informed downsampling, :solved or :elite or :soft
:instructions ["INSTRUCTIONS NOT PROVIDED"] ; must be provided
:max-batch-size 10 ; for motley-batch-lexicase-selection, the max size of a batch of cases
:max-initial-plushy-size 100 ; the maximum size of genomes in initial population
:max-generations 1000 ; generation limi when downsampling is not used, adjusted by downsampling
:parent-selection :lexicase ; see options in variation.cljc
:population-size 1000 ; the size of the GP ppopulation
:replacement-rate 0.1 ; for uniform-replacement, the rate at with items will be replaced
:simplification? false ; whether to auto-simplify solutions
:simplification-k 4 ; when auto-simplifying, max number of items deleted in single step
:simplification-steps 1000 ; when auto-simplifying, number of simplification steps to perform
:simplification-verbose? false ; when auto-simplifying, whether to print a lot of information
:single-thread-mode false ; if true, don't use multithreading
:solution-error-threshold 0 ; maximum total error for solutions
:ssx-not-bmx false ; for bmx, swap with segment with same sequence index, not by best match
:step-limit 1000 ; limit of Push interpreter steps in a Push program evaluation
:testing-data [] ; must be provided unless there is no testing data
:tournament-size 5 ; for torunament selection, the number of individuals in each tournament
:training-data [] ; must be provided
:umad-rate 0.1 ; addition rate (from which deletion rate will be derived) for UMAD
:variation {:umad 1} ; genetic operators and probabilities for their use, which should sum to 1
:tournament-comp-op min-key ; individual error comparison operator for tournament selection (switch to max-key for max)
:lexicase-comp-op min ; individual error comparison operator for lexicase selection (switch to max for max)
:population-sort-comp < ; comparision operator to use for sorting the population
}
defaulted (merge defaults argmap)]
(merge defaulted ; use the map below to include derived values in argmap
{:bmx? (some #{:bmx :bmx-umad} (keys (:variation defaulted)))})))
(defn gp (defn gp
"Main GP loop. "Main GP function"
[non-default-argmap]
On each iteration, it creates a population of random plushies using a mapper (let [argmap (fill-defaults non-default-argmap)
function and genome/make-random-plushy function, {:keys [population-size max-generations error-function solution-error-threshold dont-end
then it sorts the population by the total error using the error-function downsample? ds-parent-rate ds-parent-gens ids-type population-sort-comp]} argmap]
and sort-by function. It then takes the best individual from the sorted population, ;; print starting args
and if the parent selection is set to epsilon-lexicase, it adds the epsilons to the argmap. (prn {:starting-args (update (update argmap :error-function str)
:instructions
The function then checks if the custom-report argument is set, (fn [instrs]
if so it calls that function passing the evaluated population, (utils/not-lazy (map #(if (fn? %) (str %) %) instrs))))})
current generation and argmap. If not, it calls the report function
passing the evaluated population, current generation and argmap.
Then, it checks if the total error of the best individual is less than or equal
to the solution-error-threshold or if the current generation is greater than or
equal to the max-generations specified. If either is true, the function
exits with the best individual or nil. If not, it creates new individuals
for the next generation using the variation/new-individual function and the
repeatedly function, and then continues to the next iteration of the loop. "
[{:keys [population-size max-generations error-function instructions
max-initial-plushy-size solution-error-threshold mapper]
:or {solution-error-threshold 0.0
;; The `mapper` will perform a `map`-like operation to apply a function to every individual
;; in the population. The default is `map` but other options include `mapv`, or `pmap`.
mapper #?(:clj pmap :cljs map)}
:as argmap}]
;;
(prn {:starting-args (update (update argmap :error-function str) :instructions str)})
(println) (println)
;; ;;
(loop [generation 0 (loop [generation 0
population (mapper evaluations 0
(fn [_] {:plushy (genome/make-random-plushy instructions max-initial-plushy-size)}) population (utils/pmapallv
(range population-size))] ;creates population of random plushys (fn [_] {:plushy (genome/make-random-plushy argmap)})
(let [evaluated-pop (sort-by :total-error (range population-size)
(mapper argmap)
(partial error-function argmap (:training-data argmap)) indexed-training-data (if downsample?
population)) ;population sorted by :total-error (downsample/assign-indices-to-data (downsample/initialize-case-distances argmap) argmap)
(:training-data argmap))]
(let [training-data (if downsample?
(case (:ds-function argmap)
:case-maxmin (downsample/select-downsample-maxmin indexed-training-data argmap)
:case-maxmin-auto (downsample/select-downsample-maxmin-adaptive indexed-training-data argmap)
:case-rand (downsample/select-downsample-random indexed-training-data argmap)
(do (prn {:error "Invalid Downsample Function"})
(downsample/select-downsample-random indexed-training-data argmap)))
indexed-training-data) ;defaults to full training set
parent-reps (if
(and downsample? ; if we are down-sampling
(zero? (mod generation ds-parent-gens))) ;every ds-parent-gens generations
(take (* ds-parent-rate (count population)) (shuffle population))
'()) ;else just empty list
; parent representatives for down-sampling
rep-evaluated-pop (if downsample?
(sort-by :total-error population-sort-comp
(utils/pmapallv
(partial error-function argmap indexed-training-data)
parent-reps
argmap))
'())
evaluated-pop (sort-by :total-error population-sort-comp
(utils/pmapallv
(partial error-function argmap training-data)
population
argmap))
best-individual (first evaluated-pop) best-individual (first evaluated-pop)
best-individual-passes-ds (and downsample? (<= (:total-error best-individual) solution-error-threshold))
argmap (if (= (:parent-selection argmap) :epsilon-lexicase) argmap (if (= (:parent-selection argmap) :epsilon-lexicase)
(assoc argmap :epsilons (selection/epsilon-list evaluated-pop)) (assoc argmap :epsilons (selection/epsilon-list evaluated-pop))
argmap)] ;adds :epsilons if using epsilon-lexicase argmap)] ; epsilons
(if (:custom-report argmap) (if (:custom-report argmap)
((:custom-report argmap) evaluated-pop generation argmap) ((:custom-report argmap) evaluations evaluated-pop generation argmap)
(report evaluated-pop generation argmap)) (report evaluations evaluated-pop generation argmap training-data))
;; Did the indvidual pass all cases in ds?
(when best-individual-passes-ds
(prn {:semi-success-generation generation}))
(cond (cond
;; Success on training cases is verified on testing cases ;; If either the best individual on the ds passes all training cases, or best individual on full
(<= (:total-error best-individual) solution-error-threshold) ;; sample passes all training cases, we verify success on test cases and exit, succeeding
(if (or (and best-individual-passes-ds
(<= (:total-error (error-function argmap indexed-training-data best-individual))
solution-error-threshold))
(and (not downsample?)
(<= (:total-error best-individual)
solution-error-threshold)))
(do (prn {:success-generation generation}) (do (prn {:success-generation generation})
(prn {:successful-plushy (:plushy best-individual)})
(prn {:successful-program (genome/plushy->push (:plushy best-individual) argmap)})
(prn {:total-test-error (prn {:total-test-error
(:total-error (error-function argmap (:testing-data argmap) best-individual))}) (:total-error (error-function argmap (:testing-data argmap) best-individual))})
(when (:simplification? argmap) (when (:simplification? argmap)
(let [simplified-plushy (simplification/auto-simplify-plushy (:plushy best-individual) error-function argmap)] (let [simplified-plushy (simplification/auto-simplify-plushy (:plushy best-individual) error-function argmap)]
(prn {:total-test-error-simplified (:total-error (error-function argmap (:testing-data argmap) (hash-map :plushy simplified-plushy)))})))) (prn {:total-test-error-simplified
;; (:total-error (error-function argmap (:testing-data argmap) {:plushy simplified-plushy}))})
(>= generation max-generations) (prn {:simplified-plushy simplified-plushy})
nil (prn {:simplified-program (genome/plushy->push simplified-plushy argmap)})))
;; (if dont-end false true))
false)
(cleanup)
;; If we've evolved for as many generations as the parameters allow, exit without succeeding
(or (and (not downsample?)
(>= generation max-generations))
(and downsample?
(>= evaluations (* max-generations population-size (count indexed-training-data)))))
(cleanup)
;; Otherwise, evolve for another generation
:else (recur (inc generation) :else (recur (inc generation)
(if (:elitism argmap) (+ evaluations
(conj (repeatedly (dec population-size) (* population-size (count training-data)) ;every member evaluated on the current sample
#(variation/new-individual evaluated-pop argmap)) (if (zero? (mod generation ds-parent-gens))
(first evaluated-pop)) ;elitism maintains the most-fit individual (* (count parent-reps)
(repeatedly population-size (- (count indexed-training-data)
#(variation/new-individual evaluated-pop argmap)))))))) (count training-data)))
0) ; the parent-reps not evaluted already on down-sample
(if best-individual-passes-ds
(- (count indexed-training-data) (count training-data))
0)) ; if we checked for generalization or not
(if (:elitism argmap) ; elitism maintains the individual with lowest total error
(conj (utils/pmapallv (fn [_] (variation/new-individual evaluated-pop argmap))
(range (dec population-size))
argmap)
(first evaluated-pop))
(utils/pmapallv (fn [_] (variation/new-individual evaluated-pop argmap))
(range population-size)
argmap))
(if downsample?
(if (zero? (mod generation ds-parent-gens))
; update distances every ds-parent-gens generations
(downsample/update-case-distances rep-evaluated-pop
indexed-training-data
indexed-training-data
ids-type
(/ solution-error-threshold
(count indexed-training-data)))
indexed-training-data)
indexed-training-data)))))))

View File

@ -2,7 +2,6 @@
(:require [psb2.core :as psb2] (:require [psb2.core :as psb2]
[propeller.genome :as genome] [propeller.genome :as genome]
[propeller.push.interpreter :as interpreter] [propeller.push.interpreter :as interpreter]
[propeller.problems.data-creation :as dc]
[propeller.utils :as utils] [propeller.utils :as utils]
[propeller.push.instructions :refer [get-stack-instructions]] [propeller.push.instructions :refer [get-stack-instructions]]
[propeller.push.state :as state] [propeller.push.state :as state]
@ -56,7 +55,9 @@
:cljs (apply + errors))))) :cljs (apply + errors)))))
(defn -main (defn -main
"Runs propel-gp, giving it a map of arguments." "Runs the top-level genetic programming function, giving it a map of
arguments with defaults that can be overridden from the command line
or through a passed map."
[& args] [& args]
(gp/gp (gp/gp
(merge (merge
@ -64,6 +65,9 @@
:error-function error-function :error-function error-function
:training-data train-data :training-data train-data
:testing-data test-data :testing-data test-data
:case-t-size (count train-data)
:ds-parent-rate 0
:ds-parent-gens 1
:max-generations 300 :max-generations 300
:population-size 1000 :population-size 1000
:max-initial-plushy-size 250 :max-initial-plushy-size 250
@ -73,5 +77,4 @@
:umad-rate 0.1 :umad-rate 0.1
:variation {:umad 1.0 :crossover 0.0} :variation {:umad 1.0 :crossover 0.0}
:elitism false} :elitism false}
(apply hash-map (map #(if (string? %) (read-string %) %) args)))) (apply hash-map (map #(if (string? %) (read-string %) %) args)))))
(#?(:clj shutdown-agents)))

View File

@ -3,7 +3,6 @@
[psb2.core :as psb2] [psb2.core :as psb2]
[propeller.genome :as genome] [propeller.genome :as genome]
[propeller.push.interpreter :as interpreter] [propeller.push.interpreter :as interpreter]
[propeller.problems.data-creation :as dc]
[propeller.push.state :as state] [propeller.push.state :as state]
[propeller.push.instructions :refer [get-stack-instructions]] [propeller.push.instructions :refer [get-stack-instructions]]
[propeller.utils :as utils] [propeller.utils :as utils]
@ -74,7 +73,9 @@
:cljs (apply + errors))))) :cljs (apply + errors)))))
(defn -main (defn -main
"Runs propel-gp, giving it a map of arguments." "Runs the top-level genetic programming function, giving it a map of
arguments with defaults that can be overridden from the command line
or through a passed map."
[& args] [& args]
(gp/gp (gp/gp
(merge (merge
@ -82,6 +83,9 @@
:error-function error-function :error-function error-function
:training-data train-data :training-data train-data
:testing-data test-data :testing-data test-data
:case-t-size (count train-data)
:ds-parent-rate 0
:ds-parent-gens 1
:max-generations 300 :max-generations 300
:population-size 1000 :population-size 1000
:max-initial-plushy-size 250 :max-initial-plushy-size 250

View File

@ -4,7 +4,6 @@
[propeller.push.interpreter :as interpreter] [propeller.push.interpreter :as interpreter]
[clojure.string :as string] [clojure.string :as string]
[propeller.tools.math :as math] [propeller.tools.math :as math]
[propeller.problems.data-creation :as dc]
[propeller.utils :as utils] [propeller.utils :as utils]
[propeller.push.instructions :refer [get-stack-instructions]] [propeller.push.instructions :refer [get-stack-instructions]]
[propeller.push.state :as state] [propeller.push.state :as state]
@ -125,7 +124,9 @@
:cljs (apply + errors))))) :cljs (apply + errors)))))
(defn -main (defn -main
"Runs propel-gp, giving it a map of arguments." "Runs the top-level genetic programming function, giving it a map of
arguments with defaults that can be overridden from the command line
or through a passed map."
[& args] [& args]
(gp/gp (gp/gp
(merge (merge
@ -133,6 +134,9 @@
:error-function error-function :error-function error-function
:training-data train-data :training-data train-data
:testing-data test-data :testing-data test-data
:case-t-size (count train-data)
:ds-parent-rate 0
:ds-parent-gens 1
:max-generations 300 :max-generations 300
:population-size 1000 :population-size 1000
:max-initial-plushy-size 250 :max-initial-plushy-size 250
@ -142,5 +146,4 @@
:umad-rate 0.1 :umad-rate 0.1
:variation {:umad 1.0 :crossover 0.0} :variation {:umad 1.0 :crossover 0.0}
:elitism false} :elitism false}
(apply hash-map (map #(if (string? %) (read-string %) %) args)))) (apply hash-map (map #(if (string? %) (read-string %) %) args)))))
(#?(:clj shutdown-agents)))

View File

@ -2,7 +2,6 @@
(:require [psb2.core :as psb2] (:require [psb2.core :as psb2]
[propeller.genome :as genome] [propeller.genome :as genome]
[propeller.push.interpreter :as interpreter] [propeller.push.interpreter :as interpreter]
[propeller.problems.data-creation :as dc]
[propeller.utils :as utils] [propeller.utils :as utils]
[propeller.push.instructions :refer [get-stack-instructions]] [propeller.push.instructions :refer [get-stack-instructions]]
[propeller.push.state :as state] [propeller.push.state :as state]
@ -57,7 +56,9 @@
(defn -main (defn -main
"Runs propel-gp, giving it a map of arguments." "Runs the top-level genetic programming function, giving it a map of
arguments with defaults that can be overridden from the command line
or through a passed map."
[& args] [& args]
(gp/gp (gp/gp
(merge (merge
@ -65,6 +66,9 @@
:error-function error-function :error-function error-function
:training-data train-data :training-data train-data
:testing-data test-data :testing-data test-data
:case-t-size (count train-data)
:ds-parent-rate 0
:ds-parent-gens 1
:max-generations 300 :max-generations 300
:population-size 1000 :population-size 1000
:max-initial-plushy-size 250 :max-initial-plushy-size 250
@ -74,5 +78,4 @@
:umad-rate 0.1 :umad-rate 0.1
:variation {:umad 1.0 :crossover 0.0} :variation {:umad 1.0 :crossover 0.0}
:elitism false} :elitism false}
(apply hash-map (map #(if (string? %) (read-string %) %) args)))) (apply hash-map (map #(if (string? %) (read-string %) %) args)))))
(#?(:clj shutdown-agents)))

View File

@ -66,7 +66,9 @@
:cljs (apply + errors))))) :cljs (apply + errors)))))
(defn -main (defn -main
"Runs propel-gp, giving it a map of arguments." "Runs the top-level genetic programming function, giving it a map of
arguments with defaults that can be overridden from the command line
or through a passed map."
[& args] [& args]
(gp/gp (gp/gp
(merge (merge
@ -83,5 +85,4 @@
:umad-rate 0.1 :umad-rate 0.1
:variation {:umad 1.0 :crossover 0.0} :variation {:umad 1.0 :crossover 0.0}
:elitism false} :elitism false}
(apply hash-map (map #(if (string? %) (read-string %) %) args)))) (apply hash-map (map #(if (string? %) (read-string %) %) args)))))
(#?(:clj shutdown-agents)))

View File

@ -77,7 +77,9 @@ Source: https://arxiv.org/pdf/2106.06086.pdf"
:cljs (apply + errors))))) :cljs (apply + errors)))))
(defn -main (defn -main
"Runs propel-gp, giving it a map of arguments." "Runs the top-level genetic programming function, giving it a map of
arguments with defaults that can be overridden from the command line
or through a passed map."
[& args] [& args]
(gp/gp (gp/gp
(merge (merge
@ -94,5 +96,4 @@ Source: https://arxiv.org/pdf/2106.06086.pdf"
:umad-rate 0.1 :umad-rate 0.1
:variation {:umad 1.0 :crossover 0.0} :variation {:umad 1.0 :crossover 0.0}
:elitism false} :elitism false}
(apply hash-map (map #(if (string? %) (read-string %) %) args)))) (apply hash-map (map #(if (string? %) (read-string %) %) args)))))
(#?(:clj shutdown-agents)))

View File

@ -66,7 +66,9 @@ Source: https://arxiv.org/pdf/2106.06086.pdf"
:cljs (apply + errors))))) :cljs (apply + errors)))))
(defn -main (defn -main
"Runs propel-gp, giving it a map of arguments." "Runs the top-level genetic programming function, giving it a map of
arguments with defaults that can be overridden from the command line
or through a passed map."
[& args] [& args]
(gp/gp (gp/gp
(merge (merge
@ -83,5 +85,4 @@ Source: https://arxiv.org/pdf/2106.06086.pdf"
:umad-rate 0.1 :umad-rate 0.1
:variation {:umad 1.0 :crossover 0.0} :variation {:umad 1.0 :crossover 0.0}
:elitism false} :elitism false}
(apply hash-map (map #(if (string? %) (read-string %) %) args)))) (apply hash-map (map #(if (string? %) (read-string %) %) args)))))
(#?(:clj shutdown-agents)))

View File

@ -100,7 +100,9 @@ Source: https://arxiv.org/pdf/2106.06086.pdf"
:cljs (apply + errors))))) :cljs (apply + errors)))))
(defn -main (defn -main
"Runs propel-gp, giving it a map of arguments." "Runs the top-level genetic programming function, giving it a map of
arguments with defaults that can be overridden from the command line
or through a passed map."
[& args] [& args]
(gp/gp (gp/gp
(merge (merge
@ -117,5 +119,4 @@ Source: https://arxiv.org/pdf/2106.06086.pdf"
:umad-rate 0.1 :umad-rate 0.1
:variation {:umad 1.0 :crossover 0.0} :variation {:umad 1.0 :crossover 0.0}
:elitism false} :elitism false}
(apply hash-map (map #(if (string? %) (read-string %) %) args)))) (apply hash-map (map #(if (string? %) (read-string %) %) args)))))
(#?(:clj shutdown-agents)))

View File

@ -74,7 +74,9 @@ Source: https://arxiv.org/pdf/2106.06086.pdf"
:cljs (apply + errors))))) :cljs (apply + errors)))))
(defn -main (defn -main
"Runs propel-gp, giving it a map of arguments." "Runs the top-level genetic programming function, giving it a map of
arguments with defaults that can be overridden from the command line
or through a passed map."
[& args] [& args]
(gp/gp (gp/gp
(merge (merge
@ -91,5 +93,4 @@ Source: https://arxiv.org/pdf/2106.06086.pdf"
:umad-rate 0.1 :umad-rate 0.1
:variation {:umad 1.0 :crossover 0.0} :variation {:umad 1.0 :crossover 0.0}
:elitism false} :elitism false}
(apply hash-map (map #(if (string? %) (read-string %) %) args)))) (apply hash-map (map #(if (string? %) (read-string %) %) args)))))
(#?(:clj shutdown-agents)))

View File

@ -0,0 +1,107 @@
(ns propeller.problems.PSB2.find-pair
(:require [psb2.core :as psb2]
[propeller.genome :as genome]
[propeller.push.interpreter :as interpreter]
[propeller.utils :as utils]
[propeller.push.instructions :refer [def-instruction get-stack-instructions]]
[propeller.push.state :as state]
[propeller.tools.math :as math]
[propeller.gp :as gp]
#?(:cljs [cljs.reader :refer [read-string]])))
(def train-and-test-data (psb2/fetch-examples "data" "find-pair" 200 2000))
(def train-data (:train train-and-test-data))
(def test-data (:test train-and-test-data))
(defn random-int [] (- (rand-int 201) 100))
(defn map-vals-input
"Returns all the input values of a map"
[i]
(vals (select-keys i [:input1 :input2])))
(defn map-vals-output
"Returns the output values of a map"
[i]
(vals (select-keys i [:output1 :output2])))
(def-instruction :output-one
^{:stacks #{:integer :output}}
(fn [state]
(if (empty? (:integer state))
state
(let [top-int (state/peek-stack state :integer)]
(assoc-in state [:output :out1] top-int)))))
(def-instruction :output-two
^{:stacks #{:integer :output}}
(fn [state]
(if (empty? (:integer state))
state
(let [top-int (state/peek-stack state :integer)]
(assoc-in state [:output :out2] top-int)))))
(def instructions
(utils/not-lazy
(concat
;;; stack-specific instructions
(get-stack-instructions #{:exec :integer :vector_integer :boolean})
(list :output-one :output-two)
;;; input instructions
(list :in1 :in2)
;;; close
(list 'close)
;;; ERCs (constants)
(list -1 0 1 2 random-int))))
(defn error-function
[argmap data individual]
(let [program (genome/plushy->push (:plushy individual) argmap)
inputs (map (fn [i] (map-vals-input i)) data)
correct-outputs (map (fn [i] (map-vals-output i)) data)
outputs (map (fn [input]
(:output
(interpreter/interpret-program
program
(assoc state/empty-state :input {:in1 (nth input 0)
:in2 (nth input 1)})
(:step-limit argmap))))
inputs)
outputs-1 (map #(:out1 %) outputs)
outputs-2 (map #(:out2 %) outputs)
;_ (prn {:o1 outputs-1 :o2 outputs-2})
errors (map (fn [correct-output output-1 output-2]
(if (not (and (number? output-2) (number? output-1)))
100000
(+ (math/abs (- (first correct-output) output-1))
(math/abs (- (second correct-output) output-2)))))
correct-outputs outputs-1 outputs-2)]
(assoc individual
:behaviors outputs
:errors errors
:total-error #?(:clj (apply +' errors)
:cljs (apply + errors)))))
(defn -main
"Runs propel-gp, giving it a map of arguments."
[& args]
(gp/gp
(merge
{:instructions instructions
:error-function error-function
:training-data train-data
:testing-data test-data
:case-t-size (count train-data)
:ds-parent-rate 0
:ds-parent-gens 1
:max-generations 300
:population-size 1000
:max-initial-plushy-size 250
:step-limit 2000
:parent-selection :lexicase
:tournament-size 5
:umad-rate 0.1
:variation {:umad 1.0 :crossover 0.0}
:elitism false}
(apply hash-map (map #(if (string? %) (read-string %) %) args))))
(#?(:clj shutdown-agents)))

View File

@ -17,7 +17,21 @@ Source: https://arxiv.org/pdf/2106.06086.pdf"
[propeller.gp :as gp] [propeller.gp :as gp]
#?(:cljs [cljs.reader :refer [read-string]]))) #?(:cljs [cljs.reader :refer [read-string]])))
; =========== PROBLEM DESCRIPTION =========================
; FIZZ BUZZ from PSB2
; Given an integer x, return "Fizz" if x is
; divisible by 3, "Buzz" if x is divisible by 5, "FizzBuzz" if x
; is divisible by 3 and 5, and a string version of x if none of
; the above hold.
;
; Source: https://arxiv.org/pdf/2106.06086.pdf
; ============================================================
(def train-and-test-data "Data taken from https://zenodo.org/record/5084812" (psb2/fetch-examples "data" "fizz-buzz" 200 2000)) (def train-and-test-data "Data taken from https://zenodo.org/record/5084812" (psb2/fetch-examples "data" "fizz-buzz" 200 2000))
(def train-data (:train train-and-test-data))
(def test-data (:test train-and-test-data))
(def instructions (def instructions
"Stack-specific instructions, input instructions, close, and constants" "Stack-specific instructions, input instructions, close, and constants"
@ -63,14 +77,19 @@ Source: https://arxiv.org/pdf/2106.06086.pdf"
(defn -main (defn -main
"Runs propel-gp, giving it a map of arguments." "Runs the top-level genetic programming function, giving it a map of
arguments with defaults that can be overridden from the command line
or through a passed map."
[& args] [& args]
(gp/gp (gp/gp
(merge (merge
{:instructions instructions {:instructions instructions
:error-function error-function :error-function error-function
:training-data (:train train-and-test-data) :training-data train-data
:testing-data (:test train-and-test-data) :testing-data test-data
:case-t-size (count train-data)
:ds-parent-rate 0
:ds-parent-gens 1
:max-generations 300 :max-generations 300
:population-size 1000 :population-size 1000
:max-initial-plushy-size 250 :max-initial-plushy-size 250
@ -80,5 +99,4 @@ Source: https://arxiv.org/pdf/2106.06086.pdf"
:umad-rate 0.1 :umad-rate 0.1
:variation {:umad 1.0 :crossover 0.0} :variation {:umad 1.0 :crossover 0.0}
:elitism false} :elitism false}
(apply hash-map (map #(if (string? %) (read-string %) %) args)))) (apply hash-map (map #(if (string? %) (read-string %) %) args)))))
(#?(:clj shutdown-agents)))

View File

@ -18,7 +18,19 @@ Source: https://arxiv.org/pdf/2106.06086.pdf"
[propeller.gp :as gp] [propeller.gp :as gp]
#?(:cljs [cljs.reader :refer [read-string]]))) #?(:cljs [cljs.reader :refer [read-string]])))
; =========== PROBLEM DESCRIPTION =========================
; FUEL COST from PSB2
; Given a vector of positive integers, divide
; each by 3, round the result down to the nearest integer, and
; subtract 2. Return the sum of all of the new integers in the
; vector
;
; Source: https://arxiv.org/pdf/2106.06086.pdf
; ============================================================
(def train-and-test-data "Data taken from https://zenodo.org/record/5084812" (psb2/fetch-examples "data" "fuel-cost" 200 2000)) (def train-and-test-data "Data taken from https://zenodo.org/record/5084812" (psb2/fetch-examples "data" "fuel-cost" 200 2000))
(def train-data (:train train-and-test-data))
(def test-data (:test train-and-test-data))
; Random integer between -100 and 100 (from smallest) ; Random integer between -100 and 100 (from smallest)
(defn random-int "Random integer between -100 and 100" [] (- (rand-int 201) 100)) (defn random-int "Random integer between -100 and 100" [] (- (rand-int 201) 100))
@ -66,14 +78,19 @@ Source: https://arxiv.org/pdf/2106.06086.pdf"
:cljs (apply + errors))))) :cljs (apply + errors)))))
(defn -main (defn -main
"Runs propel-gp, giving it a map of arguments." "Runs the top-level genetic programming function, giving it a map of
arguments with defaults that can be overridden from the command line
or through a passed map."
[& args] [& args]
(gp/gp (gp/gp
(merge (merge
{:instructions instructions {:instructions instructions
:error-function error-function :error-function error-function
:training-data (:train train-and-test-data) :training-data train-data
:testing-data (:test train-and-test-data) :testing-data test-data
:case-t-size (count train-data)
:ds-parent-rate 0
:ds-parent-gens 1
:max-generations 300 :max-generations 300
:population-size 1000 :population-size 1000
:max-initial-plushy-size 250 :max-initial-plushy-size 250
@ -83,5 +100,4 @@ Source: https://arxiv.org/pdf/2106.06086.pdf"
:umad-rate 0.1 :umad-rate 0.1
:variation {:umad 1.0 :crossover 0.0} :variation {:umad 1.0 :crossover 0.0}
:elitism false} :elitism false}
(apply hash-map (map #(if (string? %) (read-string %) %) args)))) (apply hash-map (map #(if (string? %) (read-string %) %) args)))))
(#?(:clj shutdown-agents)))

View File

@ -18,6 +18,11 @@ Source: https://arxiv.org/pdf/2106.06086.pdf"
(def train-and-test-data "Data taken from https://zenodo.org/record/5084812" (psb2/fetch-examples "data" "gcd" 200 2000)) (def train-and-test-data "Data taken from https://zenodo.org/record/5084812" (psb2/fetch-examples "data" "gcd" 200 2000))
(def train-and-test-data (psb2/fetch-examples "data" "gcd" 200 2000))
(def train-data (:train train-and-test-data))
(def test-data (:test train-and-test-data))
(defn random-int "Random integer between -100 and 100" [] (- (rand-int 201) 100)) (defn random-int "Random integer between -100 and 100" [] (- (rand-int 201) 100))
(defn map-vals-input (defn map-vals-input
@ -74,14 +79,19 @@ Source: https://arxiv.org/pdf/2106.06086.pdf"
:cljs (apply + errors))))) :cljs (apply + errors)))))
(defn -main (defn -main
"Runs propel-gp, giving it a map of arguments." "Runs the top-level genetic programming function, giving it a map of
arguments with defaults that can be overridden from the command line
or through a passed map."
[& args] [& args]
(gp/gp (gp/gp
(merge (merge
{:instructions instructions {:instructions instructions
:error-function error-function :error-function error-function
:training-data (:train train-and-test-data) :training-data train-data
:testing-data (:test train-and-test-data) :testing-data test-data
:case-t-size (count train-data)
:ds-parent-rate 0
:ds-parent-gens 1
:max-generations 300 :max-generations 300
:population-size 1000 :population-size 1000
:max-initial-plushy-size 250 :max-initial-plushy-size 250
@ -91,5 +101,4 @@ Source: https://arxiv.org/pdf/2106.06086.pdf"
:umad-rate 0.1 :umad-rate 0.1
:variation {:umad 1.0 :crossover 0.0} :variation {:umad 1.0 :crossover 0.0}
:elitism false} :elitism false}
(apply hash-map (map #(if (string? %) (read-string %) %) args)))) (apply hash-map (map #(if (string? %) (read-string %) %) args)))))
(#?(:clj shutdown-agents)))

View File

@ -68,7 +68,9 @@ Source: https://arxiv.org/pdf/2106.06086.pdf"
:cljs (apply + errors))))) :cljs (apply + errors)))))
(defn -main (defn -main
"Runs propel-gp, giving it a map of arguments." "Runs the top-level genetic programming function, giving it a map of
arguments with defaults that can be overridden from the command line
or through a passed map."
[& args] [& args]
(gp/gp (gp/gp
(merge (merge
@ -85,5 +87,4 @@ Source: https://arxiv.org/pdf/2106.06086.pdf"
:umad-rate 0.1 :umad-rate 0.1
:variation {:umad 1.0 :crossover 0.0} :variation {:umad 1.0 :crossover 0.0}
:elitism false} :elitism false}
(apply hash-map (map #(if (string? %) (read-string %) %) args)))) (apply hash-map (map #(if (string? %) (read-string %) %) args)))))
(#?(:clj shutdown-agents)))

View File

@ -64,7 +64,9 @@ Source: https://arxiv.org/pdf/2106.06086.pdf"
:cljs (apply + errors))))) :cljs (apply + errors)))))
(defn -main (defn -main
"Runs propel-gp, giving it a map of arguments." "Runs the top-level genetic programming function, giving it a map of
arguments with defaults that can be overridden from the command line
or through a passed map."
[& args] [& args]
(gp/gp (gp/gp
(merge (merge
@ -81,5 +83,4 @@ Source: https://arxiv.org/pdf/2106.06086.pdf"
:umad-rate 0.1 :umad-rate 0.1
:variation {:umad 1.0 :crossover 0.0} :variation {:umad 1.0 :crossover 0.0}
:elitism false} :elitism false}
(apply hash-map (map #(if (string? %) (read-string %) %) args)))) (apply hash-map (map #(if (string? %) (read-string %) %) args)))))
(#?(:clj shutdown-agents)))

Some files were not shown because too many files have changed in this diff Show More