Compare commits
No commits in common. "500fbb5d77093ba29f4afc76158d660e316a95e3" and "9706a77ba9beedc71f7ad0639708f538eb32b782" have entirely different histories.
500fbb5d77
...
9706a77ba9
@ -60,14 +60,11 @@ library
|
|||||||
, HushGP.PushTests.IntTests
|
, HushGP.PushTests.IntTests
|
||||||
, HushGP.PushTests.GenericTests
|
, HushGP.PushTests.GenericTests
|
||||||
, HushGP.PushTests.UtilTests
|
, HushGP.PushTests.UtilTests
|
||||||
, HushGP.PushTests.GP.Selection
|
|
||||||
, HushGP.GP
|
, HushGP.GP
|
||||||
, HushGP.GP.PushArgs
|
, HushGP.GP.PushArgs
|
||||||
, HushGP.GP.Variation
|
, HushGP.GP.Variation
|
||||||
, HushGP.GP.Downsample
|
, HushGP.GP.Downsample
|
||||||
, HushGP.GP.PushData
|
, HushGP.GP.PushData
|
||||||
, HushGP.GP.Selection
|
|
||||||
, HushGP.GP.Individual
|
|
||||||
, HushGP.Problems.IntegerRegression
|
, HushGP.Problems.IntegerRegression
|
||||||
, HushGP.Tools.Metrics
|
, HushGP.Tools.Metrics
|
||||||
|
|
||||||
|
7
TODO.md
7
TODO.md
@ -6,7 +6,6 @@
|
|||||||
- [X] Implement all functions as seen in propeller
|
- [X] Implement all functions as seen in propeller
|
||||||
- [X] Implement all functions as seen in the specification
|
- [X] Implement all functions as seen in the specification
|
||||||
- [ ] Implement Linear Algebra functions as specified in the previous papers
|
- [ ] Implement Linear Algebra functions as specified in the previous papers
|
||||||
- [ ] These are in a separate branch, just need merging now
|
|
||||||
- [X] Add a function to sort a vector forward and backwards
|
- [X] Add a function to sort a vector forward and backwards
|
||||||
- [X] Disambiguate isEmpty and stackIsEmpty
|
- [X] Disambiguate isEmpty and stackIsEmpty
|
||||||
- [X] Rename Logical to Bool
|
- [X] Rename Logical to Bool
|
||||||
@ -19,7 +18,6 @@
|
|||||||
- [X] Move utility functions to their own file
|
- [X] Move utility functions to their own file
|
||||||
- [ ] Make add/sub/mult/div/mod instructions generic
|
- [ ] Make add/sub/mult/div/mod instructions generic
|
||||||
- [ ] Use template haskell to (mostly) generate functions from generic ones (Split files based on the arity of their functions)
|
- [ ] Use template haskell to (mostly) generate functions from generic ones (Split files based on the arity of their functions)
|
||||||
- [ ] Add more special functions like sqrt, pow
|
|
||||||
|
|
||||||
## PushGP TODO
|
## PushGP TODO
|
||||||
- [X] Implement a Plushy genome translator
|
- [X] Implement a Plushy genome translator
|
||||||
@ -33,11 +31,10 @@
|
|||||||
- [ ] Need to make genomes serializable (Check pysh json files)
|
- [ ] Need to make genomes serializable (Check pysh json files)
|
||||||
- [ ] Add Memory
|
- [ ] Add Memory
|
||||||
- [ ] Add history stack(s), like a call stack
|
- [ ] Add history stack(s), like a call stack
|
||||||
- [ ] Implement interpreter options (PushArgs would work well)
|
- [ ] Implement interpreter options (could probably just place this into a map)
|
||||||
- Should probably place this in a separate file
|
- Should probably place this in a separate file
|
||||||
- [X] Implement different forms of downsampling
|
- [ ] Implement different forms of downsampling
|
||||||
- [ ] Implement concurrent execution of creating random plushies and evaluating individuals
|
- [ ] Implement concurrent execution of creating random plushies and evaluating individuals
|
||||||
- [X] Devise a good way to implement ERCs
|
- [X] Devise a good way to implement ERCs
|
||||||
- [ ] Implement random simplification of genomes
|
- [ ] Implement random simplification of genomes
|
||||||
- [ ] Find a way to multi-thread this
|
- [ ] Find a way to multi-thread this
|
||||||
- [ ] Look at using `uniformShuffleList` over System.Random.Shuffle
|
|
||||||
|
@ -11,7 +11,6 @@ import HushGP.GP.PushArgs
|
|||||||
import HushGP.GP.PushData
|
import HushGP.GP.PushData
|
||||||
import HushGP.GP.Variation
|
import HushGP.GP.Variation
|
||||||
import HushGP.Genome
|
import HushGP.Genome
|
||||||
import HushGP.GP.Individual
|
|
||||||
|
|
||||||
-- import Debug.Trace (trace, traceStack)
|
-- import Debug.Trace (trace, traceStack)
|
||||||
|
|
||||||
|
@ -4,12 +4,12 @@ import System.Random.Shuffle
|
|||||||
import System.Random
|
import System.Random
|
||||||
import Data.List
|
import Data.List
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
|
import HushGP.Genome
|
||||||
import HushGP.Utility
|
import HushGP.Utility
|
||||||
import HushGP.GP.PushData
|
import HushGP.GP.PushData
|
||||||
import HushGP.GP.PushArgs
|
import HushGP.GP.PushArgs
|
||||||
import HushGP.Tools.Metrics
|
import HushGP.Tools.Metrics
|
||||||
import HushGP.Instructions.Utility
|
import HushGP.Instructions.Utility
|
||||||
import HushGP.GP.Individual
|
|
||||||
|
|
||||||
-- |Sets the index of the passed training data.
|
-- |Sets the index of the passed training data.
|
||||||
assignIndicesToData :: [PushData] -> [PushData]
|
assignIndicesToData :: [PushData] -> [PushData]
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
module HushGP.GP.Individual where
|
|
||||||
|
|
||||||
import HushGP.State
|
|
||||||
|
|
||||||
-- | The structure for an individual containing the genome, the totalFitness, and
|
|
||||||
-- the individual fitness cases for lexicase.
|
|
||||||
data Individual = Individual
|
|
||||||
{ plushy :: [Gene],
|
|
||||||
totalFitness :: Maybe Double,
|
|
||||||
fitnessCases :: Maybe [Double]
|
|
||||||
}
|
|
||||||
deriving (Show, Eq)
|
|
||||||
|
|
||||||
instance Ord Individual where
|
|
||||||
ind0 <= ind1 = totalFitness ind0 <= totalFitness ind1
|
|
||||||
|
|
||||||
-- | Extracts the fitnessCases from an Individual. Errors if the field is empty.
|
|
||||||
extractFitnessCases :: Individual -> [Double]
|
|
||||||
extractFitnessCases Individual {fitnessCases = Nothing} = error "Error: fitnessCases is empty!"
|
|
||||||
extractFitnessCases Individual {fitnessCases = Just xs} = xs
|
|
||||||
|
|
||||||
extractTotalFitness :: Individual -> Double
|
|
||||||
extractTotalFitness Individual {totalFitness = Nothing} = error "Error: totalFitness is empty!"
|
|
||||||
extractTotalFitness Individual {totalFitness = Just x} = x
|
|
@ -3,7 +3,6 @@ module HushGP.GP.PushArgs where
|
|||||||
import HushGP.State
|
import HushGP.State
|
||||||
import HushGP.Instructions
|
import HushGP.Instructions
|
||||||
import HushGP.GP.PushData
|
import HushGP.GP.PushData
|
||||||
import HushGP.GP.Individual
|
|
||||||
import Data.Map qualified as Map
|
import Data.Map qualified as Map
|
||||||
|
|
||||||
-- | The structure holding the arguments for the various aspects
|
-- | The structure holding the arguments for the various aspects
|
||||||
@ -97,11 +96,7 @@ data PushArgs = PushArgs
|
|||||||
epsilons :: Maybe [Double],
|
epsilons :: Maybe [Double],
|
||||||
-- | Used with the CaseMaxminAuto downsampling strategy. Tells downsampling to stop when
|
-- | Used with the CaseMaxminAuto downsampling strategy. Tells downsampling to stop when
|
||||||
-- the maximum minimum distance is too far away.
|
-- the maximum minimum distance is too far away.
|
||||||
caseDelta :: Double,
|
caseDelta :: Double
|
||||||
-- | Used in lexicase selection. If initialCases is present will use those before randomly
|
|
||||||
-- selecting from the population for initial cases. Can raise a value into the IO monad using
|
|
||||||
-- `pure @IO`
|
|
||||||
initialCases :: Maybe [Int]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
-- | The default values for which all runs of Hush derive
|
-- | The default values for which all runs of Hush derive
|
||||||
@ -148,6 +143,5 @@ defaultPushArgs = PushArgs {
|
|||||||
umadRate = 0.1,
|
umadRate = 0.1,
|
||||||
variation = Map.fromList [("umad", 1.0)],
|
variation = Map.fromList [("umad", 1.0)],
|
||||||
epsilons = Nothing,
|
epsilons = Nothing,
|
||||||
caseDelta = 0,
|
caseDelta = 0
|
||||||
initialCases = Nothing
|
|
||||||
}
|
}
|
||||||
|
@ -1,32 +0,0 @@
|
|||||||
module HushGP.GP.Selection where
|
|
||||||
|
|
||||||
import Data.List
|
|
||||||
import System.Random
|
|
||||||
import System.Random.Shuffle
|
|
||||||
import HushGP.GP.PushArgs
|
|
||||||
import HushGP.GP.Individual
|
|
||||||
|
|
||||||
-- | Tournament selection based off tournament size from PushArgs and a population.
|
|
||||||
-- Takes the individual with the lowest total error in the tournament.
|
|
||||||
tournamentSelection :: PushArgs -> [Individual] -> IO Individual
|
|
||||||
tournamentSelection PushArgs{tournamentSize = tSize} pop = do
|
|
||||||
shuffledPop <- shuffle' pop (length pop) <$> initStdGen
|
|
||||||
let tournSet = take tSize shuffledPop
|
|
||||||
pure $ minimum tournSet
|
|
||||||
|
|
||||||
-- |Selects an individual from the population using lexicase selection.
|
|
||||||
-- Lexicase parent selection filters the population by considering one random training case at a time,
|
|
||||||
-- eliminating any individuals with errors for the current case that are worse than the best error in the selection pool,
|
|
||||||
-- until a single individual remains. This is the top level function.
|
|
||||||
lexicaseSelection :: PushArgs -> [Individual] -> IO Individual
|
|
||||||
lexicaseSelection PushArgs{initialCases = iCases} pop = do
|
|
||||||
startCases <- maybe (shuffle' [0..lehp] lehp <$> initStdGen) (pure @IO) iCases
|
|
||||||
undefined
|
|
||||||
where
|
|
||||||
lehp :: Int -- length of the extracted fitness cases of the head of the passed population.
|
|
||||||
lehp = length $ extractFitnessCases $
|
|
||||||
case uncons pop of
|
|
||||||
Just (x, _) -> x
|
|
||||||
_ -> error "Error: Population in lexicaseSelection cannot be empty!"
|
|
||||||
|
|
||||||
-- lexicaseSelection' ::
|
|
@ -1,7 +1,7 @@
|
|||||||
module HushGP.GP.Variation where
|
module HushGP.GP.Variation where
|
||||||
|
|
||||||
|
import HushGP.Genome
|
||||||
import HushGP.GP.PushArgs
|
import HushGP.GP.PushArgs
|
||||||
import HushGP.GP.Individual
|
|
||||||
|
|
||||||
newIndividual :: PushArgs -> [Individual] -> Individual
|
newIndividual :: PushArgs -> [Individual] -> Individual
|
||||||
newIndividual = error "Implement this later"
|
newIndividual = error "Implement this later"
|
||||||
|
@ -7,11 +7,31 @@ import HushGP.GP.PushArgs
|
|||||||
import HushGP.Instructions.Opens
|
import HushGP.Instructions.Opens
|
||||||
import HushGP.State
|
import HushGP.State
|
||||||
import HushGP.Utility
|
import HushGP.Utility
|
||||||
import HushGP.GP.Individual
|
|
||||||
|
|
||||||
-- import HushGP.Instructions
|
-- import HushGP.Instructions
|
||||||
-- import Debug.Trace
|
-- import Debug.Trace
|
||||||
|
|
||||||
|
-- | The structure for an individual containing the genome, the totalFitness, and
|
||||||
|
-- the individual fitness cases for lexicase.
|
||||||
|
data Individual = Individual
|
||||||
|
{ plushy :: [Gene],
|
||||||
|
totalFitness :: Maybe Double,
|
||||||
|
fitnessCases :: Maybe [Double]
|
||||||
|
}
|
||||||
|
deriving (Show, Eq)
|
||||||
|
|
||||||
|
instance Ord Individual where
|
||||||
|
ind0 <= ind1 = totalFitness ind0 <= totalFitness ind1
|
||||||
|
|
||||||
|
-- | Extracts the fitnessCases from an Individual. Errors if the field is empty.
|
||||||
|
extractFitnessCases :: Individual -> [Double]
|
||||||
|
extractFitnessCases Individual {fitnessCases = Nothing} = error "Error: fitnessCases is empty!"
|
||||||
|
extractFitnessCases Individual {fitnessCases = Just xs} = xs
|
||||||
|
|
||||||
|
extractTotalFitness :: Individual -> Double
|
||||||
|
extractTotalFitness Individual {totalFitness = Nothing} = error "Error: totalFitness is empty!"
|
||||||
|
extractTotalFitness Individual {totalFitness = Just x} = x
|
||||||
|
|
||||||
-- | Makes a random individual based on the variables in a passed PushArgs.
|
-- | Makes a random individual based on the variables in a passed PushArgs.
|
||||||
makeRandomIndividual :: PushArgs -> IO Individual
|
makeRandomIndividual :: PushArgs -> IO Individual
|
||||||
makeRandomIndividual pushArgs = do
|
makeRandomIndividual pushArgs = do
|
||||||
|
@ -1,22 +0,0 @@
|
|||||||
module HushGP.PushTests.GP.Selection where
|
|
||||||
|
|
||||||
import Data.List
|
|
||||||
import HushGP.GP.Individual
|
|
||||||
import HushGP.State
|
|
||||||
import HushGP.Utility
|
|
||||||
|
|
||||||
-- | One of the steps in the lexicase selection process for selecting initial survivors.
|
|
||||||
tempFunc0 :: [[Individual]]
|
|
||||||
tempFunc0 = groupBy (\x y -> fitnessCases x == fitnessCases y) testInds
|
|
||||||
|
|
||||||
-- \| Another step forward in the lexicase selection process.
|
|
||||||
survivors :: IO [Individual]
|
|
||||||
survivors = mapM randElem tempFunc0
|
|
||||||
|
|
||||||
-- | A list of individuals used for testing.
|
|
||||||
testInds :: [Individual]
|
|
||||||
testInds =
|
|
||||||
[ Individual{plushy = [Close], totalFitness = Just 1000, fitnessCases = Just [500,500]}
|
|
||||||
, Individual{plushy = [Close], totalFitness = Just 1000, fitnessCases = Just [400,600]}
|
|
||||||
, Individual{plushy = [Close], totalFitness = Just 900, fitnessCases = Just [500,400]}
|
|
||||||
]
|
|
@ -23,7 +23,3 @@ mapIndexed = mapIndexed' 0
|
|||||||
mapIndexed' :: Int -> (Int -> a -> b) -> [a] -> [b]
|
mapIndexed' :: Int -> (Int -> a -> b) -> [a] -> [b]
|
||||||
mapIndexed' _ _ [] = []
|
mapIndexed' _ _ [] = []
|
||||||
mapIndexed' count f (x : xs) = f count x : mapIndexed' (count + 1) f xs
|
mapIndexed' count f (x : xs) = f count x : mapIndexed' (count + 1) f xs
|
||||||
|
|
||||||
-- | Returns a random element from a passed list. No generator required.
|
|
||||||
randElem :: [a] -> IO a
|
|
||||||
randElem xs = (xs !!) . fst . uniformR (0, length xs - 1) <$> initStdGen
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user