Commit f7360b88 authored by Hans-Peter Deifel's avatar Hans-Peter Deifel 🐢
Browse files

wta: Swap algorithm if transition count is too large

The existing algorithm for generating unique transitions is inefficient if the
transition count is close to the maximal number of transitions. This now
switches to a different algorithm if the transition count is above 70% of the
maximum.
parent 44999948
Loading
Loading
Loading
Loading
+17 −1
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@ import Control.Arrow ( (&&&) )
import qualified Data.Map.Strict            as M
import qualified Data.Set                   as S
import           Data.Coerce
import           Data.Ratio

import           Types                   hiding ( spec )
import           Probability
@@ -98,13 +99,28 @@ genTransitions = do

-- TODO Implement (Random IndexedTransition)
uniqueTransitions :: Int -> IndexedTransition -> IO [IndexedTransition]
uniqueTransitions num (IndexedTransition.Index max) = helper S.empty num
uniqueTransitions num idxMax@(IndexedTransition.Index max)
  | fromIntegral num < fromIntegral max * (7%10) = uniqueTransitionsByGeneration num idxMax
  | otherwise       = uniqueTransitionsByElimination num idxMax

uniqueTransitionsByGeneration :: Int -> IndexedTransition -> IO [IndexedTransition]
uniqueTransitionsByGeneration num (IndexedTransition.Index max) = helper S.empty num
  where
    helper m 0 = return $ coerce (S.toList m)
    helper m c = do
      x <- randomRIO (0, max-1)
      if x `S.member` m then helper m c else helper (S.insert x m) (c-1)

uniqueTransitionsByElimination :: Int -> IndexedTransition -> IO [IndexedTransition]
uniqueTransitionsByElimination num (IndexedTransition.Index max) = helper whole num
  where
    helper free 0 = return $ coerce (S.toList (S.difference whole free))
    helper free c = do
      idx <- randomRIO (0, S.size free - 1)
      let x = S.elemAt idx free
      helper (S.delete x free) (c-1)

    whole = S.fromList [0..max-1]

genTransitions' :: Int -> Generator m (Vector (Vector (Transition m)))
genTransitions' numTransitions = do