Files
mcm-mfp/task3/__pycache__/08_visualize.cpython-313.pyc

181 lines
24 KiB
Plaintext
Raw Normal View History

2026-01-19 15:05:55 +08:00
<EFBFBD>
2026-01-20 01:55:46 +08:00
soni<6E>=<00>
<01><><00>SrSSKJr SSKJr SSKrSSKJr SSKrSSK r SSK
2026-01-19 19:38:38 +08:00
r SSK r \"\ R"55S- r\"\ R"55S- r\R#SSS 9 \R#SSS 9 \R$R'S
2026-01-20 01:55:46 +08:00
\"\55 \R$R'S \"\55 SSKr\R,"S 5 SSKJr SS KJr SSKJr \"\5R=5R>r SSSSSSSSSS. r!Sr"Sr#S*Sjr$\"SS9"SS55r%S+Sjr&S,S jr'S-S!jr(S.S"jr)S.S#jr*S.S$jr+S.S%jr,S.S&jr-S.S'jr.S*S(jr/\0S):Xa\/"5 gg)/u4
Task 3 - Step 8: 可视化Fig.1/2/4/5/6
2026-01-19 15:05:55 +08:00
=====================================
输入:
- 01_distance.xlsx (sites: 经纬度、mu/sigma)
2026-01-20 01:55:46 +08:00
- 02_pairing.xlsx (selected_pairs: 配对连线)
2026-01-19 15:05:55 +08:00
- 03_allocation.xlsx (allocation: q*, E_total)
- 05_calendar.xlsx (calendar: 365天×2槽位排程)
- 06_evaluate.xlsx (pair_risk: 缺口概率分布)
输出:
- figures/fig1_pairing_map.png
- figures/fig2_allocation_scatter.png
2026-01-20 01:55:46 +08:00
- figures/fig6_fairness_satisfaction.png
2026-01-19 15:05:55 +08:00
- figures/fig4_calendar_heatmap.png
- figures/fig5_risk_distribution.png
2026-01-20 01:55:46 +08:00
<EFBFBD>)<01> annotations)<01> dataclassN)<01>Path<74>mm_task3_mplconfig<69>mm_task3_xdg_cacheT<65><02>parents<74>exist_ok<6F> MPLCONFIGDIR<49>XDG_CACHE_HOME<4D>Agg)<01>colors)<01>cyclerz#D7D1C7z#3F3F3Fz#8FA3A7z#6E858Az#AEB8A6z#C6AA9Bz#D2B8B3z#8C857Az#B07A6A) <09>grid<69>text<78>
2026-01-19 19:38:38 +08:00
muted_blue<EFBFBD>muted_blue_dark<72>sage<67>clay<61>rose<73> warm_gray<61>
2026-01-20 01:55:46 +08:00
terracottaz#FFFFFFz#DADDE1c <01><><00>[RR0S[_S[_S[_S[_S[
S_S[
S_S[
S_S [
S_S
[_S S _S S_SS_SS_SS_SS_SS_S[_[[ S[
S[
S[
S[
S[
S/5S.E5 g) Nzfigure.facecolorzaxes.facecolorzsavefig.facecolorzaxes.edgecolorzaxes.labelcolorrz xtick.colorz ytick.colorz
2026-01-19 19:38:38 +08:00
text.colorz
grid.colorz
grid.alpha皙<61><E79A99><EFBFBD><EFBFBD><EFBFBD>?z axes.gridTzaxes.titleweight<68>semiboldzaxes.titlesize<7A> zaxes.labelsize<7A>
2026-01-20 01:55:46 +08:00
zlegend.frameonzlegend.framealpha<68><61><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?zlegend.facecolor<6F>colorrrrrr)zlegend.edgecolorzaxes.prop_cycle)<07>plt<6C>rcParams<6D>update<74>FIG_BG<42>FIG_GRID<49>MORANDIr<00><00><00>task3/08_visualize.py<70>_apply_morandi_styler)Bs0<00><00><07>L<EFBFBD>L<EFBFBD><17><17>
<EFBFBD> <1E><06>
<EFBFBD> <1C>f<EFBFBD>
<EFBFBD> <20><16>
<EFBFBD> <1D>h<EFBFBD> 
2026-01-19 19:38:38 +08:00
<EFBFBD>
<1E>w<EFBFBD>v<EFBFBD><EFBFBD> 
<EFBFBD> <1A>7<EFBFBD>6<EFBFBD>?<3F> 
<EFBFBD> <1A>7<EFBFBD>6<EFBFBD>?<3F>
<EFBFBD> <19>'<27>&<26>/<2F>
2026-01-20 01:55:46 +08:00
<EFBFBD> <19>(<28>
2026-01-19 19:38:38 +08:00
<EFBFBD> <19>$<24>
<EFBFBD> <18><14>
<EFBFBD> <1F>
<EFBFBD>
<EFBFBD> <1D>b<EFBFBD>
<EFBFBD> <1D>b<EFBFBD>
<EFBFBD> <1D>d<EFBFBD>
<EFBFBD> <20><13>!
2026-01-20 01:55:46 +08:00
<EFBFBD>" <1F><06>#
<EFBFBD>$!)<29>%<25><17><1B>L<EFBFBD>)<29><1B>F<EFBFBD>O<EFBFBD><1B>F<EFBFBD>O<EFBFBD><1B>F<EFBFBD>O<EFBFBD><1B>K<EFBFBD>(<28> <12> <0E>'
<EFBFBD>r')<01>frozenc<01>R<00>\rSrSr%S\S'S\S'S\S'S\S'S\S'S\S'S rg
) <0B>Paths<68>er<00> distance_xlsx<73> pairing_xlsx<73>allocation_xlsx<73> calendar_xlsx<73> evaluate_xlsx<73> figures_dirr&N)<06>__name__<5F>
__module__<EFBFBD> __qualname__<5F>__firstlineno__<5F>__annotations__<5F>__static_attributes__r&r'r(r,r,es&<00><00><17><17><16><16><19><19><17><17><17><17><15>r'r,c <01>r<00>[[S- [S- [S- [S- [S- [S- S9$)Nz01_distance.xlsxz02_pairing.xlsxz03_allocation.xlsxz05_calendar.xlsxz06_evaluate.xlsx<73>figures)r.r/r0r1r2r3)r,<00>BASE_DIRr&r'r(<00>_default_pathsr=osD<00><00> <10><1E>!3<>3<><1D> 1<>1<> <20>#7<>7<><1E>!3<>3<><1E>!3<>3<><1C>y<EFBFBD>(<28>  <06>r'c<01>L<00>UR5(d[SUS35eg)NzMissing required file: z&. Run the earlier steps first (01~06).)<02>exists<74>FileNotFoundError)<01>paths r(<00> _require_filerBzs,<00><00> <0F>;<3B>;<3B>=<3D>=<3D><1F>%<25>d<EFBFBD>V<EFBFBD>+Q<> R<>
2026-01-19 15:05:55 +08:00
<EFBFBD>
2026-01-20 01:55:46 +08:00
<EFBFBD> r'c<01><00>X::aX4$X4$)Nr&)<02>a<>bs r(<00> _pair_keyrF<00>s<00><00><16>V<EFBFBD>A<EFBFBD>6<EFBFBD>'<27>!<21><16>'r'c <01>n<00>[5 SSSS.n[R"URSS9n[R"URSS9nUR 5nUSR [5US'[US R [55R[US
2026-01-19 19:38:38 +08:00
R [555nUSRU5US '[R"S S S9upVUR5H<>upx[US 5n [US
5n
URUSU :HRSn URUSU
2026-01-20 01:55:46 +08:00
:HRSn UR!U SU S/U SU S/USSSSS9 M<> X"S n X"S )nUR#U SU SSUSSS[%U 5S3SS9 [%U5S:<3A>a,UR#USUSSUSSS S![%U5S3S"S#9 UR'S$[%U5S%35 UR)S&5 UR+S'5 UR-S(S)S*9 UR/S+S(S,9 UR0S-- nUR35 UR5U[6S.9 [R8"U5 U$)/Nz#e76f51z#6c757dz#bc6c25)<03>paired<65>unpaired<65>link<6E>sites<65><01>
sheet_name<EFBFBD>selected_pairs<72>site_id<69> site_i_id<69> site_j_id<69> is_paired)g!@g@<40><><00><02>figsize<7A>dpir<00>lon<6F>latrJg<00>?g333333<33>?<3F>)r<00>alpha<68> linewidth<74>zorder<65>rHrzPaired sites (n=<3D>)<29>)<05>srrZ<00>labelr\<00>rI<00>xzUnpaired sites (n=<3D>)r`rrZ<00>markerrar\z&Fig.1 Pairing map (sites + selected n=z links)<29> Longitude<64>LatitudeTr<00>rZ<00>best<73><02>loc<6F>frameonzfig1_pairing_map.png)<01> facecolor)r)<00>pd<70>
read_excelr.r/<00>copy<70>astype<70>int<6E>set<65>union<6F>isinr <00>subplots<74>iterrowsrk<00>iloc<6F>plot<6F>scatter<65>len<65> set_title<6C>
2026-01-19 15:05:55 +08:00
set_xlabel<EFBFBD>
2026-01-20 01:55:46 +08:00
set_ylabelr<00>legendr3<00> tight_layout<75>savefigr#<00>close)<10>paths<68> fig1_colorsrK<00>pairs<72>
paired_ids<EFBFBD>fig<69>ax<61>_<>row<6F>i<>j<>si<73>sjrHrI<00>outs r(<00>fig1_pairing_mapr<70><00>s<><00><00><18><1A><1C><1D><19><06>K<EFBFBD> <0F>M<EFBFBD>M<EFBFBD>%<25>-<2D>-<2D>'<27> B<>E<EFBFBD> <0E>M<EFBFBD>M<EFBFBD>%<25>,<2C>,<2C>9I<39> J<>E<EFBFBD> <11>J<EFBFBD>J<EFBFBD>L<EFBFBD>E<EFBFBD><1C>Y<EFBFBD>'<27>.<2E>.<2E>s<EFBFBD>3<>E<EFBFBD>)<29><14><14>U<EFBFBD>;<3B>'<27>.<2E>.<2E>s<EFBFBD>3<>4<>:<3A>:<3A> <0B>E<EFBFBD>+<2B> <1E> %<25> %<25>c<EFBFBD> *<2A>+<2B><06>J<EFBFBD><1F>y<EFBFBD>)<29>.<2E>.<2E>z<EFBFBD>:<3A>E<EFBFBD>+<2B><16><11>l<EFBFBD>l<EFBFBD>:<3A>3<EFBFBD>7<>G<EFBFBD>C<EFBFBD><17>.<2E>.<2E>"<22><06><01> <0F><03>K<EFBFBD> <20> !<21><01> <0F><03>K<EFBFBD> <20> !<21><01> <12>Y<EFBFBD>Y<EFBFBD>u<EFBFBD>Y<EFBFBD>'<27>1<EFBFBD>,<2C> -<2D> 2<> 2<>1<EFBFBD> 5<><02> <12>Y<EFBFBD>Y<EFBFBD>u<EFBFBD>Y<EFBFBD>'<27>1<EFBFBD>,<2C> -<2D> 2<> 2<>1<EFBFBD> 5<><02>
2026-01-19 19:38:38 +08:00
<EFBFBD><07><07> <0F><05>Y<EFBFBD><02>5<EFBFBD> <09> "<22> <0F><05>Y<EFBFBD><02>5<EFBFBD> <09> "<22><1D>f<EFBFBD>%<25><15><19><14> <10>
2026-01-19 15:05:55 +08:00
<EFBFBD> #<23><13><1B>%<25> &<26>F<EFBFBD><14>K<EFBFBD>(<28>(<28>)<29>H<EFBFBD><06>J<EFBFBD>J<EFBFBD><0E>u<EFBFBD> <0A><0E>u<EFBFBD> <0A>
2026-01-19 19:38:38 +08:00
<0C><19>(<28>#<23><11> <20><13>V<EFBFBD><1B> <0A>Q<EFBFBD>/<2F><10><0F><06> <0B>8<EFBFBD>}<7D>q<EFBFBD><18>
2026-01-19 15:05:55 +08:00
<EFBFBD>
<EFBFBD>
2026-01-19 19:38:38 +08:00
<EFBFBD> <14>U<EFBFBD>O<EFBFBD> <14>U<EFBFBD>O<EFBFBD><10><1D>j<EFBFBD>)<29><15><16>&<26>s<EFBFBD>8<EFBFBD>}<7D>o<EFBFBD>Q<EFBFBD>7<><14> <13>
2026-01-20 01:55:46 +08:00
<EFBFBD><07>L<EFBFBD>L<EFBFBD>9<>#<23>e<EFBFBD>*<2A><1C>W<EFBFBD>M<>N<><06>M<EFBFBD>M<EFBFBD>+<2B><1E><06>M<EFBFBD>M<EFBFBD>*<2A><1D><06>G<EFBFBD>G<EFBFBD>D<EFBFBD><04>G<EFBFBD><1D><06>I<EFBFBD>I<EFBFBD>&<26>$<24>I<EFBFBD>'<27>
2026-01-19 15:05:55 +08:00
<0F>
<1B>
<1B>4<>
2026-01-20 01:55:46 +08:00
4<EFBFBD>C<EFBFBD><07><14><14><16><07>K<EFBFBD>K<EFBFBD><03>v<EFBFBD>K<EFBFBD>&<26><07>I<EFBFBD>I<EFBFBD>c<EFBFBD>N<EFBFBD> <0E>Jr'c<01>d<00>[R"URSS9R5n[R"URSS9R5nUSR [ 5US'USR [ 5US'[USR [ 55R[USR [ 555n/nUR5H<>upVUR[ US5[US5[US 5[US
5[US 5[US 5[ US5[ US5U;S .5 M<> /nUR5HXupVUR[ US5[ US5[US5[US5[US5S.5 MZ [S- nS[R"USSS9S[R"USSS9S3n UR!U SS9 U$)NrKrLrNrO<00>krPrQ<00> site_namerXrW<00>mu<6D>sigma)rOr<>rX<00>lngr<67>r<>r<>rR<00> site_i_name<6D> site_j_name<6D>distance)rPrQr<>r<>r<>zfig1_points.jsz<73>// Auto-generated from `task3/01_distance.xlsx` (sites) + `task3/02_pairing.xlsx` (selected_pairs)
2026-01-19 19:38:38 +08:00
// Usage: open `task3/fig1_carto.html` in a browser (same directory must contain this file).
window.FIG1_POINTS = F)<02>,<2C>:)<02> ensure_ascii<69>
separatorsz;
window.FIG1_LINKS = z;
2026-01-20 01:55:46 +08:00
zutf-8)<01>encoding)rnror.rpr/rqrrrsrtrw<00>append<6E>str<74>floatr<<00>json<6F>dumps<70>
2026-01-19 19:38:38 +08:00
write_text)
2026-01-20 01:55:46 +08:00
r<EFBFBD>rKr<>r<><00>pointsr<73><00>r<>linksr<73><00>payloads
r(<00>export_fig1_points_jsr<73><00>s
2026-01-19 19:38:38 +08:00
<00><00> <0E>M<EFBFBD>M<EFBFBD>%<25>-<2D>-<2D>'<27> B<> G<> G<> I<>E<EFBFBD> <0E>M<EFBFBD>M<EFBFBD>%<25>,<2C>,<2C>9I<39> J<> O<> O<> Q<>E<EFBFBD><1C>Y<EFBFBD>'<27>.<2E>.<2E>s<EFBFBD>3<>E<EFBFBD>)<29><14><16>s<EFBFBD><1A>"<22>"<22>3<EFBFBD>'<27>E<EFBFBD>#<23>J<EFBFBD><14>U<EFBFBD>;<3B>'<27>.<2E>.<2E>s<EFBFBD>3<>4<>:<3A>:<3A> <0B>E<EFBFBD>+<2B> <1E> %<25> %<25>c<EFBFBD> *<2A>+<2B><06>J<EFBFBD><10>F<EFBFBD><15><0E><0E> <20><04><01><0E> <0A> <0A><1E>q<EFBFBD><19>|<7C>,<2C> <20><11>;<3B><1E>0<><1C>Q<EFBFBD>u<EFBFBD>X<EFBFBD><EFBFBD><1C>Q<EFBFBD>u<EFBFBD>X<EFBFBD><EFBFBD><1B>A<EFBFBD>d<EFBFBD>G<EFBFBD>n<EFBFBD><1E>q<EFBFBD><17>z<EFBFBD>*<2A><18><11>3<EFBFBD><16>[<5B> <20><11>9<EFBFBD><1C>.<2E>*<2A><<3C> <0E>
<EFBFBD>!<21> <0F>E<EFBFBD><15><0E><0E> <20><04><01> <0A> <0C> <0C> <20><11>;<3B><1E>0<> <20><11>;<3B><1E>0<>"<22>1<EFBFBD>]<5D>#3<>4<>"<22>1<EFBFBD>]<5D>#3<>4<>!<21>!<21>J<EFBFBD>-<2D>0<>  <0E>
<EFBFBD>!<21> <13>%<25>
%<25>C<EFBFBD> <20> $<24>
<EFBFBD>
2026-01-20 01:55:46 +08:00
<EFBFBD>6<EFBFBD><05>R\<5C> ]<5D>^<5E>_<1F>#<23>z<EFBFBD>z<EFBFBD>%<25>e<EFBFBD>PZ<50>[<5B>\<5C>\_<> a<01> <0C> <08>N<EFBFBD>N<EFBFBD>7<EFBFBD>W<EFBFBD>N<EFBFBD>-<2D> <0E>Jr'c
<01><00>[5 [R"URSS9nUSR [
2026-01-19 19:38:38 +08:00
S9nUSUSUS-- R [
S9nUSUSUS-- R [
S9nS U-
n[ R"S
S S S SS9upgSU4SU4SU4/n[Xx5GHGun up<>U RU USS[SSS9 [R"U 5R5(a<>[R"U5R5(a<>[U 5S:<3A>a<>[R"X<>S
5n [R "[ [R""U 55[ [R$"U 55S5n U SU -U S
-nU R'X<>[SSSS9 U R)U
2026-01-20 01:55:46 +08:00
5 U R+S5 U R-SS S!9 GMJ USR/S"5 UR1S#[U5S$3S%S&9 UR35 UR4S'- nUR7US([8S)9 [ R:"U5 U$)*N<>
allocationrL<00>q_ratio<69><01>dtype<70>mu_i<5F>mu_j<5F>sigma_i<5F>sigma_j<5F><00>?rYrd)<02> <00>ffffff@rST)rUrV<00>shareyz $q^*/Q$ vs $\mu_i/(\mu_i+\mu_j)$z)$q^*/Q$ vs $\sigma_i/(\sigma_i+\sigma_j)$z)$q^*/Q$ vs $\sigma_j/(\sigma_i+\sigma_j)$rbg<><67><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?r<00>none)r`rZr<00> edgecolorr_<00>drr<00>@gffffff<66>?)rr[rZrcrrhz$q^*/Q$z%Fig.2 Allocation strategy scatter (n=z pairs)<29>R<EFBFBD><1E><>Q<EFBFBD>?<3F><01>yzfig2_allocation_scatter.png<6E>tight<68><02> bbox_inchesrm)r)rnror0<00>to_numpyr<79>r rv<00>ziprzr%<00>np<6E>isfinite<74>allr{<00>polyfit<69>linspace<63>min<69>maxryr|r}rr~<00>suptitler<65>r3r<>r#r<>)r<><00>dfr<66><00>mu_share<72> sigma_share<72> sigma_j_sharer<65><00>axes<65>panelsr<73><00>titlerc<00>coef<65>xx<78>yyr<79>s r(<00>fig2_allocation_scatterr<72>sH<00><00><18><1A> <0B><1D><1D>u<EFBFBD>,<2C>,<2C><1C> F<>B<EFBFBD><10><19>m<EFBFBD>$<24>$<24>5<EFBFBD>$<24>1<>G<EFBFBD><12>6<EFBFBD>
2026-01-19 15:05:55 +08:00
<EFBFBD>b<EFBFBD><16>j<EFBFBD>2<EFBFBD>f<EFBFBD>:<3A>5<>6<>@<40>@<40>u<EFBFBD>@<40>M<>H<EFBFBD><15>i<EFBFBD>=<3D>B<EFBFBD>y<EFBFBD>M<EFBFBD>B<EFBFBD>y<EFBFBD>M<EFBFBD>$A<>B<>L<>L<>SX<53>L<>Y<>K<EFBFBD><17>+<2B>%<25>M<EFBFBD><13> <0C> <0C>Q<EFBFBD><01>9<EFBFBD>#<23>d<EFBFBD>K<>I<EFBFBD>C<EFBFBD>
/<2F><08>9<> 7<><1B>E<> 7<><1D>G<><06>F<EFBFBD> <1E>d<EFBFBD>+<2B><0E><02>J<EFBFBD>U<EFBFBD>
<EFBFBD>
<EFBFBD>
2026-01-19 19:38:38 +08:00
<EFBFBD> <0A> <13><10><15><19>,<2C>'<27><1C> <13>
<EFBFBD> <0E>;<3B>;<3B>q<EFBFBD>><3E> <1D> <1D> <1F> <1F>B<EFBFBD>K<EFBFBD>K<EFBFBD><07>$8<>$<<3C>$<<3C>$><3E>$><3E>3<EFBFBD>q<EFBFBD>6<EFBFBD>Q<EFBFBD>;<3B><15>:<3A>:<3A>a<EFBFBD>!<21>,<2C>D<EFBFBD><13><1B><1B>U<EFBFBD>2<EFBFBD>6<EFBFBD>6<EFBFBD>!<21>9<EFBFBD>-<2D>u<EFBFBD>R<EFBFBD>V<EFBFBD>V<EFBFBD>A<EFBFBD>Y<EFBFBD>/?<3F><13>E<>B<EFBFBD><15>a<EFBFBD><17>2<EFBFBD><1C><04>Q<EFBFBD><07>'<27>B<EFBFBD> <0E>G<EFBFBD>G<EFBFBD>B<EFBFBD>'<27>,<2C>"7<>3<EFBFBD>d<EFBFBD>G<EFBFBD> S<>
2026-01-19 15:05:55 +08:00
<EFBFBD> <0C> <0C>U<EFBFBD><1B>
<EFBFBD> <0A> <0A>c<EFBFBD><1A>
2026-01-20 01:55:46 +08:00
<EFBFBD><07><07><04>D<EFBFBD><07>!<21>!,<2C>$ <09><11>G<EFBFBD><16><16>y<EFBFBD>!<21><07>L<EFBFBD>L<EFBFBD>8<><13>R<EFBFBD><17> <09><17>I<>T<EFBFBD>L<EFBFBD>R<><07><14><14><16>
2026-01-19 15:05:55 +08:00
<0F>
<1B>
<1B>;<3B>
2026-01-20 01:55:46 +08:00
;<3B>C<EFBFBD><07>K<EFBFBD>K<EFBFBD><03><17>F<EFBFBD>K<EFBFBD>;<3B><07>I<EFBFBD>I<EFBFBD>c<EFBFBD>N<EFBFBD> <0E>Jr'c <01><><00>[5 [R"URSS9SS/nUSR [
2026-01-19 19:38:38 +08:00
5US'[ [USUS55n[R"URSS9/SQR5nUSR [
5US'USR [
5US'UR5VVVs0sHupEn[XE5[U5_M nnnn[R"URS S9n[R"S
[R [S 9n UR#5GHAup<>[ U S 5n S GH&n [%U SU S35R'5R)5nU SU S3nU R+SU S3[R 5n[R,"U5(aM|[ U5nUS:Xa5[UR+U[R 55X<>S-
2026-01-19 15:05:55 +08:00
U S-
2026-01-19 19:38:38 +08:00
4'M<>US:XdM<>[R,"U5(aM<>[ U5nUR+[UU5[R 5X<>S-
2026-01-19 15:05:55 +08:00
U S-
2026-01-20 01:55:46 +08:00
4'GM) GMD [.R0"SSS9unn[2R4R7S[8S[:S[:SS/5nUR=U R>SUS9nURASS/S S!/S"9 URCS#5 URES$5 /S%Qn[RF"S/USS&-5n/S'QnURIUUS"9 URKUUS(S)S*9nURMS+5 URO5 URPS,- nURSUS-[8S.9 [.RT"U5 U$s snnnf)/NrKrLrOr<>r<>)rPrQ<00>E_totalrPrQ<00>calendar)imr_r<><00>day)rYr_<00>slot_<74>_type<70>_site_i<5F>_site_j<5F>singlerY<00>dual)r<>g<><67><EFBFBD><EFBFBD><EFBFBD><EFBFBD>@rSrT<00>morandiz#E7E1D7rrz#5F7478<37>auto)<02>aspect<63>cmaprzSlot 1zSlot 2)<01>labelsz Day of yearz2Fig.4 Calendar heatmap (expected service per slot)) <0C><00>r<><00>r<>r<>r<>r<>r<>r<>r<>r<><00><><EFBFBD><EFBFBD><EFBFBD>) <0C>Jan<61>Feb<65>Mar<61>Apr<70>May<61>Jun<75>Jul<75>Aug<75>Sep<65>Oct<63>Nov<6F>Decg<63><1E><>Q<EFBFBD><51>?g{<14>G<EFBFBD>z<EFBFBD>?)r<><00>fraction<6F>padzExpected servicezfig4_calendar_heatmap.pngr<67>r<>)+r)rnror.rqrr<00>dictr<74>r0rpr<>rFr<>r1r<><00>full<6C>nanrwr<><00>strip<69>lower<65>get<65>isnar rv<00>mcolors<72>LinearSegmentedColormap<61> from_listr#r%<00>imshow<6F>T<>
set_yticksr}r|<00>cumsum<75>
set_xticks<EFBFBD>colorbar<61> set_labelr<6C>r3r<>r<>)r<>rK<00>mu_by_id<69>allocr<63>r<><00>e<>pair_E<5F>cal<61>expected<65>idxr<78>r<><00>slot<6F>typ<79>i_id<69>j_idr<64>r<>r<><00>im<69>
month_days<EFBFBD> month_starts<74> month_labels<6C>cbarr<72>s r(<00>fig4_calendar_heatmapr.sd<00><00><18><1A> <0E>M<EFBFBD>M<EFBFBD>%<25>-<2D>-<2D>'<27> B<>I<EFBFBD>t<EFBFBD>CT<43> U<>E<EFBFBD><1C>Y<EFBFBD>'<27>.<2E>.<2E>s<EFBFBD>3<>E<EFBFBD>)<29><14><13>C<EFBFBD><05>i<EFBFBD>(<28>%<25><04>+<2B>6<>7<>H<EFBFBD> <0E>M<EFBFBD>M<EFBFBD>%<25>/<2F>/<2F>L<EFBFBD> I<>-<2D> <06>
2026-01-19 15:05:55 +08:00
<EFBFBD>d<EFBFBD>f<EFBFBD>
<EFBFBD><1F>{<7B>+<2B>2<>2<>3<EFBFBD>7<>E<EFBFBD>+<2B><16><1E>{<7B>+<2B>2<>2<>3<EFBFBD>7<>E<EFBFBD>+<2B><16>7<<3C>~<7E>~<7E>7G<37> H<>7G<37>G<EFBFBD>A<EFBFBD>!<21>i<EFBFBD><01>o<EFBFBD>u<EFBFBD>Q<EFBFBD>x<EFBFBD>'<27>7G<37>F<EFBFBD> H<>
<0C>-<2D>-<2D><05>+<2B>+<2B>
<EFBFBD>
2026-01-20 01:55:46 +08:00
C<EFBFBD>C<EFBFBD><11>w<EFBFBD>w<EFBFBD>x<EFBFBD><12><16><16>u<EFBFBD>5<>H<EFBFBD><17>L<EFBFBD>L<EFBFBD>N<EFBFBD><08><03><11>#<23>e<EFBFBD>*<2A>o<EFBFBD><03><1A>D<EFBFBD><15>c<EFBFBD>E<EFBFBD>$<24><16>u<EFBFBD>-<2D>.<2E>/<2F>5<>5<>7<>=<3D>=<3D>?<3F>C<EFBFBD><13>e<EFBFBD>D<EFBFBD>6<EFBFBD><17>)<29>*<2A>A<EFBFBD><13><07><07>%<25><04>v<EFBFBD>W<EFBFBD>-<2D>r<EFBFBD>v<EFBFBD>v<EFBFBD>6<>A<EFBFBD><11>w<EFBFBD>w<EFBFBD>q<EFBFBD>z<EFBFBD>z<EFBFBD><18><16>q<EFBFBD>6<EFBFBD>D<EFBFBD><12>h<EFBFBD><EFBFBD>.3<EFBFBD>H<EFBFBD>L<EFBFBD>L<EFBFBD><14>r<EFBFBD>v<EFBFBD>v<EFBFBD>4N<34>.O<><08>q<EFBFBD><17>$<24><11>(<28>*<2A>+<2B><14><06><1D><15>7<EFBFBD>7<EFBFBD>1<EFBFBD>:<3A>:<3A><1C><1A>1<EFBFBD>v<EFBFBD><04>.4<EFBFBD>j<EFBFBD>j<EFBFBD><19>4<EFBFBD><14>9N<39>PR<50>PV<50>PV<50>.W<><08>q<EFBFBD><17>$<24><11>(<28>*<2A>+<2B><1B>#<23>$<12>l<EFBFBD>l<EFBFBD>9<EFBFBD>#<23>6<>G<EFBFBD>C<EFBFBD><12> <12> *<2A> *<2A> 4<> 4<><11> <12> <15> <13>F<EFBFBD>O<EFBFBD> <13>L<EFBFBD> !<21> <15> 
2026-01-19 19:38:38 +08:00
<EFBFBD> <06>D<EFBFBD>
<0C><19><19>8<EFBFBD>:<3A>:<3A>f<EFBFBD>4<EFBFBD><19> 8<>B<EFBFBD><06>M<EFBFBD>M<EFBFBD>1<EFBFBD>a<EFBFBD>&<26>(<28>H<EFBFBD>!5<>M<EFBFBD>6<><06>M<EFBFBD>M<EFBFBD>-<2D> <20><06>L<EFBFBD>L<EFBFBD>E<>F<>A<>J<EFBFBD><15>9<EFBFBD>9<EFBFBD>a<EFBFBD>S<EFBFBD>:<3A>c<EFBFBD>r<EFBFBD>?<3F>2<>3<>L<EFBFBD>g<>L<EFBFBD><06>M<EFBFBD>M<EFBFBD>,<2C>|<7C>M<EFBFBD>4<> <0E><<3C><<3C><02>r<EFBFBD>D<EFBFBD>d<EFBFBD><<3C> ;<3B>D<EFBFBD><08>N<EFBFBD>N<EFBFBD>%<25>&<26><07><14><14><16>
2026-01-19 15:05:55 +08:00
<0F>
<1B>
<1B>9<>
2026-01-20 01:55:46 +08:00
9<EFBFBD>C<EFBFBD><07>K<EFBFBD>K<EFBFBD><03><17>F<EFBFBD>K<EFBFBD>;<3B><07>I<EFBFBD>I<EFBFBD>c<EFBFBD>N<EFBFBD> <0E>J<EFBFBD><4A>iIs<00>!"O(c <01><><00>[5 [R"URSS9R 5nUSR [ S9nU[R"U5n[R"SSSSS 9up4US
nURUS [S S [S9 UR[ [R"U55[SSS[R"U5S3S9 UR!S5 UR#S5 UR%S5 UR'SSS9 UR)SSS9 USn[R*"U5SSS2nUR-[R."S[1U5S-5USSS[S [S![S"S#9 UR!S$5 UR#S%5 UR%S&5 UR'SSS9 UR3S'[1U5S(3S)S*9 UR55 UR6S+- nUR9US,[S-9 [R:"U5 U$).N<> pair_riskrL<00>shortfall_prob_eitherr<72>rYr_<00>rr<>rSrTrrrr<00><04>binsrrZr<>r<><E79A99><EFBFBD><EFBFBD>@<40>mean=<3D>.3f<EFBFBD>rr[ra<00> Histogramz#Shortfall probability (either site)<29>CountTrrhrirjr<><00>og<6F><67><EFBFBD><EFBFBD><EFBFBD><EFBFBD> @g<><67><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?rrg333333<33>?)re<00>
markersizer[r<00>markerfacecolor<6F>markeredgecolor<6F>markeredgewidthzSorted by risk (descending)z Pair rankzShortfall probabilityz!Fig.5 Risk distribution across n=z pairsr<73>r<>zfig5_risk_distribution.pngr<67>r<>)r)rnror2rpr<>r<>r<>r<>r rv<00>histr%r#<00>axvline<6E>meanr|r}r~rr<00>sortry<00>aranger{r<>r<>r3r<>r<>)r<><00>risk<73>pr<70>r<>r<><00>p_sortedr<64>s r(<00>fig5_risk_distributionr2qs<00><00><18><1A> <0A>=<3D>=<3D><15>,<2C>,<2C><1B> E<> J<> J<> L<>D<EFBFBD> <0C> $<24>%<25>.<2E>.<2E>U<EFBFBD>.<2E>;<3B>A<EFBFBD> <09>"<22>+<2B>+<2B>a<EFBFBD>.<2E><19>A<EFBFBD><13> <0C> <0C>Q<EFBFBD><01>9<EFBFBD>#<23>><3E>I<EFBFBD>C<EFBFBD> <0A>a<EFBFBD><17>B<EFBFBD><06>G<EFBFBD>G<EFBFBD>A<EFBFBD>B<EFBFBD>g<EFBFBD>f<EFBFBD>o<EFBFBD>S<EFBFBD>F<EFBFBD>G<EFBFBD>K<><06>J<EFBFBD>J<EFBFBD> <0A>b<EFBFBD>g<EFBFBD>g<EFBFBD>a<EFBFBD>j<EFBFBD><19><15>l<EFBFBD>#<23><15><15>b<EFBFBD>g<EFBFBD>g<EFBFBD>a<EFBFBD>j<EFBFBD><13>%<25>&<26> <0F><06> <07>L<EFBFBD>L<EFBFBD><1B><1D><06>M<EFBFBD>M<EFBFBD>7<>8<><06>M<EFBFBD>M<EFBFBD>'<27><1A><06>G<EFBFBD>G<EFBFBD>D<EFBFBD><04>G<EFBFBD><1D><06>I<EFBFBD>I<EFBFBD>&<26>$<24>I<EFBFBD>'<27> <0A>a<EFBFBD><17>B<EFBFBD><11>w<EFBFBD>w<EFBFBD>q<EFBFBD>z<EFBFBD>$<24>B<EFBFBD>$<24><1F>H<EFBFBD><06>G<EFBFBD>G<EFBFBD>
<EFBFBD> <09> <09>!<21>S<EFBFBD><18>]<5D>Q<EFBFBD>&<26>'<27><10><12><16><15><15>'<27>(<28><1F> <0C>-<2D><1E><1B> <0C>
<06><07>L<EFBFBD>L<EFBFBD>.<2E>/<2F><06>M<EFBFBD>M<EFBFBD>+<2B><1E><06>M<EFBFBD>M<EFBFBD>)<29>*<2A><06>G<EFBFBD>G<EFBFBD>D<EFBFBD><04>G<EFBFBD><1D><07>L<EFBFBD>L<EFBFBD>4<>S<EFBFBD><11>V<EFBFBD>H<EFBFBD>F<EFBFBD>C<>t<EFBFBD>L<EFBFBD>L<><07><14><14><16>
2026-01-19 15:05:55 +08:00
<0F>
<1B>
<1B>:<3A>
2026-01-20 01:55:46 +08:00
:<3A>C<EFBFBD><07>K<EFBFBD>K<EFBFBD><03><17>F<EFBFBD>K<EFBFBD>;<3B><07>I<EFBFBD>I<EFBFBD>c<EFBFBD>N<EFBFBD> <0E>Jr'c <01><><00>[5 [R"URSS9R 5nUSR [ S9nU[R"U5n[R"U5n[U5nUS:Xd[R"U5S::a3[R"SS/5n[R"SS/5nSnO<>[R"U5n[R"S/[R"SUS-5U- /5n[R"S/X<>S - /5nSS
[ [R "Xe55--
n["R$"SS S S S9up<>U
Sn U R'US[(SS[*S9 U R-[ [R."U55[(SSS[R."U5S3S9 U R1S5 U R3S5 U R5S5 U R7SSS9 U R9SSS9 U
Sn U R;XV[(S SS!S9 U R;SS/SS/[(S"S#S$S%S&9 U R1S'US(S)35 U R3S*5 U R5S+5 U R=SS5 U R?SS5 U R7SSS9 U R9S,SS9 U RAS-[U5S.3S/S09 U RC5 URDS1- n U RGU S2[*S39 ["RH"U 5 U $)4N<34>site_satisfactionrL<00>satisfaction_rate_rr<72>rgr<>rYr<>r<>r_rrSrTr<>rrrrrr z.2fr"zSatisfaction rate distributionzSatisfaction rate $r_i$r$Trrhrirjrz Lorenz curverz--gffffff<66>?z Equality line)r<00> linestyler[razLorenz curve (Gini=r!r^zCumulative share of sitesz Cumulative share of satisfactionz lower rightzFig.6 Fairness diagnostics (n=z sites)r<>r<>zfig6_fairness_satisfaction.pngr<67>r<>)%r)rnror2rpr<>r<>r<>r<>r-r{<00>sum<75>arrayr<00> concatenater.<00> trapezoidr rvr*r%r#r+r,r|r}r~rrry<00>set_xlim<69>set_ylimr<6D>r<>r3r<>r<>) r<>r<>r<><00>r_sorted<65>nrcr<><00>gini<6E>cumr<6D>r<>r<>r<>s r(<00>fig6_fairness_satisfactionrA<00>s<><00><00><18><1A> <0B><1D><1D>u<EFBFBD>*<2A>*<2A>7J<37> K<> P<> P<> R<>B<EFBFBD>
<EFBFBD> <20>!<21>*<2A>*<2A><15>*<2A>7<>A<EFBFBD> <09>"<22>+<2B>+<2B>a<EFBFBD>.<2E><19>A<EFBFBD><11>w<EFBFBD>w<EFBFBD>q<EFBFBD>z<EFBFBD>H<EFBFBD> <0C>H<EFBFBD> <0A>A<EFBFBD><08>A<EFBFBD>v<EFBFBD><12><16><16><08>!<21>Q<EFBFBD>&<26> <0E>H<EFBFBD>H<EFBFBD>c<EFBFBD>3<EFBFBD>Z<EFBFBD> <20><01> <0E>H<EFBFBD>H<EFBFBD>c<EFBFBD>3<EFBFBD>Z<EFBFBD> <20><01><12><04><10>i<EFBFBD>i<EFBFBD><08>!<21><03> <0E>N<EFBFBD>N<EFBFBD>S<EFBFBD>E<EFBFBD>2<EFBFBD>9<EFBFBD>9<EFBFBD>Q<EFBFBD><01>A<EFBFBD><05>#6<><11>#:<3A>;<3B> <<3C><01> <0E>N<EFBFBD>N<EFBFBD>S<EFBFBD>E<EFBFBD>3<EFBFBD>R<EFBFBD><17>=<3D>1<> 2<><01><12>S<EFBFBD>5<EFBFBD><12><1C><1C>a<EFBFBD>!3<>4<>4<>4<><04><13> <0C> <0C>Q<EFBFBD><01>9<EFBFBD>#<23>><3E>I<EFBFBD>C<EFBFBD> <0A>a<EFBFBD><17>B<EFBFBD><06>G<EFBFBD>G<EFBFBD>A<EFBFBD>B<EFBFBD>g<EFBFBD>l<EFBFBD>3<>3<EFBFBD>&<26>G<EFBFBD>Q<><06>J<EFBFBD>J<EFBFBD>u<EFBFBD>R<EFBFBD>W<EFBFBD>W<EFBFBD>Q<EFBFBD>Z<EFBFBD> <20><07> <0C>(=<3D><13>V[<5B>\^<5E>\c<>\c<>de<64>\f<>gj<67>[k<>Tl<54>J<EFBFBD>m<><06>L<EFBFBD>L<EFBFBD>1<>2<><06>M<EFBFBD>M<EFBFBD>+<2B>,<2C><06>M<EFBFBD>M<EFBFBD>'<27><1A><06>G<EFBFBD>G<EFBFBD>D<EFBFBD><04>G<EFBFBD><1D><06>I<EFBFBD>I<EFBFBD>&<26>$<24>I<EFBFBD>'<27> <0A>a<EFBFBD><17>B<EFBFBD><06>G<EFBFBD>G<EFBFBD>A<EFBFBD><07><06><0F>3<EFBFBD>n<EFBFBD>G<EFBFBD>M<><06>G<EFBFBD>G<EFBFBD>Q<EFBFBD><01>F<EFBFBD>Q<EFBFBD><01>F<EFBFBD>'<27>+<2B>"6<>$<24>RU<52>]l<>G<EFBFBD>m<><06>L<EFBFBD>L<EFBFBD>&<26>t<EFBFBD>C<EFBFBD>j<EFBFBD><01>2<>3<><06>M<EFBFBD>M<EFBFBD>-<2D>.<2E><06>M<EFBFBD>M<EFBFBD>4<>5<><06>K<EFBFBD>K<EFBFBD><01>1<EFBFBD><15><06>K<EFBFBD>K<EFBFBD><01>1<EFBFBD><15><06>G<EFBFBD>G<EFBFBD>D<EFBFBD><04>G<EFBFBD><1D><06>I<EFBFBD>I<EFBFBD>-<2D><14>I<EFBFBD>.<2E><07>L<EFBFBD>L<EFBFBD>1<>#<23>a<EFBFBD>&<26><18><17>A<>T<EFBFBD>L<EFBFBD>J<><07><14><14><16>
<0F>
<1B>
<1B>><3E>
><3E>C<EFBFBD><07>K<EFBFBD>K<EFBFBD><03><17>F<EFBFBD>K<EFBFBD>;<3B><07>I<EFBFBD>I<EFBFBD>c<EFBFBD>N<EFBFBD> <0E>Jr'c<01>4<00>[5nURURURURUR
4Hn[ U5 M URRSSS9 [S5 [S5 [S5 [U5n[SUR[535 [U5n[SUR[535 [U5n[SUR[535 [U5n[SUR[535 [!U5n[SUR[535 [#U5n[SUR[535 g)NTrz<============================================================zTask 3 - Step 8: VisualizationzSaved: )r=r.r/r0r1r2rBr3<00>mkdir<69>printr<74><00> relative_tor<r<>r<>rArr2)r<>r0<00>out1<74>out1_js<6A>out2<74>out6<74>out4<74>out5s r(<00>mainrL<00>s]<00><00> <1A> <1C>E<EFBFBD> <0A><1B><1B> <0A><1A><1A> <0A><1D><1D> <0A><1B><1B> <0A><1B><1B> <06><01> <16>a<EFBFBD><18><06>
2026-01-19 15:05:55 +08:00
<EFBFBD><15><15><1B><1B>D<EFBFBD>4<EFBFBD><1B>8<> <09>(<28>O<EFBFBD> <09>
*<2A>+<2B> <09>(<28>O<EFBFBD> <1B>E<EFBFBD> "<22>D<EFBFBD> <09>G<EFBFBD>D<EFBFBD>$<24>$<24>X<EFBFBD>.<2E>/<2F>
2026-01-19 19:38:38 +08:00
0<EFBFBD>1<>#<23>E<EFBFBD>*<2A>G<EFBFBD> <09>G<EFBFBD>G<EFBFBD>'<27>'<27><08>1<>2<>
3<EFBFBD>4<> "<22>5<EFBFBD> )<29>D<EFBFBD> <09>G<EFBFBD>D<EFBFBD>$<24>$<24>X<EFBFBD>.<2E>/<2F>
2026-01-20 01:55:46 +08:00
0<EFBFBD>1<> %<25>e<EFBFBD> ,<2C>D<EFBFBD> <09>G<EFBFBD>D<EFBFBD>$<24>$<24>X<EFBFBD>.<2E>/<2F>
2026-01-19 15:05:55 +08:00
0<EFBFBD>1<> <20><15> '<27>D<EFBFBD> <09>G<EFBFBD>D<EFBFBD>$<24>$<24>X<EFBFBD>.<2E>/<2F>
0<EFBFBD>1<> !<21>%<25> (<28>D<EFBFBD> <09>G<EFBFBD>D<EFBFBD>$<24>$<24>X<EFBFBD>.<2E>/<2F>
2026-01-20 01:55:46 +08:00
0<EFBFBD>1r'<00>__main__)<02>return<72>None)rNr,)rArrNrO)rDrrrErrrNztuple[int, int])r<>r,rNr)1<>__doc__<5F>
__future__r<00> dataclassesrr<><00>pathlibr<00>os<6F>tempfile<6C>numpyr<79><00>pandasrn<00>
gettempdir<EFBFBD>_mpl_config_dir<69>_xdg_cache_dirrC<00>environ<6F>
setdefaultr<EFBFBD><00>
matplotlib<EFBFBD>use<73>matplotlib.pyplot<6F>pyplotr rr<>r<00>__file__<5F>resolve<76>parentr<r%r#r$r)r,r=rBrFr<>r<>r<>rr2rArLr4r&r'r(<00><module>rds<><00><01><04>&#<23>!<21> <0B><18> <09><0F><12><13><16>x<EFBFBD>*<2A>*<2A>,<2C>-<2D>0D<30>D<><0F><15>h<EFBFBD>)<29>)<29>+<2B>,<2C>/C<>C<><0E><0F><15><15>d<EFBFBD>T<EFBFBD><15>2<><0E><14><14>T<EFBFBD>D<EFBFBD><14>1<><02>
2026-01-19 15:05:55 +08:00
<EFBFBD>
<EFBFBD><15><15>n<EFBFBD>c<EFBFBD>/<2F>&:<3A>;<3B><02>
<EFBFBD>
<EFBFBD><15><15>&<26><03>N<EFBFBD>(;<3B><<3C><11>
2026-01-20 01:55:46 +08:00
<EFBFBD><0E><0E>u<EFBFBD><15><1F>(<28><19> <10><08>><3E> !<21> !<21> #<23> *<2A> *<2A><08> <16> <15><1B> <20> <15> <15> <15><1A><1B>
<02><07>
<13><06> <14><08> <06>F <0B>$<24><17><16><16><18><16><06>
<EFBFBD>(<28>G<0F>T.<0F>b+<0F>\@<0F>F.<0F>b0<0F>f2<>< <0C>z<EFBFBD><19><08>F<EFBFBD>r'