# HG changeset patch # User Benjamin Weber # Date 1666778180 -7200 # Wed Oct 26 11:56:20 2022 +0200 # Node ID 14c248fe4cb2283e9b338837a0e7a6119718ace9 # Parent 68a60e002b1b35e2bf54893542752bd425aa8df0 implement new setReworks mechanism that calls Random only for no of jobs to be reworked (was all jobs) diff --git a/src/Main.elm b/src/Main.elm --- a/src/Main.elm +++ b/src/Main.elm @@ -17,9 +17,9 @@ import Lib exposing (..) import Maybe.Extra exposing (..) import Numbers exposing (Quartile(..), quartile) +import Rework exposing (..) import Round exposing (..) import Stats exposing (..) -import Step exposing (..) import Task import Time import Types exposing (..) diff --git a/src/Rework.elm b/src/Rework.elm --- a/src/Rework.elm +++ b/src/Rework.elm @@ -3,6 +3,7 @@ import Field exposing (..) import Random import Random.Extra +import Random.List import Types exposing (..) @@ -27,3 +28,84 @@ setReworksSingleMode : ProbPerRound -> List Job -> Random.Generator (List Job) setReworksSingleMode p = Random.Extra.traverse (setRework p) + + + +-- new setRework mechanism to improve perf with increasing no. of jobs on w0 +-- aim: constant computing amount for increasing no. of jobs on w0 +-- relevance: rework mechanism consumes ≈ half of computing time, which is the biggest chunk +-- example situation: 100 jobs on w0, rework probability is 1% +-- approach: pick 1 job by random and set it to require rework +-- sub-problem: what if we end up with decimal no. of jobs, +-- i.e. 100 jobs at 0.5% rework probability => 0.5 jobs +-- or 2 jobs at 1 % rework probability => 0.02 jobs +-- approach: 0.5 and 0.02 jobs are probabilities 0.5 and 0.02 for +-- an additional job to be picked and set to require rework +-- reworkProb * jobsAtW0 +-- (nonDecimal, decimal) = … +-- jobsToRequireRework = nonDecimal + additional decimal +-- newW0 = setRework jobsToRequireRework w0 +--additional : Float -> Random.Generator Bool +--additional prob = _ +-- | p is percentage, i.e. 0.1 is 0.1% + + +bool : Float -> Random.Generator Bool +bool p = + Random.map (\n -> n < round (p * 1000 / 100)) <| Random.int 1 1000 + + +detNoOfJobsRequiringRework : ProbPerRound -> Int -> Random.Generator Int +detNoOfJobsRequiringRework p w0Count = + let + reworkJobs = + p * toFloat w0Count + + nonDecimal = + round reworkJobs + + decimal = + reworkJobs - toFloat nonDecimal + + additional = + Random.map + (\x -> + if x then + 1 + + else + 0 + ) + <| + bool decimal + in + Random.map (\x -> nonDecimal + x) additional + + +setReworks : ProbPerRound -> ( Field, Field ) -> Random.Generator ( Field, Field ) +setReworks p ( kf, nkf ) = + Random.map2 Tuple.pair (setReworksFieldWrapper p kf) (setReworksFieldWrapper p nkf) + + +setReworksFieldWrapper : ProbPerRound -> Field -> Random.Generator Field +setReworksFieldWrapper p field = + detNoOfJobsRequiringRework p (List.length field.w0) |> Random.andThen (setReworksField field) + + +setReworksField : Field -> Int -> Random.Generator Field +setReworksField field n = + Random.map (\x -> { field | w0 = x }) <| setReworkNew n field.w0 + + +setReworkNew : Int -> List Job -> Random.Generator (List Job) +setReworkNew n = + let + toRework = + List.map (\x -> updateRework x NeedsRework) + in + Random.map (\( a, b ) -> toRework a ++ b) << Random.List.choices n + + +setReworksCmd : Model -> Cmd Msg +setReworksCmd model = + Random.generate SetReworksDone <| setReworks model.reworkProbPerRound ( model.kit, model.nkit ) diff --git a/src/Step.elm b/src/Step.elm deleted file mode 100644 --- a/src/Step.elm +++ /dev/null @@ -1,25 +0,0 @@ -module Step exposing (..) - -import Random -import Random.Extra -import Rework exposing (..) -import Types exposing (..) - - - --- step mode - - -setReworksField : ProbPerRound -> Field -> Random.Generator Field -setReworksField p f = - Random.Extra.traverse (setRework p) f.w0 |> Random.andThen (\x -> Random.constant { f | w0 = x }) - - -setReworks : ProbPerRound -> ( Field, Field ) -> Random.Generator ( Field, Field ) -setReworks p ( kf, nkf ) = - Random.map2 Tuple.pair (setReworksField p kf) (setReworksField p nkf) - - -setReworksCmd : Model -> Cmd Msg -setReworksCmd model = - Random.generate SetReworksDone <| setReworks model.reworkProbPerRound ( model.kit, model.nkit )