⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 koza-gp.lisp

📁 this code define genetic programming tools and some applications
💻 LISP
📖 第 1 页 / 共 3 页
字号:
;;; Copyright (c) John Koza, All rights reserved.;;; U.S. Patent #4,935,877.  Other patents pending.;============================================================;;; Kernel(defstruct individual  program   (standardized-fitness 0)  (adjusted-fitness 0)  (normalized-fitness 0)  (hits 0))(defvar *number-of-fitness-cases* :unbound  "The number of fitness cases")(defvar *max-depth-for-new-individuals* :unbound  "The maximum depth for individuals of the initial   random generation")(defvar *max-depth-for-individuals-after-crossover* :unbound  "The maximum depth of new individuals created by crossover")(defvar *fitness-proportionate-reproduction-fraction* :unbound  "The fraction of the population that will experience fitness   proportionate reproduction (with reselection)   during each generation")(defvar *crossover-at-any-point-fraction* :unbound  "The fraction of the population that will experience   crossover at any point in the tree (including terminals)   during each generation")(defvar *crossover-at-function-point-fraction* :unbound  "The fraction of the population that will experience   crossover at a function (internal) point in the tree   during each generation.")(defvar *max-depth-for-new-subtrees-in-mutants* :unbound  "The maximum depth of new subtrees created by mutation")(defvar *method-of-selection* :unbound  "The method of selecting individuals in the population.   Either :fitness-proportionate, :tournament or   :fitness-proportionate-with-over-selection.")(defvar *method-of-generation* :unbound  "Can be any one of :grow, :full, :ramped-half-and-half")(defvar *seed* :unbound  "The seed for the Park-Miller congruential randomizer.")(defvar *best-of-run-individual* :unbound  "The best individual found during this run.")(defvar *generation-of-best-of-run-individual* :unbound  "The generation at which the best-of-run individual was found.")(defun run-genetic-programming-system           (problem-function            seed            maximum-generations            size-of-population            &rest seeded-programs);; Check validity of some arguments  (assert (and (integerp maximum-generations)               (not (minusp maximum-generations)))          (maximum-generations)          "Maximum-generations must be a non-negative ~           integer, not ~S" maximum-generations)  (assert (and (integerp size-of-population)               (plusp size-of-population))          (size-of-population)          "Size-Of-Population must be a positive integer, ~           not ~S" size-of-population)  (assert (or (and (symbolp problem-function)                   (fboundp problem-function))              (functionp problem-function))          (problem-function)          "Problem-Function must be a function.")  (assert (numberp seed) (seed)          "The randomizer seed must be a number");; Set the global randomizer seed.  (setf *seed* (coerce seed 'double-float));; Initialize best-of-run recording variables  (setf *generation-of-best-of-run-individual* 0)  (setf *best-of-run-individual* nil);; Get the six problem-specific functions needed to ;; specify this problem as returned by a call to;; problem-function  (multiple-value-bind (function-set-creator                        terminal-set-creator                        fitness-cases-creator                        fitness-function                        parameter-definer                        termination-predicate)      (funcall problem-function);; Get the function set and its associated;; argument map    (multiple-value-bind (function-set argument-map)        (funcall function-set-creator);; Set up the parameters using parameter-definer      (funcall parameter-definer);; Print out parameters report      (describe-parameters-for-run        maximum-generations size-of-population);; Set up the terminal-set using terminal-set-creator      (let ((terminal-set (funcall terminal-set-creator)));; Create the population        (let ((population                (create-population                  size-of-population function-set argument-map                  terminal-set seeded-programs)));; Define the fitness cases using the;; fitness-cases-creator function          (let ((fitness-cases (funcall fitness-cases-creator))                ;; New-Programs is used in the breeding of the                ;; new population.  Create it here to reduce                ;; consing.                (new-programs (make-array size-of-population)));; Now run the Genetic Programming Paradigm using ;; the fitness-function and termination-predicate provided            (execute-generations              population new-programs fitness-cases              maximum-generations fitness-function              termination-predicate function-set              argument-map terminal-set);; Finally print out a report            (report-on-run);; Return the population and fitness cases;; (for debugging)             (values population fitness-cases)))))))(defun report-on-run ()  "Prints out the best-of-run individual."  (let ((*print-pretty* t))    (format t "~5%The best-of-run individual program ~               for this run was found on ~%generation ~D and had a ~               standardized fitness measure ~               of ~D and ~D hit~P.  ~%It was:~%~S"            *generation-of-best-of-run-individual*            (individual-standardized-fitness *best-of-run-individual*)            (individual-hits *best-of-run-individual*)            (individual-hits *best-of-run-individual*)            (individual-program *best-of-run-individual*))))(defun report-on-generation (generation-number population)  "Prints out the best individual at the end of each generation"  (let ((best-individual (aref population 0))        (size-of-population (length population))        (sum 0.0)        (*print-pretty* t))    ;; Add up all of the standardized fitnesses to get average    (dotimes (index size-of-population)      (incf sum (individual-standardized-fitness                  (aref population index))))    (format t "~2%Generation ~D:  Average standardized-fitness ~               = ~S.  ~%~               The best individual program of the population ~               had a ~%standardized fitness measure of ~D ~               and ~D hit~P. ~%It was: ~%~S"            generation-number (/ sum (length population))            (individual-standardized-fitness best-individual)            (individual-hits best-individual)            (individual-hits best-individual)            (individual-program best-individual))))(defun print-population (population)  "Given a population, this prints it out (for debugging) "  (let ((*print-pretty* t))    (dotimes (index (length population))      (let ((individual (aref population index)))        (format t "~&~D   ~S    ~S"                index                (individual-standardized-fitness individual)                (individual-program individual))))))(defun describe-parameters-for-run    (maximum-generations size-of-population)  "Lists the parameter settings for this run."  (format t "~2%Parameters used for this run.~              ~%=============================")  (format t "~%Maximum number of Generations:~50T~D"          maximum-generations)  (format t "~%Size of Population:~50T~D" size-of-population)  (format t "~%Maximum depth of new individuals:~50T~D"          *max-depth-for-new-individuals*)  (format t "~%Maximum depth of new subtrees for mutants:~50T~D"          *max-depth-for-new-subtrees-in-mutants*)  (format t     "~%Maximum depth of individuals after crossover:~50T~D"     *max-depth-for-individuals-after-crossover*)  (format t     "~%Fitness-proportionate reproduction fraction:~50T~D"     *fitness-proportionate-reproduction-fraction*)  (format t "~%Crossover at any point fraction:~50T~D"          *crossover-at-any-point-fraction*)  (format t "~%Crossover at function points fraction:~50T~D"          *crossover-at-function-point-fraction*)  (format t "~%Number of fitness cases:~50T~D"          *number-of-fitness-cases*)  (format t "~%Selection method: ~50T~A" *method-of-selection*)  (format t "~%Generation method: ~50T~A" *method-of-generation*)  (format t "~%Randomizer seed: ~50T~D" *seed*))(defvar *generation-0-uniquifier-table*        (make-hash-table :test #'equal)  "Used to guarantee that all generation 0 individuals   are unique")(defun create-population (size-of-population function-set                          argument-map terminal-set                          seeded-programs)  "Creates the population.  This is an array of size   size-of-population that is initialized to contain individual   records.  The Program slot of each individual is initialized   to a suitable random program except for the first N programs,   where N = (length seeded-programs).  For these first N   individuals the individual is initialized with the respective   seeded program.  This is very useful in debugging."  (let ((population (make-array size-of-population))        (minimum-depth-of-trees 1)        (attempts-at-this-individual 0)        (full-cycle-p nil))    (do ((individual-index 0))        ((>= individual-index size-of-population))      (when (zerop (mod individual-index                        (max 1 (- *max-depth-for-new-individuals*                               minimum-depth-of-trees))))        (setf full-cycle-p (not full-cycle-p)))      (let ((new-program              (if (< individual-index (length seeded-programs))                  ;; Pick a seeded individual                  (nth individual-index seeded-programs)                  ;; Create a new random program.                  (create-individual-program                    function-set argument-map terminal-set                     (ecase *method-of-generation*                      ((:full :grow) *max-depth-for-new-individuals*)                      (:ramped-half-and-half                        (+ minimum-depth-of-trees                           (mod individual-index                                (- *max-depth-for-new-individuals*                                   minimum-depth-of-trees)))))                    t                    (ecase *method-of-generation*                      (:full t)                      (:grow nil)                      (:ramped-half-and-half                        full-cycle-p))))))        ;; Check if we have already created this program.        ;; If not then store it and move on.        ;; If we have then try again.        (cond ((< individual-index (length seeded-programs))               (setf (aref population individual-index)                     (make-individual :program new-program))               (incf individual-index))              ((not (gethash new-program                             *generation-0-uniquifier-table*))               (setf (aref population individual-index)                     (make-individual :program new-program))               (setf (gethash new-program                              *generation-0-uniquifier-table*)                     t)               (setf attempts-at-this-individual 0)               (incf individual-index))              ((> attempts-at-this-individual 20)               ;; Then this depth has probably filled up, so               ;; bump the depth counter.               (incf minimum-depth-of-trees)               ;; Bump the max depth too to keep in line with new minimum.               (setf *max-depth-for-new-individuals*                     (max *max-depth-for-new-individuals*                          minimum-depth-of-trees)))              (:otherwise (incf attempts-at-this-individual)))))    ;; Flush out uniquifier table to that no pointers    ;; are kept to generation 0 individuals.    (clrhash *generation-0-uniquifier-table*)    ;; Return the population that we've just created.    population))(defun choose-from-terminal-set (terminal-set)  "Chooses a random terminal from the terminal set.    If the terminal chosen is the ephemeral   :Floating-Point-Random-Constant,   then a floating-point single precision random constant   is created in the range -5.0->5.0.   If :Integer-Random-Constant is chosen then an integer random    constant is generated in the range -10 to +10."  (let ((choice (nth (random-integer (length terminal-set))                     terminal-set)))    (case choice      (:floating-point-random-constant        ;; pick a random number in the range -5.0 ---> +5.0.        ;; Coerce it to be single precision floating-point.        ;; Double precision is more expensive        ;; A similar clause to this could be used to coerce it        ;; to double prevision if you really need        ;; double precision.        ;; This is also the place to modify if you need a range        ;; other than -5.0 ---> +5.0.        (coerce (- (random-floating-point-number 10.0) 5.0)                'single-float))      (:integer-random-constant        ;; pick a random integer in the range -10 ---> +10.        (- (random-integer 21) 10))      (otherwise choice))))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -