rl-satton-0.1.2.4: examples/Examples/Ch4_GridWorld/MC.hs
{-# LANGUAGE QuasiQuotes #-}
module Examples.Ch4_GridWorld.MC where
import qualified Data.List as List
import qualified Data.HashMap.Strict as HashMap
import qualified Data.Set as Set
-- import qualified Control.Monad. as Set
import Control.Monad.Except
import RL.Types
import RL.Imports
import RL.MC as MC
import Examples.Ch4_GridWorld.Rules(GW(..), Point, Action)
import qualified Examples.Ch4_GridWorld.Rules as Rules
import qualified Examples.Ch4_GridWorld.DP as DP
instance (Fractional num, Real num, Ord num) => MC_Problem (GW num) Point Action num where
mc_is_terminal = Rules.isTerminal
mc_reward gw s a s' = -1
-- | Uniform random policy iteration with MC alg
gw_iter_mc :: GW MC_Number -> IO ()
gw_iter_mc gw =
let
o = MC.defaultOpts {
o_alpha = 0.1
}
cnt = 20*10^3
g0 = pureMT 33 -- Initial RNG
q0 = MC.emptyQ 0 -- Initial Q table
st_q :: Lens' (a,b,c) a
st_q = _1
st_i :: Lens' (a,b,c) b
st_i = _2
st_len :: Lens' (a,b,c) c
st_len = _3
in do
{- Reference StateVal -}
(v_dp, p_dp) <- DP.gw_iter_dp gw
Rules.withLearnPlot cnt $ \d ->
flip evalRndT_ g0 $ do
flip execStateT (q0,0,0) $ do
loop $ do
s0 <- Rules.arbitraryState gw
a0 <- uniform [minBound..maxBound]
i <- use st_i
q <- use st_q
st_len %= const 0
mq <-
runExceptT $ do
mc_es_learn o q s0 a0 $ MC gw $ \s a -> do
st_len %= (+1)
l <- use st_len
when (l > 200) $ do
throwError $ "Episode is too long"
return $ Rules.transition gw s a
case mq of
Right q' -> do
liftIO $ putStrLn $ "Loop i = " <> show i
liftIO $ Rules.showV gw (HashMap.toList $ MC.toV q')
liftIO $ pushData d i (MC.diffV (MC.toV q') v_dp)
st_i %= (+1)
st_q %= const q'
Left err -> do
liftIO $ putStrLn $ "Skipping episode due to error: " <> err
return ()