Coverage for moptipyapps / prodsched / rop_multisimulation.py: 93%
30 statements
« prev ^ index » next coverage.py v7.13.1, created at 2025-12-30 03:25 +0000
« prev ^ index » next coverage.py v7.13.1, created at 2025-12-30 03:25 +0000
1"""
2A simulator for multiple runs of the ROP scenario.
4Re-Order-Point (ROP) scenarios are such that for each product, a value `X` is
5provided. Once there are no more than `X` elements of that product in the
6warehouse, one new unit is ordered to be produced.
7Therefore, we have `n_products` such `X` values.
8A simulation in this scenario is implemented in
9:mod:`~moptipyapps.prodsched.rop_simulation` as class
10:class:`~moptipyapps.prodsched.rop_simulation.ROPSimulation`.
12This module here provides the functionality to simulate this ROP-approach
13over *multiple* instances (:class:`~moptipyapps.prodsched.instance.Instance`).
14It acts as an :class:`~moptipy.api.encoding.Encoding` that converts a re-order
15point into an instance of
16:class:`~moptipyapps.prodsched.multistatistics.MultiStatistics` which can then
17be used as basis to compute the values of (potentially multiple)
18objective functions, such as those given in package
19:mod:`~moptipyapps.prodsched.objectives`.
21Now, doing a multi-simulation is costly.
22It takes from half a second to several seconds.
23It is unlikely that we can do more than a million in any run of an
24optimization algorithm.
25Therefore, we use an internal caching mechanism to store all the input
26vectors and output statistics.
27This may consume quite some memory, but it might be faster.
29>>> from moptipyapps.prodsched.mfc_generator import sample_mfc_instance
30>>> from moptipyapps.prodsched.mfc_generator import Product
31>>> from moptipyapps.prodsched.mfc_generator import Station
32>>> from moptipyapps.utils.sampling import Gamma
33>>> from moptipyapps.prodsched.multistatistics import to_stream
35>>> inst1 = sample_mfc_instance(seed=100)
36>>> inst2 = sample_mfc_instance(seed=200)
38>>> instances = (inst1, inst2)
39>>> space = MultiStatisticsSpace(instances)
40>>> ms = ROPMultiSimulation(space)
42>>> x1 = np.array([4, 6, 3, 4, 4, 6, 3, 5, 6, 10])
43>>> y = space.create()
44>>> ms.decode(x1, y)
45>>> for s in to_stream(y):
46... if "time" not in s:
47... print(s)
48-------- Instance 0: 'mfc_10_13_10000_0x64' -------
49stat;total;product_0;product_1;product_2;product_3;product_4;product_5;\
50product_6;product_7;product_8;product_9
51trp.min;5.2184145757182705;5.2184145757182705;8.901258396714184;\
529.297175556856018;7.298761505635412;8.93985302431065;12.606621860129053;\
537.656178022299173;20.904266810249283;19.5732602761791;20.522703426695443
54trp.mean;32.405411220867336;22.45718865883824;29.222031978321247;\
5525.136275651698107;25.884250065648388;27.37383814423524;32.10269885414455;\
5621.905835255853667;45.11627023942567;44.78387873021794;49.465651426661886
57trp.max;101.42283298962138;56.30942379913131;74.17811849023519;\
5858.955465373336665;60.209164983262326;60.66621167329777;74.4357130671624;\
5947.944841355481;83.29062031809917;96.5279603056706;101.42283298962138
60trp.sd;14.352456423754838;8.966715472534952;10.260311480773648;\
618.824583884361449;9.375043161957333;9.776116378207652;10.962890512009123;\
626.691465594834237;12.613587720623373;12.30244975508726;13.52381481631245
63cwt.min;0.026454757136889384;0.026454757136889384;2.30483638259102;\
640.054286282554130594;0.16648942892061314;0.1385205442725237;\
652.2444075501571206;0.16694429707604286;0.2360807359827959;0.2894682031374032;\
660.7020815078112719
67cwt.mean;8.296470547393602;4.437533958350662;12.615320110639914;\
684.7164029806433545;6.611310521050654;8.350460109042185;7.55452574755307;\
695.82304931358363;9.068938196877168;17.21719619156937;6.710247622764048
70cwt.max;37.76460269749805;11.383554877750612;25.02207987420161;\
7116.22657205109499;24.355088852856625;23.499199642416897;24.507644884798083;\
7227.834403782263507;29.068687291493006;37.76460269749805;12.188275706294007
73cwt.sd;8.072214752396842;3.8478370296451603;9.569679438559595;\
744.197433045217076;7.324722986150041;6.142260031783497;6.213481379280693;\
757.142777751769366;7.629569041217826;11.995928244823393;5.761419012759379
76fill.rate;0.9475719810915342;0.9673295454545454;0.9869565217391304;\
770.9121037463976945;0.9595808383233533;0.93033381712627;0.9775280898876404;\
780.9477401129943502;0.8531073446327684;0.9452449567723343;0.9957983193277311
79stocklevel.mean;29.106301317812118;2.760696025360742;4.137393715988243;\
801.5507610335648132;2.5500355305055966;2.3659654563794095;3.7559706390001586;\
811.811228677305335;1.5668982789103876;2.657874734996926;5.949477225800507
82fulfilled.rate;1;1;1;1;1;1;1;1;1;1;1
83-------- Instance 1: 'mfc_10_13_10000_0xc8' -------
84stat;total;product_0;product_1;product_2;product_3;product_4;product_5;\
85product_6;product_7;product_8;product_9
86trp.min;6.530138861169689;6.530138861169689;9.628902017961991;\
878.559079500931148;9.008831732480758;8.17345928487157;10.857776143797764;\
887.1989408754006945;20.221688833546978;20.764475417566246;18.683929092542712
89trp.mean;31.011119751546097;20.636089799689874;27.67447485260846;\
9023.897005119242046;24.208477302980572;25.25418917347286;29.761302044694876;\
9123.04493364417017;43.39775607053671;45.37848659776272;46.77244686997264
92trp.max;82.04580382289168;45.2064686844069;55.755010710267015;\
9347.241916696964836;46.46518160018422;56.86270345999128;58.305458902948885;\
9452.54891087334727;80.98768370429207;80.62246465566932;82.04580382289168
95trp.sd;12.96227404463328;6.684031626500774;7.995431160774385;\
967.132422793760531;7.239745166217043;8.109774006790918;8.249688118912145;\
977.915621083543569;10.500873112173776;10.750658149592526;10.934157433002026
98cwt.min;0.011249992165176081;0.5337058348654864;0.8014497560352538;\
990.2827261678148716;1.4241222500077129;0.011249992165176081;7.901938969392177;\
1000.041148101390717784;0.08459428467904218;0.10726475210685749;
101cwt.mean;7.183224986008803;1.9535417603494485;0.8014497560352538;\
1024.619753737796203;9.370441335605987;7.744917661655692;7.901938969392177;\
1038.052111019031262;8.505184343659167;5.922113521223626;
104cwt.max;31.446190263142853;5.290086057329063;0.8014497560352538;\
10510.883639956720799;25.608040164921476;24.178558590047942;7.901938969392177;\
10631.446190263142853;21.35684648685401;16.312679904455308;
107cwt.sd;6.15364337829274;1.7473126971982065;;3.440991075922831;\
1086.485559248771155;6.715154696592823;;7.703968965710594;6.633960138504885;\
1093.8259446158453017;
110fill.rate;0.9628522630230573;0.9901408450704225;0.9985569985569985;\
1110.9544159544159544;0.9635343618513323;0.9702127659574468;0.998546511627907;\
1120.9175108538350217;0.9149855907780979;0.919831223628692;1
113stocklevel.mean;30.090461520030797;2.907712049060156;4.261495763524114;\
1141.6231331746350672;2.565318363579915;2.472060544282644;4.079218485848546;\
1151.786007080448915;1.7664180248890007;2.4348085700118425;6.194289463750593
116fulfilled.rate;1;1;1;1;1;1;1;1;1;1;1
118>>> x2 = np.array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1])
119>>> ms.decode(x2, y)
120>>> for s in to_stream(y):
121... if "time" not in s:
122... print(s)
123-------- Instance 0: 'mfc_10_13_10000_0x64' -------
124stat;total;product_0;product_1;product_2;product_3;product_4;product_5;\
125product_6;product_7;product_8;product_9
126trp.min;7.663287715103252;7.663287715103252;9.095457148523565;\
1277.766240497990111;8.562181846958993;9.316040128631357;10.985466232731596;\
1287.918294809653162;21.60147394131036;17.547777378904357;21.955240879517987
129trp.mean;32.182938074849496;22.140701244808632;28.47300655868274;\
13025.03367526681401;25.540081292675946;27.45355145426555;31.790509174952756;\
13122.848381852082664;44.52135481443732;44.628532680799054;48.780078255964575
132trp.max;90.86353698620042;59.31124925844961;67.52985535834341;\
13353.98557871595767;59.61194121202789;59.45241944832833;67.31898313910006;\
13456.0614850141219;81.02729637887933;80.10102521519639;90.86353698620042
135trp.sd;13.55080270389196;8.168678848316368;9.338600023998156;\
1368.450479951599732;8.617636871353389;9.348284373344056;10.208637939870723;\
1377.518466597403155;10.930234897788171;10.544143459268716;12.157006455407252
138cwt.min;0.011910352755876374;0.052322628985166375;0.011910352755876374;\
1390.10146378360695962;0.0524298188602188;0.025453817918787536;\
1400.05183870049131656;0.019666362641146407;0.08505119605797518;\
1410.041104098391770094;0.35634199392734445
142cwt.mean;17.582567285448004;9.404399139690337;13.569942297813908;\
1439.604699962010896;10.98311819636398;13.02578680799254;16.36199335629276;\
1449.05433728777719;24.801083270074987;24.958902762745797;30.451958550810023
145cwt.max;77.9385378023253;38.626600188006705;53.98496252245468;\
14638.07134509071511;42.09266935074265;47.99381408201043;48.82502650356764;\
14744.910304177168655;61.19671763574479;61.32131436097461;77.9385378023253
148cwt.sd;12.680595891084934;6.984547071390763;9.43383821564051;\
1497.012918522038577;7.891903498485814;9.033444211571616;9.757435017677162;\
1507.598286359665955;11.356538993918976;11.731098098924933;14.099099363785335
151fill.rate;0.2175906030654634;0.40767045454545453;0.2492753623188406;\
1520.3314121037463977;0.3158682634730539;0.28156748911465895;\
1530.17134831460674158;0.3714689265536723;0.002824858757062147;\
1540.018731988472622477;0.0350140056022409
155stocklevel.mean;1.6302006108805502;0.3367466779925779;0.19929696858529114;\
1560.15581052878690257;0.27567206398796995;0.2210582880452966;\
1570.14995708383534714;0.261766524058465;0.00048013843604374936;\
1580.006324013813991379;0.02308832333866472
159fulfilled.rate;0.9982810485603781;0.9985795454545454;1;1;0.9985029940119761;\
1600.9985486211901307;0.9929775280898876;1;0.9971751412429378;\
1610.9985590778097982;0.9985994397759104
162-------- Instance 1: 'mfc_10_13_10000_0xc8' -------
163stat;total;product_0;product_1;product_2;product_3;product_4;product_5;\
164product_6;product_7;product_8;product_9
165trp.min;6.456526072982342;6.456526072982342;10.280447092151007;\
1666.8487732247867825;7.0104482929637015;6.928763679217354;10.310002410918969;\
1676.5546482603685945;18.98639893585596;20.305760878712135;19.684816736973517
168trp.mean;30.62233294764437;20.55618285379736;26.886775958390697;2\
1693.309369645366303;23.990410121167177;25.071330781848836;29.668457645437183;\
17022.39107965050359;43.25662277895463;44.56350867653903;46.348319919246514
171trp.max;78.42550095496154;50.8966871369812;54.1070436589971;\
17248.669180978890836;52.42258290758127;55.73600798325697;57.290713516881624;\
17353.713961902238225;78.26718994789553;78.42550095496154;76.74843649876311
174trp.sd;13.071194037915653;7.013910120253621;8.186009510157717;\
1757.519377794772064;7.702542096043028;8.526420667544688;8.8970364463244;\
1767.682875953156183;10.548987944489301;10.828886793958864;10.898005970008226
177cwt.min;0.0004850386339967372;0.00456283385574352;0.056539264354796614;\
1780.005326168571627932;0.008960725403085235;0.08762150885104347;\
1790.01698932920680818;0.0004850386339967372;0.2800049970701366;\
1800.31679782128776424;0.12185953505104408
181cwt.mean;16.459929680370593;8.156568809736969;12.374646871831668;\
1828.300740034967504;10.371317340036168;10.931842774336376;14.222659911890325;\
1839.16345905328603;23.137826511457558;25.434148525686762;27.66379761065284
184cwt.max;60.919637988946306;29.480300784184692;35.16766467176876;\
18536.653507062645986;39.00025180235298;45.453680537177206;43.580941370786604;\
18645.28946949821329;56.024945551713245;59.28160733189452;60.919637988946306
187cwt.sd;12.118506999914882;6.044408962707157;7.728932055062374;\
1886.268950876605313;7.854789647395754;7.732399117687471;8.863583544578608;\
1897.7525558824150504;11.241315012712777;12.118136175485233;12.596354952532373
190fill.rate;0.24110446911471678;0.44084507042253523;0.2712842712842713;\
1910.36182336182336183;0.3394109396914446;0.32340425531914896;\
1920.21075581395348839;0.4196816208393632;0.002881844380403458;\
1930.01969057665260197;0.025034770514603615
194stocklevel.mean;1.8113476672429796;0.3802859636659473;0.23439669327549575;\
1950.19451906423091544;0.2559188646462229;0.2206691076289149;0.1935442874513864;\
1960.3124656055438941;0.00017487014444265826;0.008074900603352099;\
1970.011298310052408007
198fulfilled.rate;0.9987190435525192;1;0.9985569985569985;1;1;1;1;1;\
1990.9985590778097982;0.9929676511954993;0.9972183588317107
201Now the caching kicks in:
203>>> x2 = np.array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1])
204>>> ms.decode(x2, y)
205>>> for s in to_stream(y):
206... if "time" not in s:
207... print(s)
208-------- Instance 0: 'mfc_10_13_10000_0x64' -------
209stat;total;product_0;product_1;product_2;product_3;product_4;product_5;\
210product_6;product_7;product_8;product_9
211trp.min;7.663287715103252;7.663287715103252;9.095457148523565;\
2127.766240497990111;8.562181846958993;9.316040128631357;10.985466232731596;\
2137.918294809653162;21.60147394131036;17.547777378904357;21.955240879517987
214trp.mean;32.182938074849496;22.140701244808632;28.47300655868274;\
21525.03367526681401;25.540081292675946;27.45355145426555;31.790509174952756;\
21622.848381852082664;44.52135481443732;44.628532680799054;48.780078255964575
217trp.max;90.86353698620042;59.31124925844961;67.52985535834341;\
21853.98557871595767;59.61194121202789;59.45241944832833;67.31898313910006;\
21956.0614850141219;81.02729637887933;80.10102521519639;90.86353698620042
220trp.sd;13.55080270389196;8.168678848316368;9.338600023998156;\
2218.450479951599732;8.617636871353389;9.348284373344056;10.208637939870723;\
2227.518466597403155;10.930234897788171;10.544143459268716;12.157006455407252
223cwt.min;0.011910352755876374;0.052322628985166375;0.011910352755876374;\
2240.10146378360695962;0.0524298188602188;0.025453817918787536;\
2250.05183870049131656;0.019666362641146407;0.08505119605797518;\
2260.041104098391770094;0.35634199392734445
227cwt.mean;17.582567285448004;9.404399139690337;13.569942297813908;\
2289.604699962010896;10.98311819636398;13.02578680799254;16.36199335629276;\
2299.05433728777719;24.801083270074987;24.958902762745797;30.451958550810023
230cwt.max;77.9385378023253;38.626600188006705;53.98496252245468;\
23138.07134509071511;42.09266935074265;47.99381408201043;48.82502650356764;\
23244.910304177168655;61.19671763574479;61.32131436097461;77.9385378023253
233cwt.sd;12.680595891084934;6.984547071390763;9.43383821564051;\
2347.012918522038577;7.891903498485814;9.033444211571616;9.757435017677162;\
2357.598286359665955;11.356538993918976;11.731098098924933;14.099099363785335
236fill.rate;0.2175906030654634;0.40767045454545453;0.2492753623188406;\
2370.3314121037463977;0.3158682634730539;0.28156748911465895;\
2380.17134831460674158;0.3714689265536723;0.002824858757062147;\
2390.018731988472622477;0.0350140056022409
240stocklevel.mean;1.6302006108805502;0.3367466779925779;0.19929696858529114;\
2410.15581052878690257;0.27567206398796995;0.2210582880452966;\
2420.14995708383534714;0.261766524058465;0.00048013843604374936;\
2430.006324013813991379;0.02308832333866472
244fulfilled.rate;0.9982810485603781;0.9985795454545454;1;1;0.9985029940119761;\
2450.9985486211901307;0.9929775280898876;1;0.9971751412429378;\
2460.9985590778097982;0.9985994397759104
247-------- Instance 1: 'mfc_10_13_10000_0xc8' -------
248stat;total;product_0;product_1;product_2;product_3;product_4;product_5;\
249product_6;product_7;product_8;product_9
250trp.min;6.456526072982342;6.456526072982342;10.280447092151007;\
2516.8487732247867825;7.0104482929637015;6.928763679217354;10.310002410918969;\
2526.5546482603685945;18.98639893585596;20.305760878712135;19.684816736973517
253trp.mean;30.62233294764437;20.55618285379736;26.886775958390697;2\
2543.309369645366303;23.990410121167177;25.071330781848836;29.668457645437183;\
25522.39107965050359;43.25662277895463;44.56350867653903;46.348319919246514
256trp.max;78.42550095496154;50.8966871369812;54.1070436589971;\
25748.669180978890836;52.42258290758127;55.73600798325697;57.290713516881624;\
25853.713961902238225;78.26718994789553;78.42550095496154;76.74843649876311
259trp.sd;13.071194037915653;7.013910120253621;8.186009510157717;\
2607.519377794772064;7.702542096043028;8.526420667544688;8.8970364463244;\
2617.682875953156183;10.548987944489301;10.828886793958864;10.898005970008226
262cwt.min;0.0004850386339967372;0.00456283385574352;0.056539264354796614;\
2630.005326168571627932;0.008960725403085235;0.08762150885104347;\
2640.01698932920680818;0.0004850386339967372;0.2800049970701366;\
2650.31679782128776424;0.12185953505104408
266cwt.mean;16.459929680370593;8.156568809736969;12.374646871831668;\
2678.300740034967504;10.371317340036168;10.931842774336376;14.222659911890325;\
2689.16345905328603;23.137826511457558;25.434148525686762;27.66379761065284
269cwt.max;60.919637988946306;29.480300784184692;35.16766467176876;\
27036.653507062645986;39.00025180235298;45.453680537177206;43.580941370786604;\
27145.28946949821329;56.024945551713245;59.28160733189452;60.919637988946306
272cwt.sd;12.118506999914882;6.044408962707157;7.728932055062374;\
2736.268950876605313;7.854789647395754;7.732399117687471;8.863583544578608;\
2747.7525558824150504;11.241315012712777;12.118136175485233;12.596354952532373
275fill.rate;0.24110446911471678;0.44084507042253523;0.2712842712842713;\
2760.36182336182336183;0.3394109396914446;0.32340425531914896;\
2770.21075581395348839;0.4196816208393632;0.002881844380403458;\
2780.01969057665260197;0.025034770514603615
279stocklevel.mean;1.8113476672429796;0.3802859636659473;0.23439669327549575;\
2800.19451906423091544;0.2559188646462229;0.2206691076289149;0.1935442874513864;\
2810.3124656055438941;0.00017487014444265826;0.008074900603352099;\
2820.011298310052408007
283fulfilled.rate;0.9987190435525192;1;0.9985569985569985;1;1;1;1;1;\
2840.9985590778097982;0.9929676511954993;0.9972183588317107
286>>> x1 = np.array([4, 6, 3, 4, 4, 6, 3, 5, 6, 10])
287>>> y = space.create()
288>>> ms.decode(x1, y)
289>>> for s in to_stream(y):
290... if "time" not in s:
291... print(s)
292-------- Instance 0: 'mfc_10_13_10000_0x64' -------
293stat;total;product_0;product_1;product_2;product_3;product_4;product_5;\
294product_6;product_7;product_8;product_9
295trp.min;5.2184145757182705;5.2184145757182705;8.901258396714184;\
2969.297175556856018;7.298761505635412;8.93985302431065;12.606621860129053;\
2977.656178022299173;20.904266810249283;19.5732602761791;20.522703426695443
298trp.mean;32.405411220867336;22.45718865883824;29.222031978321247;\
29925.136275651698107;25.884250065648388;27.37383814423524;32.10269885414455;\
30021.905835255853667;45.11627023942567;44.78387873021794;49.465651426661886
301trp.max;101.42283298962138;56.30942379913131;74.17811849023519;\
30258.955465373336665;60.209164983262326;60.66621167329777;74.4357130671624;\
30347.944841355481;83.29062031809917;96.5279603056706;101.42283298962138
304trp.sd;14.352456423754838;8.966715472534952;10.260311480773648;\
3058.824583884361449;9.375043161957333;9.776116378207652;10.962890512009123;\
3066.691465594834237;12.613587720623373;12.30244975508726;13.52381481631245
307cwt.min;0.026454757136889384;0.026454757136889384;2.30483638259102;\
3080.054286282554130594;0.16648942892061314;0.1385205442725237;\
3092.2444075501571206;0.16694429707604286;0.2360807359827959;0.2894682031374032;\
3100.7020815078112719
311cwt.mean;8.296470547393602;4.437533958350662;12.615320110639914;\
3124.7164029806433545;6.611310521050654;8.350460109042185;7.55452574755307;\
3135.82304931358363;9.068938196877168;17.21719619156937;6.710247622764048
314cwt.max;37.76460269749805;11.383554877750612;25.02207987420161;\
31516.22657205109499;24.355088852856625;23.499199642416897;24.507644884798083;\
31627.834403782263507;29.068687291493006;37.76460269749805;12.188275706294007
317cwt.sd;8.072214752396842;3.8478370296451603;9.569679438559595;\
3184.197433045217076;7.324722986150041;6.142260031783497;6.213481379280693;\
3197.142777751769366;7.629569041217826;11.995928244823393;5.761419012759379
320fill.rate;0.9475719810915342;0.9673295454545454;0.9869565217391304;\
3210.9121037463976945;0.9595808383233533;0.93033381712627;0.9775280898876404;\
3220.9477401129943502;0.8531073446327684;0.9452449567723343;0.9957983193277311
323stocklevel.mean;29.106301317812118;2.760696025360742;4.137393715988243;\
3241.5507610335648132;2.5500355305055966;2.3659654563794095;3.7559706390001586;\
3251.811228677305335;1.5668982789103876;2.657874734996926;5.949477225800507
326fulfilled.rate;1;1;1;1;1;1;1;1;1;1;1
327-------- Instance 1: 'mfc_10_13_10000_0xc8' -------
328stat;total;product_0;product_1;product_2;product_3;product_4;product_5;\
329product_6;product_7;product_8;product_9
330trp.min;6.530138861169689;6.530138861169689;9.628902017961991;\
3318.559079500931148;9.008831732480758;8.17345928487157;10.857776143797764;\
3327.1989408754006945;20.221688833546978;20.764475417566246;18.683929092542712
333trp.mean;31.011119751546097;20.636089799689874;27.67447485260846;\
33423.897005119242046;24.208477302980572;25.25418917347286;29.761302044694876;\
33523.04493364417017;43.39775607053671;45.37848659776272;46.77244686997264
336trp.max;82.04580382289168;45.2064686844069;55.755010710267015;\
33747.241916696964836;46.46518160018422;56.86270345999128;58.305458902948885;\
33852.54891087334727;80.98768370429207;80.62246465566932;82.04580382289168
339trp.sd;12.96227404463328;6.684031626500774;7.995431160774385;\
3407.132422793760531;7.239745166217043;8.109774006790918;8.249688118912145;\
3417.915621083543569;10.500873112173776;10.750658149592526;10.934157433002026
342cwt.min;0.011249992165176081;0.5337058348654864;0.8014497560352538;\
3430.2827261678148716;1.4241222500077129;0.011249992165176081;7.901938969392177;\
3440.041148101390717784;0.08459428467904218;0.10726475210685749;
345cwt.mean;7.183224986008803;1.9535417603494485;0.8014497560352538;\
3464.619753737796203;9.370441335605987;7.744917661655692;7.901938969392177;\
3478.052111019031262;8.505184343659167;5.922113521223626;
348cwt.max;31.446190263142853;5.290086057329063;0.8014497560352538;\
34910.883639956720799;25.608040164921476;24.178558590047942;7.901938969392177;\
35031.446190263142853;21.35684648685401;16.312679904455308;
351cwt.sd;6.15364337829274;1.7473126971982065;;3.440991075922831;\
3526.485559248771155;6.715154696592823;;7.703968965710594;6.633960138504885;\
3533.8259446158453017;
354fill.rate;0.9628522630230573;0.9901408450704225;0.9985569985569985;\
3550.9544159544159544;0.9635343618513323;0.9702127659574468;0.998546511627907;\
3560.9175108538350217;0.9149855907780979;0.919831223628692;1
357stocklevel.mean;30.090461520030797;2.907712049060156;4.261495763524114;\
3581.6231331746350672;2.565318363579915;2.472060544282644;4.079218485848546;\
3591.786007080448915;1.7664180248890007;2.4348085700118425;6.194289463750593
360fulfilled.rate;1;1;1;1;1;1;1;1;1;1;1
361"""
362from typing import Final
364import numpy as np
365from moptipy.api.encoding import Encoding
366from pycommons.types import type_error
368from moptipyapps.prodsched.multistatistics import (
369 MultiStatistics,
370 MultiStatisticsSpace,
371)
372from moptipyapps.prodsched.rop_simulation import ROPSimulation
373from moptipyapps.prodsched.statistics_collector import StatisticsCollector
376class ROPMultiSimulation(Encoding):
377 """A multi-simulation that caches the results for reuse."""
379 def __init__(self, space: MultiStatisticsSpace) -> None:
380 """
381 Instantiate the multi-statistics decoding.
383 :param instances: the packing instance
384 """
385 if not isinstance(space, MultiStatisticsSpace):
386 raise type_error(space, "space", MultiStatisticsSpace)
387 #: the statistics collectors
388 col: Final[tuple[StatisticsCollector, ...]] = tuple(
389 StatisticsCollector(inst) for inst in space.instances)
390 #: the simulations and collectors
391 self.__simulations: Final[tuple[tuple[
392 ROPSimulation, StatisticsCollector], ...]] = tuple(
393 (ROPSimulation(inst, col[i]), col[i])
394 for i, inst in enumerate(space.instances))
395 #: the internal cache
396 self.__cache: Final[dict[tuple[int, ...], MultiStatistics]] = {}
397 #: the internal space
398 self.__space: Final[MultiStatisticsSpace] = space
400 def decode(self, x: np.ndarray, y: MultiStatistics) -> None:
401 """
402 Map a ROP setting to a multi-statistics.
404 This method uses an internal cache: The same re-order points will
405 yield the same statistics.
407 :param x: the array
408 :param y: the Gantt chart
409 """
410 # First we map the vector to a tuple of integers.
411 x_tuple: Final[tuple[int, ...]] = tuple(map(int, x))
412 # Now we can look up this tuple in the cache.
413 if x_tuple in self.__cache:
414 # If we get here, this means we already simulated this ROP.
415 # Since the simulations are deterministic, we can re-use the
416 # result.
417 self.__space.copy(y, self.__cache[x_tuple])
418 return # And we are done.
420 # If we get here, the ROP is new.
421 # So we simulate it.
422 for i, (sim, col) in enumerate(self.__simulations):
423 col.set_dest(y.per_instance[i])
424 sim.ctrl_reset()
425 sim.set_rop(x_tuple)
426 sim.ctrl_run()
428 # The simulation is completed. We can now cache the result.
429 cached: Final[MultiStatistics] = self.__space.create()
430 self.__space.copy(cached, y)
431 self.__cache[x_tuple] = cached
433 def __str__(self) -> str:
434 """
435 Get the name of this decoding.
437 :return: `"rms"`
438 :rtype: str
439 """
440 return "rms"