[{"data":1,"prerenderedAt":7366},["ShallowReactive",2],{"uc-warehouse-planning":3},{"en":4,"de":3982},{"id":5,"title":6,"body":7,"description":13,"extension":3975,"faq":3976,"meta":3977,"navigation":96,"path":3978,"seo":3979,"stem":3980,"__hash__":3981},"content\u002Fuse-cases\u002Fwarehouse-planning.md","Warehouse planning when the market turns",{"type":8,"value":9,"toc":3966},"minimark",[10,14,21,29,32,35,40,43,56,59,62,626,631,635,638,641,644,1137,1141,1144,1995,1998,2001,2119,2122,2126,2129,2250,2253,2256,2429,2432,2435,2439,2442,2453,2460,3295,3298,3301,3586,3589,3592,3596,3599,3785,3788,3791,3925,3928,3931,3934,3938,3941,3962],[11,12,13],"p",{},"You plan your warehouse network according to the demand forecast. But because the forecast is never exact, you keep a safety margin and plan each warehouse to 95% of its capacity. That is not wrong. In a calm market, with forecasts that miss by about 15%, a 95% margin is practically optimal. On our test data, it costs nothing extra in the median and at most 4% in the worst case.",[11,15,16],{},[17,18],"img",{"alt":19,"src":20},"Left: a map of five possible warehouse sites and eight customer regions. Three sites have a warehouse, and a line runs from each region to the warehouse that serves it. Right: the yearly demand on one warehouse over 100,000 simulated years, in a calm and in a turned market. The average is the same in both markets. In the turned market, demand swings further, so more pallets don't fit.","\u002Fuse-cases\u002Fwarehouse-planning\u002Fwarehouse-planning.svg",[11,22,23,24,28],{},"But that margin was learned in a calm market. Suppose the market suddenly changes. Your forecasts now miss by about 30%, and on top of that, the regions you serve are ",[25,26,27],"em",{},"correlated",", that is, demand there rises and falls in step. Those pallets that don't fit into your warehouses go to a third-party logistics provider. With demand for its services higher, that provider now charges twice as much as before. The same 95% safety margin then costs a median 14.5% more per year than the plan Quicopt finds, and as much as 36% more in the worst of our 20 test networks. Even with a 90% margin, it is still 6.7% more. Planning with the demand forecast alone does worse still, even when a solver proves the plan optimal. In the median, that plan costs 18% more, and it costs almost 50% more than the solver promised.",[11,30,31],{},"Quicopt builds the forecast error directly into the plan. You tell it how far demand may stray from the forecast. Quicopt then chooses the warehouse network that is cheapest across all possible outcomes, and tells you exactly what that network will cost (to within 2% in our tests, which is excellent given the forecast error). When the market changes, you only need to update the forecast parameters instead of re-learning a margin.",[11,33,34],{},"Below we plan all 20 test networks both ways, in the calm and in the turned market, with code you can run yourself.",[36,37,39],"h2",{"id":38},"twenty-warehouse-networks","Twenty warehouse networks",[11,41,42],{},"Each of the 20 networks has five sites where you could run a warehouse and eight customer regions, spread over a map of 600 × 800 km. Each region is served from exactly one warehouse. A year's cost has three parts:",[44,45,46,50,53],"ul",{},[47,48,49],"li",{},"a fixed cost for every warehouse you run;",[47,51,52],{},"transport, priced by distance and by each region's demand that year;",[47,54,55],{},"a premium for overflow.",[11,57,58],{},"Overflow is the part of a year's demand that a warehouse cannot hold. It goes to a third-party logistics provider, who charges a premium per pallet.",[11,60,61],{},"We draw the 20 networks at random, each from a fixed seed, so you can reproduce every number on this page. Demand and capacity are in thousand pallets a year, costs in thousand EUR a year. Network 11 is the one we look at in detail: of the 20 test networks, it is the one where planning for the forecast goes worst once the market turns.",[63,64,69],"pre",{"className":65,"code":66,"language":67,"meta":68,"style":68},"language-python shiki shiki-themes github-dark","import numpy as np\n\nSITES, REGIONS = 5, 8\nTRANSPORT = 0.02          # EUR per pallet and km\n\n\ndef network(number):\n    \"\"\"Network `number`: distances between sites and regions, each region's\n    forecast, and each site's capacity and fixed cost.\"\"\"\n    rng = np.random.default_rng(number)\n    site_xy = rng.uniform([0, 0], [600, 800], (SITES, 2))        # km\n    region_xy = rng.uniform([0, 0], [600, 800], (REGIONS, 2))\n    return {\n        \"distance\": np.linalg.norm(site_xy[:, None, :] - region_xy[None, :, :], axis=2),\n        \"forecast\": rng.uniform(60, 140, REGIONS),      # thousand pallets a year\n        \"capacity\": rng.uniform(200, 350, SITES),       # thousand pallets a year\n        \"fixed_cost\": rng.uniform(800, 1200, SITES),    # thousand EUR a year\n    }\n\n\nnetworks = [network(number) for number in range(20)]\n\nshown = networks[11]\nprint(\"site  capacity  fixed cost\")\nfor s in range(SITES):\n    print(f\"{s:4}  {shown['capacity'][s]:8.0f}  {shown['fixed_cost'][s]:10.0f}\")\nprint(\"\\nregion  forecast\")\nfor r in range(REGIONS):\n    print(f\"{r:6}  {shown['forecast'][r]:8.0f}\")\n","python","",[70,71,72,91,98,122,137,142,147,160,167,173,185,230,265,274,311,338,363,388,394,399,404,436,441,458,472,491,552,569,587],"code",{"__ignoreMap":68},[73,74,77,81,85,88],"span",{"class":75,"line":76},"line",1,[73,78,80],{"class":79},"snl16","import",[73,82,84],{"class":83},"s95oV"," numpy ",[73,86,87],{"class":79},"as",[73,89,90],{"class":83}," np\n",[73,92,94],{"class":75,"line":93},2,[73,95,97],{"emptyLinePlaceholder":96},true,"\n",[73,99,101,105,108,111,114,117,119],{"class":75,"line":100},3,[73,102,104],{"class":103},"sDLfK","SITES",[73,106,107],{"class":83},", ",[73,109,110],{"class":103},"REGIONS",[73,112,113],{"class":79}," =",[73,115,116],{"class":103}," 5",[73,118,107],{"class":83},[73,120,121],{"class":103},"8\n",[73,123,125,128,130,133],{"class":75,"line":124},4,[73,126,127],{"class":103},"TRANSPORT",[73,129,113],{"class":79},[73,131,132],{"class":103}," 0.02",[73,134,136],{"class":135},"sAwPA","          # EUR per pallet and km\n",[73,138,140],{"class":75,"line":139},5,[73,141,97],{"emptyLinePlaceholder":96},[73,143,145],{"class":75,"line":144},6,[73,146,97],{"emptyLinePlaceholder":96},[73,148,150,153,157],{"class":75,"line":149},7,[73,151,152],{"class":79},"def",[73,154,156],{"class":155},"svObZ"," network",[73,158,159],{"class":83},"(number):\n",[73,161,163],{"class":75,"line":162},8,[73,164,166],{"class":165},"sU2Wk","    \"\"\"Network `number`: distances between sites and regions, each region's\n",[73,168,170],{"class":75,"line":169},9,[73,171,172],{"class":165},"    forecast, and each site's capacity and fixed cost.\"\"\"\n",[73,174,176,179,182],{"class":75,"line":175},10,[73,177,178],{"class":83},"    rng ",[73,180,181],{"class":79},"=",[73,183,184],{"class":83}," np.random.default_rng(number)\n",[73,186,188,191,193,196,199,201,203,206,209,211,214,217,219,221,224,227],{"class":75,"line":187},11,[73,189,190],{"class":83},"    site_xy ",[73,192,181],{"class":79},[73,194,195],{"class":83}," rng.uniform([",[73,197,198],{"class":103},"0",[73,200,107],{"class":83},[73,202,198],{"class":103},[73,204,205],{"class":83},"], [",[73,207,208],{"class":103},"600",[73,210,107],{"class":83},[73,212,213],{"class":103},"800",[73,215,216],{"class":83},"], (",[73,218,104],{"class":103},[73,220,107],{"class":83},[73,222,223],{"class":103},"2",[73,225,226],{"class":83},"))        ",[73,228,229],{"class":135},"# km\n",[73,231,233,236,238,240,242,244,246,248,250,252,254,256,258,260,262],{"class":75,"line":232},12,[73,234,235],{"class":83},"    region_xy ",[73,237,181],{"class":79},[73,239,195],{"class":83},[73,241,198],{"class":103},[73,243,107],{"class":83},[73,245,198],{"class":103},[73,247,205],{"class":83},[73,249,208],{"class":103},[73,251,107],{"class":83},[73,253,213],{"class":103},[73,255,216],{"class":83},[73,257,110],{"class":103},[73,259,107],{"class":83},[73,261,223],{"class":103},[73,263,264],{"class":83},"))\n",[73,266,268,271],{"class":75,"line":267},13,[73,269,270],{"class":79},"    return",[73,272,273],{"class":83}," {\n",[73,275,277,280,283,286,289,292,295,297,300,304,306,308],{"class":75,"line":276},14,[73,278,279],{"class":165},"        \"distance\"",[73,281,282],{"class":83},": np.linalg.norm(site_xy[:, ",[73,284,285],{"class":103},"None",[73,287,288],{"class":83},", :] ",[73,290,291],{"class":79},"-",[73,293,294],{"class":83}," region_xy[",[73,296,285],{"class":103},[73,298,299],{"class":83},", :, :], ",[73,301,303],{"class":302},"s9osk","axis",[73,305,181],{"class":79},[73,307,223],{"class":103},[73,309,310],{"class":83},"),\n",[73,312,314,317,320,323,325,328,330,332,335],{"class":75,"line":313},15,[73,315,316],{"class":165},"        \"forecast\"",[73,318,319],{"class":83},": rng.uniform(",[73,321,322],{"class":103},"60",[73,324,107],{"class":83},[73,326,327],{"class":103},"140",[73,329,107],{"class":83},[73,331,110],{"class":103},[73,333,334],{"class":83},"),      ",[73,336,337],{"class":135},"# thousand pallets a year\n",[73,339,341,344,346,349,351,354,356,358,361],{"class":75,"line":340},16,[73,342,343],{"class":165},"        \"capacity\"",[73,345,319],{"class":83},[73,347,348],{"class":103},"200",[73,350,107],{"class":83},[73,352,353],{"class":103},"350",[73,355,107],{"class":83},[73,357,104],{"class":103},[73,359,360],{"class":83},"),       ",[73,362,337],{"class":135},[73,364,366,369,371,373,375,378,380,382,385],{"class":75,"line":365},17,[73,367,368],{"class":165},"        \"fixed_cost\"",[73,370,319],{"class":83},[73,372,213],{"class":103},[73,374,107],{"class":83},[73,376,377],{"class":103},"1200",[73,379,107],{"class":83},[73,381,104],{"class":103},[73,383,384],{"class":83},"),    ",[73,386,387],{"class":135},"# thousand EUR a year\n",[73,389,391],{"class":75,"line":390},18,[73,392,393],{"class":83},"    }\n",[73,395,397],{"class":75,"line":396},19,[73,398,97],{"emptyLinePlaceholder":96},[73,400,402],{"class":75,"line":401},20,[73,403,97],{"emptyLinePlaceholder":96},[73,405,407,410,412,415,418,421,424,427,430,433],{"class":75,"line":406},21,[73,408,409],{"class":83},"networks ",[73,411,181],{"class":79},[73,413,414],{"class":83}," [network(number) ",[73,416,417],{"class":79},"for",[73,419,420],{"class":83}," number ",[73,422,423],{"class":79},"in",[73,425,426],{"class":103}," range",[73,428,429],{"class":83},"(",[73,431,432],{"class":103},"20",[73,434,435],{"class":83},")]\n",[73,437,439],{"class":75,"line":438},22,[73,440,97],{"emptyLinePlaceholder":96},[73,442,444,447,449,452,455],{"class":75,"line":443},23,[73,445,446],{"class":83},"shown ",[73,448,181],{"class":79},[73,450,451],{"class":83}," networks[",[73,453,454],{"class":103},"11",[73,456,457],{"class":83},"]\n",[73,459,461,464,466,469],{"class":75,"line":460},24,[73,462,463],{"class":103},"print",[73,465,429],{"class":83},[73,467,468],{"class":165},"\"site  capacity  fixed cost\"",[73,470,471],{"class":83},")\n",[73,473,475,477,480,482,484,486,488],{"class":75,"line":474},25,[73,476,417],{"class":79},[73,478,479],{"class":83}," s ",[73,481,423],{"class":79},[73,483,426],{"class":103},[73,485,429],{"class":83},[73,487,104],{"class":103},[73,489,490],{"class":83},"):\n",[73,492,494,497,499,502,505,508,511,514,517,520,523,526,529,532,534,536,538,541,543,546,548,550],{"class":75,"line":493},26,[73,495,496],{"class":103},"    print",[73,498,429],{"class":83},[73,500,501],{"class":79},"f",[73,503,504],{"class":165},"\"",[73,506,507],{"class":103},"{",[73,509,510],{"class":83},"s",[73,512,513],{"class":79},":4",[73,515,516],{"class":103},"}",[73,518,519],{"class":103},"  {",[73,521,522],{"class":83},"shown[",[73,524,525],{"class":165},"'capacity'",[73,527,528],{"class":83},"][s]",[73,530,531],{"class":79},":8.0f",[73,533,516],{"class":103},[73,535,519],{"class":103},[73,537,522],{"class":83},[73,539,540],{"class":165},"'fixed_cost'",[73,542,528],{"class":83},[73,544,545],{"class":79},":10.0f",[73,547,516],{"class":103},[73,549,504],{"class":165},[73,551,471],{"class":83},[73,553,555,557,559,561,564,567],{"class":75,"line":554},27,[73,556,463],{"class":103},[73,558,429],{"class":83},[73,560,504],{"class":165},[73,562,563],{"class":103},"\\n",[73,565,566],{"class":165},"region  forecast\"",[73,568,471],{"class":83},[73,570,572,574,577,579,581,583,585],{"class":75,"line":571},28,[73,573,417],{"class":79},[73,575,576],{"class":83}," r ",[73,578,423],{"class":79},[73,580,426],{"class":103},[73,582,429],{"class":83},[73,584,110],{"class":103},[73,586,490],{"class":83},[73,588,590,592,594,596,598,600,603,606,608,610,612,615,618,620,622,624],{"class":75,"line":589},29,[73,591,496],{"class":103},[73,593,429],{"class":83},[73,595,501],{"class":79},[73,597,504],{"class":165},[73,599,507],{"class":103},[73,601,602],{"class":83},"r",[73,604,605],{"class":79},":6",[73,607,516],{"class":103},[73,609,519],{"class":103},[73,611,522],{"class":83},[73,613,614],{"class":165},"'forecast'",[73,616,617],{"class":83},"][r]",[73,619,531],{"class":79},[73,621,516],{"class":103},[73,623,504],{"class":165},[73,625,471],{"class":83},[627,628],"cell-output",{":lines":629,"label":630},"[\"site  capacity  fixed cost\",\"   0       264         887\",\"   1       222         813\",\"   2       301         880\",\"   3       230         938\",\"   4       335         988\",\"\",\"region  forecast\",\"     0        79\",\"     1       124\",\"     2       129\",\"     3        70\",\"     4        97\",\"     5        82\",\"     6        67\",\"     7       132\"]","Output",[36,632,634],{"id":633},"two-markets","Two markets",[11,636,637],{},"A market, on this page, is three numbers. The forecast error says how far a region's yearly demand typically strays from its forecast (one standard deviation). The correlation says how strongly demand in the regions rises and falls together. The overflow premium is the third-party logistics provider's price per pallet.",[11,639,640],{},"In the calm market, your forecasts miss by about 15%, the regions are independent of each other, and overflow costs EUR 40 per pallet. In the turned market, forecasts miss by about 30%, any two regions are correlated at 0.5, and overflow costs EUR 80 per pallet.",[11,642,643],{},"We judge every plan by its real cost. That is its average yearly cost over 100,000 simulated years of the market it faces.",[63,645,647],{"className":65,"code":646,"language":67,"meta":68,"style":68},"calm = {\"error\": 0.15, \"correlation\": 0.0, \"overflow\": 40.0}\nturned = {\"error\": 0.30, \"correlation\": 0.5, \"overflow\": 80.0}\n\n\ndef years(net, market, n, seed):\n    \"\"\"`n` simulated years of demand: one row per year, one column per region.\"\"\"\n    rng = np.random.default_rng(seed)\n    own = rng.standard_normal((n, REGIONS))     # each region's own swing\n    shared = rng.standard_normal((n, 1))        # the swing all regions share\n    rho = market[\"correlation\"]\n    swing = np.sqrt(1 - rho) * own + np.sqrt(rho) * shared\n    return np.maximum(net[\"forecast\"] + market[\"error\"] * net[\"forecast\"] * swing, 0.0)\n\n\ndef yearly_cost(net, market, plan, demand):\n    \"\"\"The cost of `plan` in each simulated year: fixed costs, transport, overflow.\"\"\"\n    open_sites, serves = plan\n    transport = (TRANSPORT * net[\"distance\"][serves, np.arange(REGIONS)] * demand).sum(axis=1)\n    load = np.zeros((len(demand), SITES))\n    for r in range(REGIONS):\n        load[:, serves[r]] += demand[:, r]\n    overflow = np.maximum(load - net[\"capacity\"] * open_sites, 0.0).sum(axis=1)\n    return net[\"fixed_cost\"] @ open_sites + transport + market[\"overflow\"] * overflow\n\n\ndef real_cost(number, market, plan):\n    \"\"\"The plan's average yearly cost over 100,000 simulated years.\"\"\"\n    net = networks[number]\n    return yearly_cost(net, market, plan, years(net, market, 100_000, seed=number + 2000)).mean()\n",[70,648,649,691,727,731,735,745,750,759,777,794,808,843,882,886,890,900,905,915,956,976,993,1004,1041,1076,1080,1084,1094,1099,1109],{"__ignoreMap":68},[73,650,651,654,656,659,662,665,668,670,673,675,678,680,683,685,688],{"class":75,"line":76},[73,652,653],{"class":83},"calm ",[73,655,181],{"class":79},[73,657,658],{"class":83}," {",[73,660,661],{"class":165},"\"error\"",[73,663,664],{"class":83},": ",[73,666,667],{"class":103},"0.15",[73,669,107],{"class":83},[73,671,672],{"class":165},"\"correlation\"",[73,674,664],{"class":83},[73,676,677],{"class":103},"0.0",[73,679,107],{"class":83},[73,681,682],{"class":165},"\"overflow\"",[73,684,664],{"class":83},[73,686,687],{"class":103},"40.0",[73,689,690],{"class":83},"}\n",[73,692,693,696,698,700,702,704,707,709,711,713,716,718,720,722,725],{"class":75,"line":93},[73,694,695],{"class":83},"turned ",[73,697,181],{"class":79},[73,699,658],{"class":83},[73,701,661],{"class":165},[73,703,664],{"class":83},[73,705,706],{"class":103},"0.30",[73,708,107],{"class":83},[73,710,672],{"class":165},[73,712,664],{"class":83},[73,714,715],{"class":103},"0.5",[73,717,107],{"class":83},[73,719,682],{"class":165},[73,721,664],{"class":83},[73,723,724],{"class":103},"80.0",[73,726,690],{"class":83},[73,728,729],{"class":75,"line":100},[73,730,97],{"emptyLinePlaceholder":96},[73,732,733],{"class":75,"line":124},[73,734,97],{"emptyLinePlaceholder":96},[73,736,737,739,742],{"class":75,"line":139},[73,738,152],{"class":79},[73,740,741],{"class":155}," years",[73,743,744],{"class":83},"(net, market, n, seed):\n",[73,746,747],{"class":75,"line":144},[73,748,749],{"class":165},"    \"\"\"`n` simulated years of demand: one row per year, one column per region.\"\"\"\n",[73,751,752,754,756],{"class":75,"line":149},[73,753,178],{"class":83},[73,755,181],{"class":79},[73,757,758],{"class":83}," np.random.default_rng(seed)\n",[73,760,761,764,766,769,771,774],{"class":75,"line":162},[73,762,763],{"class":83},"    own ",[73,765,181],{"class":79},[73,767,768],{"class":83}," rng.standard_normal((n, ",[73,770,110],{"class":103},[73,772,773],{"class":83},"))     ",[73,775,776],{"class":135},"# each region's own swing\n",[73,778,779,782,784,786,789,791],{"class":75,"line":169},[73,780,781],{"class":83},"    shared ",[73,783,181],{"class":79},[73,785,768],{"class":83},[73,787,788],{"class":103},"1",[73,790,226],{"class":83},[73,792,793],{"class":135},"# the swing all regions share\n",[73,795,796,799,801,804,806],{"class":75,"line":175},[73,797,798],{"class":83},"    rho ",[73,800,181],{"class":79},[73,802,803],{"class":83}," market[",[73,805,672],{"class":165},[73,807,457],{"class":83},[73,809,810,813,815,818,820,823,826,829,832,835,838,840],{"class":75,"line":187},[73,811,812],{"class":83},"    swing ",[73,814,181],{"class":79},[73,816,817],{"class":83}," np.sqrt(",[73,819,788],{"class":103},[73,821,822],{"class":79}," -",[73,824,825],{"class":83}," rho) ",[73,827,828],{"class":79},"*",[73,830,831],{"class":83}," own ",[73,833,834],{"class":79},"+",[73,836,837],{"class":83}," np.sqrt(rho) ",[73,839,828],{"class":79},[73,841,842],{"class":83}," shared\n",[73,844,845,847,850,853,856,858,860,862,864,866,869,871,873,875,878,880],{"class":75,"line":232},[73,846,270],{"class":79},[73,848,849],{"class":83}," np.maximum(net[",[73,851,852],{"class":165},"\"forecast\"",[73,854,855],{"class":83},"] ",[73,857,834],{"class":79},[73,859,803],{"class":83},[73,861,661],{"class":165},[73,863,855],{"class":83},[73,865,828],{"class":79},[73,867,868],{"class":83}," net[",[73,870,852],{"class":165},[73,872,855],{"class":83},[73,874,828],{"class":79},[73,876,877],{"class":83}," swing, ",[73,879,677],{"class":103},[73,881,471],{"class":83},[73,883,884],{"class":75,"line":267},[73,885,97],{"emptyLinePlaceholder":96},[73,887,888],{"class":75,"line":276},[73,889,97],{"emptyLinePlaceholder":96},[73,891,892,894,897],{"class":75,"line":313},[73,893,152],{"class":79},[73,895,896],{"class":155}," yearly_cost",[73,898,899],{"class":83},"(net, market, plan, demand):\n",[73,901,902],{"class":75,"line":340},[73,903,904],{"class":165},"    \"\"\"The cost of `plan` in each simulated year: fixed costs, transport, overflow.\"\"\"\n",[73,906,907,910,912],{"class":75,"line":365},[73,908,909],{"class":83},"    open_sites, serves ",[73,911,181],{"class":79},[73,913,914],{"class":83}," plan\n",[73,916,917,920,922,925,927,930,932,935,938,940,943,945,948,950,952,954],{"class":75,"line":390},[73,918,919],{"class":83},"    transport ",[73,921,181],{"class":79},[73,923,924],{"class":83}," (",[73,926,127],{"class":103},[73,928,929],{"class":79}," *",[73,931,868],{"class":83},[73,933,934],{"class":165},"\"distance\"",[73,936,937],{"class":83},"][serves, np.arange(",[73,939,110],{"class":103},[73,941,942],{"class":83},")] ",[73,944,828],{"class":79},[73,946,947],{"class":83}," demand).sum(",[73,949,303],{"class":302},[73,951,181],{"class":79},[73,953,788],{"class":103},[73,955,471],{"class":83},[73,957,958,961,963,966,969,972,974],{"class":75,"line":396},[73,959,960],{"class":83},"    load ",[73,962,181],{"class":79},[73,964,965],{"class":83}," np.zeros((",[73,967,968],{"class":103},"len",[73,970,971],{"class":83},"(demand), ",[73,973,104],{"class":103},[73,975,264],{"class":83},[73,977,978,981,983,985,987,989,991],{"class":75,"line":401},[73,979,980],{"class":79},"    for",[73,982,576],{"class":83},[73,984,423],{"class":79},[73,986,426],{"class":103},[73,988,429],{"class":83},[73,990,110],{"class":103},[73,992,490],{"class":83},[73,994,995,998,1001],{"class":75,"line":406},[73,996,997],{"class":83},"        load[:, serves[r]] ",[73,999,1000],{"class":79},"+=",[73,1002,1003],{"class":83}," demand[:, r]\n",[73,1005,1006,1009,1011,1014,1016,1018,1021,1023,1025,1028,1030,1033,1035,1037,1039],{"class":75,"line":438},[73,1007,1008],{"class":83},"    overflow ",[73,1010,181],{"class":79},[73,1012,1013],{"class":83}," np.maximum(load ",[73,1015,291],{"class":79},[73,1017,868],{"class":83},[73,1019,1020],{"class":165},"\"capacity\"",[73,1022,855],{"class":83},[73,1024,828],{"class":79},[73,1026,1027],{"class":83}," open_sites, ",[73,1029,677],{"class":103},[73,1031,1032],{"class":83},").sum(",[73,1034,303],{"class":302},[73,1036,181],{"class":79},[73,1038,788],{"class":103},[73,1040,471],{"class":83},[73,1042,1043,1045,1047,1050,1052,1055,1058,1060,1063,1065,1067,1069,1071,1073],{"class":75,"line":443},[73,1044,270],{"class":79},[73,1046,868],{"class":83},[73,1048,1049],{"class":165},"\"fixed_cost\"",[73,1051,855],{"class":83},[73,1053,1054],{"class":79},"@",[73,1056,1057],{"class":83}," open_sites ",[73,1059,834],{"class":79},[73,1061,1062],{"class":83}," transport ",[73,1064,834],{"class":79},[73,1066,803],{"class":83},[73,1068,682],{"class":165},[73,1070,855],{"class":83},[73,1072,828],{"class":79},[73,1074,1075],{"class":83}," overflow\n",[73,1077,1078],{"class":75,"line":460},[73,1079,97],{"emptyLinePlaceholder":96},[73,1081,1082],{"class":75,"line":474},[73,1083,97],{"emptyLinePlaceholder":96},[73,1085,1086,1088,1091],{"class":75,"line":493},[73,1087,152],{"class":79},[73,1089,1090],{"class":155}," real_cost",[73,1092,1093],{"class":83},"(number, market, plan):\n",[73,1095,1096],{"class":75,"line":554},[73,1097,1098],{"class":165},"    \"\"\"The plan's average yearly cost over 100,000 simulated years.\"\"\"\n",[73,1100,1101,1104,1106],{"class":75,"line":571},[73,1102,1103],{"class":83},"    net ",[73,1105,181],{"class":79},[73,1107,1108],{"class":83}," networks[number]\n",[73,1110,1111,1113,1116,1119,1121,1124,1126,1129,1131,1134],{"class":75,"line":589},[73,1112,270],{"class":79},[73,1114,1115],{"class":83}," yearly_cost(net, market, plan, years(net, market, ",[73,1117,1118],{"class":103},"100_000",[73,1120,107],{"class":83},[73,1122,1123],{"class":302},"seed",[73,1125,181],{"class":79},[73,1127,1128],{"class":83},"number ",[73,1130,834],{"class":79},[73,1132,1133],{"class":103}," 2000",[73,1135,1136],{"class":83},")).mean()\n",[36,1138,1140],{"id":1139},"planning-for-the-forecast","Planning for the forecast",[11,1142,1143],{},"The usual way to plan the network is a mixed-integer linear program (MILP). It chooses which warehouses to run and which warehouse serves each region, so that the cost is lowest if every region's demand equals its forecast. HiGHS, an open-source solver, solves it and proves the plan optimal.",[63,1145,1147],{"className":65,"code":1146,"language":67,"meta":68,"style":68},"import pyomo.environ as pyo\n\n\ndef plan_for_forecast(number, market, margin=1.0):\n    \"\"\"The network that is cheapest if every region's demand equals its forecast,\n    proven optimal by HiGHS. With a margin below 1, each warehouse counts as\n    holding only that share of its capacity. Returns the plan and the cost the\n    solver promises.\"\"\"\n    net = networks[number]\n    m = pyo.ConcreteModel()\n    m.open = pyo.Var(range(SITES), domain=pyo.Binary)                    # run a warehouse at site s?\n    m.serve = pyo.Var(range(SITES), range(REGIONS), domain=pyo.Binary)   # does site s serve region r?\n    m.over = pyo.Var(range(SITES), domain=pyo.NonNegativeReals)          # overflow at site s\n    m.once = pyo.Constraint(range(REGIONS), rule=lambda m, r: sum(m.serve[s, r] for s in range(SITES)) == 1)\n    m.only_open = pyo.Constraint(range(SITES), range(REGIONS), rule=lambda m, s, r: m.serve[s, r] \u003C= m.open[s])\n    m.overflow = pyo.Constraint(range(SITES), rule=lambda m, s: m.over[s] >= sum(\n        net[\"forecast\"][r] * m.serve[s, r] for r in range(REGIONS)) - margin * net[\"capacity\"][s] * m.open[s])\n    m.cost = pyo.Objective(sense=pyo.minimize, expr=(\n        sum(net[\"fixed_cost\"][s] * m.open[s] for s in range(SITES))\n        + sum(TRANSPORT * net[\"distance\"][s, r] * net[\"forecast\"][r] * m.serve[s, r]\n              for s in range(SITES) for r in range(REGIONS))\n        + market[\"overflow\"] * sum(m.over[s] for s in range(SITES))))\n    solver = pyo.SolverFactory(\"appsi_highs\")\n    solver.config.mip_gap = 0.0\n    assert pyo.check_optimal_termination(solver.solve(m))\n    open_sites = np.array([round(m.open[s].value) for s in range(SITES)])\n    serves = np.array([max(range(SITES), key=lambda s: m.serve[s, r].value) for r in range(REGIONS)])\n    return (open_sites, serves), pyo.value(m.cost)\n\n\ndef describe(plan):\n    open_sites, serves = plan\n    warehouses = \", \".join(str(s) for s in range(SITES) if open_sites[s])\n    return f\"warehouses at sites {warehouses}; regions 0-7 served from sites {' '.join(map(str, serves))}\"\n\n\nplan, promised = plan_for_forecast(11, calm)\nreal = real_cost(11, calm, plan)\nprint(describe(plan))\nprint(f\"cost the solver promises   {promised:6,.0f}\")\nprint(f\"real cost                  {real:6,.0f}   ({real \u002F promised - 1:+.1%})\")\n",[70,1148,1149,1161,1165,1169,1186,1191,1196,1201,1206,1214,1224,1255,1290,1317,1373,1411,1444,1491,1516,1547,1580,1612,1644,1659,1669,1677,1708,1752,1759,1763,1768,1779,1788,1828,1871,1876,1881,1897,1913,1921,1947],{"__ignoreMap":68},[73,1150,1151,1153,1156,1158],{"class":75,"line":76},[73,1152,80],{"class":79},[73,1154,1155],{"class":83}," pyomo.environ ",[73,1157,87],{"class":79},[73,1159,1160],{"class":83}," pyo\n",[73,1162,1163],{"class":75,"line":93},[73,1164,97],{"emptyLinePlaceholder":96},[73,1166,1167],{"class":75,"line":100},[73,1168,97],{"emptyLinePlaceholder":96},[73,1170,1171,1173,1176,1179,1181,1184],{"class":75,"line":124},[73,1172,152],{"class":79},[73,1174,1175],{"class":155}," plan_for_forecast",[73,1177,1178],{"class":83},"(number, market, margin",[73,1180,181],{"class":79},[73,1182,1183],{"class":103},"1.0",[73,1185,490],{"class":83},[73,1187,1188],{"class":75,"line":139},[73,1189,1190],{"class":165},"    \"\"\"The network that is cheapest if every region's demand equals its forecast,\n",[73,1192,1193],{"class":75,"line":144},[73,1194,1195],{"class":165},"    proven optimal by HiGHS. With a margin below 1, each warehouse counts as\n",[73,1197,1198],{"class":75,"line":149},[73,1199,1200],{"class":165},"    holding only that share of its capacity. Returns the plan and the cost the\n",[73,1202,1203],{"class":75,"line":162},[73,1204,1205],{"class":165},"    solver promises.\"\"\"\n",[73,1207,1208,1210,1212],{"class":75,"line":169},[73,1209,1103],{"class":83},[73,1211,181],{"class":79},[73,1213,1108],{"class":83},[73,1215,1216,1219,1221],{"class":75,"line":175},[73,1217,1218],{"class":83},"    m ",[73,1220,181],{"class":79},[73,1222,1223],{"class":83}," pyo.ConcreteModel()\n",[73,1225,1226,1229,1231,1234,1237,1239,1241,1244,1247,1249,1252],{"class":75,"line":187},[73,1227,1228],{"class":83},"    m.open ",[73,1230,181],{"class":79},[73,1232,1233],{"class":83}," pyo.Var(",[73,1235,1236],{"class":103},"range",[73,1238,429],{"class":83},[73,1240,104],{"class":103},[73,1242,1243],{"class":83},"), ",[73,1245,1246],{"class":302},"domain",[73,1248,181],{"class":79},[73,1250,1251],{"class":83},"pyo.Binary)                    ",[73,1253,1254],{"class":135},"# run a warehouse at site s?\n",[73,1256,1257,1260,1262,1264,1266,1268,1270,1272,1274,1276,1278,1280,1282,1284,1287],{"class":75,"line":232},[73,1258,1259],{"class":83},"    m.serve ",[73,1261,181],{"class":79},[73,1263,1233],{"class":83},[73,1265,1236],{"class":103},[73,1267,429],{"class":83},[73,1269,104],{"class":103},[73,1271,1243],{"class":83},[73,1273,1236],{"class":103},[73,1275,429],{"class":83},[73,1277,110],{"class":103},[73,1279,1243],{"class":83},[73,1281,1246],{"class":302},[73,1283,181],{"class":79},[73,1285,1286],{"class":83},"pyo.Binary)   ",[73,1288,1289],{"class":135},"# does site s serve region r?\n",[73,1291,1292,1295,1297,1299,1301,1303,1305,1307,1309,1311,1314],{"class":75,"line":267},[73,1293,1294],{"class":83},"    m.over ",[73,1296,181],{"class":79},[73,1298,1233],{"class":83},[73,1300,1236],{"class":103},[73,1302,429],{"class":83},[73,1304,104],{"class":103},[73,1306,1243],{"class":83},[73,1308,1246],{"class":302},[73,1310,181],{"class":79},[73,1312,1313],{"class":83},"pyo.NonNegativeReals)          ",[73,1315,1316],{"class":135},"# overflow at site s\n",[73,1318,1319,1322,1324,1327,1329,1331,1333,1335,1338,1341,1344,1347,1350,1352,1354,1356,1358,1360,1362,1365,1368,1371],{"class":75,"line":276},[73,1320,1321],{"class":83},"    m.once ",[73,1323,181],{"class":79},[73,1325,1326],{"class":83}," pyo.Constraint(",[73,1328,1236],{"class":103},[73,1330,429],{"class":83},[73,1332,110],{"class":103},[73,1334,1243],{"class":83},[73,1336,1337],{"class":302},"rule",[73,1339,1340],{"class":79},"=lambda",[73,1342,1343],{"class":83}," m, r: ",[73,1345,1346],{"class":103},"sum",[73,1348,1349],{"class":83},"(m.serve[s, r] ",[73,1351,417],{"class":79},[73,1353,479],{"class":83},[73,1355,423],{"class":79},[73,1357,426],{"class":103},[73,1359,429],{"class":83},[73,1361,104],{"class":103},[73,1363,1364],{"class":83},")) ",[73,1366,1367],{"class":79},"==",[73,1369,1370],{"class":103}," 1",[73,1372,471],{"class":83},[73,1374,1375,1378,1380,1382,1384,1386,1388,1390,1392,1394,1396,1398,1400,1402,1405,1408],{"class":75,"line":313},[73,1376,1377],{"class":83},"    m.only_open ",[73,1379,181],{"class":79},[73,1381,1326],{"class":83},[73,1383,1236],{"class":103},[73,1385,429],{"class":83},[73,1387,104],{"class":103},[73,1389,1243],{"class":83},[73,1391,1236],{"class":103},[73,1393,429],{"class":83},[73,1395,110],{"class":103},[73,1397,1243],{"class":83},[73,1399,1337],{"class":302},[73,1401,1340],{"class":79},[73,1403,1404],{"class":83}," m, s, r: m.serve[s, r] ",[73,1406,1407],{"class":79},"\u003C=",[73,1409,1410],{"class":83}," m.open[s])\n",[73,1412,1413,1416,1418,1420,1422,1424,1426,1428,1430,1432,1435,1438,1441],{"class":75,"line":340},[73,1414,1415],{"class":83},"    m.overflow ",[73,1417,181],{"class":79},[73,1419,1326],{"class":83},[73,1421,1236],{"class":103},[73,1423,429],{"class":83},[73,1425,104],{"class":103},[73,1427,1243],{"class":83},[73,1429,1337],{"class":302},[73,1431,1340],{"class":79},[73,1433,1434],{"class":83}," m, s: m.over[s] ",[73,1436,1437],{"class":79},">=",[73,1439,1440],{"class":103}," sum",[73,1442,1443],{"class":83},"(\n",[73,1445,1446,1449,1451,1454,1456,1459,1461,1463,1465,1467,1469,1471,1473,1475,1478,1480,1482,1484,1487,1489],{"class":75,"line":365},[73,1447,1448],{"class":83},"        net[",[73,1450,852],{"class":165},[73,1452,1453],{"class":83},"][r] ",[73,1455,828],{"class":79},[73,1457,1458],{"class":83}," m.serve[s, r] ",[73,1460,417],{"class":79},[73,1462,576],{"class":83},[73,1464,423],{"class":79},[73,1466,426],{"class":103},[73,1468,429],{"class":83},[73,1470,110],{"class":103},[73,1472,1364],{"class":83},[73,1474,291],{"class":79},[73,1476,1477],{"class":83}," margin ",[73,1479,828],{"class":79},[73,1481,868],{"class":83},[73,1483,1020],{"class":165},[73,1485,1486],{"class":83},"][s] ",[73,1488,828],{"class":79},[73,1490,1410],{"class":83},[73,1492,1493,1496,1498,1501,1504,1506,1509,1512,1514],{"class":75,"line":390},[73,1494,1495],{"class":83},"    m.cost ",[73,1497,181],{"class":79},[73,1499,1500],{"class":83}," pyo.Objective(",[73,1502,1503],{"class":302},"sense",[73,1505,181],{"class":79},[73,1507,1508],{"class":83},"pyo.minimize, ",[73,1510,1511],{"class":302},"expr",[73,1513,181],{"class":79},[73,1515,1443],{"class":83},[73,1517,1518,1521,1524,1526,1528,1530,1533,1535,1537,1539,1541,1543,1545],{"class":75,"line":396},[73,1519,1520],{"class":103},"        sum",[73,1522,1523],{"class":83},"(net[",[73,1525,1049],{"class":165},[73,1527,1486],{"class":83},[73,1529,828],{"class":79},[73,1531,1532],{"class":83}," m.open[s] ",[73,1534,417],{"class":79},[73,1536,479],{"class":83},[73,1538,423],{"class":79},[73,1540,426],{"class":103},[73,1542,429],{"class":83},[73,1544,104],{"class":103},[73,1546,264],{"class":83},[73,1548,1549,1552,1554,1556,1558,1560,1562,1564,1567,1569,1571,1573,1575,1577],{"class":75,"line":401},[73,1550,1551],{"class":79},"        +",[73,1553,1440],{"class":103},[73,1555,429],{"class":83},[73,1557,127],{"class":103},[73,1559,929],{"class":79},[73,1561,868],{"class":83},[73,1563,934],{"class":165},[73,1565,1566],{"class":83},"][s, r] ",[73,1568,828],{"class":79},[73,1570,868],{"class":83},[73,1572,852],{"class":165},[73,1574,1453],{"class":83},[73,1576,828],{"class":79},[73,1578,1579],{"class":83}," m.serve[s, r]\n",[73,1581,1582,1585,1587,1589,1591,1593,1595,1598,1600,1602,1604,1606,1608,1610],{"class":75,"line":406},[73,1583,1584],{"class":79},"              for",[73,1586,479],{"class":83},[73,1588,423],{"class":79},[73,1590,426],{"class":103},[73,1592,429],{"class":83},[73,1594,104],{"class":103},[73,1596,1597],{"class":83},") ",[73,1599,417],{"class":79},[73,1601,576],{"class":83},[73,1603,423],{"class":79},[73,1605,426],{"class":103},[73,1607,429],{"class":83},[73,1609,110],{"class":103},[73,1611,264],{"class":83},[73,1613,1614,1616,1618,1620,1622,1624,1626,1629,1631,1633,1635,1637,1639,1641],{"class":75,"line":438},[73,1615,1551],{"class":79},[73,1617,803],{"class":83},[73,1619,682],{"class":165},[73,1621,855],{"class":83},[73,1623,828],{"class":79},[73,1625,1440],{"class":103},[73,1627,1628],{"class":83},"(m.over[s] ",[73,1630,417],{"class":79},[73,1632,479],{"class":83},[73,1634,423],{"class":79},[73,1636,426],{"class":103},[73,1638,429],{"class":83},[73,1640,104],{"class":103},[73,1642,1643],{"class":83},"))))\n",[73,1645,1646,1649,1651,1654,1657],{"class":75,"line":443},[73,1647,1648],{"class":83},"    solver ",[73,1650,181],{"class":79},[73,1652,1653],{"class":83}," pyo.SolverFactory(",[73,1655,1656],{"class":165},"\"appsi_highs\"",[73,1658,471],{"class":83},[73,1660,1661,1664,1666],{"class":75,"line":460},[73,1662,1663],{"class":83},"    solver.config.mip_gap ",[73,1665,181],{"class":79},[73,1667,1668],{"class":103}," 0.0\n",[73,1670,1671,1674],{"class":75,"line":474},[73,1672,1673],{"class":79},"    assert",[73,1675,1676],{"class":83}," pyo.check_optimal_termination(solver.solve(m))\n",[73,1678,1679,1682,1684,1687,1690,1693,1695,1697,1699,1701,1703,1705],{"class":75,"line":493},[73,1680,1681],{"class":83},"    open_sites ",[73,1683,181],{"class":79},[73,1685,1686],{"class":83}," np.array([",[73,1688,1689],{"class":103},"round",[73,1691,1692],{"class":83},"(m.open[s].value) ",[73,1694,417],{"class":79},[73,1696,479],{"class":83},[73,1698,423],{"class":79},[73,1700,426],{"class":103},[73,1702,429],{"class":83},[73,1704,104],{"class":103},[73,1706,1707],{"class":83},")])\n",[73,1709,1710,1713,1715,1717,1720,1722,1724,1726,1728,1730,1733,1735,1738,1740,1742,1744,1746,1748,1750],{"class":75,"line":554},[73,1711,1712],{"class":83},"    serves ",[73,1714,181],{"class":79},[73,1716,1686],{"class":83},[73,1718,1719],{"class":103},"max",[73,1721,429],{"class":83},[73,1723,1236],{"class":103},[73,1725,429],{"class":83},[73,1727,104],{"class":103},[73,1729,1243],{"class":83},[73,1731,1732],{"class":302},"key",[73,1734,1340],{"class":79},[73,1736,1737],{"class":83}," s: m.serve[s, r].value) ",[73,1739,417],{"class":79},[73,1741,576],{"class":83},[73,1743,423],{"class":79},[73,1745,426],{"class":103},[73,1747,429],{"class":83},[73,1749,110],{"class":103},[73,1751,1707],{"class":83},[73,1753,1754,1756],{"class":75,"line":571},[73,1755,270],{"class":79},[73,1757,1758],{"class":83}," (open_sites, serves), pyo.value(m.cost)\n",[73,1760,1761],{"class":75,"line":589},[73,1762,97],{"emptyLinePlaceholder":96},[73,1764,1766],{"class":75,"line":1765},30,[73,1767,97],{"emptyLinePlaceholder":96},[73,1769,1771,1773,1776],{"class":75,"line":1770},31,[73,1772,152],{"class":79},[73,1774,1775],{"class":155}," describe",[73,1777,1778],{"class":83},"(plan):\n",[73,1780,1782,1784,1786],{"class":75,"line":1781},32,[73,1783,909],{"class":83},[73,1785,181],{"class":79},[73,1787,914],{"class":83},[73,1789,1791,1794,1796,1799,1802,1805,1808,1810,1812,1814,1816,1818,1820,1822,1825],{"class":75,"line":1790},33,[73,1792,1793],{"class":83},"    warehouses ",[73,1795,181],{"class":79},[73,1797,1798],{"class":165}," \", \"",[73,1800,1801],{"class":83},".join(",[73,1803,1804],{"class":103},"str",[73,1806,1807],{"class":83},"(s) ",[73,1809,417],{"class":79},[73,1811,479],{"class":83},[73,1813,423],{"class":79},[73,1815,426],{"class":103},[73,1817,429],{"class":83},[73,1819,104],{"class":103},[73,1821,1597],{"class":83},[73,1823,1824],{"class":79},"if",[73,1826,1827],{"class":83}," open_sites[s])\n",[73,1829,1831,1833,1836,1839,1841,1844,1846,1849,1851,1854,1856,1859,1861,1863,1866,1868],{"class":75,"line":1830},34,[73,1832,270],{"class":79},[73,1834,1835],{"class":79}," f",[73,1837,1838],{"class":165},"\"warehouses at sites ",[73,1840,507],{"class":103},[73,1842,1843],{"class":83},"warehouses",[73,1845,516],{"class":103},[73,1847,1848],{"class":165},"; regions 0-7 served from sites ",[73,1850,507],{"class":103},[73,1852,1853],{"class":165},"' '",[73,1855,1801],{"class":83},[73,1857,1858],{"class":103},"map",[73,1860,429],{"class":83},[73,1862,1804],{"class":103},[73,1864,1865],{"class":83},", serves))",[73,1867,516],{"class":103},[73,1869,1870],{"class":165},"\"\n",[73,1872,1874],{"class":75,"line":1873},35,[73,1875,97],{"emptyLinePlaceholder":96},[73,1877,1879],{"class":75,"line":1878},36,[73,1880,97],{"emptyLinePlaceholder":96},[73,1882,1884,1887,1889,1892,1894],{"class":75,"line":1883},37,[73,1885,1886],{"class":83},"plan, promised ",[73,1888,181],{"class":79},[73,1890,1891],{"class":83}," plan_for_forecast(",[73,1893,454],{"class":103},[73,1895,1896],{"class":83},", calm)\n",[73,1898,1900,1903,1905,1908,1910],{"class":75,"line":1899},38,[73,1901,1902],{"class":83},"real ",[73,1904,181],{"class":79},[73,1906,1907],{"class":83}," real_cost(",[73,1909,454],{"class":103},[73,1911,1912],{"class":83},", calm, plan)\n",[73,1914,1916,1918],{"class":75,"line":1915},39,[73,1917,463],{"class":103},[73,1919,1920],{"class":83},"(describe(plan))\n",[73,1922,1924,1926,1928,1930,1933,1935,1938,1941,1943,1945],{"class":75,"line":1923},40,[73,1925,463],{"class":103},[73,1927,429],{"class":83},[73,1929,501],{"class":79},[73,1931,1932],{"class":165},"\"cost the solver promises   ",[73,1934,507],{"class":103},[73,1936,1937],{"class":83},"promised",[73,1939,1940],{"class":79},":6,.0f",[73,1942,516],{"class":103},[73,1944,504],{"class":165},[73,1946,471],{"class":83},[73,1948,1950,1952,1954,1956,1959,1961,1964,1966,1968,1971,1973,1975,1978,1981,1983,1985,1988,1990,1993],{"class":75,"line":1949},41,[73,1951,463],{"class":103},[73,1953,429],{"class":83},[73,1955,501],{"class":79},[73,1957,1958],{"class":165},"\"real cost                  ",[73,1960,507],{"class":103},[73,1962,1963],{"class":83},"real",[73,1965,1940],{"class":79},[73,1967,516],{"class":103},[73,1969,1970],{"class":165},"   (",[73,1972,507],{"class":103},[73,1974,1902],{"class":83},[73,1976,1977],{"class":79},"\u002F",[73,1979,1980],{"class":83}," promised ",[73,1982,291],{"class":79},[73,1984,1370],{"class":103},[73,1986,1987],{"class":79},":+.1%",[73,1989,516],{"class":103},[73,1991,1992],{"class":165},")\"",[73,1994,471],{"class":83},[627,1996],{":lines":1997,"label":630},"[\"warehouses at sites 0, 1, 4; regions 0-7 served from sites 4 1 0 4 4 1 4 0\",\"cost the solver promises    5,998\",\"real cost                   6,589   (+9.8%)\"]",[11,1999,2000],{},"For network 11, the solver promises 5,998 a year. In the simulated years, the same plan costs 6,589, about 10% more. The swings around the forecast do not cancel out. Demand above the forecast overfills a warehouse and pays the overflow premium. Demand below the forecast only leaves space empty. So the average year costs more than the forecast year. Across all 20 networks in the calm market:",[63,2002,2004],{"className":65,"code":2003,"language":67,"meta":68,"style":68},"def median_and_worst(values):\n    return f\"median {np.median(values):+.1%}, worst {np.max(values):+.1%}\"\n\n\nabove_promise = []\nfor number in range(20):\n    plan, promised = plan_for_forecast(number, calm)\n    above_promise.append(real_cost(number, calm, plan) \u002F promised - 1)\nprint(\"real cost above the promise:\", median_and_worst(above_promise))\n",[70,2005,2006,2016,2048,2052,2056,2066,2082,2092,2107],{"__ignoreMap":68},[73,2007,2008,2010,2013],{"class":75,"line":76},[73,2009,152],{"class":79},[73,2011,2012],{"class":155}," median_and_worst",[73,2014,2015],{"class":83},"(values):\n",[73,2017,2018,2020,2022,2025,2027,2030,2032,2034,2037,2039,2042,2044,2046],{"class":75,"line":93},[73,2019,270],{"class":79},[73,2021,1835],{"class":79},[73,2023,2024],{"class":165},"\"median ",[73,2026,507],{"class":103},[73,2028,2029],{"class":83},"np.median(values)",[73,2031,1987],{"class":79},[73,2033,516],{"class":103},[73,2035,2036],{"class":165},", worst ",[73,2038,507],{"class":103},[73,2040,2041],{"class":83},"np.max(values)",[73,2043,1987],{"class":79},[73,2045,516],{"class":103},[73,2047,1870],{"class":165},[73,2049,2050],{"class":75,"line":100},[73,2051,97],{"emptyLinePlaceholder":96},[73,2053,2054],{"class":75,"line":124},[73,2055,97],{"emptyLinePlaceholder":96},[73,2057,2058,2061,2063],{"class":75,"line":139},[73,2059,2060],{"class":83},"above_promise ",[73,2062,181],{"class":79},[73,2064,2065],{"class":83}," []\n",[73,2067,2068,2070,2072,2074,2076,2078,2080],{"class":75,"line":144},[73,2069,417],{"class":79},[73,2071,420],{"class":83},[73,2073,423],{"class":79},[73,2075,426],{"class":103},[73,2077,429],{"class":83},[73,2079,432],{"class":103},[73,2081,490],{"class":83},[73,2083,2084,2087,2089],{"class":75,"line":149},[73,2085,2086],{"class":83},"    plan, promised ",[73,2088,181],{"class":79},[73,2090,2091],{"class":83}," plan_for_forecast(number, calm)\n",[73,2093,2094,2097,2099,2101,2103,2105],{"class":75,"line":162},[73,2095,2096],{"class":83},"    above_promise.append(real_cost(number, calm, plan) ",[73,2098,1977],{"class":79},[73,2100,1980],{"class":83},[73,2102,291],{"class":79},[73,2104,1370],{"class":103},[73,2106,471],{"class":83},[73,2108,2109,2111,2113,2116],{"class":75,"line":169},[73,2110,463],{"class":103},[73,2112,429],{"class":83},[73,2114,2115],{"class":165},"\"real cost above the promise:\"",[73,2117,2118],{"class":83},", median_and_worst(above_promise))\n",[627,2120],{":lines":2121,"label":630},"[\"real cost above the promise: median +6.4%, worst +12.3%\"]",[36,2123,2125],{"id":2124},"a-safety-margin","A safety margin",[11,2127,2128],{},"Planners know this, and they keep a safety margin. In the MILP, a margin means counting each warehouse as smaller than it is. When it plans to 95% of capacity, the MILP treats anything above 95% as overflow and prices it that way. For network 11:",[63,2130,2132],{"className":65,"code":2131,"language":67,"meta":68,"style":68},"MARGINS = [1.0, 0.95, 0.90, 0.85, 0.80]\n\nfor margin in MARGINS:\n    plan, _ = plan_for_forecast(11, calm, margin)\n    print(f\"plan to {margin:4.0%} of capacity: real cost {real_cost(11, calm, plan):6,.0f}   {describe(plan)}\")\n",[70,2133,2134,2168,2172,2186,2200],{"__ignoreMap":68},[73,2135,2136,2139,2141,2144,2146,2148,2151,2153,2156,2158,2161,2163,2166],{"class":75,"line":76},[73,2137,2138],{"class":103},"MARGINS",[73,2140,113],{"class":79},[73,2142,2143],{"class":83}," [",[73,2145,1183],{"class":103},[73,2147,107],{"class":83},[73,2149,2150],{"class":103},"0.95",[73,2152,107],{"class":83},[73,2154,2155],{"class":103},"0.90",[73,2157,107],{"class":83},[73,2159,2160],{"class":103},"0.85",[73,2162,107],{"class":83},[73,2164,2165],{"class":103},"0.80",[73,2167,457],{"class":83},[73,2169,2170],{"class":75,"line":93},[73,2171,97],{"emptyLinePlaceholder":96},[73,2173,2174,2176,2178,2180,2183],{"class":75,"line":100},[73,2175,417],{"class":79},[73,2177,1477],{"class":83},[73,2179,423],{"class":79},[73,2181,2182],{"class":103}," MARGINS",[73,2184,2185],{"class":83},":\n",[73,2187,2188,2191,2193,2195,2197],{"class":75,"line":124},[73,2189,2190],{"class":83},"    plan, _ ",[73,2192,181],{"class":79},[73,2194,1891],{"class":83},[73,2196,454],{"class":103},[73,2198,2199],{"class":83},", calm, margin)\n",[73,2201,2202,2204,2206,2208,2211,2213,2216,2219,2221,2224,2226,2229,2231,2234,2236,2238,2241,2244,2246,2248],{"class":75,"line":139},[73,2203,496],{"class":103},[73,2205,429],{"class":83},[73,2207,501],{"class":79},[73,2209,2210],{"class":165},"\"plan to ",[73,2212,507],{"class":103},[73,2214,2215],{"class":83},"margin",[73,2217,2218],{"class":79},":4.0%",[73,2220,516],{"class":103},[73,2222,2223],{"class":165}," of capacity: real cost ",[73,2225,507],{"class":103},[73,2227,2228],{"class":83},"real_cost(",[73,2230,454],{"class":103},[73,2232,2233],{"class":83},", calm, plan)",[73,2235,1940],{"class":79},[73,2237,516],{"class":103},[73,2239,2240],{"class":103},"   {",[73,2242,2243],{"class":83},"describe(plan)",[73,2245,516],{"class":103},[73,2247,504],{"class":165},[73,2249,471],{"class":83},[627,2251],{":lines":2252,"label":630},"[\"plan to 100% of capacity: real cost  6,589   warehouses at sites 0, 1, 4; regions 0-7 served from sites 4 1 0 4 4 1 4 0\",\"plan to  95% of capacity: real cost  6,312   warehouses at sites 1, 2, 4; regions 0-7 served from sites 4 1 2 4 4 1 4 2\",\"plan to  90% of capacity: real cost  6,500   warehouses at sites 0, 2, 4; regions 0-7 served from sites 0 4 2 0 4 4 0 2\",\"plan to  85% of capacity: real cost  6,510   warehouses at sites 0, 1, 2, 4; regions 0-7 served from sites 0 1 2 4 4 4 1 0\",\"plan to  80% of capacity: real cost  6,572   warehouses at sites 0, 1, 2, 4; regions 0-7 served from sites 0 1 2 4 4 4 2 0\"]",[11,2254,2255],{},"A 95% margin cuts network 11's real cost from 6,589 to 6,312. Wider margins cost more again, because they reserve space that is rarely used. Which margin is cheapest differs from network to network:",[63,2257,2259],{"className":65,"code":2258,"language":67,"meta":68,"style":68},"cheapest = {margin: 0 for margin in MARGINS}\nfor number in range(20):\n    costs = {margin: real_cost(number, calm, plan_for_forecast(number, calm, margin)[0]) for margin in MARGINS}\n    for margin, cost in costs.items():\n        if cost \u003C= min(costs.values()) * (1 + 1e-9):      # two margins that give the same plan both count\n            cheapest[margin] += 1\nfor margin, count in cheapest.items():\n    print(f\"plan to {margin:4.0%} of capacity is cheapest in {count:2} of 20 networks\")\n",[70,2260,2261,2284,2300,2325,2337,2371,2381,2393],{"__ignoreMap":68},[73,2262,2263,2266,2268,2271,2273,2276,2278,2280,2282],{"class":75,"line":76},[73,2264,2265],{"class":83},"cheapest ",[73,2267,181],{"class":79},[73,2269,2270],{"class":83}," {margin: ",[73,2272,198],{"class":103},[73,2274,2275],{"class":79}," for",[73,2277,1477],{"class":83},[73,2279,423],{"class":79},[73,2281,2182],{"class":103},[73,2283,690],{"class":83},[73,2285,2286,2288,2290,2292,2294,2296,2298],{"class":75,"line":93},[73,2287,417],{"class":79},[73,2289,420],{"class":83},[73,2291,423],{"class":79},[73,2293,426],{"class":103},[73,2295,429],{"class":83},[73,2297,432],{"class":103},[73,2299,490],{"class":83},[73,2301,2302,2305,2307,2310,2312,2315,2317,2319,2321,2323],{"class":75,"line":100},[73,2303,2304],{"class":83},"    costs ",[73,2306,181],{"class":79},[73,2308,2309],{"class":83}," {margin: real_cost(number, calm, plan_for_forecast(number, calm, margin)[",[73,2311,198],{"class":103},[73,2313,2314],{"class":83},"]) ",[73,2316,417],{"class":79},[73,2318,1477],{"class":83},[73,2320,423],{"class":79},[73,2322,2182],{"class":103},[73,2324,690],{"class":83},[73,2326,2327,2329,2332,2334],{"class":75,"line":124},[73,2328,980],{"class":79},[73,2330,2331],{"class":83}," margin, cost ",[73,2333,423],{"class":79},[73,2335,2336],{"class":83}," costs.items():\n",[73,2338,2339,2342,2345,2347,2350,2353,2355,2357,2359,2362,2365,2368],{"class":75,"line":139},[73,2340,2341],{"class":79},"        if",[73,2343,2344],{"class":83}," cost ",[73,2346,1407],{"class":79},[73,2348,2349],{"class":103}," min",[73,2351,2352],{"class":83},"(costs.values()) ",[73,2354,828],{"class":79},[73,2356,924],{"class":83},[73,2358,788],{"class":103},[73,2360,2361],{"class":79}," +",[73,2363,2364],{"class":103}," 1e-9",[73,2366,2367],{"class":83},"):      ",[73,2369,2370],{"class":135},"# two margins that give the same plan both count\n",[73,2372,2373,2376,2378],{"class":75,"line":144},[73,2374,2375],{"class":83},"            cheapest[margin] ",[73,2377,1000],{"class":79},[73,2379,2380],{"class":103}," 1\n",[73,2382,2383,2385,2388,2390],{"class":75,"line":149},[73,2384,417],{"class":79},[73,2386,2387],{"class":83}," margin, count ",[73,2389,423],{"class":79},[73,2391,2392],{"class":83}," cheapest.items():\n",[73,2394,2395,2397,2399,2401,2403,2405,2407,2409,2411,2414,2416,2419,2422,2424,2427],{"class":75,"line":162},[73,2396,496],{"class":103},[73,2398,429],{"class":83},[73,2400,501],{"class":79},[73,2402,2210],{"class":165},[73,2404,507],{"class":103},[73,2406,2215],{"class":83},[73,2408,2218],{"class":79},[73,2410,516],{"class":103},[73,2412,2413],{"class":165}," of capacity is cheapest in ",[73,2415,507],{"class":103},[73,2417,2418],{"class":83},"count",[73,2420,2421],{"class":79},":2",[73,2423,516],{"class":103},[73,2425,2426],{"class":165}," of 20 networks\"",[73,2428,471],{"class":83},[627,2430],{":lines":2431,"label":630},"[\"plan to 100% of capacity is cheapest in  9 of 20 networks\",\"plan to  95% of capacity is cheapest in 14 of 20 networks\",\"plan to  90% of capacity is cheapest in 10 of 20 networks\",\"plan to  85% of capacity is cheapest in  3 of 20 networks\",\"plan to  80% of capacity is cheapest in  1 of 20 networks\"]",[11,2433,2434],{},"Where two margins give the same plan, both count. The forecast does not tell you which margin fits a network. You find out by simulating, or after years of running that network.",[36,2436,2438],{"id":2437},"planning-with-the-forecast-error","Planning with the forecast error",[11,2440,2441],{},"Quicopt takes the forecast error into the problem. You write the same cost as in the MILP, with one change: each region's demand is a random number around its forecast. Quicopt draws 1,000 years from it and chooses the network with the lowest average cost over those years.",[11,2443,2444,2445,2448,2449,2452],{},"Two things in the model below differ from the MILP. The network is a split of the eight regions among the five sites (",[70,2446,2447],{},"partition","). Each region belongs to exactly one site's part, and a site costs its fixed fee as soon as its part is not empty. Overflow is written as what it is, ",[70,2450,2451],{},"maximum(load - capacity, 0)"," in every simulated year.",[11,2454,2455,2456,2459],{},"In the turned market the regions share part of their swing. The model states that as one more random number, ",[70,2457,2458],{},"market",", which moves every region's demand at once.",[63,2461,2463],{"className":65,"code":2462,"language":67,"meta":68,"style":68},"from quicopt import Client\nfrom quicopt.stochastic import Normal, set_distribution, set_scenarios, expectation, maximum\nfrom quicopt.structured import partition, lookup_table\n\nclient = Client()\n\n\ndef plan_with_quicopt(number, market):\n    \"\"\"The network with the lowest average cost over 1,000 years that Quicopt draws\n    from the forecast and its error. Returns the plan and Quicopt's estimate of\n    its cost.\"\"\"\n    net = networks[number]\n    rho = market[\"correlation\"]\n    spread = market[\"error\"] * net[\"forecast\"]\n    m = pyo.ConcreteModel()\n    set_scenarios(m, 1000, seed=7)\n    split = partition(m, \"network\", REGIONS, SITES)      # region r is served by site part_of(r)\n    m.demand = pyo.Var(range(REGIONS))                   # each region's own swing around its forecast\n    for r in range(REGIONS):\n        set_distribution(m, m.demand[r], Normal(net[\"forecast\"][r], np.sqrt(1 - rho) * spread[r]),\n                         name=f\"demand_{r}\")\n    demand = [m.demand[r] for r in range(REGIONS)]\n    if rho > 0:\n        m.market = pyo.Var()                             # the swing all regions share\n        set_distribution(m, m.market, Normal(0.0, 1.0), name=\"market\")\n        demand = [demand[r] + float(np.sqrt(rho) * spread[r]) * m.market for r in range(REGIONS)]\n    freight = lookup_table(m, \"freight\", (TRANSPORT * net[\"distance\"]).tolist())   # per pallet, [site][region]\n    site = [split.part_of(r) for r in range(REGIONS)]\n    load = [sum(pyo.Expr_if(IF=site[r] == s, THEN=demand[r], ELSE=0.0) for r in range(REGIONS))\n            for s in range(SITES)]\n    cost = (sum(pyo.Expr_if(IF=split.size_of(s) >= 1, THEN=net[\"fixed_cost\"][s], ELSE=0.0) for s in range(SITES))\n            + sum(freight[site[r], r] * demand[r] for r in range(REGIONS))\n            + sum(market[\"overflow\"] * maximum(load[s] - net[\"capacity\"][s], 0.0) for s in range(SITES)))\n    m.cost = pyo.Objective(expr=expectation(cost), sense=pyo.minimize)\n    result = client.solve(m)\n    assert result.feasible\n    found = result.structures[\"network\"]\n    return (np.array([int(n >= 1) for n in found.size_of]), np.array(found.part_of)), result.objective\n\n\nplan, estimate = plan_with_quicopt(11, calm)\nreal = real_cost(11, calm, plan)\nprint(describe(plan))\nprint(f\"Quicopt's estimate   {estimate:6,.0f}\")\nprint(f\"real cost            {real:6,.0f}   ({real \u002F estimate - 1:+.1%})\")\n",[70,2464,2465,2478,2490,2502,2506,2516,2520,2524,2534,2539,2544,2549,2557,2569,2590,2598,2617,2644,2665,2681,2702,2724,2748,2764,2776,2799,2841,2871,2895,2952,2969,3029,3058,3103,3125,3135,3142,3156,3185,3189,3193,3207,3220,3227,3252],{"__ignoreMap":68},[73,2466,2467,2470,2473,2475],{"class":75,"line":76},[73,2468,2469],{"class":79},"from",[73,2471,2472],{"class":83}," quicopt ",[73,2474,80],{"class":79},[73,2476,2477],{"class":83}," Client\n",[73,2479,2480,2482,2485,2487],{"class":75,"line":93},[73,2481,2469],{"class":79},[73,2483,2484],{"class":83}," quicopt.stochastic ",[73,2486,80],{"class":79},[73,2488,2489],{"class":83}," Normal, set_distribution, set_scenarios, expectation, maximum\n",[73,2491,2492,2494,2497,2499],{"class":75,"line":100},[73,2493,2469],{"class":79},[73,2495,2496],{"class":83}," quicopt.structured ",[73,2498,80],{"class":79},[73,2500,2501],{"class":83}," partition, lookup_table\n",[73,2503,2504],{"class":75,"line":124},[73,2505,97],{"emptyLinePlaceholder":96},[73,2507,2508,2511,2513],{"class":75,"line":139},[73,2509,2510],{"class":83},"client ",[73,2512,181],{"class":79},[73,2514,2515],{"class":83}," Client()\n",[73,2517,2518],{"class":75,"line":144},[73,2519,97],{"emptyLinePlaceholder":96},[73,2521,2522],{"class":75,"line":149},[73,2523,97],{"emptyLinePlaceholder":96},[73,2525,2526,2528,2531],{"class":75,"line":162},[73,2527,152],{"class":79},[73,2529,2530],{"class":155}," plan_with_quicopt",[73,2532,2533],{"class":83},"(number, market):\n",[73,2535,2536],{"class":75,"line":169},[73,2537,2538],{"class":165},"    \"\"\"The network with the lowest average cost over 1,000 years that Quicopt draws\n",[73,2540,2541],{"class":75,"line":175},[73,2542,2543],{"class":165},"    from the forecast and its error. Returns the plan and Quicopt's estimate of\n",[73,2545,2546],{"class":75,"line":187},[73,2547,2548],{"class":165},"    its cost.\"\"\"\n",[73,2550,2551,2553,2555],{"class":75,"line":232},[73,2552,1103],{"class":83},[73,2554,181],{"class":79},[73,2556,1108],{"class":83},[73,2558,2559,2561,2563,2565,2567],{"class":75,"line":267},[73,2560,798],{"class":83},[73,2562,181],{"class":79},[73,2564,803],{"class":83},[73,2566,672],{"class":165},[73,2568,457],{"class":83},[73,2570,2571,2574,2576,2578,2580,2582,2584,2586,2588],{"class":75,"line":276},[73,2572,2573],{"class":83},"    spread ",[73,2575,181],{"class":79},[73,2577,803],{"class":83},[73,2579,661],{"class":165},[73,2581,855],{"class":83},[73,2583,828],{"class":79},[73,2585,868],{"class":83},[73,2587,852],{"class":165},[73,2589,457],{"class":83},[73,2591,2592,2594,2596],{"class":75,"line":313},[73,2593,1218],{"class":83},[73,2595,181],{"class":79},[73,2597,1223],{"class":83},[73,2599,2600,2603,2606,2608,2610,2612,2615],{"class":75,"line":340},[73,2601,2602],{"class":83},"    set_scenarios(m, ",[73,2604,2605],{"class":103},"1000",[73,2607,107],{"class":83},[73,2609,1123],{"class":302},[73,2611,181],{"class":79},[73,2613,2614],{"class":103},"7",[73,2616,471],{"class":83},[73,2618,2619,2622,2624,2627,2630,2632,2634,2636,2638,2641],{"class":75,"line":365},[73,2620,2621],{"class":83},"    split ",[73,2623,181],{"class":79},[73,2625,2626],{"class":83}," partition(m, ",[73,2628,2629],{"class":165},"\"network\"",[73,2631,107],{"class":83},[73,2633,110],{"class":103},[73,2635,107],{"class":83},[73,2637,104],{"class":103},[73,2639,2640],{"class":83},")      ",[73,2642,2643],{"class":135},"# region r is served by site part_of(r)\n",[73,2645,2646,2649,2651,2653,2655,2657,2659,2662],{"class":75,"line":390},[73,2647,2648],{"class":83},"    m.demand ",[73,2650,181],{"class":79},[73,2652,1233],{"class":83},[73,2654,1236],{"class":103},[73,2656,429],{"class":83},[73,2658,110],{"class":103},[73,2660,2661],{"class":83},"))                   ",[73,2663,2664],{"class":135},"# each region's own swing around its forecast\n",[73,2666,2667,2669,2671,2673,2675,2677,2679],{"class":75,"line":396},[73,2668,980],{"class":79},[73,2670,576],{"class":83},[73,2672,423],{"class":79},[73,2674,426],{"class":103},[73,2676,429],{"class":83},[73,2678,110],{"class":103},[73,2680,490],{"class":83},[73,2682,2683,2686,2688,2691,2693,2695,2697,2699],{"class":75,"line":401},[73,2684,2685],{"class":83},"        set_distribution(m, m.demand[r], Normal(net[",[73,2687,852],{"class":165},[73,2689,2690],{"class":83},"][r], np.sqrt(",[73,2692,788],{"class":103},[73,2694,822],{"class":79},[73,2696,825],{"class":83},[73,2698,828],{"class":79},[73,2700,2701],{"class":83}," spread[r]),\n",[73,2703,2704,2707,2709,2711,2714,2716,2718,2720,2722],{"class":75,"line":406},[73,2705,2706],{"class":302},"                         name",[73,2708,181],{"class":79},[73,2710,501],{"class":79},[73,2712,2713],{"class":165},"\"demand_",[73,2715,507],{"class":103},[73,2717,602],{"class":83},[73,2719,516],{"class":103},[73,2721,504],{"class":165},[73,2723,471],{"class":83},[73,2725,2726,2729,2731,2734,2736,2738,2740,2742,2744,2746],{"class":75,"line":438},[73,2727,2728],{"class":83},"    demand ",[73,2730,181],{"class":79},[73,2732,2733],{"class":83}," [m.demand[r] ",[73,2735,417],{"class":79},[73,2737,576],{"class":83},[73,2739,423],{"class":79},[73,2741,426],{"class":103},[73,2743,429],{"class":83},[73,2745,110],{"class":103},[73,2747,435],{"class":83},[73,2749,2750,2753,2756,2759,2762],{"class":75,"line":443},[73,2751,2752],{"class":79},"    if",[73,2754,2755],{"class":83}," rho ",[73,2757,2758],{"class":79},">",[73,2760,2761],{"class":103}," 0",[73,2763,2185],{"class":83},[73,2765,2766,2769,2771,2774],{"class":75,"line":460},[73,2767,2768],{"class":83},"        m.market ",[73,2770,181],{"class":79},[73,2772,2773],{"class":83}," pyo.Var()                             ",[73,2775,793],{"class":135},[73,2777,2778,2781,2783,2785,2787,2789,2792,2794,2797],{"class":75,"line":474},[73,2779,2780],{"class":83},"        set_distribution(m, m.market, Normal(",[73,2782,677],{"class":103},[73,2784,107],{"class":83},[73,2786,1183],{"class":103},[73,2788,1243],{"class":83},[73,2790,2791],{"class":302},"name",[73,2793,181],{"class":79},[73,2795,2796],{"class":165},"\"market\"",[73,2798,471],{"class":83},[73,2800,2801,2804,2806,2809,2811,2814,2817,2819,2822,2824,2827,2829,2831,2833,2835,2837,2839],{"class":75,"line":493},[73,2802,2803],{"class":83},"        demand ",[73,2805,181],{"class":79},[73,2807,2808],{"class":83}," [demand[r] ",[73,2810,834],{"class":79},[73,2812,2813],{"class":103}," float",[73,2815,2816],{"class":83},"(np.sqrt(rho) ",[73,2818,828],{"class":79},[73,2820,2821],{"class":83}," spread[r]) ",[73,2823,828],{"class":79},[73,2825,2826],{"class":83}," m.market ",[73,2828,417],{"class":79},[73,2830,576],{"class":83},[73,2832,423],{"class":79},[73,2834,426],{"class":103},[73,2836,429],{"class":83},[73,2838,110],{"class":103},[73,2840,435],{"class":83},[73,2842,2843,2846,2848,2851,2854,2857,2859,2861,2863,2865,2868],{"class":75,"line":554},[73,2844,2845],{"class":83},"    freight ",[73,2847,181],{"class":79},[73,2849,2850],{"class":83}," lookup_table(m, ",[73,2852,2853],{"class":165},"\"freight\"",[73,2855,2856],{"class":83},", (",[73,2858,127],{"class":103},[73,2860,929],{"class":79},[73,2862,868],{"class":83},[73,2864,934],{"class":165},[73,2866,2867],{"class":83},"]).tolist())   ",[73,2869,2870],{"class":135},"# per pallet, [site][region]\n",[73,2872,2873,2876,2878,2881,2883,2885,2887,2889,2891,2893],{"class":75,"line":571},[73,2874,2875],{"class":83},"    site ",[73,2877,181],{"class":79},[73,2879,2880],{"class":83}," [split.part_of(r) ",[73,2882,417],{"class":79},[73,2884,576],{"class":83},[73,2886,423],{"class":79},[73,2888,426],{"class":103},[73,2890,429],{"class":83},[73,2892,110],{"class":103},[73,2894,435],{"class":83},[73,2896,2897,2899,2901,2903,2905,2908,2911,2913,2916,2918,2921,2924,2926,2929,2932,2934,2936,2938,2940,2942,2944,2946,2948,2950],{"class":75,"line":589},[73,2898,960],{"class":83},[73,2900,181],{"class":79},[73,2902,2143],{"class":83},[73,2904,1346],{"class":103},[73,2906,2907],{"class":83},"(pyo.Expr_if(",[73,2909,2910],{"class":302},"IF",[73,2912,181],{"class":79},[73,2914,2915],{"class":83},"site[r] ",[73,2917,1367],{"class":79},[73,2919,2920],{"class":83}," s, ",[73,2922,2923],{"class":302},"THEN",[73,2925,181],{"class":79},[73,2927,2928],{"class":83},"demand[r], ",[73,2930,2931],{"class":302},"ELSE",[73,2933,181],{"class":79},[73,2935,677],{"class":103},[73,2937,1597],{"class":83},[73,2939,417],{"class":79},[73,2941,576],{"class":83},[73,2943,423],{"class":79},[73,2945,426],{"class":103},[73,2947,429],{"class":83},[73,2949,110],{"class":103},[73,2951,264],{"class":83},[73,2953,2954,2957,2959,2961,2963,2965,2967],{"class":75,"line":1765},[73,2955,2956],{"class":79},"            for",[73,2958,479],{"class":83},[73,2960,423],{"class":79},[73,2962,426],{"class":103},[73,2964,429],{"class":83},[73,2966,104],{"class":103},[73,2968,435],{"class":83},[73,2970,2971,2974,2976,2978,2980,2982,2984,2986,2989,2991,2993,2995,2997,2999,3002,3004,3007,3009,3011,3013,3015,3017,3019,3021,3023,3025,3027],{"class":75,"line":1770},[73,2972,2973],{"class":83},"    cost ",[73,2975,181],{"class":79},[73,2977,924],{"class":83},[73,2979,1346],{"class":103},[73,2981,2907],{"class":83},[73,2983,2910],{"class":302},[73,2985,181],{"class":79},[73,2987,2988],{"class":83},"split.size_of(s) ",[73,2990,1437],{"class":79},[73,2992,1370],{"class":103},[73,2994,107],{"class":83},[73,2996,2923],{"class":302},[73,2998,181],{"class":79},[73,3000,3001],{"class":83},"net[",[73,3003,1049],{"class":165},[73,3005,3006],{"class":83},"][s], ",[73,3008,2931],{"class":302},[73,3010,181],{"class":79},[73,3012,677],{"class":103},[73,3014,1597],{"class":83},[73,3016,417],{"class":79},[73,3018,479],{"class":83},[73,3020,423],{"class":79},[73,3022,426],{"class":103},[73,3024,429],{"class":83},[73,3026,104],{"class":103},[73,3028,264],{"class":83},[73,3030,3031,3034,3036,3039,3041,3044,3046,3048,3050,3052,3054,3056],{"class":75,"line":1781},[73,3032,3033],{"class":79},"            +",[73,3035,1440],{"class":103},[73,3037,3038],{"class":83},"(freight[site[r], r] ",[73,3040,828],{"class":79},[73,3042,3043],{"class":83}," demand[r] ",[73,3045,417],{"class":79},[73,3047,576],{"class":83},[73,3049,423],{"class":79},[73,3051,426],{"class":103},[73,3053,429],{"class":83},[73,3055,110],{"class":103},[73,3057,264],{"class":83},[73,3059,3060,3062,3064,3067,3069,3071,3073,3076,3078,3080,3082,3084,3086,3088,3090,3092,3094,3096,3098,3100],{"class":75,"line":1790},[73,3061,3033],{"class":79},[73,3063,1440],{"class":103},[73,3065,3066],{"class":83},"(market[",[73,3068,682],{"class":165},[73,3070,855],{"class":83},[73,3072,828],{"class":79},[73,3074,3075],{"class":83}," maximum(load[s] ",[73,3077,291],{"class":79},[73,3079,868],{"class":83},[73,3081,1020],{"class":165},[73,3083,3006],{"class":83},[73,3085,677],{"class":103},[73,3087,1597],{"class":83},[73,3089,417],{"class":79},[73,3091,479],{"class":83},[73,3093,423],{"class":79},[73,3095,426],{"class":103},[73,3097,429],{"class":83},[73,3099,104],{"class":103},[73,3101,3102],{"class":83},")))\n",[73,3104,3105,3107,3109,3111,3113,3115,3118,3120,3122],{"class":75,"line":1830},[73,3106,1495],{"class":83},[73,3108,181],{"class":79},[73,3110,1500],{"class":83},[73,3112,1511],{"class":302},[73,3114,181],{"class":79},[73,3116,3117],{"class":83},"expectation(cost), ",[73,3119,1503],{"class":302},[73,3121,181],{"class":79},[73,3123,3124],{"class":83},"pyo.minimize)\n",[73,3126,3127,3130,3132],{"class":75,"line":1873},[73,3128,3129],{"class":83},"    result ",[73,3131,181],{"class":79},[73,3133,3134],{"class":83}," client.solve(m)\n",[73,3136,3137,3139],{"class":75,"line":1878},[73,3138,1673],{"class":79},[73,3140,3141],{"class":83}," result.feasible\n",[73,3143,3144,3147,3149,3152,3154],{"class":75,"line":1883},[73,3145,3146],{"class":83},"    found ",[73,3148,181],{"class":79},[73,3150,3151],{"class":83}," result.structures[",[73,3153,2629],{"class":165},[73,3155,457],{"class":83},[73,3157,3158,3160,3163,3166,3169,3171,3173,3175,3177,3180,3182],{"class":75,"line":1899},[73,3159,270],{"class":79},[73,3161,3162],{"class":83}," (np.array([",[73,3164,3165],{"class":103},"int",[73,3167,3168],{"class":83},"(n ",[73,3170,1437],{"class":79},[73,3172,1370],{"class":103},[73,3174,1597],{"class":83},[73,3176,417],{"class":79},[73,3178,3179],{"class":83}," n ",[73,3181,423],{"class":79},[73,3183,3184],{"class":83}," found.size_of]), np.array(found.part_of)), result.objective\n",[73,3186,3187],{"class":75,"line":1915},[73,3188,97],{"emptyLinePlaceholder":96},[73,3190,3191],{"class":75,"line":1923},[73,3192,97],{"emptyLinePlaceholder":96},[73,3194,3195,3198,3200,3203,3205],{"class":75,"line":1949},[73,3196,3197],{"class":83},"plan, estimate ",[73,3199,181],{"class":79},[73,3201,3202],{"class":83}," plan_with_quicopt(",[73,3204,454],{"class":103},[73,3206,1896],{"class":83},[73,3208,3210,3212,3214,3216,3218],{"class":75,"line":3209},42,[73,3211,1902],{"class":83},[73,3213,181],{"class":79},[73,3215,1907],{"class":83},[73,3217,454],{"class":103},[73,3219,1912],{"class":83},[73,3221,3223,3225],{"class":75,"line":3222},43,[73,3224,463],{"class":103},[73,3226,1920],{"class":83},[73,3228,3230,3232,3234,3236,3239,3241,3244,3246,3248,3250],{"class":75,"line":3229},44,[73,3231,463],{"class":103},[73,3233,429],{"class":83},[73,3235,501],{"class":79},[73,3237,3238],{"class":165},"\"Quicopt's estimate   ",[73,3240,507],{"class":103},[73,3242,3243],{"class":83},"estimate",[73,3245,1940],{"class":79},[73,3247,516],{"class":103},[73,3249,504],{"class":165},[73,3251,471],{"class":83},[73,3253,3255,3257,3259,3261,3264,3266,3268,3270,3272,3274,3276,3278,3280,3283,3285,3287,3289,3291,3293],{"class":75,"line":3254},45,[73,3256,463],{"class":103},[73,3258,429],{"class":83},[73,3260,501],{"class":79},[73,3262,3263],{"class":165},"\"real cost            ",[73,3265,507],{"class":103},[73,3267,1963],{"class":83},[73,3269,1940],{"class":79},[73,3271,516],{"class":103},[73,3273,1970],{"class":165},[73,3275,507],{"class":103},[73,3277,1902],{"class":83},[73,3279,1977],{"class":79},[73,3281,3282],{"class":83}," estimate ",[73,3284,291],{"class":79},[73,3286,1370],{"class":103},[73,3288,1987],{"class":79},[73,3290,516],{"class":103},[73,3292,1992],{"class":165},[73,3294,471],{"class":83},[627,3296],{":lines":3297,"label":630},"[\"warehouses at sites 0, 1, 2, 4; regions 0-7 served from sites 0 1 2 4 4 1 4 0\",\"Quicopt's estimate    6,366\",\"real cost             6,361   (-0.1%)\"]",[11,3299,3300],{},"Quicopt's estimate of 6,366 matches the real cost of 6,361 to within 0.1%. In network 11, the 95% margin does slightly better (6,312), because Quicopt runs one warehouse more than it needs here. Across all 20 networks in the calm market, here is what each margin costs on top of Quicopt's plan:",[63,3302,3304],{"className":65,"code":3303,"language":67,"meta":68,"style":68},"def compare(market):\n    \"\"\"What each margin costs on top of Quicopt's plan, over all 20 networks, and\n    how far Quicopt's real cost lies from its estimate.\"\"\"\n    quicopt_real, real_off = [], []\n    for number in range(20):\n        plan, estimate = plan_with_quicopt(number, market)\n        quicopt_real.append(real_cost(number, market, plan))\n        real_off.append(quicopt_real[-1] \u002F estimate - 1)\n    extra = {}\n    for margin in MARGINS:\n        extra[margin] = [real_cost(number, market, plan_for_forecast(number, market, margin)[0]) \u002F quicopt_real[number] - 1\n                         for number in range(20)]\n        label = \"plan for the forecast\" if margin == 1 else f\"plan to {margin:.0%} of capacity\"\n        print(f\"{label:24}  {median_and_worst(extra[margin])}\")\n    print(f\"\\nQuicopt's real cost against its estimate: from {min(real_off):+.1%} to {max(real_off):+.1%}\")\n    return extra\n\n\ncalm_extra = compare(calm)\n",[70,3305,3306,3316,3321,3326,3336,3352,3362,3367,3388,3398,3410,3433,3450,3488,3520,3561,3568,3572,3576],{"__ignoreMap":68},[73,3307,3308,3310,3313],{"class":75,"line":76},[73,3309,152],{"class":79},[73,3311,3312],{"class":155}," compare",[73,3314,3315],{"class":83},"(market):\n",[73,3317,3318],{"class":75,"line":93},[73,3319,3320],{"class":165},"    \"\"\"What each margin costs on top of Quicopt's plan, over all 20 networks, and\n",[73,3322,3323],{"class":75,"line":100},[73,3324,3325],{"class":165},"    how far Quicopt's real cost lies from its estimate.\"\"\"\n",[73,3327,3328,3331,3333],{"class":75,"line":124},[73,3329,3330],{"class":83},"    quicopt_real, real_off ",[73,3332,181],{"class":79},[73,3334,3335],{"class":83}," [], []\n",[73,3337,3338,3340,3342,3344,3346,3348,3350],{"class":75,"line":139},[73,3339,980],{"class":79},[73,3341,420],{"class":83},[73,3343,423],{"class":79},[73,3345,426],{"class":103},[73,3347,429],{"class":83},[73,3349,432],{"class":103},[73,3351,490],{"class":83},[73,3353,3354,3357,3359],{"class":75,"line":144},[73,3355,3356],{"class":83},"        plan, estimate ",[73,3358,181],{"class":79},[73,3360,3361],{"class":83}," plan_with_quicopt(number, market)\n",[73,3363,3364],{"class":75,"line":149},[73,3365,3366],{"class":83},"        quicopt_real.append(real_cost(number, market, plan))\n",[73,3368,3369,3372,3374,3376,3378,3380,3382,3384,3386],{"class":75,"line":162},[73,3370,3371],{"class":83},"        real_off.append(quicopt_real[",[73,3373,291],{"class":79},[73,3375,788],{"class":103},[73,3377,855],{"class":83},[73,3379,1977],{"class":79},[73,3381,3282],{"class":83},[73,3383,291],{"class":79},[73,3385,1370],{"class":103},[73,3387,471],{"class":83},[73,3389,3390,3393,3395],{"class":75,"line":169},[73,3391,3392],{"class":83},"    extra ",[73,3394,181],{"class":79},[73,3396,3397],{"class":83}," {}\n",[73,3399,3400,3402,3404,3406,3408],{"class":75,"line":175},[73,3401,980],{"class":79},[73,3403,1477],{"class":83},[73,3405,423],{"class":79},[73,3407,2182],{"class":103},[73,3409,2185],{"class":83},[73,3411,3412,3415,3417,3420,3422,3424,3426,3429,3431],{"class":75,"line":187},[73,3413,3414],{"class":83},"        extra[margin] ",[73,3416,181],{"class":79},[73,3418,3419],{"class":83}," [real_cost(number, market, plan_for_forecast(number, market, margin)[",[73,3421,198],{"class":103},[73,3423,2314],{"class":83},[73,3425,1977],{"class":79},[73,3427,3428],{"class":83}," quicopt_real[number] ",[73,3430,291],{"class":79},[73,3432,2380],{"class":103},[73,3434,3435,3438,3440,3442,3444,3446,3448],{"class":75,"line":232},[73,3436,3437],{"class":79},"                         for",[73,3439,420],{"class":83},[73,3441,423],{"class":79},[73,3443,426],{"class":103},[73,3445,429],{"class":83},[73,3447,432],{"class":103},[73,3449,435],{"class":83},[73,3451,3452,3455,3457,3460,3463,3465,3467,3469,3472,3474,3476,3478,3480,3483,3485],{"class":75,"line":267},[73,3453,3454],{"class":83},"        label ",[73,3456,181],{"class":79},[73,3458,3459],{"class":165}," \"plan for the forecast\"",[73,3461,3462],{"class":79}," if",[73,3464,1477],{"class":83},[73,3466,1367],{"class":79},[73,3468,1370],{"class":103},[73,3470,3471],{"class":79}," else",[73,3473,1835],{"class":79},[73,3475,2210],{"class":165},[73,3477,507],{"class":103},[73,3479,2215],{"class":83},[73,3481,3482],{"class":79},":.0%",[73,3484,516],{"class":103},[73,3486,3487],{"class":165}," of capacity\"\n",[73,3489,3490,3493,3495,3497,3499,3501,3504,3507,3509,3511,3514,3516,3518],{"class":75,"line":276},[73,3491,3492],{"class":103},"        print",[73,3494,429],{"class":83},[73,3496,501],{"class":79},[73,3498,504],{"class":165},[73,3500,507],{"class":103},[73,3502,3503],{"class":83},"label",[73,3505,3506],{"class":79},":24",[73,3508,516],{"class":103},[73,3510,519],{"class":103},[73,3512,3513],{"class":83},"median_and_worst(extra[margin])",[73,3515,516],{"class":103},[73,3517,504],{"class":165},[73,3519,471],{"class":83},[73,3521,3522,3524,3526,3528,3530,3532,3535,3538,3541,3543,3545,3548,3551,3553,3555,3557,3559],{"class":75,"line":313},[73,3523,496],{"class":103},[73,3525,429],{"class":83},[73,3527,501],{"class":79},[73,3529,504],{"class":165},[73,3531,563],{"class":103},[73,3533,3534],{"class":165},"Quicopt's real cost against its estimate: from ",[73,3536,3537],{"class":103},"{min",[73,3539,3540],{"class":83},"(real_off)",[73,3542,1987],{"class":79},[73,3544,516],{"class":103},[73,3546,3547],{"class":165}," to ",[73,3549,3550],{"class":103},"{max",[73,3552,3540],{"class":83},[73,3554,1987],{"class":79},[73,3556,516],{"class":103},[73,3558,504],{"class":165},[73,3560,471],{"class":83},[73,3562,3563,3565],{"class":75,"line":340},[73,3564,270],{"class":79},[73,3566,3567],{"class":83}," extra\n",[73,3569,3570],{"class":75,"line":365},[73,3571,97],{"emptyLinePlaceholder":96},[73,3573,3574],{"class":75,"line":390},[73,3575,97],{"emptyLinePlaceholder":96},[73,3577,3578,3581,3583],{"class":75,"line":396},[73,3579,3580],{"class":83},"calm_extra ",[73,3582,181],{"class":79},[73,3584,3585],{"class":83}," compare(calm)\n",[627,3587],{":lines":3588,"label":630},"[\"plan for the forecast     median +0.3%, worst +7.7%\",\"plan to 95% of capacity   median +0.0%, worst +4.1%\",\"plan to 90% of capacity   median +0.6%, worst +7.6%\",\"plan to 85% of capacity   median +4.3%, worst +12.5%\",\"plan to 80% of capacity   median +8.4%, worst +29.0%\",\"\",\"Quicopt's real cost against its estimate: from -0.3% to +0.1%\"]",[11,3590,3591],{},"In a calm market, a 95% margin costs nothing extra in the median network and at most 4% in the worst. A planner with that margin is doing well. What Quicopt adds in a calm market is an honest estimate. It states the cost you will pay, while the proven plan really costs a median 6.4% more than it promised.",[36,3593,3595],{"id":3594},"when-the-market-turns","When the market turns",[11,3597,3598],{},"Now the same 20 networks face the turned market. The forecasts stay the same. What changes is the market around them. Network 11 first:",[63,3600,3602],{"className":65,"code":3601,"language":67,"meta":68,"style":68},"plan, promised = plan_for_forecast(11, turned)\nprint(f\"plan for the forecast:     promised {promised:6,.0f}, real cost {real_cost(11, turned, plan):6,.0f}   {describe(plan)}\")\nfor margin in MARGINS[1:]:\n    plan, _ = plan_for_forecast(11, turned, margin)\n    print(f\"plan to {margin:.0%} of capacity:  real cost {real_cost(11, turned, plan):6,.0f}\")\nplan, estimate = plan_with_quicopt(11, turned)\nprint(f\"Quicopt:                   estimate {estimate:6,.0f}, real cost {real_cost(11, turned, plan):6,.0f}   {describe(plan)}\")\n",[70,3603,3604,3617,3662,3680,3693,3730,3742],{"__ignoreMap":68},[73,3605,3606,3608,3610,3612,3614],{"class":75,"line":76},[73,3607,1886],{"class":83},[73,3609,181],{"class":79},[73,3611,1891],{"class":83},[73,3613,454],{"class":103},[73,3615,3616],{"class":83},", turned)\n",[73,3618,3619,3621,3623,3625,3628,3630,3632,3634,3636,3639,3641,3643,3645,3648,3650,3652,3654,3656,3658,3660],{"class":75,"line":93},[73,3620,463],{"class":103},[73,3622,429],{"class":83},[73,3624,501],{"class":79},[73,3626,3627],{"class":165},"\"plan for the forecast:     promised ",[73,3629,507],{"class":103},[73,3631,1937],{"class":83},[73,3633,1940],{"class":79},[73,3635,516],{"class":103},[73,3637,3638],{"class":165},", real cost ",[73,3640,507],{"class":103},[73,3642,2228],{"class":83},[73,3644,454],{"class":103},[73,3646,3647],{"class":83},", turned, plan)",[73,3649,1940],{"class":79},[73,3651,516],{"class":103},[73,3653,2240],{"class":103},[73,3655,2243],{"class":83},[73,3657,516],{"class":103},[73,3659,504],{"class":165},[73,3661,471],{"class":83},[73,3663,3664,3666,3668,3670,3672,3675,3677],{"class":75,"line":100},[73,3665,417],{"class":79},[73,3667,1477],{"class":83},[73,3669,423],{"class":79},[73,3671,2182],{"class":103},[73,3673,3674],{"class":83},"[",[73,3676,788],{"class":103},[73,3678,3679],{"class":83},":]:\n",[73,3681,3682,3684,3686,3688,3690],{"class":75,"line":124},[73,3683,2190],{"class":83},[73,3685,181],{"class":79},[73,3687,1891],{"class":83},[73,3689,454],{"class":103},[73,3691,3692],{"class":83},", turned, margin)\n",[73,3694,3695,3697,3699,3701,3703,3705,3707,3709,3711,3714,3716,3718,3720,3722,3724,3726,3728],{"class":75,"line":139},[73,3696,496],{"class":103},[73,3698,429],{"class":83},[73,3700,501],{"class":79},[73,3702,2210],{"class":165},[73,3704,507],{"class":103},[73,3706,2215],{"class":83},[73,3708,3482],{"class":79},[73,3710,516],{"class":103},[73,3712,3713],{"class":165}," of capacity:  real cost ",[73,3715,507],{"class":103},[73,3717,2228],{"class":83},[73,3719,454],{"class":103},[73,3721,3647],{"class":83},[73,3723,1940],{"class":79},[73,3725,516],{"class":103},[73,3727,504],{"class":165},[73,3729,471],{"class":83},[73,3731,3732,3734,3736,3738,3740],{"class":75,"line":144},[73,3733,3197],{"class":83},[73,3735,181],{"class":79},[73,3737,3202],{"class":83},[73,3739,454],{"class":103},[73,3741,3616],{"class":83},[73,3743,3744,3746,3748,3750,3753,3755,3757,3759,3761,3763,3765,3767,3769,3771,3773,3775,3777,3779,3781,3783],{"class":75,"line":149},[73,3745,463],{"class":103},[73,3747,429],{"class":83},[73,3749,501],{"class":79},[73,3751,3752],{"class":165},"\"Quicopt:                   estimate ",[73,3754,507],{"class":103},[73,3756,3243],{"class":83},[73,3758,1940],{"class":79},[73,3760,516],{"class":103},[73,3762,3638],{"class":165},[73,3764,507],{"class":103},[73,3766,2228],{"class":83},[73,3768,454],{"class":103},[73,3770,3647],{"class":83},[73,3772,1940],{"class":79},[73,3774,516],{"class":103},[73,3776,2240],{"class":103},[73,3778,2243],{"class":83},[73,3780,516],{"class":103},[73,3782,504],{"class":165},[73,3784,471],{"class":83},[627,3786],{":lines":3787,"label":630},"[\"plan for the forecast:     promised  5,998, real cost 10,790   warehouses at sites 0, 1, 4; regions 0-7 served from sites 4 1 0 4 4 1 4 0\",\"plan to 95% of capacity:  real cost  9,748\",\"plan to 90% of capacity:  real cost  7,706\",\"plan to 85% of capacity:  real cost  7,171\",\"plan to 80% of capacity:  real cost  7,171\",\"Quicopt:                   estimate  7,079, real cost  7,145   warehouses at sites 0, 1, 2, 4; regions 0-7 served from sites 2 1 2 4 4 4 0 0\"]",[11,3789,3790],{},"The plan for the forecast is the same as in the calm market, and the solver still promises 5,998. Its real cost is now 10,790. The 95% margin that fit the calm market costs 9,748, which is 36% more than Quicopt's new plan at 7,145. Widening the margin helps, but it only catches up with Quicopt at 85%. Quicopt itself only needed the new market numbers, and its estimate of 7,079 is within 1% of the real cost. Across all 20 networks in the turned market:",[63,3792,3794],{"className":65,"code":3793,"language":67,"meta":68,"style":68},"turned_extra = compare(turned)\n\nabove_promise = []\nfor number in range(20):\n    plan, promised = plan_for_forecast(number, turned)\n    above_promise.append(real_cost(number, turned, plan) \u002F promised - 1)\nprint(\"plan for the forecast, real cost above the promise:\", median_and_worst(above_promise))\nworst = int(np.argmax(turned_extra[1.0]))\nprint(f\"worst network for the plan for the forecast: {worst} ({turned_extra[1.0][worst]:+.1%})\")\n",[70,3795,3796,3806,3810,3818,3834,3843,3858,3869,3887],{"__ignoreMap":68},[73,3797,3798,3801,3803],{"class":75,"line":76},[73,3799,3800],{"class":83},"turned_extra ",[73,3802,181],{"class":79},[73,3804,3805],{"class":83}," compare(turned)\n",[73,3807,3808],{"class":75,"line":93},[73,3809,97],{"emptyLinePlaceholder":96},[73,3811,3812,3814,3816],{"class":75,"line":100},[73,3813,2060],{"class":83},[73,3815,181],{"class":79},[73,3817,2065],{"class":83},[73,3819,3820,3822,3824,3826,3828,3830,3832],{"class":75,"line":124},[73,3821,417],{"class":79},[73,3823,420],{"class":83},[73,3825,423],{"class":79},[73,3827,426],{"class":103},[73,3829,429],{"class":83},[73,3831,432],{"class":103},[73,3833,490],{"class":83},[73,3835,3836,3838,3840],{"class":75,"line":139},[73,3837,2086],{"class":83},[73,3839,181],{"class":79},[73,3841,3842],{"class":83}," plan_for_forecast(number, turned)\n",[73,3844,3845,3848,3850,3852,3854,3856],{"class":75,"line":144},[73,3846,3847],{"class":83},"    above_promise.append(real_cost(number, turned, plan) ",[73,3849,1977],{"class":79},[73,3851,1980],{"class":83},[73,3853,291],{"class":79},[73,3855,1370],{"class":103},[73,3857,471],{"class":83},[73,3859,3860,3862,3864,3867],{"class":75,"line":149},[73,3861,463],{"class":103},[73,3863,429],{"class":83},[73,3865,3866],{"class":165},"\"plan for the forecast, real cost above the promise:\"",[73,3868,2118],{"class":83},[73,3870,3871,3874,3876,3879,3882,3884],{"class":75,"line":162},[73,3872,3873],{"class":83},"worst ",[73,3875,181],{"class":79},[73,3877,3878],{"class":103}," int",[73,3880,3881],{"class":83},"(np.argmax(turned_extra[",[73,3883,1183],{"class":103},[73,3885,3886],{"class":83},"]))\n",[73,3888,3889,3891,3893,3895,3898,3900,3903,3905,3907,3909,3912,3914,3917,3919,3921,3923],{"class":75,"line":169},[73,3890,463],{"class":103},[73,3892,429],{"class":83},[73,3894,501],{"class":79},[73,3896,3897],{"class":165},"\"worst network for the plan for the forecast: ",[73,3899,507],{"class":103},[73,3901,3902],{"class":83},"worst",[73,3904,516],{"class":103},[73,3906,924],{"class":165},[73,3908,507],{"class":103},[73,3910,3911],{"class":83},"turned_extra[",[73,3913,1183],{"class":103},[73,3915,3916],{"class":83},"][worst]",[73,3918,1987],{"class":79},[73,3920,516],{"class":103},[73,3922,1992],{"class":165},[73,3924,471],{"class":83},[627,3926],{":lines":3927,"label":630},"[\"plan for the forecast     median +18.3%, worst +51.0%\",\"plan to 95% of capacity   median +14.5%, worst +36.4%\",\"plan to 90% of capacity   median +6.7%, worst +27.3%\",\"plan to 85% of capacity   median +1.3%, worst +13.0%\",\"plan to 80% of capacity   median +1.2%, worst +5.3%\",\"\",\"Quicopt's real cost against its estimate: from +0.3% to +1.9%\",\"plan for the forecast, real cost above the promise: median +48.6%, worst +89.8%\",\"worst network for the plan for the forecast: 11 (+51.0%)\"]",[11,3929,3930],{},"The margin that fit the calm market now costs a median 14.5% more than Quicopt's plan, and up to 36% more. Planning for the forecast costs 18% more in the median network, and its real cost lies almost 50% above what the solver promises.",[11,3932,3933],{},"When the market turns, a planner widens the margin. But by how much? The forecast error has doubled, so a planner might double the headroom too, from 5% of capacity to 10%. That is the 90% margin, and it still costs a median 6.7% more than Quicopt's plan, and up to 27% more. The margin that fits the turned market is 80%, four times the old headroom. With it, the planner ties Quicopt again. But the turn changed all three numbers of the market at once, and one margin has to absorb them all. Nothing in the new numbers points to 80%. You find out by simulating, or by paying the overflow bills of the next few years. Quicopt takes the three new numbers as they are.",[36,3935,3937],{"id":3936},"questions-for-your-planning-team","Questions for your planning team",[11,3939,3940],{},"Whether your network looks more like the calm or the turned market is something only your data can tell. Three questions help to find out:",[3942,3943,3944,3951,3957],"ol",{},[47,3945,3946,3950],{},[3947,3948,3949],"strong",{},"How do you buffer today?"," A flat capacity margin (\"we plan warehouses to 85%\"), or a safety allowance per region (the forecast plus some multiple of its error)? How was its size chosen?",[47,3952,3953,3956],{},[3947,3954,3955],{},"How accurate are your forecasts, and how uneven is that accuracy?"," The typical error per region or product, and whether established markets and new ones differ much.",[47,3958,3959],{},[3947,3960,3961],{},"When did you last change your margin, and what made you change it?",[3963,3964,3965],"style",{},"html pre.shiki code .snl16, html code.shiki .snl16{--shiki-default:#F97583}html pre.shiki code .s95oV, html code.shiki .s95oV{--shiki-default:#E1E4E8}html pre.shiki code .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}html pre.shiki code .svObZ, html code.shiki .svObZ{--shiki-default:#B392F0}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}html pre.shiki code .s9osk, html code.shiki .s9osk{--shiki-default:#FFAB70}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":68,"searchDepth":93,"depth":93,"links":3967},[3968,3969,3970,3971,3972,3973,3974],{"id":38,"depth":93,"text":39},{"id":633,"depth":93,"text":634},{"id":1139,"depth":93,"text":1140},{"id":2124,"depth":93,"text":2125},{"id":2437,"depth":93,"text":2438},{"id":3594,"depth":93,"text":3595},{"id":3936,"depth":93,"text":3937},"md",null,{},"\u002Fuse-cases\u002Fwarehouse-planning",{"title":6,"description":13},"use-cases\u002Fwarehouse-planning","EyvBZHdyAVdikGoalIfK7PDGusEfr4sf3LWaBC3d7uc",{"id":3983,"title":3984,"body":3985,"description":3989,"extension":3975,"faq":3976,"meta":7361,"navigation":96,"path":7362,"seo":7363,"stem":7364,"__hash__":7365},"content\u002Fuse-cases\u002Fwarehouse-planning.de.md","Lagerplanung, wenn der Markt kippt",{"type":8,"value":3986,"toc":7352},[3987,3990,3996,4003,4006,4009,4013,4016,4027,4030,4033,4453,4456,4460,4463,4466,4469,4879,4883,4886,5610,5612,5615,5719,5721,5725,5728,5830,5832,5835,5983,5985,5988,5992,5995,6004,6010,6748,6750,6753,7003,7005,7008,7012,7015,7191,7193,7196,7316,7318,7321,7324,7328,7331,7350],[11,3988,3989],{},"Sie planen Ihr Lagernetz entsprechend der Bedarfsprognose. Weil die Prognose nie genau stimmt, halten Sie jedoch eine Sicherheitsmarge und planen jedes Lager auf 95 % seiner Kapazität. Das ist nicht falsch. In einem ruhigen Markt, in dem die Prognosen um etwa 15 % danebenliegen, ist eine Marge von 95 % quasi optimal. Auf unseren Testdaten kostet dies im Median nichts extra und im schlechtesten Fall höchstens 4 %.",[11,3991,3992],{},[17,3993],{"alt":3994,"src":3995},"Links: eine Karte mit fünf möglichen Lagerstandorten und acht Kundenregionen. An drei Standorten steht ein Lager, und von jeder Region führt eine Linie zu dem Lager, das sie beliefert. Rechts: der jährliche Bedarf an einem Lager über 100.000 simulierte Jahre, im ruhigen und im gekippten Markt. Im Schnitt ist der Bedarf in beiden Märkten gleich. Im gekippten Markt schwankt er stärker, deshalb finden mehr Paletten keinen Platz.","\u002Fuse-cases\u002Fwarehouse-planning\u002Fwarehouse-planning.de.svg",[11,3997,3998,3999,4002],{},"Doch diese Marge stammt aus einem ruhigen Markt. Nehmen wir an, der Markt verändert sich plötzlich. Ihre Prognosen liegen nun um etwa 30 % daneben, und darüber hinaus sind Ihre zu beliefernden Regionen ",[25,4000,4001],{},"korreliert",", d. h. die Nachfrage dort steigt und fällt im Takt. Jene Paletten, die nicht in Ihre Lager passen, gehen an einen externen Logistikdienstleister. Dieser Dienstleister verlangt bei höherer Nachfrage nach seinen Diensten nun doppelt so viel Geld wie zuvor. Dieselbe Sicherheitsmarge von 95 % kostet dann im Median 14,5 % mehr pro Jahr als der Plan, den Quicopt findet, und im schlechtesten unserer 20 Testnetze sogar 36 % mehr. Auch mit einer Marge von 90 % sind es noch 6,7 % mehr. Wer allein mit der Nachfrageprognose plant, schneidet noch schlechter ab, selbst wenn ein Solver den Plan als optimal beweist. Im Median kostet dieser Plan 18 % mehr, und er kostet fast 50 % mehr, als der Solver versprochen hat.",[11,4004,4005],{},"Quicopt plant den Prognosefehler direkt ein. Sie geben an, wie weit der Bedarf von der Prognose abweichen kann. Quicopt wählt dann das Lagernetz, das über alle Eventualitäten gesehen am günstigsten ist, und sagt Ihnen, was dieses Netz genau kosten wird (in unseren Tests auf 2 % genau – was hervorragend ist, wenn man den Prognosefehler bedenkt). Wenn der Markt sich ändert, müssen Sie nur die Prognoseparameter aktualisieren, anstatt eine Marge neu zu lernen.",[11,4007,4008],{},"Im Folgenden planen wir alle 20 Testnetze auf beide Arten, im ruhigen und im gekippten Markt, mit Code, den Sie selbst ausführen können.",[36,4010,4012],{"id":4011},"zwanzig-lagernetze","Zwanzig Lagernetze",[11,4014,4015],{},"Jedes der 20 Netze hat fünf Standorte, an denen Sie ein Lager betreiben könnten, und acht Kundenregionen, verteilt auf einer Karte von 600 × 800 km. Jede Region wird aus genau einem Lager beliefert. Die Kosten eines Jahres bestehen aus drei Teilen:",[44,4017,4018,4021,4024],{},[47,4019,4020],{},"den Fixkosten für jedes Lager, das Sie betreiben;",[47,4022,4023],{},"den Transportkosten, berechnet nach der Entfernung und nach dem Bedarf jeder Region in diesem Jahr;",[47,4025,4026],{},"einem Aufpreis für Überlauf.",[11,4028,4029],{},"Überlauf ist der Teil des Jahresbedarfs, den ein Lager nicht aufnehmen kann. Er geht an einen externen Logistikdienstleister, der dafür pro Palette einen Aufpreis verlangt.",[11,4031,4032],{},"Wir ziehen die 20 Netze zufällig, jedes aus einem festen Seed, sodass Sie jede Zahl auf dieser Seite nachrechnen können. Bedarf und Kapazität sind in Tausend Paletten pro Jahr angegeben, Kosten in Tausend EUR pro Jahr. Netz 11 sehen wir uns genauer an: Von den 20 Testnetzen ist es dasjenige, in dem die Planung für die Prognose am schlechtesten abschneidet, sobald der Markt kippt.",[63,4034,4035],{"className":65,"code":66,"language":67,"meta":68,"style":68},[70,4036,4037,4047,4051,4067,4077,4081,4085,4093,4097,4101,4109,4143,4175,4181,4207,4227,4247,4267,4271,4275,4279,4301,4305,4317,4327,4343,4389,4403,4419],{"__ignoreMap":68},[73,4038,4039,4041,4043,4045],{"class":75,"line":76},[73,4040,80],{"class":79},[73,4042,84],{"class":83},[73,4044,87],{"class":79},[73,4046,90],{"class":83},[73,4048,4049],{"class":75,"line":93},[73,4050,97],{"emptyLinePlaceholder":96},[73,4052,4053,4055,4057,4059,4061,4063,4065],{"class":75,"line":100},[73,4054,104],{"class":103},[73,4056,107],{"class":83},[73,4058,110],{"class":103},[73,4060,113],{"class":79},[73,4062,116],{"class":103},[73,4064,107],{"class":83},[73,4066,121],{"class":103},[73,4068,4069,4071,4073,4075],{"class":75,"line":124},[73,4070,127],{"class":103},[73,4072,113],{"class":79},[73,4074,132],{"class":103},[73,4076,136],{"class":135},[73,4078,4079],{"class":75,"line":139},[73,4080,97],{"emptyLinePlaceholder":96},[73,4082,4083],{"class":75,"line":144},[73,4084,97],{"emptyLinePlaceholder":96},[73,4086,4087,4089,4091],{"class":75,"line":149},[73,4088,152],{"class":79},[73,4090,156],{"class":155},[73,4092,159],{"class":83},[73,4094,4095],{"class":75,"line":162},[73,4096,166],{"class":165},[73,4098,4099],{"class":75,"line":169},[73,4100,172],{"class":165},[73,4102,4103,4105,4107],{"class":75,"line":175},[73,4104,178],{"class":83},[73,4106,181],{"class":79},[73,4108,184],{"class":83},[73,4110,4111,4113,4115,4117,4119,4121,4123,4125,4127,4129,4131,4133,4135,4137,4139,4141],{"class":75,"line":187},[73,4112,190],{"class":83},[73,4114,181],{"class":79},[73,4116,195],{"class":83},[73,4118,198],{"class":103},[73,4120,107],{"class":83},[73,4122,198],{"class":103},[73,4124,205],{"class":83},[73,4126,208],{"class":103},[73,4128,107],{"class":83},[73,4130,213],{"class":103},[73,4132,216],{"class":83},[73,4134,104],{"class":103},[73,4136,107],{"class":83},[73,4138,223],{"class":103},[73,4140,226],{"class":83},[73,4142,229],{"class":135},[73,4144,4145,4147,4149,4151,4153,4155,4157,4159,4161,4163,4165,4167,4169,4171,4173],{"class":75,"line":232},[73,4146,235],{"class":83},[73,4148,181],{"class":79},[73,4150,195],{"class":83},[73,4152,198],{"class":103},[73,4154,107],{"class":83},[73,4156,198],{"class":103},[73,4158,205],{"class":83},[73,4160,208],{"class":103},[73,4162,107],{"class":83},[73,4164,213],{"class":103},[73,4166,216],{"class":83},[73,4168,110],{"class":103},[73,4170,107],{"class":83},[73,4172,223],{"class":103},[73,4174,264],{"class":83},[73,4176,4177,4179],{"class":75,"line":267},[73,4178,270],{"class":79},[73,4180,273],{"class":83},[73,4182,4183,4185,4187,4189,4191,4193,4195,4197,4199,4201,4203,4205],{"class":75,"line":276},[73,4184,279],{"class":165},[73,4186,282],{"class":83},[73,4188,285],{"class":103},[73,4190,288],{"class":83},[73,4192,291],{"class":79},[73,4194,294],{"class":83},[73,4196,285],{"class":103},[73,4198,299],{"class":83},[73,4200,303],{"class":302},[73,4202,181],{"class":79},[73,4204,223],{"class":103},[73,4206,310],{"class":83},[73,4208,4209,4211,4213,4215,4217,4219,4221,4223,4225],{"class":75,"line":313},[73,4210,316],{"class":165},[73,4212,319],{"class":83},[73,4214,322],{"class":103},[73,4216,107],{"class":83},[73,4218,327],{"class":103},[73,4220,107],{"class":83},[73,4222,110],{"class":103},[73,4224,334],{"class":83},[73,4226,337],{"class":135},[73,4228,4229,4231,4233,4235,4237,4239,4241,4243,4245],{"class":75,"line":340},[73,4230,343],{"class":165},[73,4232,319],{"class":83},[73,4234,348],{"class":103},[73,4236,107],{"class":83},[73,4238,353],{"class":103},[73,4240,107],{"class":83},[73,4242,104],{"class":103},[73,4244,360],{"class":83},[73,4246,337],{"class":135},[73,4248,4249,4251,4253,4255,4257,4259,4261,4263,4265],{"class":75,"line":365},[73,4250,368],{"class":165},[73,4252,319],{"class":83},[73,4254,213],{"class":103},[73,4256,107],{"class":83},[73,4258,377],{"class":103},[73,4260,107],{"class":83},[73,4262,104],{"class":103},[73,4264,384],{"class":83},[73,4266,387],{"class":135},[73,4268,4269],{"class":75,"line":390},[73,4270,393],{"class":83},[73,4272,4273],{"class":75,"line":396},[73,4274,97],{"emptyLinePlaceholder":96},[73,4276,4277],{"class":75,"line":401},[73,4278,97],{"emptyLinePlaceholder":96},[73,4280,4281,4283,4285,4287,4289,4291,4293,4295,4297,4299],{"class":75,"line":406},[73,4282,409],{"class":83},[73,4284,181],{"class":79},[73,4286,414],{"class":83},[73,4288,417],{"class":79},[73,4290,420],{"class":83},[73,4292,423],{"class":79},[73,4294,426],{"class":103},[73,4296,429],{"class":83},[73,4298,432],{"class":103},[73,4300,435],{"class":83},[73,4302,4303],{"class":75,"line":438},[73,4304,97],{"emptyLinePlaceholder":96},[73,4306,4307,4309,4311,4313,4315],{"class":75,"line":443},[73,4308,446],{"class":83},[73,4310,181],{"class":79},[73,4312,451],{"class":83},[73,4314,454],{"class":103},[73,4316,457],{"class":83},[73,4318,4319,4321,4323,4325],{"class":75,"line":460},[73,4320,463],{"class":103},[73,4322,429],{"class":83},[73,4324,468],{"class":165},[73,4326,471],{"class":83},[73,4328,4329,4331,4333,4335,4337,4339,4341],{"class":75,"line":474},[73,4330,417],{"class":79},[73,4332,479],{"class":83},[73,4334,423],{"class":79},[73,4336,426],{"class":103},[73,4338,429],{"class":83},[73,4340,104],{"class":103},[73,4342,490],{"class":83},[73,4344,4345,4347,4349,4351,4353,4355,4357,4359,4361,4363,4365,4367,4369,4371,4373,4375,4377,4379,4381,4383,4385,4387],{"class":75,"line":493},[73,4346,496],{"class":103},[73,4348,429],{"class":83},[73,4350,501],{"class":79},[73,4352,504],{"class":165},[73,4354,507],{"class":103},[73,4356,510],{"class":83},[73,4358,513],{"class":79},[73,4360,516],{"class":103},[73,4362,519],{"class":103},[73,4364,522],{"class":83},[73,4366,525],{"class":165},[73,4368,528],{"class":83},[73,4370,531],{"class":79},[73,4372,516],{"class":103},[73,4374,519],{"class":103},[73,4376,522],{"class":83},[73,4378,540],{"class":165},[73,4380,528],{"class":83},[73,4382,545],{"class":79},[73,4384,516],{"class":103},[73,4386,504],{"class":165},[73,4388,471],{"class":83},[73,4390,4391,4393,4395,4397,4399,4401],{"class":75,"line":554},[73,4392,463],{"class":103},[73,4394,429],{"class":83},[73,4396,504],{"class":165},[73,4398,563],{"class":103},[73,4400,566],{"class":165},[73,4402,471],{"class":83},[73,4404,4405,4407,4409,4411,4413,4415,4417],{"class":75,"line":571},[73,4406,417],{"class":79},[73,4408,576],{"class":83},[73,4410,423],{"class":79},[73,4412,426],{"class":103},[73,4414,429],{"class":83},[73,4416,110],{"class":103},[73,4418,490],{"class":83},[73,4420,4421,4423,4425,4427,4429,4431,4433,4435,4437,4439,4441,4443,4445,4447,4449,4451],{"class":75,"line":589},[73,4422,496],{"class":103},[73,4424,429],{"class":83},[73,4426,501],{"class":79},[73,4428,504],{"class":165},[73,4430,507],{"class":103},[73,4432,602],{"class":83},[73,4434,605],{"class":79},[73,4436,516],{"class":103},[73,4438,519],{"class":103},[73,4440,522],{"class":83},[73,4442,614],{"class":165},[73,4444,617],{"class":83},[73,4446,531],{"class":79},[73,4448,516],{"class":103},[73,4450,504],{"class":165},[73,4452,471],{"class":83},[627,4454],{":lines":629,"label":4455},"Ausgabe",[36,4457,4459],{"id":4458},"zwei-märkte","Zwei Märkte",[11,4461,4462],{},"Ein Markt besteht auf dieser Seite aus drei Zahlen. Der Prognosefehler gibt an, wie weit der Jahresbedarf einer Region typischerweise von ihrer Prognose abweicht (eine Standardabweichung). Die Korrelation gibt an, wie stark die Nachfrage in den Regionen gemeinsam steigt und fällt. Der Aufpreis für Überlauf ist der Preis des externen Logistikdienstleisters pro Palette.",[11,4464,4465],{},"Im ruhigen Markt liegen Ihre Prognosen um etwa 15 % daneben, die Regionen sind unabhängig voneinander, und Überlauf kostet 40 EUR pro Palette. Im gekippten Markt liegen die Prognosen um etwa 30 % daneben, je zwei Regionen sind mit 0,5 korreliert, und Überlauf kostet 80 EUR pro Palette.",[11,4467,4468],{},"Wir beurteilen jeden Plan nach seinen tatsächlichen Kosten. Das sind die durchschnittlichen Jahreskosten des Plans über 100.000 simulierte Jahre des Marktes, in dem er sich bewähren muss.",[63,4470,4471],{"className":65,"code":646,"language":67,"meta":68,"style":68},[70,4472,4473,4505,4537,4541,4545,4553,4557,4565,4579,4593,4605,4631,4665,4669,4673,4681,4685,4693,4727,4743,4759,4767,4799,4829,4833,4837,4845,4849,4857],{"__ignoreMap":68},[73,4474,4475,4477,4479,4481,4483,4485,4487,4489,4491,4493,4495,4497,4499,4501,4503],{"class":75,"line":76},[73,4476,653],{"class":83},[73,4478,181],{"class":79},[73,4480,658],{"class":83},[73,4482,661],{"class":165},[73,4484,664],{"class":83},[73,4486,667],{"class":103},[73,4488,107],{"class":83},[73,4490,672],{"class":165},[73,4492,664],{"class":83},[73,4494,677],{"class":103},[73,4496,107],{"class":83},[73,4498,682],{"class":165},[73,4500,664],{"class":83},[73,4502,687],{"class":103},[73,4504,690],{"class":83},[73,4506,4507,4509,4511,4513,4515,4517,4519,4521,4523,4525,4527,4529,4531,4533,4535],{"class":75,"line":93},[73,4508,695],{"class":83},[73,4510,181],{"class":79},[73,4512,658],{"class":83},[73,4514,661],{"class":165},[73,4516,664],{"class":83},[73,4518,706],{"class":103},[73,4520,107],{"class":83},[73,4522,672],{"class":165},[73,4524,664],{"class":83},[73,4526,715],{"class":103},[73,4528,107],{"class":83},[73,4530,682],{"class":165},[73,4532,664],{"class":83},[73,4534,724],{"class":103},[73,4536,690],{"class":83},[73,4538,4539],{"class":75,"line":100},[73,4540,97],{"emptyLinePlaceholder":96},[73,4542,4543],{"class":75,"line":124},[73,4544,97],{"emptyLinePlaceholder":96},[73,4546,4547,4549,4551],{"class":75,"line":139},[73,4548,152],{"class":79},[73,4550,741],{"class":155},[73,4552,744],{"class":83},[73,4554,4555],{"class":75,"line":144},[73,4556,749],{"class":165},[73,4558,4559,4561,4563],{"class":75,"line":149},[73,4560,178],{"class":83},[73,4562,181],{"class":79},[73,4564,758],{"class":83},[73,4566,4567,4569,4571,4573,4575,4577],{"class":75,"line":162},[73,4568,763],{"class":83},[73,4570,181],{"class":79},[73,4572,768],{"class":83},[73,4574,110],{"class":103},[73,4576,773],{"class":83},[73,4578,776],{"class":135},[73,4580,4581,4583,4585,4587,4589,4591],{"class":75,"line":169},[73,4582,781],{"class":83},[73,4584,181],{"class":79},[73,4586,768],{"class":83},[73,4588,788],{"class":103},[73,4590,226],{"class":83},[73,4592,793],{"class":135},[73,4594,4595,4597,4599,4601,4603],{"class":75,"line":175},[73,4596,798],{"class":83},[73,4598,181],{"class":79},[73,4600,803],{"class":83},[73,4602,672],{"class":165},[73,4604,457],{"class":83},[73,4606,4607,4609,4611,4613,4615,4617,4619,4621,4623,4625,4627,4629],{"class":75,"line":187},[73,4608,812],{"class":83},[73,4610,181],{"class":79},[73,4612,817],{"class":83},[73,4614,788],{"class":103},[73,4616,822],{"class":79},[73,4618,825],{"class":83},[73,4620,828],{"class":79},[73,4622,831],{"class":83},[73,4624,834],{"class":79},[73,4626,837],{"class":83},[73,4628,828],{"class":79},[73,4630,842],{"class":83},[73,4632,4633,4635,4637,4639,4641,4643,4645,4647,4649,4651,4653,4655,4657,4659,4661,4663],{"class":75,"line":232},[73,4634,270],{"class":79},[73,4636,849],{"class":83},[73,4638,852],{"class":165},[73,4640,855],{"class":83},[73,4642,834],{"class":79},[73,4644,803],{"class":83},[73,4646,661],{"class":165},[73,4648,855],{"class":83},[73,4650,828],{"class":79},[73,4652,868],{"class":83},[73,4654,852],{"class":165},[73,4656,855],{"class":83},[73,4658,828],{"class":79},[73,4660,877],{"class":83},[73,4662,677],{"class":103},[73,4664,471],{"class":83},[73,4666,4667],{"class":75,"line":267},[73,4668,97],{"emptyLinePlaceholder":96},[73,4670,4671],{"class":75,"line":276},[73,4672,97],{"emptyLinePlaceholder":96},[73,4674,4675,4677,4679],{"class":75,"line":313},[73,4676,152],{"class":79},[73,4678,896],{"class":155},[73,4680,899],{"class":83},[73,4682,4683],{"class":75,"line":340},[73,4684,904],{"class":165},[73,4686,4687,4689,4691],{"class":75,"line":365},[73,4688,909],{"class":83},[73,4690,181],{"class":79},[73,4692,914],{"class":83},[73,4694,4695,4697,4699,4701,4703,4705,4707,4709,4711,4713,4715,4717,4719,4721,4723,4725],{"class":75,"line":390},[73,4696,919],{"class":83},[73,4698,181],{"class":79},[73,4700,924],{"class":83},[73,4702,127],{"class":103},[73,4704,929],{"class":79},[73,4706,868],{"class":83},[73,4708,934],{"class":165},[73,4710,937],{"class":83},[73,4712,110],{"class":103},[73,4714,942],{"class":83},[73,4716,828],{"class":79},[73,4718,947],{"class":83},[73,4720,303],{"class":302},[73,4722,181],{"class":79},[73,4724,788],{"class":103},[73,4726,471],{"class":83},[73,4728,4729,4731,4733,4735,4737,4739,4741],{"class":75,"line":396},[73,4730,960],{"class":83},[73,4732,181],{"class":79},[73,4734,965],{"class":83},[73,4736,968],{"class":103},[73,4738,971],{"class":83},[73,4740,104],{"class":103},[73,4742,264],{"class":83},[73,4744,4745,4747,4749,4751,4753,4755,4757],{"class":75,"line":401},[73,4746,980],{"class":79},[73,4748,576],{"class":83},[73,4750,423],{"class":79},[73,4752,426],{"class":103},[73,4754,429],{"class":83},[73,4756,110],{"class":103},[73,4758,490],{"class":83},[73,4760,4761,4763,4765],{"class":75,"line":406},[73,4762,997],{"class":83},[73,4764,1000],{"class":79},[73,4766,1003],{"class":83},[73,4768,4769,4771,4773,4775,4777,4779,4781,4783,4785,4787,4789,4791,4793,4795,4797],{"class":75,"line":438},[73,4770,1008],{"class":83},[73,4772,181],{"class":79},[73,4774,1013],{"class":83},[73,4776,291],{"class":79},[73,4778,868],{"class":83},[73,4780,1020],{"class":165},[73,4782,855],{"class":83},[73,4784,828],{"class":79},[73,4786,1027],{"class":83},[73,4788,677],{"class":103},[73,4790,1032],{"class":83},[73,4792,303],{"class":302},[73,4794,181],{"class":79},[73,4796,788],{"class":103},[73,4798,471],{"class":83},[73,4800,4801,4803,4805,4807,4809,4811,4813,4815,4817,4819,4821,4823,4825,4827],{"class":75,"line":443},[73,4802,270],{"class":79},[73,4804,868],{"class":83},[73,4806,1049],{"class":165},[73,4808,855],{"class":83},[73,4810,1054],{"class":79},[73,4812,1057],{"class":83},[73,4814,834],{"class":79},[73,4816,1062],{"class":83},[73,4818,834],{"class":79},[73,4820,803],{"class":83},[73,4822,682],{"class":165},[73,4824,855],{"class":83},[73,4826,828],{"class":79},[73,4828,1075],{"class":83},[73,4830,4831],{"class":75,"line":460},[73,4832,97],{"emptyLinePlaceholder":96},[73,4834,4835],{"class":75,"line":474},[73,4836,97],{"emptyLinePlaceholder":96},[73,4838,4839,4841,4843],{"class":75,"line":493},[73,4840,152],{"class":79},[73,4842,1090],{"class":155},[73,4844,1093],{"class":83},[73,4846,4847],{"class":75,"line":554},[73,4848,1098],{"class":165},[73,4850,4851,4853,4855],{"class":75,"line":571},[73,4852,1103],{"class":83},[73,4854,181],{"class":79},[73,4856,1108],{"class":83},[73,4858,4859,4861,4863,4865,4867,4869,4871,4873,4875,4877],{"class":75,"line":589},[73,4860,270],{"class":79},[73,4862,1115],{"class":83},[73,4864,1118],{"class":103},[73,4866,107],{"class":83},[73,4868,1123],{"class":302},[73,4870,181],{"class":79},[73,4872,1128],{"class":83},[73,4874,834],{"class":79},[73,4876,1133],{"class":103},[73,4878,1136],{"class":83},[36,4880,4882],{"id":4881},"planen-für-die-prognose","Planen für die Prognose",[11,4884,4885],{},"Üblicherweise wird das Netz mit einem gemischt-ganzzahligen linearen Programm (MILP) geplant. Es wählt, welche Lager betrieben werden und welches Lager jede Region beliefert, sodass die Kosten am niedrigsten sind, wenn der Bedarf jeder Region genau ihrer Prognose entspricht. HiGHS, ein Open-Source-Solver, löst es und beweist, dass der Plan optimal ist.",[63,4887,4888],{"className":65,"code":1146,"language":67,"meta":68,"style":68},[70,4889,4890,4900,4904,4908,4922,4926,4930,4934,4938,4946,4954,4978,5010,5034,5080,5114,5142,5184,5204,5232,5262,5292,5322,5334,5342,5348,5374,5414,5420,5424,5428,5436,5444,5476,5510,5514,5518,5530,5542,5548,5570],{"__ignoreMap":68},[73,4891,4892,4894,4896,4898],{"class":75,"line":76},[73,4893,80],{"class":79},[73,4895,1155],{"class":83},[73,4897,87],{"class":79},[73,4899,1160],{"class":83},[73,4901,4902],{"class":75,"line":93},[73,4903,97],{"emptyLinePlaceholder":96},[73,4905,4906],{"class":75,"line":100},[73,4907,97],{"emptyLinePlaceholder":96},[73,4909,4910,4912,4914,4916,4918,4920],{"class":75,"line":124},[73,4911,152],{"class":79},[73,4913,1175],{"class":155},[73,4915,1178],{"class":83},[73,4917,181],{"class":79},[73,4919,1183],{"class":103},[73,4921,490],{"class":83},[73,4923,4924],{"class":75,"line":139},[73,4925,1190],{"class":165},[73,4927,4928],{"class":75,"line":144},[73,4929,1195],{"class":165},[73,4931,4932],{"class":75,"line":149},[73,4933,1200],{"class":165},[73,4935,4936],{"class":75,"line":162},[73,4937,1205],{"class":165},[73,4939,4940,4942,4944],{"class":75,"line":169},[73,4941,1103],{"class":83},[73,4943,181],{"class":79},[73,4945,1108],{"class":83},[73,4947,4948,4950,4952],{"class":75,"line":175},[73,4949,1218],{"class":83},[73,4951,181],{"class":79},[73,4953,1223],{"class":83},[73,4955,4956,4958,4960,4962,4964,4966,4968,4970,4972,4974,4976],{"class":75,"line":187},[73,4957,1228],{"class":83},[73,4959,181],{"class":79},[73,4961,1233],{"class":83},[73,4963,1236],{"class":103},[73,4965,429],{"class":83},[73,4967,104],{"class":103},[73,4969,1243],{"class":83},[73,4971,1246],{"class":302},[73,4973,181],{"class":79},[73,4975,1251],{"class":83},[73,4977,1254],{"class":135},[73,4979,4980,4982,4984,4986,4988,4990,4992,4994,4996,4998,5000,5002,5004,5006,5008],{"class":75,"line":232},[73,4981,1259],{"class":83},[73,4983,181],{"class":79},[73,4985,1233],{"class":83},[73,4987,1236],{"class":103},[73,4989,429],{"class":83},[73,4991,104],{"class":103},[73,4993,1243],{"class":83},[73,4995,1236],{"class":103},[73,4997,429],{"class":83},[73,4999,110],{"class":103},[73,5001,1243],{"class":83},[73,5003,1246],{"class":302},[73,5005,181],{"class":79},[73,5007,1286],{"class":83},[73,5009,1289],{"class":135},[73,5011,5012,5014,5016,5018,5020,5022,5024,5026,5028,5030,5032],{"class":75,"line":267},[73,5013,1294],{"class":83},[73,5015,181],{"class":79},[73,5017,1233],{"class":83},[73,5019,1236],{"class":103},[73,5021,429],{"class":83},[73,5023,104],{"class":103},[73,5025,1243],{"class":83},[73,5027,1246],{"class":302},[73,5029,181],{"class":79},[73,5031,1313],{"class":83},[73,5033,1316],{"class":135},[73,5035,5036,5038,5040,5042,5044,5046,5048,5050,5052,5054,5056,5058,5060,5062,5064,5066,5068,5070,5072,5074,5076,5078],{"class":75,"line":276},[73,5037,1321],{"class":83},[73,5039,181],{"class":79},[73,5041,1326],{"class":83},[73,5043,1236],{"class":103},[73,5045,429],{"class":83},[73,5047,110],{"class":103},[73,5049,1243],{"class":83},[73,5051,1337],{"class":302},[73,5053,1340],{"class":79},[73,5055,1343],{"class":83},[73,5057,1346],{"class":103},[73,5059,1349],{"class":83},[73,5061,417],{"class":79},[73,5063,479],{"class":83},[73,5065,423],{"class":79},[73,5067,426],{"class":103},[73,5069,429],{"class":83},[73,5071,104],{"class":103},[73,5073,1364],{"class":83},[73,5075,1367],{"class":79},[73,5077,1370],{"class":103},[73,5079,471],{"class":83},[73,5081,5082,5084,5086,5088,5090,5092,5094,5096,5098,5100,5102,5104,5106,5108,5110,5112],{"class":75,"line":313},[73,5083,1377],{"class":83},[73,5085,181],{"class":79},[73,5087,1326],{"class":83},[73,5089,1236],{"class":103},[73,5091,429],{"class":83},[73,5093,104],{"class":103},[73,5095,1243],{"class":83},[73,5097,1236],{"class":103},[73,5099,429],{"class":83},[73,5101,110],{"class":103},[73,5103,1243],{"class":83},[73,5105,1337],{"class":302},[73,5107,1340],{"class":79},[73,5109,1404],{"class":83},[73,5111,1407],{"class":79},[73,5113,1410],{"class":83},[73,5115,5116,5118,5120,5122,5124,5126,5128,5130,5132,5134,5136,5138,5140],{"class":75,"line":340},[73,5117,1415],{"class":83},[73,5119,181],{"class":79},[73,5121,1326],{"class":83},[73,5123,1236],{"class":103},[73,5125,429],{"class":83},[73,5127,104],{"class":103},[73,5129,1243],{"class":83},[73,5131,1337],{"class":302},[73,5133,1340],{"class":79},[73,5135,1434],{"class":83},[73,5137,1437],{"class":79},[73,5139,1440],{"class":103},[73,5141,1443],{"class":83},[73,5143,5144,5146,5148,5150,5152,5154,5156,5158,5160,5162,5164,5166,5168,5170,5172,5174,5176,5178,5180,5182],{"class":75,"line":365},[73,5145,1448],{"class":83},[73,5147,852],{"class":165},[73,5149,1453],{"class":83},[73,5151,828],{"class":79},[73,5153,1458],{"class":83},[73,5155,417],{"class":79},[73,5157,576],{"class":83},[73,5159,423],{"class":79},[73,5161,426],{"class":103},[73,5163,429],{"class":83},[73,5165,110],{"class":103},[73,5167,1364],{"class":83},[73,5169,291],{"class":79},[73,5171,1477],{"class":83},[73,5173,828],{"class":79},[73,5175,868],{"class":83},[73,5177,1020],{"class":165},[73,5179,1486],{"class":83},[73,5181,828],{"class":79},[73,5183,1410],{"class":83},[73,5185,5186,5188,5190,5192,5194,5196,5198,5200,5202],{"class":75,"line":390},[73,5187,1495],{"class":83},[73,5189,181],{"class":79},[73,5191,1500],{"class":83},[73,5193,1503],{"class":302},[73,5195,181],{"class":79},[73,5197,1508],{"class":83},[73,5199,1511],{"class":302},[73,5201,181],{"class":79},[73,5203,1443],{"class":83},[73,5205,5206,5208,5210,5212,5214,5216,5218,5220,5222,5224,5226,5228,5230],{"class":75,"line":396},[73,5207,1520],{"class":103},[73,5209,1523],{"class":83},[73,5211,1049],{"class":165},[73,5213,1486],{"class":83},[73,5215,828],{"class":79},[73,5217,1532],{"class":83},[73,5219,417],{"class":79},[73,5221,479],{"class":83},[73,5223,423],{"class":79},[73,5225,426],{"class":103},[73,5227,429],{"class":83},[73,5229,104],{"class":103},[73,5231,264],{"class":83},[73,5233,5234,5236,5238,5240,5242,5244,5246,5248,5250,5252,5254,5256,5258,5260],{"class":75,"line":401},[73,5235,1551],{"class":79},[73,5237,1440],{"class":103},[73,5239,429],{"class":83},[73,5241,127],{"class":103},[73,5243,929],{"class":79},[73,5245,868],{"class":83},[73,5247,934],{"class":165},[73,5249,1566],{"class":83},[73,5251,828],{"class":79},[73,5253,868],{"class":83},[73,5255,852],{"class":165},[73,5257,1453],{"class":83},[73,5259,828],{"class":79},[73,5261,1579],{"class":83},[73,5263,5264,5266,5268,5270,5272,5274,5276,5278,5280,5282,5284,5286,5288,5290],{"class":75,"line":406},[73,5265,1584],{"class":79},[73,5267,479],{"class":83},[73,5269,423],{"class":79},[73,5271,426],{"class":103},[73,5273,429],{"class":83},[73,5275,104],{"class":103},[73,5277,1597],{"class":83},[73,5279,417],{"class":79},[73,5281,576],{"class":83},[73,5283,423],{"class":79},[73,5285,426],{"class":103},[73,5287,429],{"class":83},[73,5289,110],{"class":103},[73,5291,264],{"class":83},[73,5293,5294,5296,5298,5300,5302,5304,5306,5308,5310,5312,5314,5316,5318,5320],{"class":75,"line":438},[73,5295,1551],{"class":79},[73,5297,803],{"class":83},[73,5299,682],{"class":165},[73,5301,855],{"class":83},[73,5303,828],{"class":79},[73,5305,1440],{"class":103},[73,5307,1628],{"class":83},[73,5309,417],{"class":79},[73,5311,479],{"class":83},[73,5313,423],{"class":79},[73,5315,426],{"class":103},[73,5317,429],{"class":83},[73,5319,104],{"class":103},[73,5321,1643],{"class":83},[73,5323,5324,5326,5328,5330,5332],{"class":75,"line":443},[73,5325,1648],{"class":83},[73,5327,181],{"class":79},[73,5329,1653],{"class":83},[73,5331,1656],{"class":165},[73,5333,471],{"class":83},[73,5335,5336,5338,5340],{"class":75,"line":460},[73,5337,1663],{"class":83},[73,5339,181],{"class":79},[73,5341,1668],{"class":103},[73,5343,5344,5346],{"class":75,"line":474},[73,5345,1673],{"class":79},[73,5347,1676],{"class":83},[73,5349,5350,5352,5354,5356,5358,5360,5362,5364,5366,5368,5370,5372],{"class":75,"line":493},[73,5351,1681],{"class":83},[73,5353,181],{"class":79},[73,5355,1686],{"class":83},[73,5357,1689],{"class":103},[73,5359,1692],{"class":83},[73,5361,417],{"class":79},[73,5363,479],{"class":83},[73,5365,423],{"class":79},[73,5367,426],{"class":103},[73,5369,429],{"class":83},[73,5371,104],{"class":103},[73,5373,1707],{"class":83},[73,5375,5376,5378,5380,5382,5384,5386,5388,5390,5392,5394,5396,5398,5400,5402,5404,5406,5408,5410,5412],{"class":75,"line":554},[73,5377,1712],{"class":83},[73,5379,181],{"class":79},[73,5381,1686],{"class":83},[73,5383,1719],{"class":103},[73,5385,429],{"class":83},[73,5387,1236],{"class":103},[73,5389,429],{"class":83},[73,5391,104],{"class":103},[73,5393,1243],{"class":83},[73,5395,1732],{"class":302},[73,5397,1340],{"class":79},[73,5399,1737],{"class":83},[73,5401,417],{"class":79},[73,5403,576],{"class":83},[73,5405,423],{"class":79},[73,5407,426],{"class":103},[73,5409,429],{"class":83},[73,5411,110],{"class":103},[73,5413,1707],{"class":83},[73,5415,5416,5418],{"class":75,"line":571},[73,5417,270],{"class":79},[73,5419,1758],{"class":83},[73,5421,5422],{"class":75,"line":589},[73,5423,97],{"emptyLinePlaceholder":96},[73,5425,5426],{"class":75,"line":1765},[73,5427,97],{"emptyLinePlaceholder":96},[73,5429,5430,5432,5434],{"class":75,"line":1770},[73,5431,152],{"class":79},[73,5433,1775],{"class":155},[73,5435,1778],{"class":83},[73,5437,5438,5440,5442],{"class":75,"line":1781},[73,5439,909],{"class":83},[73,5441,181],{"class":79},[73,5443,914],{"class":83},[73,5445,5446,5448,5450,5452,5454,5456,5458,5460,5462,5464,5466,5468,5470,5472,5474],{"class":75,"line":1790},[73,5447,1793],{"class":83},[73,5449,181],{"class":79},[73,5451,1798],{"class":165},[73,5453,1801],{"class":83},[73,5455,1804],{"class":103},[73,5457,1807],{"class":83},[73,5459,417],{"class":79},[73,5461,479],{"class":83},[73,5463,423],{"class":79},[73,5465,426],{"class":103},[73,5467,429],{"class":83},[73,5469,104],{"class":103},[73,5471,1597],{"class":83},[73,5473,1824],{"class":79},[73,5475,1827],{"class":83},[73,5477,5478,5480,5482,5484,5486,5488,5490,5492,5494,5496,5498,5500,5502,5504,5506,5508],{"class":75,"line":1830},[73,5479,270],{"class":79},[73,5481,1835],{"class":79},[73,5483,1838],{"class":165},[73,5485,507],{"class":103},[73,5487,1843],{"class":83},[73,5489,516],{"class":103},[73,5491,1848],{"class":165},[73,5493,507],{"class":103},[73,5495,1853],{"class":165},[73,5497,1801],{"class":83},[73,5499,1858],{"class":103},[73,5501,429],{"class":83},[73,5503,1804],{"class":103},[73,5505,1865],{"class":83},[73,5507,516],{"class":103},[73,5509,1870],{"class":165},[73,5511,5512],{"class":75,"line":1873},[73,5513,97],{"emptyLinePlaceholder":96},[73,5515,5516],{"class":75,"line":1878},[73,5517,97],{"emptyLinePlaceholder":96},[73,5519,5520,5522,5524,5526,5528],{"class":75,"line":1883},[73,5521,1886],{"class":83},[73,5523,181],{"class":79},[73,5525,1891],{"class":83},[73,5527,454],{"class":103},[73,5529,1896],{"class":83},[73,5531,5532,5534,5536,5538,5540],{"class":75,"line":1899},[73,5533,1902],{"class":83},[73,5535,181],{"class":79},[73,5537,1907],{"class":83},[73,5539,454],{"class":103},[73,5541,1912],{"class":83},[73,5543,5544,5546],{"class":75,"line":1915},[73,5545,463],{"class":103},[73,5547,1920],{"class":83},[73,5549,5550,5552,5554,5556,5558,5560,5562,5564,5566,5568],{"class":75,"line":1923},[73,5551,463],{"class":103},[73,5553,429],{"class":83},[73,5555,501],{"class":79},[73,5557,1932],{"class":165},[73,5559,507],{"class":103},[73,5561,1937],{"class":83},[73,5563,1940],{"class":79},[73,5565,516],{"class":103},[73,5567,504],{"class":165},[73,5569,471],{"class":83},[73,5571,5572,5574,5576,5578,5580,5582,5584,5586,5588,5590,5592,5594,5596,5598,5600,5602,5604,5606,5608],{"class":75,"line":1949},[73,5573,463],{"class":103},[73,5575,429],{"class":83},[73,5577,501],{"class":79},[73,5579,1958],{"class":165},[73,5581,507],{"class":103},[73,5583,1963],{"class":83},[73,5585,1940],{"class":79},[73,5587,516],{"class":103},[73,5589,1970],{"class":165},[73,5591,507],{"class":103},[73,5593,1902],{"class":83},[73,5595,1977],{"class":79},[73,5597,1980],{"class":83},[73,5599,291],{"class":79},[73,5601,1370],{"class":103},[73,5603,1987],{"class":79},[73,5605,516],{"class":103},[73,5607,1992],{"class":165},[73,5609,471],{"class":83},[627,5611],{":lines":1997,"label":4455},[11,5613,5614],{},"Für Netz 11 verspricht der Solver 5.998 pro Jahr. In den simulierten Jahren kostet derselbe Plan 6.589, etwa 10 % mehr. Die Schwankungen um die Prognose heben sich nicht auf. Bedarf über der Prognose überfüllt ein Lager, und für den Überlauf fällt der Aufpreis an. Bedarf unter der Prognose lässt nur Platz leer. Deshalb kostet das durchschnittliche Jahr mehr als das Prognosejahr. Über alle 20 Netze im ruhigen Markt:",[63,5616,5617],{"className":65,"code":2003,"language":67,"meta":68,"style":68},[70,5618,5619,5627,5655,5659,5663,5671,5687,5695,5709],{"__ignoreMap":68},[73,5620,5621,5623,5625],{"class":75,"line":76},[73,5622,152],{"class":79},[73,5624,2012],{"class":155},[73,5626,2015],{"class":83},[73,5628,5629,5631,5633,5635,5637,5639,5641,5643,5645,5647,5649,5651,5653],{"class":75,"line":93},[73,5630,270],{"class":79},[73,5632,1835],{"class":79},[73,5634,2024],{"class":165},[73,5636,507],{"class":103},[73,5638,2029],{"class":83},[73,5640,1987],{"class":79},[73,5642,516],{"class":103},[73,5644,2036],{"class":165},[73,5646,507],{"class":103},[73,5648,2041],{"class":83},[73,5650,1987],{"class":79},[73,5652,516],{"class":103},[73,5654,1870],{"class":165},[73,5656,5657],{"class":75,"line":100},[73,5658,97],{"emptyLinePlaceholder":96},[73,5660,5661],{"class":75,"line":124},[73,5662,97],{"emptyLinePlaceholder":96},[73,5664,5665,5667,5669],{"class":75,"line":139},[73,5666,2060],{"class":83},[73,5668,181],{"class":79},[73,5670,2065],{"class":83},[73,5672,5673,5675,5677,5679,5681,5683,5685],{"class":75,"line":144},[73,5674,417],{"class":79},[73,5676,420],{"class":83},[73,5678,423],{"class":79},[73,5680,426],{"class":103},[73,5682,429],{"class":83},[73,5684,432],{"class":103},[73,5686,490],{"class":83},[73,5688,5689,5691,5693],{"class":75,"line":149},[73,5690,2086],{"class":83},[73,5692,181],{"class":79},[73,5694,2091],{"class":83},[73,5696,5697,5699,5701,5703,5705,5707],{"class":75,"line":162},[73,5698,2096],{"class":83},[73,5700,1977],{"class":79},[73,5702,1980],{"class":83},[73,5704,291],{"class":79},[73,5706,1370],{"class":103},[73,5708,471],{"class":83},[73,5710,5711,5713,5715,5717],{"class":75,"line":169},[73,5712,463],{"class":103},[73,5714,429],{"class":83},[73,5716,2115],{"class":165},[73,5718,2118],{"class":83},[627,5720],{":lines":2121,"label":4455},[36,5722,5724],{"id":5723},"eine-sicherheitsmarge","Eine Sicherheitsmarge",[11,5726,5727],{},"Planer wissen das und halten eine Sicherheitsmarge. Im MILP bedeutet eine Marge, jedes Lager kleiner zu rechnen, als es ist. Plant das MILP auf 95 % der Kapazität, behandelt es alles über 95 % als Überlauf und bepreist es auch so. Für Netz 11:",[63,5729,5730],{"className":65,"code":2131,"language":67,"meta":68,"style":68},[70,5731,5732,5760,5764,5776,5788],{"__ignoreMap":68},[73,5733,5734,5736,5738,5740,5742,5744,5746,5748,5750,5752,5754,5756,5758],{"class":75,"line":76},[73,5735,2138],{"class":103},[73,5737,113],{"class":79},[73,5739,2143],{"class":83},[73,5741,1183],{"class":103},[73,5743,107],{"class":83},[73,5745,2150],{"class":103},[73,5747,107],{"class":83},[73,5749,2155],{"class":103},[73,5751,107],{"class":83},[73,5753,2160],{"class":103},[73,5755,107],{"class":83},[73,5757,2165],{"class":103},[73,5759,457],{"class":83},[73,5761,5762],{"class":75,"line":93},[73,5763,97],{"emptyLinePlaceholder":96},[73,5765,5766,5768,5770,5772,5774],{"class":75,"line":100},[73,5767,417],{"class":79},[73,5769,1477],{"class":83},[73,5771,423],{"class":79},[73,5773,2182],{"class":103},[73,5775,2185],{"class":83},[73,5777,5778,5780,5782,5784,5786],{"class":75,"line":124},[73,5779,2190],{"class":83},[73,5781,181],{"class":79},[73,5783,1891],{"class":83},[73,5785,454],{"class":103},[73,5787,2199],{"class":83},[73,5789,5790,5792,5794,5796,5798,5800,5802,5804,5806,5808,5810,5812,5814,5816,5818,5820,5822,5824,5826,5828],{"class":75,"line":139},[73,5791,496],{"class":103},[73,5793,429],{"class":83},[73,5795,501],{"class":79},[73,5797,2210],{"class":165},[73,5799,507],{"class":103},[73,5801,2215],{"class":83},[73,5803,2218],{"class":79},[73,5805,516],{"class":103},[73,5807,2223],{"class":165},[73,5809,507],{"class":103},[73,5811,2228],{"class":83},[73,5813,454],{"class":103},[73,5815,2233],{"class":83},[73,5817,1940],{"class":79},[73,5819,516],{"class":103},[73,5821,2240],{"class":103},[73,5823,2243],{"class":83},[73,5825,516],{"class":103},[73,5827,504],{"class":165},[73,5829,471],{"class":83},[627,5831],{":lines":2252,"label":4455},[11,5833,5834],{},"Eine Marge von 95 % senkt die tatsächlichen Kosten von Netz 11 von 6.589 auf 6.312. Größere Margen kosten wieder mehr, weil sie Platz reservieren, der selten gebraucht wird. Welche Marge am günstigsten ist, unterscheidet sich von Netz zu Netz:",[63,5836,5837],{"className":65,"code":2258,"language":67,"meta":68,"style":68},[70,5838,5839,5859,5875,5897,5907,5933,5941,5951],{"__ignoreMap":68},[73,5840,5841,5843,5845,5847,5849,5851,5853,5855,5857],{"class":75,"line":76},[73,5842,2265],{"class":83},[73,5844,181],{"class":79},[73,5846,2270],{"class":83},[73,5848,198],{"class":103},[73,5850,2275],{"class":79},[73,5852,1477],{"class":83},[73,5854,423],{"class":79},[73,5856,2182],{"class":103},[73,5858,690],{"class":83},[73,5860,5861,5863,5865,5867,5869,5871,5873],{"class":75,"line":93},[73,5862,417],{"class":79},[73,5864,420],{"class":83},[73,5866,423],{"class":79},[73,5868,426],{"class":103},[73,5870,429],{"class":83},[73,5872,432],{"class":103},[73,5874,490],{"class":83},[73,5876,5877,5879,5881,5883,5885,5887,5889,5891,5893,5895],{"class":75,"line":100},[73,5878,2304],{"class":83},[73,5880,181],{"class":79},[73,5882,2309],{"class":83},[73,5884,198],{"class":103},[73,5886,2314],{"class":83},[73,5888,417],{"class":79},[73,5890,1477],{"class":83},[73,5892,423],{"class":79},[73,5894,2182],{"class":103},[73,5896,690],{"class":83},[73,5898,5899,5901,5903,5905],{"class":75,"line":124},[73,5900,980],{"class":79},[73,5902,2331],{"class":83},[73,5904,423],{"class":79},[73,5906,2336],{"class":83},[73,5908,5909,5911,5913,5915,5917,5919,5921,5923,5925,5927,5929,5931],{"class":75,"line":139},[73,5910,2341],{"class":79},[73,5912,2344],{"class":83},[73,5914,1407],{"class":79},[73,5916,2349],{"class":103},[73,5918,2352],{"class":83},[73,5920,828],{"class":79},[73,5922,924],{"class":83},[73,5924,788],{"class":103},[73,5926,2361],{"class":79},[73,5928,2364],{"class":103},[73,5930,2367],{"class":83},[73,5932,2370],{"class":135},[73,5934,5935,5937,5939],{"class":75,"line":144},[73,5936,2375],{"class":83},[73,5938,1000],{"class":79},[73,5940,2380],{"class":103},[73,5942,5943,5945,5947,5949],{"class":75,"line":149},[73,5944,417],{"class":79},[73,5946,2387],{"class":83},[73,5948,423],{"class":79},[73,5950,2392],{"class":83},[73,5952,5953,5955,5957,5959,5961,5963,5965,5967,5969,5971,5973,5975,5977,5979,5981],{"class":75,"line":162},[73,5954,496],{"class":103},[73,5956,429],{"class":83},[73,5958,501],{"class":79},[73,5960,2210],{"class":165},[73,5962,507],{"class":103},[73,5964,2215],{"class":83},[73,5966,2218],{"class":79},[73,5968,516],{"class":103},[73,5970,2413],{"class":165},[73,5972,507],{"class":103},[73,5974,2418],{"class":83},[73,5976,2421],{"class":79},[73,5978,516],{"class":103},[73,5980,2426],{"class":165},[73,5982,471],{"class":83},[627,5984],{":lines":2431,"label":4455},[11,5986,5987],{},"Wo zwei Margen denselben Plan ergeben, zählen beide. Die Prognose sagt Ihnen nicht, welche Marge zu einem Netz passt. Das finden Sie durch Simulation heraus oder erst nach Jahren mit diesem Netz.",[36,5989,5991],{"id":5990},"planen-mit-dem-prognosefehler","Planen mit dem Prognosefehler",[11,5993,5994],{},"Quicopt nimmt den Prognosefehler in das Problem auf. Sie schreiben dieselben Kosten wie im MILP, mit einer Änderung: Der Bedarf jeder Region ist eine Zufallszahl um ihre Prognose. Quicopt zieht daraus 1.000 Jahre und wählt das Netz mit den niedrigsten durchschnittlichen Kosten über diese Jahre.",[11,5996,5997,5998,6000,6001,6003],{},"Zwei Dinge im Modell unten unterscheiden sich vom MILP. Das Netz ist eine Aufteilung der acht Regionen auf die fünf Standorte (",[70,5999,2447],{},"). Jede Region gehört zum Teil genau eines Standorts, und ein Standort kostet seine Fixkosten, sobald sein Teil nicht leer ist. Den Überlauf schreibt das Modell so, wie er ist: ",[70,6002,2451],{}," in jedem simulierten Jahr.",[11,6005,6006,6007,6009],{},"Im gekippten Markt teilen die Regionen einen Teil ihrer Schwankung. Das Modell drückt das als eine weitere Zufallszahl aus, ",[70,6008,2458],{},", die den Bedarf aller Regionen zugleich bewegt.",[63,6011,6012],{"className":65,"code":2462,"language":67,"meta":68,"style":68},[70,6013,6014,6024,6034,6044,6048,6056,6060,6064,6072,6076,6080,6084,6092,6104,6124,6132,6148,6170,6188,6204,6222,6242,6264,6276,6286,6306,6342,6366,6388,6438,6454,6510,6536,6578,6598,6606,6612,6624,6648,6652,6656,6668,6680,6686,6708],{"__ignoreMap":68},[73,6015,6016,6018,6020,6022],{"class":75,"line":76},[73,6017,2469],{"class":79},[73,6019,2472],{"class":83},[73,6021,80],{"class":79},[73,6023,2477],{"class":83},[73,6025,6026,6028,6030,6032],{"class":75,"line":93},[73,6027,2469],{"class":79},[73,6029,2484],{"class":83},[73,6031,80],{"class":79},[73,6033,2489],{"class":83},[73,6035,6036,6038,6040,6042],{"class":75,"line":100},[73,6037,2469],{"class":79},[73,6039,2496],{"class":83},[73,6041,80],{"class":79},[73,6043,2501],{"class":83},[73,6045,6046],{"class":75,"line":124},[73,6047,97],{"emptyLinePlaceholder":96},[73,6049,6050,6052,6054],{"class":75,"line":139},[73,6051,2510],{"class":83},[73,6053,181],{"class":79},[73,6055,2515],{"class":83},[73,6057,6058],{"class":75,"line":144},[73,6059,97],{"emptyLinePlaceholder":96},[73,6061,6062],{"class":75,"line":149},[73,6063,97],{"emptyLinePlaceholder":96},[73,6065,6066,6068,6070],{"class":75,"line":162},[73,6067,152],{"class":79},[73,6069,2530],{"class":155},[73,6071,2533],{"class":83},[73,6073,6074],{"class":75,"line":169},[73,6075,2538],{"class":165},[73,6077,6078],{"class":75,"line":175},[73,6079,2543],{"class":165},[73,6081,6082],{"class":75,"line":187},[73,6083,2548],{"class":165},[73,6085,6086,6088,6090],{"class":75,"line":232},[73,6087,1103],{"class":83},[73,6089,181],{"class":79},[73,6091,1108],{"class":83},[73,6093,6094,6096,6098,6100,6102],{"class":75,"line":267},[73,6095,798],{"class":83},[73,6097,181],{"class":79},[73,6099,803],{"class":83},[73,6101,672],{"class":165},[73,6103,457],{"class":83},[73,6105,6106,6108,6110,6112,6114,6116,6118,6120,6122],{"class":75,"line":276},[73,6107,2573],{"class":83},[73,6109,181],{"class":79},[73,6111,803],{"class":83},[73,6113,661],{"class":165},[73,6115,855],{"class":83},[73,6117,828],{"class":79},[73,6119,868],{"class":83},[73,6121,852],{"class":165},[73,6123,457],{"class":83},[73,6125,6126,6128,6130],{"class":75,"line":313},[73,6127,1218],{"class":83},[73,6129,181],{"class":79},[73,6131,1223],{"class":83},[73,6133,6134,6136,6138,6140,6142,6144,6146],{"class":75,"line":340},[73,6135,2602],{"class":83},[73,6137,2605],{"class":103},[73,6139,107],{"class":83},[73,6141,1123],{"class":302},[73,6143,181],{"class":79},[73,6145,2614],{"class":103},[73,6147,471],{"class":83},[73,6149,6150,6152,6154,6156,6158,6160,6162,6164,6166,6168],{"class":75,"line":365},[73,6151,2621],{"class":83},[73,6153,181],{"class":79},[73,6155,2626],{"class":83},[73,6157,2629],{"class":165},[73,6159,107],{"class":83},[73,6161,110],{"class":103},[73,6163,107],{"class":83},[73,6165,104],{"class":103},[73,6167,2640],{"class":83},[73,6169,2643],{"class":135},[73,6171,6172,6174,6176,6178,6180,6182,6184,6186],{"class":75,"line":390},[73,6173,2648],{"class":83},[73,6175,181],{"class":79},[73,6177,1233],{"class":83},[73,6179,1236],{"class":103},[73,6181,429],{"class":83},[73,6183,110],{"class":103},[73,6185,2661],{"class":83},[73,6187,2664],{"class":135},[73,6189,6190,6192,6194,6196,6198,6200,6202],{"class":75,"line":396},[73,6191,980],{"class":79},[73,6193,576],{"class":83},[73,6195,423],{"class":79},[73,6197,426],{"class":103},[73,6199,429],{"class":83},[73,6201,110],{"class":103},[73,6203,490],{"class":83},[73,6205,6206,6208,6210,6212,6214,6216,6218,6220],{"class":75,"line":401},[73,6207,2685],{"class":83},[73,6209,852],{"class":165},[73,6211,2690],{"class":83},[73,6213,788],{"class":103},[73,6215,822],{"class":79},[73,6217,825],{"class":83},[73,6219,828],{"class":79},[73,6221,2701],{"class":83},[73,6223,6224,6226,6228,6230,6232,6234,6236,6238,6240],{"class":75,"line":406},[73,6225,2706],{"class":302},[73,6227,181],{"class":79},[73,6229,501],{"class":79},[73,6231,2713],{"class":165},[73,6233,507],{"class":103},[73,6235,602],{"class":83},[73,6237,516],{"class":103},[73,6239,504],{"class":165},[73,6241,471],{"class":83},[73,6243,6244,6246,6248,6250,6252,6254,6256,6258,6260,6262],{"class":75,"line":438},[73,6245,2728],{"class":83},[73,6247,181],{"class":79},[73,6249,2733],{"class":83},[73,6251,417],{"class":79},[73,6253,576],{"class":83},[73,6255,423],{"class":79},[73,6257,426],{"class":103},[73,6259,429],{"class":83},[73,6261,110],{"class":103},[73,6263,435],{"class":83},[73,6265,6266,6268,6270,6272,6274],{"class":75,"line":443},[73,6267,2752],{"class":79},[73,6269,2755],{"class":83},[73,6271,2758],{"class":79},[73,6273,2761],{"class":103},[73,6275,2185],{"class":83},[73,6277,6278,6280,6282,6284],{"class":75,"line":460},[73,6279,2768],{"class":83},[73,6281,181],{"class":79},[73,6283,2773],{"class":83},[73,6285,793],{"class":135},[73,6287,6288,6290,6292,6294,6296,6298,6300,6302,6304],{"class":75,"line":474},[73,6289,2780],{"class":83},[73,6291,677],{"class":103},[73,6293,107],{"class":83},[73,6295,1183],{"class":103},[73,6297,1243],{"class":83},[73,6299,2791],{"class":302},[73,6301,181],{"class":79},[73,6303,2796],{"class":165},[73,6305,471],{"class":83},[73,6307,6308,6310,6312,6314,6316,6318,6320,6322,6324,6326,6328,6330,6332,6334,6336,6338,6340],{"class":75,"line":493},[73,6309,2803],{"class":83},[73,6311,181],{"class":79},[73,6313,2808],{"class":83},[73,6315,834],{"class":79},[73,6317,2813],{"class":103},[73,6319,2816],{"class":83},[73,6321,828],{"class":79},[73,6323,2821],{"class":83},[73,6325,828],{"class":79},[73,6327,2826],{"class":83},[73,6329,417],{"class":79},[73,6331,576],{"class":83},[73,6333,423],{"class":79},[73,6335,426],{"class":103},[73,6337,429],{"class":83},[73,6339,110],{"class":103},[73,6341,435],{"class":83},[73,6343,6344,6346,6348,6350,6352,6354,6356,6358,6360,6362,6364],{"class":75,"line":554},[73,6345,2845],{"class":83},[73,6347,181],{"class":79},[73,6349,2850],{"class":83},[73,6351,2853],{"class":165},[73,6353,2856],{"class":83},[73,6355,127],{"class":103},[73,6357,929],{"class":79},[73,6359,868],{"class":83},[73,6361,934],{"class":165},[73,6363,2867],{"class":83},[73,6365,2870],{"class":135},[73,6367,6368,6370,6372,6374,6376,6378,6380,6382,6384,6386],{"class":75,"line":571},[73,6369,2875],{"class":83},[73,6371,181],{"class":79},[73,6373,2880],{"class":83},[73,6375,417],{"class":79},[73,6377,576],{"class":83},[73,6379,423],{"class":79},[73,6381,426],{"class":103},[73,6383,429],{"class":83},[73,6385,110],{"class":103},[73,6387,435],{"class":83},[73,6389,6390,6392,6394,6396,6398,6400,6402,6404,6406,6408,6410,6412,6414,6416,6418,6420,6422,6424,6426,6428,6430,6432,6434,6436],{"class":75,"line":589},[73,6391,960],{"class":83},[73,6393,181],{"class":79},[73,6395,2143],{"class":83},[73,6397,1346],{"class":103},[73,6399,2907],{"class":83},[73,6401,2910],{"class":302},[73,6403,181],{"class":79},[73,6405,2915],{"class":83},[73,6407,1367],{"class":79},[73,6409,2920],{"class":83},[73,6411,2923],{"class":302},[73,6413,181],{"class":79},[73,6415,2928],{"class":83},[73,6417,2931],{"class":302},[73,6419,181],{"class":79},[73,6421,677],{"class":103},[73,6423,1597],{"class":83},[73,6425,417],{"class":79},[73,6427,576],{"class":83},[73,6429,423],{"class":79},[73,6431,426],{"class":103},[73,6433,429],{"class":83},[73,6435,110],{"class":103},[73,6437,264],{"class":83},[73,6439,6440,6442,6444,6446,6448,6450,6452],{"class":75,"line":1765},[73,6441,2956],{"class":79},[73,6443,479],{"class":83},[73,6445,423],{"class":79},[73,6447,426],{"class":103},[73,6449,429],{"class":83},[73,6451,104],{"class":103},[73,6453,435],{"class":83},[73,6455,6456,6458,6460,6462,6464,6466,6468,6470,6472,6474,6476,6478,6480,6482,6484,6486,6488,6490,6492,6494,6496,6498,6500,6502,6504,6506,6508],{"class":75,"line":1770},[73,6457,2973],{"class":83},[73,6459,181],{"class":79},[73,6461,924],{"class":83},[73,6463,1346],{"class":103},[73,6465,2907],{"class":83},[73,6467,2910],{"class":302},[73,6469,181],{"class":79},[73,6471,2988],{"class":83},[73,6473,1437],{"class":79},[73,6475,1370],{"class":103},[73,6477,107],{"class":83},[73,6479,2923],{"class":302},[73,6481,181],{"class":79},[73,6483,3001],{"class":83},[73,6485,1049],{"class":165},[73,6487,3006],{"class":83},[73,6489,2931],{"class":302},[73,6491,181],{"class":79},[73,6493,677],{"class":103},[73,6495,1597],{"class":83},[73,6497,417],{"class":79},[73,6499,479],{"class":83},[73,6501,423],{"class":79},[73,6503,426],{"class":103},[73,6505,429],{"class":83},[73,6507,104],{"class":103},[73,6509,264],{"class":83},[73,6511,6512,6514,6516,6518,6520,6522,6524,6526,6528,6530,6532,6534],{"class":75,"line":1781},[73,6513,3033],{"class":79},[73,6515,1440],{"class":103},[73,6517,3038],{"class":83},[73,6519,828],{"class":79},[73,6521,3043],{"class":83},[73,6523,417],{"class":79},[73,6525,576],{"class":83},[73,6527,423],{"class":79},[73,6529,426],{"class":103},[73,6531,429],{"class":83},[73,6533,110],{"class":103},[73,6535,264],{"class":83},[73,6537,6538,6540,6542,6544,6546,6548,6550,6552,6554,6556,6558,6560,6562,6564,6566,6568,6570,6572,6574,6576],{"class":75,"line":1790},[73,6539,3033],{"class":79},[73,6541,1440],{"class":103},[73,6543,3066],{"class":83},[73,6545,682],{"class":165},[73,6547,855],{"class":83},[73,6549,828],{"class":79},[73,6551,3075],{"class":83},[73,6553,291],{"class":79},[73,6555,868],{"class":83},[73,6557,1020],{"class":165},[73,6559,3006],{"class":83},[73,6561,677],{"class":103},[73,6563,1597],{"class":83},[73,6565,417],{"class":79},[73,6567,479],{"class":83},[73,6569,423],{"class":79},[73,6571,426],{"class":103},[73,6573,429],{"class":83},[73,6575,104],{"class":103},[73,6577,3102],{"class":83},[73,6579,6580,6582,6584,6586,6588,6590,6592,6594,6596],{"class":75,"line":1830},[73,6581,1495],{"class":83},[73,6583,181],{"class":79},[73,6585,1500],{"class":83},[73,6587,1511],{"class":302},[73,6589,181],{"class":79},[73,6591,3117],{"class":83},[73,6593,1503],{"class":302},[73,6595,181],{"class":79},[73,6597,3124],{"class":83},[73,6599,6600,6602,6604],{"class":75,"line":1873},[73,6601,3129],{"class":83},[73,6603,181],{"class":79},[73,6605,3134],{"class":83},[73,6607,6608,6610],{"class":75,"line":1878},[73,6609,1673],{"class":79},[73,6611,3141],{"class":83},[73,6613,6614,6616,6618,6620,6622],{"class":75,"line":1883},[73,6615,3146],{"class":83},[73,6617,181],{"class":79},[73,6619,3151],{"class":83},[73,6621,2629],{"class":165},[73,6623,457],{"class":83},[73,6625,6626,6628,6630,6632,6634,6636,6638,6640,6642,6644,6646],{"class":75,"line":1899},[73,6627,270],{"class":79},[73,6629,3162],{"class":83},[73,6631,3165],{"class":103},[73,6633,3168],{"class":83},[73,6635,1437],{"class":79},[73,6637,1370],{"class":103},[73,6639,1597],{"class":83},[73,6641,417],{"class":79},[73,6643,3179],{"class":83},[73,6645,423],{"class":79},[73,6647,3184],{"class":83},[73,6649,6650],{"class":75,"line":1915},[73,6651,97],{"emptyLinePlaceholder":96},[73,6653,6654],{"class":75,"line":1923},[73,6655,97],{"emptyLinePlaceholder":96},[73,6657,6658,6660,6662,6664,6666],{"class":75,"line":1949},[73,6659,3197],{"class":83},[73,6661,181],{"class":79},[73,6663,3202],{"class":83},[73,6665,454],{"class":103},[73,6667,1896],{"class":83},[73,6669,6670,6672,6674,6676,6678],{"class":75,"line":3209},[73,6671,1902],{"class":83},[73,6673,181],{"class":79},[73,6675,1907],{"class":83},[73,6677,454],{"class":103},[73,6679,1912],{"class":83},[73,6681,6682,6684],{"class":75,"line":3222},[73,6683,463],{"class":103},[73,6685,1920],{"class":83},[73,6687,6688,6690,6692,6694,6696,6698,6700,6702,6704,6706],{"class":75,"line":3229},[73,6689,463],{"class":103},[73,6691,429],{"class":83},[73,6693,501],{"class":79},[73,6695,3238],{"class":165},[73,6697,507],{"class":103},[73,6699,3243],{"class":83},[73,6701,1940],{"class":79},[73,6703,516],{"class":103},[73,6705,504],{"class":165},[73,6707,471],{"class":83},[73,6709,6710,6712,6714,6716,6718,6720,6722,6724,6726,6728,6730,6732,6734,6736,6738,6740,6742,6744,6746],{"class":75,"line":3254},[73,6711,463],{"class":103},[73,6713,429],{"class":83},[73,6715,501],{"class":79},[73,6717,3263],{"class":165},[73,6719,507],{"class":103},[73,6721,1963],{"class":83},[73,6723,1940],{"class":79},[73,6725,516],{"class":103},[73,6727,1970],{"class":165},[73,6729,507],{"class":103},[73,6731,1902],{"class":83},[73,6733,1977],{"class":79},[73,6735,3282],{"class":83},[73,6737,291],{"class":79},[73,6739,1370],{"class":103},[73,6741,1987],{"class":79},[73,6743,516],{"class":103},[73,6745,1992],{"class":165},[73,6747,471],{"class":83},[627,6749],{":lines":3297,"label":4455},[11,6751,6752],{},"Quicopts Schätzung von 6.366 trifft die tatsächlichen Kosten von 6.361 auf 0,1 % genau. In Netz 11 schneidet die Marge von 95 % etwas besser ab (6.312), weil Quicopt hier ein Lager mehr betreibt als nötig. Über alle 20 Netze im ruhigen Markt kostet jede Marge so viel mehr als der Plan von Quicopt:",[63,6754,6755],{"className":65,"code":3303,"language":67,"meta":68,"style":68},[70,6756,6757,6765,6769,6773,6781,6797,6805,6809,6829,6837,6849,6869,6885,6917,6945,6981,6987,6991,6995],{"__ignoreMap":68},[73,6758,6759,6761,6763],{"class":75,"line":76},[73,6760,152],{"class":79},[73,6762,3312],{"class":155},[73,6764,3315],{"class":83},[73,6766,6767],{"class":75,"line":93},[73,6768,3320],{"class":165},[73,6770,6771],{"class":75,"line":100},[73,6772,3325],{"class":165},[73,6774,6775,6777,6779],{"class":75,"line":124},[73,6776,3330],{"class":83},[73,6778,181],{"class":79},[73,6780,3335],{"class":83},[73,6782,6783,6785,6787,6789,6791,6793,6795],{"class":75,"line":139},[73,6784,980],{"class":79},[73,6786,420],{"class":83},[73,6788,423],{"class":79},[73,6790,426],{"class":103},[73,6792,429],{"class":83},[73,6794,432],{"class":103},[73,6796,490],{"class":83},[73,6798,6799,6801,6803],{"class":75,"line":144},[73,6800,3356],{"class":83},[73,6802,181],{"class":79},[73,6804,3361],{"class":83},[73,6806,6807],{"class":75,"line":149},[73,6808,3366],{"class":83},[73,6810,6811,6813,6815,6817,6819,6821,6823,6825,6827],{"class":75,"line":162},[73,6812,3371],{"class":83},[73,6814,291],{"class":79},[73,6816,788],{"class":103},[73,6818,855],{"class":83},[73,6820,1977],{"class":79},[73,6822,3282],{"class":83},[73,6824,291],{"class":79},[73,6826,1370],{"class":103},[73,6828,471],{"class":83},[73,6830,6831,6833,6835],{"class":75,"line":169},[73,6832,3392],{"class":83},[73,6834,181],{"class":79},[73,6836,3397],{"class":83},[73,6838,6839,6841,6843,6845,6847],{"class":75,"line":175},[73,6840,980],{"class":79},[73,6842,1477],{"class":83},[73,6844,423],{"class":79},[73,6846,2182],{"class":103},[73,6848,2185],{"class":83},[73,6850,6851,6853,6855,6857,6859,6861,6863,6865,6867],{"class":75,"line":187},[73,6852,3414],{"class":83},[73,6854,181],{"class":79},[73,6856,3419],{"class":83},[73,6858,198],{"class":103},[73,6860,2314],{"class":83},[73,6862,1977],{"class":79},[73,6864,3428],{"class":83},[73,6866,291],{"class":79},[73,6868,2380],{"class":103},[73,6870,6871,6873,6875,6877,6879,6881,6883],{"class":75,"line":232},[73,6872,3437],{"class":79},[73,6874,420],{"class":83},[73,6876,423],{"class":79},[73,6878,426],{"class":103},[73,6880,429],{"class":83},[73,6882,432],{"class":103},[73,6884,435],{"class":83},[73,6886,6887,6889,6891,6893,6895,6897,6899,6901,6903,6905,6907,6909,6911,6913,6915],{"class":75,"line":267},[73,6888,3454],{"class":83},[73,6890,181],{"class":79},[73,6892,3459],{"class":165},[73,6894,3462],{"class":79},[73,6896,1477],{"class":83},[73,6898,1367],{"class":79},[73,6900,1370],{"class":103},[73,6902,3471],{"class":79},[73,6904,1835],{"class":79},[73,6906,2210],{"class":165},[73,6908,507],{"class":103},[73,6910,2215],{"class":83},[73,6912,3482],{"class":79},[73,6914,516],{"class":103},[73,6916,3487],{"class":165},[73,6918,6919,6921,6923,6925,6927,6929,6931,6933,6935,6937,6939,6941,6943],{"class":75,"line":276},[73,6920,3492],{"class":103},[73,6922,429],{"class":83},[73,6924,501],{"class":79},[73,6926,504],{"class":165},[73,6928,507],{"class":103},[73,6930,3503],{"class":83},[73,6932,3506],{"class":79},[73,6934,516],{"class":103},[73,6936,519],{"class":103},[73,6938,3513],{"class":83},[73,6940,516],{"class":103},[73,6942,504],{"class":165},[73,6944,471],{"class":83},[73,6946,6947,6949,6951,6953,6955,6957,6959,6961,6963,6965,6967,6969,6971,6973,6975,6977,6979],{"class":75,"line":313},[73,6948,496],{"class":103},[73,6950,429],{"class":83},[73,6952,501],{"class":79},[73,6954,504],{"class":165},[73,6956,563],{"class":103},[73,6958,3534],{"class":165},[73,6960,3537],{"class":103},[73,6962,3540],{"class":83},[73,6964,1987],{"class":79},[73,6966,516],{"class":103},[73,6968,3547],{"class":165},[73,6970,3550],{"class":103},[73,6972,3540],{"class":83},[73,6974,1987],{"class":79},[73,6976,516],{"class":103},[73,6978,504],{"class":165},[73,6980,471],{"class":83},[73,6982,6983,6985],{"class":75,"line":340},[73,6984,270],{"class":79},[73,6986,3567],{"class":83},[73,6988,6989],{"class":75,"line":365},[73,6990,97],{"emptyLinePlaceholder":96},[73,6992,6993],{"class":75,"line":390},[73,6994,97],{"emptyLinePlaceholder":96},[73,6996,6997,6999,7001],{"class":75,"line":396},[73,6998,3580],{"class":83},[73,7000,181],{"class":79},[73,7002,3585],{"class":83},[627,7004],{":lines":3588,"label":4455},[11,7006,7007],{},"Im ruhigen Markt kostet eine Marge von 95 % im Median nichts extra und im schlechtesten Netz höchstens 4 %. Wer mit dieser Marge plant, liegt gut. Was Quicopt im ruhigen Markt beiträgt, ist eine ehrliche Schätzung. Sie nennt die Kosten, die Sie zahlen werden, während der bewiesene Plan tatsächlich im Median 6,4 % mehr kostet, als er versprochen hat.",[36,7009,7011],{"id":7010},"wenn-der-markt-kippt","Wenn der Markt kippt",[11,7013,7014],{},"Nun stehen dieselben 20 Netze im gekippten Markt. Die Prognosen bleiben dieselben. Was sich ändert, ist der Markt um sie herum. Zuerst Netz 11:",[63,7016,7017],{"className":65,"code":3601,"language":67,"meta":68,"style":68},[70,7018,7019,7031,7073,7089,7101,7137,7149],{"__ignoreMap":68},[73,7020,7021,7023,7025,7027,7029],{"class":75,"line":76},[73,7022,1886],{"class":83},[73,7024,181],{"class":79},[73,7026,1891],{"class":83},[73,7028,454],{"class":103},[73,7030,3616],{"class":83},[73,7032,7033,7035,7037,7039,7041,7043,7045,7047,7049,7051,7053,7055,7057,7059,7061,7063,7065,7067,7069,7071],{"class":75,"line":93},[73,7034,463],{"class":103},[73,7036,429],{"class":83},[73,7038,501],{"class":79},[73,7040,3627],{"class":165},[73,7042,507],{"class":103},[73,7044,1937],{"class":83},[73,7046,1940],{"class":79},[73,7048,516],{"class":103},[73,7050,3638],{"class":165},[73,7052,507],{"class":103},[73,7054,2228],{"class":83},[73,7056,454],{"class":103},[73,7058,3647],{"class":83},[73,7060,1940],{"class":79},[73,7062,516],{"class":103},[73,7064,2240],{"class":103},[73,7066,2243],{"class":83},[73,7068,516],{"class":103},[73,7070,504],{"class":165},[73,7072,471],{"class":83},[73,7074,7075,7077,7079,7081,7083,7085,7087],{"class":75,"line":100},[73,7076,417],{"class":79},[73,7078,1477],{"class":83},[73,7080,423],{"class":79},[73,7082,2182],{"class":103},[73,7084,3674],{"class":83},[73,7086,788],{"class":103},[73,7088,3679],{"class":83},[73,7090,7091,7093,7095,7097,7099],{"class":75,"line":124},[73,7092,2190],{"class":83},[73,7094,181],{"class":79},[73,7096,1891],{"class":83},[73,7098,454],{"class":103},[73,7100,3692],{"class":83},[73,7102,7103,7105,7107,7109,7111,7113,7115,7117,7119,7121,7123,7125,7127,7129,7131,7133,7135],{"class":75,"line":139},[73,7104,496],{"class":103},[73,7106,429],{"class":83},[73,7108,501],{"class":79},[73,7110,2210],{"class":165},[73,7112,507],{"class":103},[73,7114,2215],{"class":83},[73,7116,3482],{"class":79},[73,7118,516],{"class":103},[73,7120,3713],{"class":165},[73,7122,507],{"class":103},[73,7124,2228],{"class":83},[73,7126,454],{"class":103},[73,7128,3647],{"class":83},[73,7130,1940],{"class":79},[73,7132,516],{"class":103},[73,7134,504],{"class":165},[73,7136,471],{"class":83},[73,7138,7139,7141,7143,7145,7147],{"class":75,"line":144},[73,7140,3197],{"class":83},[73,7142,181],{"class":79},[73,7144,3202],{"class":83},[73,7146,454],{"class":103},[73,7148,3616],{"class":83},[73,7150,7151,7153,7155,7157,7159,7161,7163,7165,7167,7169,7171,7173,7175,7177,7179,7181,7183,7185,7187,7189],{"class":75,"line":149},[73,7152,463],{"class":103},[73,7154,429],{"class":83},[73,7156,501],{"class":79},[73,7158,3752],{"class":165},[73,7160,507],{"class":103},[73,7162,3243],{"class":83},[73,7164,1940],{"class":79},[73,7166,516],{"class":103},[73,7168,3638],{"class":165},[73,7170,507],{"class":103},[73,7172,2228],{"class":83},[73,7174,454],{"class":103},[73,7176,3647],{"class":83},[73,7178,1940],{"class":79},[73,7180,516],{"class":103},[73,7182,2240],{"class":103},[73,7184,2243],{"class":83},[73,7186,516],{"class":103},[73,7188,504],{"class":165},[73,7190,471],{"class":83},[627,7192],{":lines":3787,"label":4455},[11,7194,7195],{},"Der Plan für die Prognose ist derselbe wie im ruhigen Markt, und der Solver verspricht weiterhin 5.998. Die tatsächlichen Kosten des Plans liegen nun bei 10.790. Die Marge von 95 %, die zum ruhigen Markt passte, kostet 9.748, also 36 % mehr als der neue Plan von Quicopt mit 7.145. Eine größere Marge hilft, aber erst bei 85 % holt sie Quicopt ein. Quicopt selbst brauchte nur die neuen Zahlen des Marktes, und Quicopts Schätzung von 7.079 weicht um weniger als 1 % von den tatsächlichen Kosten ab. Über alle 20 Netze im gekippten Markt:",[63,7197,7198],{"className":65,"code":3793,"language":67,"meta":68,"style":68},[70,7199,7200,7208,7212,7220,7236,7244,7258,7268,7282],{"__ignoreMap":68},[73,7201,7202,7204,7206],{"class":75,"line":76},[73,7203,3800],{"class":83},[73,7205,181],{"class":79},[73,7207,3805],{"class":83},[73,7209,7210],{"class":75,"line":93},[73,7211,97],{"emptyLinePlaceholder":96},[73,7213,7214,7216,7218],{"class":75,"line":100},[73,7215,2060],{"class":83},[73,7217,181],{"class":79},[73,7219,2065],{"class":83},[73,7221,7222,7224,7226,7228,7230,7232,7234],{"class":75,"line":124},[73,7223,417],{"class":79},[73,7225,420],{"class":83},[73,7227,423],{"class":79},[73,7229,426],{"class":103},[73,7231,429],{"class":83},[73,7233,432],{"class":103},[73,7235,490],{"class":83},[73,7237,7238,7240,7242],{"class":75,"line":139},[73,7239,2086],{"class":83},[73,7241,181],{"class":79},[73,7243,3842],{"class":83},[73,7245,7246,7248,7250,7252,7254,7256],{"class":75,"line":144},[73,7247,3847],{"class":83},[73,7249,1977],{"class":79},[73,7251,1980],{"class":83},[73,7253,291],{"class":79},[73,7255,1370],{"class":103},[73,7257,471],{"class":83},[73,7259,7260,7262,7264,7266],{"class":75,"line":149},[73,7261,463],{"class":103},[73,7263,429],{"class":83},[73,7265,3866],{"class":165},[73,7267,2118],{"class":83},[73,7269,7270,7272,7274,7276,7278,7280],{"class":75,"line":162},[73,7271,3873],{"class":83},[73,7273,181],{"class":79},[73,7275,3878],{"class":103},[73,7277,3881],{"class":83},[73,7279,1183],{"class":103},[73,7281,3886],{"class":83},[73,7283,7284,7286,7288,7290,7292,7294,7296,7298,7300,7302,7304,7306,7308,7310,7312,7314],{"class":75,"line":169},[73,7285,463],{"class":103},[73,7287,429],{"class":83},[73,7289,501],{"class":79},[73,7291,3897],{"class":165},[73,7293,507],{"class":103},[73,7295,3902],{"class":83},[73,7297,516],{"class":103},[73,7299,924],{"class":165},[73,7301,507],{"class":103},[73,7303,3911],{"class":83},[73,7305,1183],{"class":103},[73,7307,3916],{"class":83},[73,7309,1987],{"class":79},[73,7311,516],{"class":103},[73,7313,1992],{"class":165},[73,7315,471],{"class":83},[627,7317],{":lines":3927,"label":4455},[11,7319,7320],{},"Die Marge, die zum ruhigen Markt passte, kostet jetzt im Median 14,5 % mehr als der Plan von Quicopt, und bis zu 36 % mehr. Die Planung für die Prognose kostet im Median 18 % mehr, und ihre tatsächlichen Kosten liegen fast 50 % über dem, was der Solver verspricht.",[11,7322,7323],{},"Wenn der Markt kippt, vergrößern Sie die Marge. Aber um wie viel? Der Prognosefehler hat sich verdoppelt, also verdoppeln Sie vielleicht auch die Reserve, von 5 % der Kapazität auf 10 %. Das ist die Marge von 90 %, und sie kostet im Median immer noch 6,7 % mehr als der Plan von Quicopt, und bis zu 27 % mehr. Die Marge, die zum gekippten Markt passt, ist 80 %, das Vierfache der alten Reserve. Damit ziehen Sie wieder mit Quicopt gleich. Doch mit dem Umschwung haben sich alle drei Zahlen des Marktes zugleich verändert, und eine einzige Marge muss sie alle auffangen. Nichts in den neuen Zahlen deutet auf 80 %. Das finden Sie durch Simulation heraus, oder indem Sie die Überlaufrechnungen der nächsten Jahre bezahlen. Quicopt nimmt die drei neuen Zahlen, wie sie sind.",[36,7325,7327],{"id":7326},"fragen-an-ihr-planungsteam","Fragen an Ihr Planungsteam",[11,7329,7330],{},"Ob Ihr Netz eher dem ruhigen oder dem gekippten Markt gleicht, können nur Ihre Daten zeigen. Drei Fragen helfen, es herauszufinden:",[3942,7332,7333,7339,7345],{},[47,7334,7335,7338],{},[3947,7336,7337],{},"Wie puffern Sie heute?"," Mit einer pauschalen Kapazitätsmarge („wir planen Lager auf 85 %“) oder mit einem Sicherheitszuschlag pro Region (die Prognose plus ein Vielfaches ihres Fehlers)? Wie wurde die Höhe des Puffers festgelegt?",[47,7340,7341,7344],{},[3947,7342,7343],{},"Wie genau sind Ihre Prognosen, und wie ungleich ist diese Genauigkeit verteilt?"," Der typische Fehler pro Region oder Produkt, und ob sich etablierte und neue Märkte stark unterscheiden.",[47,7346,7347],{},[3947,7348,7349],{},"Wann haben Sie Ihre Marge zuletzt geändert, und was hat Sie dazu bewogen?",[3963,7351,3965],{},{"title":68,"searchDepth":93,"depth":93,"links":7353},[7354,7355,7356,7357,7358,7359,7360],{"id":4011,"depth":93,"text":4012},{"id":4458,"depth":93,"text":4459},{"id":4881,"depth":93,"text":4882},{"id":5723,"depth":93,"text":5724},{"id":5990,"depth":93,"text":5991},{"id":7010,"depth":93,"text":7011},{"id":7326,"depth":93,"text":7327},{},"\u002Fuse-cases\u002Fwarehouse-planning.de",{"title":3984,"description":3989},"use-cases\u002Fwarehouse-planning.de","iOoSBpbpAyq4NgS7Pv_H7Sb27FhWh2nrt_QoOwBLzoA",1793021636892]