almost done with lexicase

This commit is contained in:
Rowan Torbitzky-Lane 2025-03-02 01:56:50 -06:00
parent 500fbb5d77
commit 3815130d09
3 changed files with 16 additions and 6 deletions

View File

@ -7,7 +7,8 @@ import HushGP.State
data Individual = Individual data Individual = Individual
{ plushy :: [Gene], { plushy :: [Gene],
totalFitness :: Maybe Double, totalFitness :: Maybe Double,
fitnessCases :: Maybe [Double] fitnessCases :: Maybe [Double],
selectionCases :: Maybe [Int]
} }
deriving (Show, Eq) deriving (Show, Eq)

View File

@ -5,6 +5,7 @@ import System.Random
import System.Random.Shuffle import System.Random.Shuffle
import HushGP.GP.PushArgs import HushGP.GP.PushArgs
import HushGP.GP.Individual import HushGP.GP.Individual
import HushGP.Utility
-- | Tournament selection based off tournament size from PushArgs and a population. -- | Tournament selection based off tournament size from PushArgs and a population.
-- Takes the individual with the lowest total error in the tournament. -- Takes the individual with the lowest total error in the tournament.
@ -21,7 +22,8 @@ tournamentSelection PushArgs{tournamentSize = tSize} pop = do
lexicaseSelection :: PushArgs -> [Individual] -> IO Individual lexicaseSelection :: PushArgs -> [Individual] -> IO Individual
lexicaseSelection PushArgs{initialCases = iCases} pop = do lexicaseSelection PushArgs{initialCases = iCases} pop = do
startCases <- maybe (shuffle' [0..lehp] lehp <$> initStdGen) (pure @IO) iCases startCases <- maybe (shuffle' [0..lehp] lehp <$> initStdGen) (pure @IO) iCases
undefined survivors <- mapM randElem (groupBy (\x y -> fitnessCases x == fitnessCases y) pop)
lexicaseSelection' survivors startCases startCases
where where
lehp :: Int -- length of the extracted fitness cases of the head of the passed population. lehp :: Int -- length of the extracted fitness cases of the head of the passed population.
lehp = length $ extractFitnessCases $ lehp = length $ extractFitnessCases $
@ -29,4 +31,11 @@ lexicaseSelection PushArgs{initialCases = iCases} pop = do
Just (x, _) -> x Just (x, _) -> x
_ -> error "Error: Population in lexicaseSelection cannot be empty!" _ -> error "Error: Population in lexicaseSelection cannot be empty!"
-- lexicaseSelection' :: lexicaseSelection' :: [Individual] -> [Int] -> [Int] -> IO Individual
lexicaseSelection' survivors cases initialCases =
if null cases || null (drop 1 survivors)
then (\ind -> ind{selectionCases = Just initialCases}) <$> randElem survivors
else lexicaseSelection' ()
where
minErrorForCase :: Double
minErrorForCase = minimum $ map ((\x -> x !! case uncons cases of Just (y, _) -> y; _ -> error "Error: cases is empty!") . extractFitnessCases) survivors

View File

@ -16,7 +16,7 @@ survivors = mapM randElem tempFunc0
-- | A list of individuals used for testing. -- | A list of individuals used for testing.
testInds :: [Individual] testInds :: [Individual]
testInds = testInds =
[ Individual{plushy = [Close], totalFitness = Just 1000, fitnessCases = Just [500,500]} [ Individual{plushy = [Close], totalFitness = Just 1000, fitnessCases = Just [500,500], selectionCases = Nothing}
, Individual{plushy = [Close], totalFitness = Just 1000, fitnessCases = Just [400,600]} , Individual{plushy = [Close], totalFitness = Just 1000, fitnessCases = Just [400,600], selectionCases = Nothing}
, Individual{plushy = [Close], totalFitness = Just 900, fitnessCases = Just [500,400]} , Individual{plushy = [Close], totalFitness = Just 900, fitnessCases = Just [500,400], selectionCases = Nothing}
] ]