feat(scenario): scenario runner, extensions and working copy

scenario.py runs all five simulators of the core from a JSON scenario file,
with sweeps, and reproduces 20 of the note's data files (14 byte for byte,
6 column-wise). Extensions live outside the core and must reproduce it
exactly in a limit case; paadrag_tidsserie is the worked example.
arbeidskopi.py gives the user a copy of the model they can change.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-11-11 14:17:32 +01:00
commit 03151cfb3b
Signed by: ktg
SSH key fingerprint: SHA256:JakMjO6FTBBzN0Bhfj9saOoEjaFxlSdYuZQQpM/lF9Q
36 changed files with 3580 additions and 5 deletions

View file

@ -0,0 +1,11 @@
{
"navn": "avviklingstid_koordinert",
"beskrivelse": "Hvor raskt bør restansen avvikles når påtale og budsjett koordineres? Den koordinerte regelen (avsnitt 8.5) leder saker utenom og bestiller kapasitet slik at restansen over målet avvikles over T_clear måneder. Notatet har 24, 48 og uendelig i tabellen over endogene tiltak og nevner 12 i teksten; her er spennet fra 6 til 96 måneder i én kjøring, med kriminalitet, tillit, saksbehandlingstid, kapasitet og andel utenom side om side.",
"modell": "simulate_endo",
"regel": "koord",
"slutt": 180,
"sveip": {
"parameter": "parametere.ENDO.T_clear",
"verdier": [6, 12, 24, 48, 96, "inf"]
}
}

View file

@ -0,0 +1,17 @@
{
"navn": "kvalitetssloyfe",
"beskrivelse": "Hva gjør kvalitetssløyfen (prosessuell kvalitet q styres etter tillitsundersøkelsen, avsnitt 8.5) med desentraliserte og koordinerte regler? Notatets tabell over endogene tiltak har den koordinerte regelen med kvalitetssløyfe; her er alle fire kombinasjonene side om side over 180 måneder.",
"modell": "simulate_endo",
"slutt": 180,
"regel": "koord",
"sveip": [
{
"parameter": "regel",
"verdier": ["desentral", "koord"]
},
{
"parameter": "parametere.ENDO.qloop",
"verdier": [false, true]
}
]
}

View file

@ -0,0 +1,17 @@
{
"navn": "endo_des",
"beskrivelse": "Gjenskaper data/endo_des.dat: desentraliserte regler (observert strøm), 180 måneder, regime A (avsnitt 8.5).",
"modell": "simulate_endo",
"regel": "desentral",
"styring": {
"regulator": "P",
"forsinkelse": 3,
"reaktivitet": 3
},
"slutt": 180,
"utdata": {
"format": "notat",
"kolonner": ["t", "K", "L", "T", "Z_rel", "xi", "tauD", "q"],
"overskrift": "t K L T Z xi tauD q"
}
}

View file

@ -0,0 +1,17 @@
{
"navn": "endo_desp",
"beskrivelse": "Gjenskaper data/endo_desp.dat: desentraliserte regler med prognose, 180 måneder, regime A (avsnitt 8.5).",
"modell": "simulate_endo",
"regel": "desentral_prog",
"styring": {
"regulator": "P",
"forsinkelse": 3,
"reaktivitet": 3
},
"slutt": 180,
"utdata": {
"format": "notat",
"kolonner": ["t", "K", "L", "T", "Z_rel", "xi", "tauD", "q"],
"overskrift": "t K L T Z xi tauD q"
}
}

View file

@ -0,0 +1,28 @@
{
"navn": "endo_e5",
"beskrivelse": "Gjenskaper data/endo_e5.dat: faste vedtak i måned 24 (scenario 5 som tidsplan), 180 måneder, regime A (avsnitt 8.5).",
"modell": "simulate_endo",
"regel": "sched",
"styring": {
"regulator": "P",
"forsinkelse": 3,
"reaktivitet": 3
},
"tiltak": {
"andel_utenom": {
"andel": 0.2,
"fra": 24
},
"kapasitet": {
"faktor": 1.34,
"fra": 24,
"over": 24
}
},
"slutt": 180,
"utdata": {
"format": "notat",
"kolonner": ["t", "K", "L", "T", "Z_rel", "xi", "tauD", "q"],
"overskrift": "t K L T Z xi tauD q"
}
}

View file

@ -0,0 +1,17 @@
{
"navn": "endo_ko",
"beskrivelse": "Gjenskaper data/endo_ko.dat: koordinert regel (T_clear = 24), 180 måneder, regime A (avsnitt 8.5).",
"modell": "simulate_endo",
"regel": "koord",
"styring": {
"regulator": "P",
"forsinkelse": 3,
"reaktivitet": 3
},
"slutt": 180,
"utdata": {
"format": "notat",
"kolonner": ["t", "K", "L", "T", "Z_rel", "xi", "tauD", "q"],
"overskrift": "t K L T Z xi tauD q"
}
}

View file

@ -0,0 +1,19 @@
{
"navn": "kjede_s1",
"beskrivelse": "Gjenskaper data/kjede_s1.dat: scenario 1: ingen flaskehals (= regime A). Regime A (forsinkelse 3, reaktivitet 3), avsnitt 8.2.",
"modell": "simulate_chain",
"styring": {
"regulator": "P",
"forsinkelse": 3,
"reaktivitet": 3
},
"parametere": {
"CH0": {
"Z": "inf"
}
},
"utdata": {
"format": "notat",
"kolonner": ["t", "K", "U", "L", "T", "Q", "tauD"]
}
}

View file

@ -0,0 +1,14 @@
{
"navn": "kjede_s2",
"beskrivelse": "Gjenskaper data/kjede_s2.dat: scenario 2: flaskehals i domstolen, ingen tiltak. Regime A (forsinkelse 3, reaktivitet 3), avsnitt 8.2.",
"modell": "simulate_chain",
"styring": {
"regulator": "P",
"forsinkelse": 3,
"reaktivitet": 3
},
"utdata": {
"format": "notat",
"kolonner": ["t", "K", "U", "L", "T", "Q", "tauD"]
}
}

View file

@ -0,0 +1,20 @@
{
"navn": "kjede_s3",
"beskrivelse": "Gjenskaper data/kjede_s3.dat: scenario 3: underordne, 20 % av sakene ledes utenom fra måned 24. Regime A (forsinkelse 3, reaktivitet 3), avsnitt 8.2.",
"modell": "simulate_chain",
"styring": {
"regulator": "P",
"forsinkelse": 3,
"reaktivitet": 3
},
"tiltak": {
"andel_utenom": {
"andel": 0.2,
"fra": 24
}
},
"utdata": {
"format": "notat",
"kolonner": ["t", "K", "U", "L", "T", "Q", "tauD"]
}
}

View file

@ -0,0 +1,21 @@
{
"navn": "kjede_s4",
"beskrivelse": "Gjenskaper data/kjede_s4.dat: scenario 4: utvide, domstolens kapasitet +34 % lineært over måned 24-48. Regime A (forsinkelse 3, reaktivitet 3), avsnitt 8.2.",
"modell": "simulate_chain",
"styring": {
"regulator": "P",
"forsinkelse": 3,
"reaktivitet": 3
},
"tiltak": {
"kapasitet": {
"faktor": 1.34,
"fra": 24,
"over": 24
}
},
"utdata": {
"format": "notat",
"kolonner": ["t", "K", "U", "L", "T", "Q", "tauD"]
}
}

View file

@ -0,0 +1,25 @@
{
"navn": "kjede_s5",
"beskrivelse": "Gjenskaper data/kjede_s5.dat: scenario 5: underordne og utvide. Regime A (forsinkelse 3, reaktivitet 3), avsnitt 8.2.",
"modell": "simulate_chain",
"styring": {
"regulator": "P",
"forsinkelse": 3,
"reaktivitet": 3
},
"tiltak": {
"andel_utenom": {
"andel": 0.2,
"fra": 24
},
"kapasitet": {
"faktor": 1.34,
"fra": 24,
"over": 24
}
},
"utdata": {
"format": "notat",
"kolonner": ["t", "K", "U", "L", "T", "Q", "tauD"]
}
}

View file

@ -0,0 +1,13 @@
{
"navn": "mpc11",
"beskrivelse": "Gjenskaper data/mpc11.dat: regime D, modellprediktiv styring (MPC) med forsinkelse 11 mnd. Tar om lag 7 sekunder.",
"modell": "simulate",
"styring": {
"regulator": "MPC",
"forsinkelse": 11
},
"utdata": {
"format": "notat",
"kolonner": ["t", "K", "U", "L", "T"]
}
}

View file

@ -0,0 +1,14 @@
{
"navn": "p11",
"beskrivelse": "Gjenskaper data/p11.dat i notatet: regime C, P-regel med reaktivitet 3 og forsinkelse 11 mnd, uten straffesakskjede (avsnitt 8.1).",
"modell": "simulate",
"styring": {
"regulator": "P",
"forsinkelse": 11,
"reaktivitet": 3
},
"utdata": {
"format": "notat",
"kolonner": ["t", "K", "U", "L", "T"]
}
}

View file

@ -0,0 +1,14 @@
{
"navn": "p11d",
"beskrivelse": "Gjenskaper data/p11d.dat: regime E, avdempet P-regel (reaktivitet 1,2) med samme forsinkelse som regime C (11 mnd).",
"modell": "simulate",
"styring": {
"regulator": "P",
"forsinkelse": 11,
"reaktivitet": 1.2
},
"utdata": {
"format": "notat",
"kolonner": ["t", "K", "U", "L", "T"]
}
}

View file

@ -0,0 +1,14 @@
{
"navn": "p3",
"beskrivelse": "Gjenskaper data/p3.dat i notatet: regime A, P-regel med reaktivitet 3 og forsinkelse 3 mnd, uten straffesakskjede (avsnitt 8.1).",
"modell": "simulate",
"styring": {
"regulator": "P",
"forsinkelse": 3,
"reaktivitet": 3
},
"utdata": {
"format": "notat",
"kolonner": ["t", "K", "U", "L", "T"]
}
}

View file

@ -0,0 +1,14 @@
{
"navn": "p6",
"beskrivelse": "Gjenskaper data/p6.dat i notatet: regime B, P-regel med reaktivitet 3 og forsinkelse 6 mnd, uten straffesakskjede (avsnitt 8.1).",
"modell": "simulate",
"styring": {
"regulator": "P",
"forsinkelse": 6,
"reaktivitet": 3
},
"utdata": {
"format": "notat",
"kolonner": ["t", "K", "U", "L", "T"]
}
}

View file

@ -0,0 +1,18 @@
{
"navn": "prio_s2",
"beskrivelse": "Gjenskaper kolonnene i data/prio_s2.dat: domstol med to sakstyper, scenario 2, ingen tiltak. Kjøringen med forrang (prio = true) gir kolonnene t, K, KA, KB, tauA og tauB; kjøringen uten (FIFO, prio = false) gir tauF (= tauA), KF (= K) og KAF (= KA).",
"modell": "simulate_chain2",
"styring": {
"regulator": "P",
"forsinkelse": 3,
"reaktivitet": 3
},
"sveip": {
"parameter": "parametere.CH2.prio",
"verdier": [true, false]
},
"utdata": {
"format": "notat",
"kolonner": ["t", "K", "KA", "KB", "tauA", "tauB"]
}
}

View file

@ -0,0 +1,24 @@
{
"navn": "prio_s3",
"beskrivelse": "Gjenskaper kolonnene i data/prio_s3.dat: domstol med to sakstyper, scenario 3, 20 % av alle saker (en tredjedel av klasse B) ledes utenom fra måned 24. Kjøringen med forrang (prio = true) gir kolonnene t, K, KA, KB, tauA og tauB; kjøringen uten (FIFO, prio = false) gir tauF (= tauA), KF (= K) og KAF (= KA).",
"modell": "simulate_chain2",
"styring": {
"regulator": "P",
"forsinkelse": 3,
"reaktivitet": 3
},
"tiltak": {
"andel_utenom": {
"andel": 0.2,
"fra": 24
}
},
"sveip": {
"parameter": "parametere.CH2.prio",
"verdier": [true, false]
},
"utdata": {
"format": "notat",
"kolonner": ["t", "K", "KA", "KB", "tauA", "tauB"]
}
}

View file

@ -0,0 +1,29 @@
{
"navn": "prio_s5",
"beskrivelse": "Gjenskaper kolonnene i data/prio_s5.dat: domstol med to sakstyper, scenario 5, underordne og utvide. Kjøringen med forrang (prio = true) gir kolonnene t, K, KA, KB, tauA og tauB; kjøringen uten (FIFO, prio = false) gir tauF (= tauA), KF (= K) og KAF (= KA).",
"modell": "simulate_chain2",
"styring": {
"regulator": "P",
"forsinkelse": 3,
"reaktivitet": 3
},
"tiltak": {
"andel_utenom": {
"andel": 0.2,
"fra": 24
},
"kapasitet": {
"faktor": 1.34,
"fra": 24,
"over": 24
}
},
"sveip": {
"parameter": "parametere.CH2.prio",
"verdier": [true, false]
},
"utdata": {
"format": "notat",
"kolonner": ["t", "K", "KA", "KB", "tauA", "tauB"]
}
}

View file

@ -0,0 +1,18 @@
{
"navn": "sat_B",
"beskrivelse": "Gjenskaper kolonnene i data/sat_B.dat: regime B (forsinkelse 6 mnd) uten politimetning og med halvmetningsnivå K_sat = 3 og 1,5 (avsnitt 8.3). Kolonnene K, Ks3 og Ks15 i notatets fil er K fra hver av de tre kjøringene.",
"modell": "simulate",
"styring": {
"regulator": "P",
"forsinkelse": 6,
"reaktivitet": 3
},
"sveip": {
"parameter": "parametere.P.ksat",
"verdier": ["inf", 3, 1.5]
},
"utdata": {
"format": "notat",
"kolonner": ["t", "K"]
}
}

View file

@ -0,0 +1,18 @@
{
"navn": "sat_C",
"beskrivelse": "Gjenskaper kolonnene i data/sat_C.dat: regime C (forsinkelse 11 mnd) uten politimetning og med halvmetningsnivå K_sat = 3 og 1,5 (avsnitt 8.3). Kolonnene K, Ks3 og Ks15 i notatets fil er K fra hver av de tre kjøringene.",
"modell": "simulate",
"styring": {
"regulator": "P",
"forsinkelse": 11,
"reaktivitet": 3
},
"sveip": {
"parameter": "parametere.P.ksat",
"verdier": ["inf", 3, 1.5]
},
"utdata": {
"format": "notat",
"kolonner": ["t", "K"]
}
}

View file

@ -0,0 +1,24 @@
{
"navn": "vippe",
"beskrivelse": "Gjenskaper kolonnene fast, p3 og p6 i data/vippe.dat: rekruttering med vippepunkt og et forbigående sjokk (Omega x 1,6 i måned 12-36), avsnitt 8.4. Rutenettet gir fast innsats (to like kjøringer, forsinkelsen brukes ikke) og P-regel med forsinkelse 3 og 6.",
"modell": "simulate_soc",
"sjokk": {
"faktor": 1.6,
"fra": 12,
"til": 36
},
"sveip": [
{
"parameter": "styring.regulator",
"verdier": ["fast", "P"]
},
{
"parameter": "styring.forsinkelse",
"verdier": [3, 6]
}
],
"utdata": {
"format": "notat",
"kolonner": ["t", "K"]
}
}

View file

@ -0,0 +1,28 @@
{
"navn": "vippe_tak",
"beskrivelse": "Gjenskaper kolonnene p3cap og p6cap i data/vippe.dat: som vippe.json, men med tak på innsatsen (Tmax = 1,5) og politimetning (K_sat = 1,5).",
"modell": "simulate_soc",
"parametere": {
"P": {
"Tmax": 1.5,
"ksat": 1.5
}
},
"sjokk": {
"faktor": 1.6,
"fra": 12,
"til": 36
},
"styring": {
"regulator": "P",
"reaktivitet": 3
},
"sveip": {
"parameter": "styring.forsinkelse",
"verdier": [3, 6]
},
"utdata": {
"format": "notat",
"kolonner": ["t", "K"]
}
}

View file

@ -0,0 +1,9 @@
{
"navn": "sjokkstorrelse_kjede",
"beskrivelse": "Hvor mye betyr størrelsen på sjokket når domstolen er en flaskehals og ingen tiltak settes inn? Notatet bruker 30 % økning i det strukturelle pådraget (scenario 2, avsnitt 8.2); her går økningen fra 10 til 60 %. Se på saksbehandlingstiden og tilliten ved slutt, og på om kriminaliteten ved slutt er lik den høyeste: da har forløpet ikke funnet en ny balanse innen 120 måneder.",
"modell": "simulate_chain",
"sveip": {
"parameter": "sjokk.faktor",
"verdier": [1.1, 1.2, 1.3, 1.45, 1.6]
}
}

View file

@ -0,0 +1,16 @@
{
"navn": "stabilitet_reaktivitet_forsinkelse",
"beskrivelse": "Hvor går grensen for når styringen selv skaper svingninger? Rutenett over reaktivitet (kp) og forsinkelse (tau) i modellen uten straffesakskjede, 240 måneder. Tabellen nederst viser spennet i K de siste 60 månedene: null betyr at svingningene har dødd ut, et tall over null at de holder seg. Sammenlign med notatets kritiske forsinkelse (proposisjon 1, Hayes), som med notatets tall er uendelig for kp = 1, 27,8 mnd for kp = 1,5, 13,8 for kp = 2, 7,2 for kp = 3, 4,2 for kp = 4,5 og 3,0 for kp = 6. Nær grensen dør svingningene sakte ut, så små tall rett under grensen er rester av innsvinget; sammenlign med spennet etter måned 60 i hovedtabellen. Over grensen vokser svingningene til taket på innsatsen (Tmax = 3) og gulvet på 0 holder dem i sjakk. Den lineære analysen gjelder små avvik fra likevekten før sjokket, simuleringen hele forløpet.",
"modell": "simulate",
"slutt": 240,
"sveip": [
{
"parameter": "styring.reaktivitet",
"verdier": [1, 1.5, 2, 3, 4.5, 6]
},
{
"parameter": "styring.forsinkelse",
"verdier": [2, 4, 6, 8, 11, 14]
}
]
}

View file

@ -0,0 +1,14 @@
{
"navn": "utvidelse_bolge",
"beskrivelse": "Hva etterlater en forbigående bølge i kriminalitetspresset? Pådraget stiger lineært med 40 % fra måned 12 til 18, ligger der til måned 36 og er tilbake på utgangsnivået i måned 48 (utvidelsen paadrag_tidsserie). Kjøres med domstolen som flaskehals (notatets CH0.Z; null i sveipet betyr notatets verdi) og uten flaskehals (\"inf\"). Spørsmålet er om køen og tillitstapet blir værende etter at presset er borte.",
"modell": "utvidelse:paadrag_tidsserie",
"slutt": 180,
"utvidelse": {
"form": "lineaer",
"punkter": [[12, 1.0], [18, 1.4], [36, 1.4], [48, 1.0]]
},
"sveip": {
"parameter": "parametere.CH0.Z",
"verdier": [null, "inf"]
}
}