Supply Chain
Centers‑of‑Gravity Calculator

  • Calculates Center-of-Gravity locations - indicative warehouse locations that minimize transport costs - given demand per customer location (and supply per supplier location), taking into account constraints. Helps to answer the question where to open (a) new warehouse(s)?
    • You can run a greenfield analysis, add predefined warehouses and constrain their capacity and move range, force a link between a customer and a (subset of) warehouse(s), group customers for single‑sourcing, add the supply-side (with auto-generated flows), run sensitivity analyses, improve demand reached within service level distance, ...
  • Selects the best warehouses from a predefined set - those that minimize transport costs (plus semi-fixed and variable warehousing costs) - taking into account constraints. Helps to answer the question which warehouse(s) to keep and which to close?
    • You can specify how many warehouses must be selected (per subset of warehouses), which ones must be included, and activate capacity and other constraints.
  • Also
    • Used worldwide since 2014 by logistics service providers, consultancies, and multinationals.
    • Your data is stored on your computer.
  • The live demo shows how it helps to optimize your supply chain network design.
We have been using Centers‑of‑Gravity Calculator for years. It is better fit for purpose than the other tools we use(d) for this and we like the way Stelling Consulting is constantly improving the tool to make it even better.
Jeroen Martens
Head of Transport Solutions Design MLE MEA &
Network Design & Supply Chain Consulting Global Practice Lead
DHL Supply Chain
🡇
 Note: via section "Collaborate" you can export map settings into a scenario file, and import map settings only from a scenario file.
Map center - Latitude
Map center - Longitude
Map zoom
Map width
Map height
Carto map
ESRI map
OpenStreetMap map
Customer/supplier size factor 
⇐ Set it such that 1st legend value becomes  
i
Center-of-Gravity size factor 
Flow size factor 
i
Customer/supplier opacity 
Center-of-Gravity opacity 
Center-of-Gravity inner color  
 Fixed Center-of-Gravity color
i
 Activate Center-of-Gravity color grid
i
Color grid stretch factor
i
Label font size 
Display transport-rated volumes
i
Display Center-of-Gravity as fixed-sized circles
i
Display customer flows
Display supplier flows
Supplier flows color  
Supplier flows arrow size 
i
Scale supplier flows arrows
Display customer IDs
Distance based customer coloring
i
 Differentiate demand map
i
 
Store
Reset
Fit

You need to enable javascript!

Or click button 'Import | Export' above each input table, enter data (tab or semicolon separated) in textarea, click button again.
You have not logged in. Changes to customers demo data are ignored. Create an account to be able to log in and run with your own customers data.

You can adjust all other input tables, parameters & constraints, and run the software, to see how it works.

Customers

141.153320.16833430AL172
246.633314.31284270AT214
346.989415.58174200AT210
447.25211.424690AT235
547.578412.73053550AT178
647.991113.887811530AT577
748.067113.17753300AT165
848.202516.41864600AT230
948.204916.27346100AT305
1048.229716.46922620AT131
1148.365613.97713340AT167
1243.331917.75135900BA295
1343.878418.35932460BA123
1450.24584.85192720BE136
1550.37534.38193420BE171
1650.41724.4473220BE161
1750.45553.96623500BE175
1850.4614.84982940BE147
1950.47974.16984600BE230
2050.5885.86022840BE142
2150.58824.32533120BE156
2250.593.39222960BE148
2350.59425.43313200BE160
2450.59786.13253280BE164
2550.64735.58326550BE328
2650.72374.55433140BE157
2750.74163.22382420BE121
2850.78864.86122980BE149
2950.81375.20892460BE123
3050.81853.27852440BE122
3150.8494.42975360BE268
3250.85215.68783520BE176
3350.88324.35519200BE460
3450.89034.73818200BE410
3550.89894.3913200BE160
3650.93165.33684880BE244
3750.94063.11816900BE345
3850.94394.04422920BE146
3950.96765.48863160BE158
4050.98364.8213280BE164
4150.98943.51063380BE169
4251.00773.3683080BE154
4351.02934.0942540BE127
4451.03534.46653280BE164
4551.05323.63079480BE474
4651.124.57342780BE139
4751.14624.33834120BE206
4851.164.82773440BE172
4951.16954.16474240BE212
5051.20625.37982480BE124
5151.2124.46863670BE184
5251.21472.9193280BE164
5351.22114.36643130BE157
5451.23293.21183610BE181
5551.23845.19493280BE164
5651.27064.50284450BE223
5751.33693.32343850BE193
5851.35314.7712780BE139
5942.68723.32734660BG233
6042.726623.315818640BG932
6153.123226.57967000BY350
6246.03388.97192940CH147
6346.12587.22742620CH131
6446.34076.19743670CH184
6546.59026.67164600CH230
6646.93747.43452700CH135
6746.969.05525800CH290
6846.96528.21832640CH132
6947.19217.56153360CH168
7047.30927.60314560CH228
7147.34759.40812520CH126
7247.37768.53815900CH295
7347.40368.03742820CH141
7447.55677.59793730CH187
7547.57779.08993340CH167
7635.030933.13745960CY298
7749.181216.67692520CZ126
7849.839718.32482800CZ140
7949.88616.47112610CZ631
8049.887914.65555000CZ250
8150.044614.56167790CZ390
8250.136814.46013000CZ150
8350.22414.07762840CZ142
8447.748710.4642420DE121
8547.844112.20044060DE203
8647.848411.28494480DE224
8747.89488.07213700DE185
8847.90839.54462560DE128
8947.98218.68013240DE162
9048.12511.60057370DE369
9148.182711.54956400DE320
9248.32548.95952620DE131
9348.337110.84774870DE244
9448.434212.41173240DE162
9548.446110.11333880DE194
9648.489111.56843560DE178
9748.726413.06732800DE140
9848.75579.18173520DE176
9948.78759.84224630DE232
10048.81839.35294300DE215
10148.96868.29096120DE306
10249.092912.35277240DE362
10349.28429.50624300DE215
10449.3417.11153370DE169
10549.357810.95455520DE276
10649.406910.99995080DE254
10749.42511.9613380DE169
10849.42888.92782440DE122
10949.46198.50934750DE238
11049.51317.9894630DE232
11149.74778.76633260DE163
11249.84577.71225360DE268
11349.962210.016615520DE776
11450.05649.06168740DE437
11550.089111.92072960DE148
11650.11311.00842500DE125
11750.11528.65634800DE240
11850.20848.19024600DE230
11950.30197.53174840DE242
12050.526110.69563180DE159
12150.549812.40752980DE149
12250.60646.92744900DE245
12350.67819.74572800DE140
12450.732811.70884840DE242
12550.777413.12323940DE197
12650.79868.68663480DE174
12750.80856.28724160DE208
12850.90016.75875900DE295
12950.93157.99582860DE143
13050.96097.38265360DE268
13151.17536.47733520DE176
13251.177313.78975600DE280
13351.186810.83034840DE242
13451.201914.52073280DE164
13551.2146.81364280DE214
13651.21619.19774360DE218
13751.30137.59813100DE155
13851.344112.93573840DE192
13951.49428.01544630DE232
14051.496712.02024360DE218
14151.52459.92083520DE176
14251.5327.36955800DE290
14351.54346.38757500DE375
14451.55577.13728980DE449
14551.7176.59462400DE120
14651.756814.03472780DE139
14751.78988.68245400DE270
14852.12357.43024200DE210
14952.15958.82322760DE138
15052.187510.6834420DE221
15152.245514.01423250DE163
15252.317912.78862740DE137
15352.323510.0994060DE203
15452.385111.64952560DE128
15552.40139.69575000DE250
15652.459413.48923220DE161
15752.511713.40793370DE169
15852.53167.72785700DE285
15952.587813.33928560DE428
16052.949313.16483280DE164
16153.08998.84413060DE153
16253.20829.35742500DE125
16353.29347.76664900DE245
16453.357411.48063360DE168
16553.4569.8083520DE176
16653.56259.99144540DE227
16753.5913.33373060DE153
16853.632710.08747780DE389
16953.95510.9566050DE303
17054.031812.42734570DE229
17154.31679.89183550DE178
17254.32569.12573340DE167
17355.614712.31887300DK365
17455.668912.553250DK163
17559.221724.1876810EE341
17635.2931-2.94922420MadridESIberia121
17735.8917-5.33053000MadridESIberia150
17836.1408-5.35362440MadridESIberia122
17936.5295-5.755411200MadridESIberia560
18036.8099-4.663212760MadridESIberia638
18137.3103-2.34286040MadridESIberia302
18237.3968-3.2311000MadridESIberia550
18337.5034-6.79915800MadridESIberia290
18437.5264-5.580714280MadridESIberia714
18537.9667-3.34425800MadridESIberia290
18637.9718-4.76917300MadridESIberia365
18738.073-1.470212160MadridESIberia608
18838.3649-0.423718480MadridESIberia924
18938.7208-5.96838840MadridESIberia442
19038.7359-1.8656000MadridESIberia300
19138.979-3.79945700MadridESIberia285
19239.3672-0.736125920MadridESIberia1296
19339.61782.90676920MadridESIberia346
19439.7771-6.29814800MadridESIberia240
19539.8069-4.11615000MadridESIberia250
19639.9488-2.12172880MadridESIberia144
19740.2532-0.13815300MadridESIberia265
19840.5295-3.766977840MadridESIberia3892
19940.6066-0.72993320MadridESIberia166
20040.6391-4.90622540MadridESIberia127
20140.7418-2.50935250MadridESIberia263
20240.7762-6.00964690MadridESIberia235
20341.05360.92185000MadridESIberia250
20441.1183-3.95733340MadridESIberia167
20541.693-6.15063160MadridESIberia158
20641.7153-4.64884600MadridESIberia230
20741.7472.072357700MadridESIberia2885
20841.8449-0.866212800MadridESIberia640
20942.06711.09734720MadridESIberia236
21042.07342.50639820MadridESIberia491
21142.1097-0.06372960MadridESIberia148
21242.1882-7.52375000MadridESIberia250
21342.2716-2.40016040MadridESIberia302
21442.3387-3.57944520MadridESIberia226
21542.3728-8.36898020MadridESIberia401
21642.4117-4.48143480MadridESIberia174
21742.6085-1.605411160MadridESIberia558
21842.63-5.89456850MadridESIberia343
21942.8386-2.74894840MadridESIberia242
22043.0522-7.37175800MadridESIberia290
22143.1264-3.99526100MadridESIberia305
22243.1369-8.475715040MadridESIberia752
22343.1534-2.15684600MadridESIberia230
22443.2274-2.94127930MadridESIberia397
22543.254-5.82557320MadridESIberia366
22660.161624.484427040FI1352
22742.179.05962400FR120
22842.63112.43883520FR176
22943.03392.47543340FR167
23043.13790.1642700FR135
23143.1855-0.87787150FR358
23243.31181.247911440FR572
23343.41896.2955440FR272
23443.54245.02877510FR376
23543.59033.3636760FR338
23643.78362.24932440FR122
23743.90027.185810900FR545
23843.9514.07743520FR176
23943.99885.2163790FR190
24044.0016-0.68423300FR165
24144.06591.36962520FR126
24244.29612.64162920FR146
24344.35610.48153240FR162
24444.72375.24952480FR124
24544.8705-0.473115430FR772
24645.12830.71132760FR138
24745.28435.57254600FR230
24845.33131.88353520FR176
24945.48216.40612960FR148
25045.66450.2512400FR120
25145.707-0.60453160FR158
25245.75174.24175480FR274
25345.76483.19227250FR363
25445.86674.71588040FR402
25545.90051.26593640FR182
25646.05965.46722520FR126
25746.07016.42983160FR158
25846.36153.12382760FR138
25946.475-0.31323220FR161
26046.58710.54763140FR157
26146.66024.54322800FR140
26246.6798-1.33153400FR170
26346.76565.72513080FR154
26446.80941.54973520FR176
26547.01222.43472680FR134
26647.05586.38973080FR154
26747.21810.72644360FR218
26847.3432-1.72856680FR334
26947.3935-0.53693730FR187
27047.46174.80034840FR242
27147.62856.95872760FR138
27247.66071.43622400FR120
27347.8153-2.86753430FR172
27447.85053.60843460FR173
27547.8677.23163280FR164
27647.91592.28664090FR205
27748.01760.23634330FR217
27848.142-0.63823580FR179
27948.15486.31453240FR162
28048.1559-1.63919960FR498
28148.2314-4.0695840FR292
28248.32114.1473440FR172
28348.4526-2.77614090FR205
28448.45571.39173020FR151
28548.52862.26167000FR350
28648.57210.07392920FR146
28748.58157.59716350FR318
28848.61382.96915050FR253
28948.7631.84217840FR392
29048.77312.45156700FR335
29148.84092.23534540FR1727
29248.86082.32738740FR437
29348.90572.451910500FR525
29448.94595.98185760FR288
29548.96844.24246850FR343
29649.00865.38143340FR167
29749.01456.79533250FR163
29849.06631.07322500FR125
29949.07292.10666200FR310
30049.0903-1.33873580FR179
30149.0927-0.35373910FR196
30249.41292.42794600FR230
30349.46573.60213400FR170
30449.67140.93065650FR283
30549.97462.30592980FR149
30650.5313.164314560FR728
30750.53752.35714750FR238
30841.918644.36282940GE147
30935.322525.02983490GR175
31037.531923.34074760GR238
31137.893523.77652640GR132
31237.93823.71793360GR168
31337.986723.72076160GR308
31437.989423.73769750GR488
31538.003823.6366160GR308
31638.018223.86414640GR232
31738.082923.83143300GR165
31838.226421.81533340GR167
31939.567920.84953520GR176
32039.571622.46813020GR151
32140.581123.01073480GR174
32240.675222.93833340GR167
32340.698623.29853700GR185
32440.772522.98973580GR179
32545.792116.02514600HR230
32647.476819.13926220HU311
32747.549219.00323700HU185
32847.631619.38114360HU218
32951.8969-8.48637960BirminghamIEIE398
33052.2523-7.12723520BirminghamIEIE176
33152.2713-9.69992800BirminghamIEIE140
33252.6541-7.24482640BirminghamIEIE132
33352.668-8.63054390BirminghamIEIE220
33453.2706-9.05674150BirminghamIEIE208
33553.3498-6.260325990BirminghamIEIE1300
33653.7179-6.35613200BirminghamIEIE160
33754.2766-8.47612880BirminghamIEIE144
33836.907814.68212600ITIT130
33937.037215.08973520ITIT176
34037.494214.84949080ITIT454
34137.875112.78163260ITIT163
34237.896913.66013920ITIT196
34338.055114.9134600ITIT230
34438.391716.11252860ITIT143
34538.973616.65024560ITIT228
34639.587216.37833370ITIT169
34739.61139.00926530ITIT327
34840.16418.17123960ITIT198
34940.22839.09852460ITIT123
35040.418715.1514510ITIT226
35140.529815.89133120ITIT156
35240.558317.26424090ITIT205
35340.641117.75682680ITIT134
35440.787714.45949910ITIT496
35540.81848.90294390ITIT220
35640.9915.08292860ITIT143
35741.032816.66327930ITIT397
35841.205914.1422420ITIT121
35941.229614.77792540ITIT127
36041.462113.19192460ITIT123
36141.528115.59694280ITIT214
36241.619813.48993320ITIT166
36341.722514.54243380ITIT169
36441.854812.501427680ITIT1384
36542.105714.46173480ITIT174
36642.173813.64182820ITIT141
36742.318714.00833240ITIT162
36842.505511.97243500ITIT175
36942.670612.40412820ITIT141
37042.678713.74793600ITIT180
37142.765711.23062960ITIT148
37243.006513.54813480ITIT174
37343.104812.64440ITIT222
37443.16311.45314060ITIT203
37543.169813.27723360ITIT168
37643.476110.6229560ITIT478
37743.487213.20562460ITIT123
37843.524311.9193520ITIT176
37943.692312.63693120ITIT156
38043.828111.21395400ITIT270
38143.95367.82983200ITIT160
38244.032512.19917100ITIT355
38344.22329.75942920ITIT146
38444.25828.32523380ITIT169
38544.344811.95494000ITIT200
38644.44211.28985760ITIT288
38744.4519.05724640ITIT232
38844.46677.55914600ITIT230
38944.54210.90654330ITIT217
39044.604810.50673670ITIT184
39144.69279.95673910ITIT196
39244.754211.78222560ITIT128
39344.82889.59743380ITIT169
39444.83538.18882720ITIT136
39544.85378.6473100ITIT155
39644.967111.85373600ITIT180
39745.02649.03484850ITIT243
39845.135610.85013260ITIT163
39945.17367.37912700ITIT635
40045.19269.89364270ITIT214
40145.392311.77876550ITIT328
40245.42211.05678620ITIT431
40345.458812.47544870ITIT244
40445.48089.119723500ITIT1175
40545.55228.1964540ITIT227
40645.617711.46493820ITIT191
40745.73629.84214720ITIT236
40845.757310.35167930ITIT397
40945.779813.62453120ITIT156
41045.809412.21133940ITIT197
41145.85718.79994840ITIT242
41245.86558.33884760ITIT238
41345.93059.15723610ITIT181
41446.129911.2022760ITIT138
41546.13579.91823180ITIT159
41646.193313.01437150ITIT358
41746.290712.16462780ITIT139
41846.664511.38933380ITIT169
41954.891723.92212620LT131
42055.150822.9553220LT161
42155.169423.88134750LT238
42255.930225.35593480LT174
42356.987424.10594750LV238
42449.81536.12963940LX197
42547.025228.85093440MD172
42641.987621.49023480MK174
42735.937514.37546120MTIT306
42850.88665.96193440NL172
42951.10765.86265720NL286
43051.37126.17112420NL121
43151.42045.4013420NL171
43251.43755.48173160NL158
43351.49244.03783120NL156
43451.58864.78132900NL145
43551.5985.09232440NL122
43651.6865.302713100NL655
43751.80645.258512640NL632
43851.84715.86354450NL223
43951.91764.48873790NL190
44051.98055.90592680NL134
44152.0235.03614920NL246
44252.0245.5572840NL142
44352.07874.31724870NL244
44452.08795.11622680NL134
44552.13265.291313740NL687
44652.15185.04512700NL135
44752.15544.49162760NL138
44852.22086.89932800NL140
44952.22445.17647900NL395
45052.30814.94424600NL230
45152.37284.90676700NL335
45252.51136.09032760NL138
45352.63074.75053120NL156
45452.73086.47235740NL287
45552.78476.90092860NL143
45653.2186.57072620NL131
45759.732610.79136450NO323
45859.934210.79947780NO389
45950.21819.0024160PL208
46051.813519.44510450PL523
46152.107721.081529210PL1461
46252.265817.62522860PL143
46352.28221.03863000PL150
46437.0213-7.93382680MadridPTIberia134
46538.525-8.89866120MadridPTIberia306
46638.7367-9.133919060MadridPTIberia953
46739.2322-8.6862620MadridPTIberia131
46839.3999-8.22452720MadridPTIberia136
46939.7425-8.80642760MadridPTIberia138
47040.2108-8.42215640MadridPTIberia282
47140.6266-8.64792840MadridPTIberia142
47240.6447-7.30442780MadridPTIberia139
47340.6592-7.91473460MadridPTIberia173
47441.1515-8.605110180MadridPTIberia509
47541.5453-8.41993940MadridPTIberia197
47644.390226.116126080RO1304
47744.440326.03425960RO298
47844.453126.12867580RO379
47944.520726.13589080RO454
48045.794525.22653040RO152
48145.930324.304418170RO909
48244.016521.005920720RS1036
48344.826220.45719300RS465
48452.232021.0158145900PL7295
48557.38712.279222750SE1138
48646.056314.504710090SI505
48746.556515.64994900SI245
48848.049818.25323140SK157
48948.066517.1553490SK175
49048.197617.14784570SK229
49148.67420.78493120SK156
49248.753619.29415640SK282
49349.135621.18673190SK160
49436.899530.70592780TR139
49537.036937.28752620TR131
49637.286735.73333040TR152
49737.869832.39944320TR216
49838.48927.226122280TR1114
49938.709735.84096160TR308
50039.624237.32572440TR122
50139.919132.7538560TR428
50240.191429.05552460TR123
50340.368936.54313260TR163
50440.907139.80052480TR124
50541.010529.002555600TR2780
50641.200736.13772900TR145
50748.379431.165624400UA1220
50848.437134.90454900UA245
50950.442430.52217780UA389
51049.2044-2.1372860BirminghamUKUK143
51150.4536-3.70992960BirminghamUKUK148
51250.4769-4.42834040BirminghamUKUK202
51350.8499-0.941919360BirminghamUKUK968
51450.8647-0.12392940BirminghamUKUK147
51550.9034-3.79712820BirminghamUKUK141
51650.9553-1.36834090BirminghamUKUK205
51751.0893-0.29953180BirminghamUKUK159
51851.0970.52012840BirminghamUKUK142
51951.1703-0.75546450BirminghamUKUK323
52051.3326-0.39053440BirminghamUKUK172
52151.37750.08539240BirminghamUKUK462
52251.41560.26932480BirminghamUKUK124
52351.4249-2.65713160BirminghamUKUK158
52451.4389-0.42693460BirminghamUKUK173
52551.44770.01232800BirminghamUKUK140
52651.4535-0.18934960BirminghamUKUK248
52751.5144-0.17853140BirminghamUKUK157
52851.5168-0.18053020BirminghamUKUK151
52951.5313-0.02583100BirminghamUKUK155
53051.5491-0.36383580BirminghamUKUK179
53151.5559-0.11552600BirminghamUKUK130
53251.56780.27253280BirminghamUKUK164
53351.5699-0.10353280BirminghamUKUK164
53451.5805-0.20733910BirminghamUKUK196
53551.5844-0.34794120BirminghamUKUK206
53651.60290.07713360BirminghamUKUK168
53751.622-3.39928700BirminghamUKUK435
53851.6633-0.38792740BirminghamUKUK137
53951.7784-0.31568840BirminghamUKUK442
54051.79240.48023440BirminghamUKUK172
54151.8347-1.29953910BirminghamUKUK196
54251.8808-4.43482780BirminghamUKUK139
54351.96790.87492560BirminghamUKUK128
54451.9687-0.1532660BirminghamUKUK133
54552.0941-0.685148300BirminghamUKUK2415
54652.22520.23782400BirminghamUKUK120
54752.273-0.86613060BirminghamUKUK153
54852.3304-1.48212800BirminghamUKUK140
54952.3767-1.83683520BirminghamUKUK176
55052.4658-1.98793420BirminghamUKUK171
55152.4664-1.888632500BirminghamUKUK1625
55252.6388-1.02364720BirminghamUKUK236
55352.66391.233114430BirminghamUKUK722
55452.72680.1283260BirminghamUKUK163
55552.9482-3.814412840BirminghamUKUK642
55653.0054-0.8013100BirminghamUKUK155
55753.2034-3.03123340BirminghamUKUK167
55853.2582-1.40472800BirminghamUKUK140
55953.3608-1.46742600BirminghamUKUK130
56053.374-2.54962720BirminghamUKUK136
56153.4236-1.45763260BirminghamUKUK163
56253.4301-1.40922420BirminghamUKUK121
56353.4669-2.22383460BirminghamUKUK173
56453.51-2.24273280BirminghamUKUK164
56553.5178-1.46472940BirminghamUKUK147
56653.5278-0.61532440BirminghamUKUK122
56753.5478-2.65383400BirminghamUKUK170
56853.6686-1.45811700BirminghamUKUK585
56953.7526-0.30072760BirminghamUKUK138
57053.7726-2.78522900BirminghamUKUK145
57153.8316-2.98043340BirminghamUKUK167
57253.8482-2.37867000BirminghamUKUK350
57353.859-1.53863130BirminghamUKUK157
57453.9762-2.01785920BirminghamUKUK296
57554.1184-0.78913220BirminghamUKUK161
57654.5486-1.12675760BirminghamUKUK288
57754.7576-2.90546200BirminghamUKUK310
57854.8088-1.77222820BirminghamUKUK141
57954.8533-1.3942760BirminghamUKUK138
58055.2237-2.02766250BirminghamUKUK313
58155.3781-3.43616000BirminghamUKUK800
58255.4331-4.5093020BirminghamUKUK151
58355.6095-3.77233360BirminghamUKUK168
58455.7945-4.20766600BirminghamUKUK330
58555.8453-4.31126500BirminghamUKUK325
58656.7077-2.75973040BirminghamUKUK152
58757.2367-2.78212780BirminghamUKUK139
58857.8682-4.44482620BirminghamUKUK131
Click on a cell to change data (and press enter), or to highlight a customer on the map. Click on header to sort data.
If customers are displayed too large on the map, then decrease size factor in Map settings (under map).
To run a greenfield analysis, you only need to enter Customer_ID, Latitude, Longitude, and Demand. All fields are explained in section
"About tables and fields"
. Try to keep the number of customers (well) below 20,000. Most supply chain models - seen during 20 years of practice - contained (far) less than 10,000 customers. Section
"About tables and fields"
provides suggestions how you may aggregate data.

Predefined warehouses (optional)

Demo data contains many warehouses to demonstrate the functionality of section
"Select best warehouses from predefined set"
.
Optional tables are linked to constraints. You need to activate constraints before data is taken into account. This is done via section
"Parameters & constraints"
- subsection
"Constraints"
. Read section
"About tables and fields"
for more info.

Suppliers (optional)

Border crossing points (optional)

After data entry, check relevant constraints, otherwise your input data will be partly ignored!
This is done via section
"Parameters & constraints"
- subsection
"Constraints"
, as is also explained in below section
"About tables and fields"
.
This section explains all input table fields. After having read it, it is handy to also read next ssection
"About using the software - Logical steps"
.

Customers

  • Customer_ID: free format identifier.
  • Latitude, Longitude is the result of converting a textual ship-to address (not sold-to adress) into geographic coordinates - a process called geocoding. You can use our:
    • Batch Geocoder - Free
    • Batch Geocoder - Paid
    • Excel interfaces with Google Maps / TomTom / BING geocoding api
    • Or use any other geocoder of your own choice.

    • Check postal codes for leading zeroes. If - for example - you notice German or French postal codes with only 4 digits only in your data instead of 5, then there is a leading zero issue/missing. This issue is quickly caused in/by Excel if you have not set your postal code column to type "text". It then may cause geocoding problems. And if you aggregate such incorrect data at two digit postal code level, you end up with an incorrect aggregation, with demand ending up at the wrong location!
    • Put aggregated demand of far-away-customers delivered by sea/air (on a country's overseas island, for example) on exit harbour/airport (latitude/longitude), to ensure that Centers-of-Gravity are pulled in the right direction, and to avoid that one of the Centers-of-Gravity ends up in such remote customer area. Or simply remove such customers completely from the model, if their aggregated demand is marginal.
    • Suggestions for aggregating customer data

      In general, try to keep your model small. If your original customer data set contains more than 20,000 records, most likely this amount can be greatly reduced by aggregating it, while keeping model outcomes valid. It will make the model run (much) faster, and prevent performance issues.

      • You may aggregate demand per 2-digit postal code if creating a supply chain model for total Europe. (Note that transport rate tables also often use some aggregated postal code zones.) Each country then means 100 customers at most. For example, customer DE-13 stands for all German customers with postal code 13XXX (ISO Alpha-2 country code for Germany is DE).
        Add 2-digit postal codes to your data table. Create a pivot table to sum the demand per 2-digit postal code. Use the geocodes of the largest customer with the applicable 2-digit postal code to locate the aggregated demand. (No need to geocode all customers!) Or simply use the geocodes from downloadable file below.


        If running a Center-of-Gravity analysis for a single country, then aggregating at 3 digit postal code level may be more appropriate. This will result in a model with 1000 customers, at most.

      • You may round each customer latitude and longitude to two digits, then aggregate demand per pair of rounded latitude, longitude. By rounding, each customer will "move" 0.78 km (or 0.5 mile) away from its original position, at most. 0.78 km being the as-the-crow-flies distance between point (0.00, 0.00) and (0.005, 0.005). The further away from the Equator, the less it becomes. At latitude 44 it is 0.68 km, at most. And on average it will be 0.37 km only. It will be unnoticeable on the map. Customer "moves" will counterbalance each other to a large extent, so Center-of-Gravity locations will be hardly affected at all (like shifting <<1 km).
        Even rounding geocodes to single digit might be acceptable using geocodes of the largest customer found within rounded-geocodes-category to locate demand, instead of rounded geocodes. (Or you may round per 0.05 or 0.025, instead of per 0.1.)

      • Or you may split your data into 20% top customers - 80% tail customers (Pareto), and aggregate tail customers only. Or you could use higher levels of aggregation for (the hinterland of) areas that have fixed warehouses. Or, for example, you could remove UK customers from your European dataset, if you know upfront that the UK will have its own warehouse(s), and run your Center-of-Gravity analysis for both UK and mainland Europe separately. Or you could invent some other aggregation method.
        In the rare event that aggregation fails to bring a workable amount of customers, and your case is about many warehouses, then split your data per region and run each region separately. Obviously, this is non-optimal.
  • Demand is the total yearly future demand of a customer, ideally expressed in your transport cost driver: volume or (volumetric) weight.
    • Though not obligatory, it is advised to enter demand figures as whole numbers.
    • Collect a full year of demand data if your business is highly seasonal. Otherwise, one month × 12, or one quarter × 4, may do.
    • Demand can be based on sales order quantities × item dimensions. But item masters are often not 100% clean. This may cause large errors. Correct outliers (items that are extremely light/heavy, small/large, with unrealistic kilogram/m3).
      If available, then use - or check against - shipment data with actual volumes or (pay)weights. Check for extremely small shipments or shipments that exceed truck capacity.
    • If a sales budget is the only info available, then demographics may help to create a geographical demand proxy.
    • Design for the future. Include demand growth percentages.
    • When to include growth percentages

      Include growth percentages if growth differs per product group / sales channel / region / customer. If not different, then you may as well ignore growth, as it will have zero effect on optimal warehouse locations. If different, then you may need to split your demand data per product group / sales channel / region if that is needed to calculate future demand volumes.

      Note that growth percentages provided separately "per product group" and "per sales channel" and "per region" (by the Sales department) most likely will cause future demand inconsistencies that may or may not need to be resolved.

      Detecting internal inconsistencies

      In the theoretical example below, growth percentages have been provided separately "per product group" and "per region". Calculated total future volume based on region growth (2114) differs from the one based on product group growth (2111). This indicates that growth percentages are internally inconsistent. As the difference between the two volume outcomes is small, the issue seems small...

      ...but it becomes more clear when viewing aggregated volumes per region, and per product group, and their corresponding output growth percentages. Either the 2 region output growth percentages do not match region input growth percentages, or the 2 product group output growth percentages do not match product group input growth percentages. Only 2 out of 4 output growth percentages match input growth percentages.

      Checking if internal inconsistencies matter or not

      A simple way to check if the above really matters is to run Center-of-Gravity Calculator both for future volumes based on region growth, and for future volumes based on product group growth, and see if warehouse locations become different (a kind of sensitivity analysis).

      Resolving internal inconsistencies

      One possible approach is the following. First, introduce growth percentages per each region-product group. Then, let Excel Solver set their values, while minimizing the sum of squared differences between input and output growth percentages (both region and product group) weighted by the customer volume (linked to that region respectively product group). Below the result of that exercise. All 4 output growth percentages now closely match input growth percentages. The mix of customer volumes makes it impossible to create 4 perfect matches.



  • Always validate your data! Check top-X customers list. Are major customers missing? Or do unknown customers appear? Check the demand map. Are gaps seen? Or do large unknown locations appear?
  • You may want to aggregate demand when creating a demand map. Otherwise, customers with (almost) the same latitude/longitude are plotted on top of each other and only a relatively small dot will be seen. Default customer opacity is 0.9 (see map settings under the map), to make customers sitting behind each other still visible. For a similar kind of reason, it can be handy to sort your customer data from large to small demand, by clicking on field header Demand, so small customers are plotted on top/in front of large ones (not behind).

Optional fields

  • Warehouse_IDs is used to assign a customer to a predefined warehouse, so it should match to a Warehouse_ID as defined in table Predefined warehouses. If left empty, then no fixed assignment applies.
    • Create a fixed assignment by entering a single warehouse_ID.
    • Create a semi-fixed assignment by entering a subset of warehouses_IDs that the solver is allowed to select from.
      Use | (pipeline) as separator between the warehouse_IDs. For example, Birmingham|Madrid|WH05.
    Check constraint "Fixed customer-warehouse assignments"
    to activate, via section
    "Parameters & constraints"
    - subsection
    "Constraints"
  • Group - free format - is used to force all customers within the same group to be delivered by the same single warehouse only (single-sourcing). What group stands for, is for you to decide. For example, a country. The group is assigned to the warehouse that comes with the lowest sum of weighted distances for this group of customers. Underlying cost calculation is still done at individual customer level. For more info, read section
    "About Center-of-Gravity algorithms"
    - subsection
    "Customer grouping"
    .
    A fixed customer-warehouse assignment takes precedence over a customer group. Warehouse capacity limits may cause a customer group to get broken up.
    Check constraint "Customer groups"
    to activate, via section
    "Parameters & constraints"
    - subsection
    "Constraints"
    .
  • Shipment_size translates into an individual customer transport rate. If specified, then it overrules the general customer shipment size. See section
    "Parameters & Constraints"
    - subsection
    "About transport rates & underlying cost curve"
    for more explanation.
  • Lead_time_distance is the individual maximum allowed distance from the warehouse. If specified, then it overrules the general lead time distance as set under section
    "Parameters & constraints"
    - subsection
    "Service level"
    . Customers are colored in black if the leadtime distance is exceeded, indicating where service is compromised. Enter the distance in the correct distance unit, miles or kilometers, as you have selected under section
    "Parameters & constraints"
    - subsection
    "Distance"
    .
  • Border_group links the customer to a border group. A border group has specific border crossing points to enter or exit the bordered area. Those border crossing points are defined in table Border Crossing Points. A flow from a warehouse to a customer will go via one of the border crossing points, unless the warehouse and customer are both inside the bordered area.
    Check constraint "Border crossing points"
    to activate, via section
    "Parameters & constraints"
    - subsection
    "Constraints"
    .

Optional fields for "Select best warehouses" functionality only

  • Qty_1 to 5 are the warehouse cost driver quantities of a customer, such as #orders, #order lines, #unit_picks, #carton_picks, #pallet_picks. You may decide yourself what each qty stands for.

Predefined warehouses (optional)

  • Check constraint "Predefined warehouses"
    to activate and include predefined warehouses in the solution, via section
    "Parameters & constraints"
    - subsection
    "Constraints"
    .

  • Warehouse_ID - free format, for example "Birmingham" - is used in the Customers and Suppliers table to assign customers or suppliers to this warehouse (instead of having the software assign customers and suppliers).
  • Latitude, Longitude is the result of converting a textual address into geographic coordinates - a process called geocoding. For more info, read the help text for fields Latitude, Longitude of Customers.

Optional fields

  • Move_limit = 0 (default) means a fixed location, > 0 means a location that may move away from its initial coordinates but no further than its move limit. To be expressed in either miles or kilometers, as you have selected under section
    "Parameters & constraints"
    - subsection
    "Distance"
    .
  • Capacity is used to limit the demand that can be assigned to a warehouse. It is total throughput capacity (in relation to demand data period), not storage capacity. Yearly througput capacity = storage capacity × yearly stock turns. If your demand data is about one quarter, then divide yearly throughput capacity by four, or else multiply all demand (and supply) by four.
    Warehouse capacity limits may cause customer groups to 'break'.
    Check constraint "Capacity limits"
    to activate, via section
    "Parameters & constraints"
    - subsection
    "Constraints"
    .
  • Transport_rate_index is used to adjust customer transport rates of all customers supplied from this warehouse. An index below 100 means transport from this warehouse to customers is relatively cheaper, an index larger than 100 means more expensive. Customer transport rates are multiplied by the warehouse Transport rate index/100, for all customers assigned to the warehouse. The lower this index, the more customers a warehouse will get assigned (unless other constraints prevent this).
  • IsSatellite = 0 (no) or 1 (yes) and is used to distinguish main warehouses from satellite warehouses. This is relevant if suppliers are activated and parameter "Link supplier to closest Main warehouse" is checked. Even if suppliers have not been activated, main→satellite warehouse flows are generated.
  • Color overwrites the default warehouse color. Format: #rrggbb (red,green,blue hexidecimal values)
    Pick color →   Color =

Optional fields for "Select best warehouses" functionality only

  • Whs_group (opt)
    • Valid entries are 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', or 'j'. If left empty, default 'a' is used.
    • Group 'j' is a special 'must-be-included' group. All warehouses in group 'j' will always be included in the selection (which of course may affect the selection of warehouses from other groups).
    • Group can be interpreted as geographical region. By grouping warehouses per region you can ensure that each region gets a warehouse, if you set the number to be selected from that group higher than 0.
  • Fixed_costs are in fact binary-fixed costs, the fixed costs apply if a warehouse is selected.
  • Rate_1 to 5 are the warehousing cost per unit throughput for up to 5 cost drivers (and linked to your customer table). Example: if customer X has Qty_1 = 10 and Qty_2 = 5, and warehouse Y has Rate_1 = 2.50, and Rate_2 = 3.75, then the variable costs of this customer X at warehouse Y are 10×2.50 + 5×3.75.

Suppliers (optional)

  • Check constraint "Suppliers"
    to activate and include suppliers, via section
    "Parameters & constraints"
    - subsection
    "Constraints"
    .

  • Supplier_ID: free format identifier.
  • Latitude, Longitude is the result of converting a textual address into geographic coordinates - a process called geocoding. For more info, read the help text for fields Latitude, Longitude of Customers.
  • Supply is the total yearly future supply of a supplier. Usually, the supply of all suppliers should - more or less - match the demand of all customers. Unless supply is about the dry ingredients of liquid finished products, for example.

Optional fields

  • Warehouse_IDs (= link to table Predefined warehouses) is used to assign a supplier to a warehouse or subset of warehouses (similar to assigning a customer to a warehouse or subset of warehouses). If left empty, the software decides which Center(s)-of-Gravity is/are supplied by the supplier. If specified, then this supplier will not supply all warehouses directly, even if supply option "Each supplier delivers to each warehouse directly" has been selected.
    Check constraint "Fixed customer-warehouse assignments"
    to activate, via section
    "Parameters & constraints"
    - subsection
    "Constraints"
    .
  • Shipment_size translates into an individual supplier transport rate.
  • Supply_option (1, 3, or 4) can be set to overrule the general supply option (1, 3, or 4) as selected under section
    "Parameters & constraints"
    - subsection
    "Supply options"
    . If you select overall option 2 "LP optimized supply flows", then individual supplier settings are ignored.

Border crossing points (optional)

  • Check constraint "Border crossing points"
    to activate, via section
    "Parameters & constraints"
    - subsection
    "Constraints"
    .

  • The use of border crossing points may improve distance accuracy and direction in which a Center-of-Gravity is pulled.
  • If an area can only be entered/exited at some specific points, you may enter these border crossing points.
  • A transport flow has to go via a border crossing point if
    • a warehouse is outside the bordered area and the customer inside ("entry")
    • a warehouse is inside the bordered area and the customer outside ("exit")
  • A flow via a border crossing point means a detour. The border crossing point causing the smallest detour is auto-detected. It also means that the warehouse is pulled towards this point instead of the customer, until the border has been crossed.
  • Border_group - free format - is the name of the bordered area with all its crossing points (latitude, longitude) entered in this table. Field border_group is also found in the customers table and used to specify which customers belong to the border group (thus defining its geographic shape). To function properly at least some customers of a bordered area should be located within a 50 km range of the border point.
  • In the picture on the right the border crossing points in the northern part of Italy prevent extreme shortcuts across the Adriatic Sea. If ferries are a valid transport option, then you may remove all border crossing points or add ferry harbours as points.
  • Current implementation handles only one border crossing point per flow, not multiple. A warehouse area exit point takes priority over a customer area entry point: "exit before entry".
If where to open (a) new warehouse(s)? is the main question, then use Calculate Center-of-Gravity locations.

Summary

  • Step 1 is running a greenfield analysis. You only need to enter demand.
  • Step 2 is replicating the current situation, to get figures to compare scenario's against, such as average customer distance. You enter current warehouses and fix customer assignments.
  • Step 3 is creating a realistic scenario that sits somewhere between the current situation and greenfield. Constraints of step 2 are partly relaxed, like "only some of the current warehouses remain as-is, but others may move to a Center-of-Gravity".
  • Step 4 (optional) is adding suppliers to include supplier transport costs in the optimization.

1. Greenfield analysis

100% optimization freedom
  • Free amount of new warehouses at Center-of-Gravity locations
  • All customers reassignable
  • No warehouse capacity limits

3. Realistic scenario

Some optimization freedom
  • Some warehouses as is
  • Some warehouses closed
  • Some warehouses extended
  • Some warehouses added
  • Some customers reassignable
  • Some warehouse capacity limits applicable

2. Current situation

Zero optimization freedom
  • All warehouses as is
  • All customer assignments as is (so warehouse capacity limits are respected without defining those explicitly)
100% ←------ Optimization freedom ------→0%
Before setting up your own model, it may be helpful to play around with the demo data first, to get an idea of how the software works, and to check out - for instance - what data relates to what constraint.

A first run

  • Fill out table Customers under section
    "Input tables"
    .
    • You can start with only the 4 obligatory fields filled: Customer_ID, Latitude, Longitude, Demand.
    • All fields are explained in section
      "Input tables"
      - subsection
      "About tables and fields"
      .
  • Select the number of Center-of-Gravity under section
    "Calculate Center-of-Gravity locations"
  • Press Calculate. That's it!
  • Main output - including Center-of-Gravity locations - is found in section
    "Output - Reports"
    . All reports can easily be copied into Excel.

Assess service levels

  • View the service level distance chart under section
    "Output - Service level distances"
    showing percentage of demand and customers reached per distance. This indicates if more warehouses should be opened, or if some could be closed.
  • Check option "distance based customer coloring" under
    "Map settings"
    below map. Customers beyond acceptable lead time distance (set under
    "Parameters & Constraints"
    - subsection
    "Service level"
    ) become black. Based on this map you may decide to add/relocate warehouses. Or accept that some customers will have a longer lead time - which is probably already the case in reality. A few far-away customers should not be driving your supply chain network design!
  • Check option "Improve service level" under section
    "Parameters & Constraints"
    - subsection
    "Service level"
    and rerun. Service level will be improved at the expense of increased transport costs.

Run sensitivity analyses

  • Go to section
    "Parameters & constraints"
    - subsection
    "Sensitivity analysis"
    .
  • Check option "Randomize each demand quantity" and rerun. Each customer demand temporarily changes between −X% and +X%. See how it affects Center-of-Gravity.
  • Check option "Display cost-increase-areas" and rerun. A grey area around each Center-of-Gravity appears. If the warehouse would be located at the dotted border, then its transport costs would increase X%.

Fix warehouse locations

To fix warehouses at their current locations:
  • Set field Move_range set to 0 in input table Predefined warehouses.
  • Check constraint "Predefined warehouses" under section
    "Parameters & constraints"
    - subsection
    "Constraints"
    , and rerun.

Fix customer-warehouse assignments

To assign customers to their current warehouse:
  • Enter field Warehouse_ID in table Customers
  • Check constraint "Fixed customer warehouse assignments" under section
    "Parameters & constraints"
    - subsection
    "Constraints"
    , and rerun.
  • Displaying current warehouse-customer links may already reveil some room for improvement.
  • Fixing current customer-warehouse assignments automatically means that current capacity limits will be respected, so there is no need to enter those explicitly, yet.

Gradually relax some constraints

  • Investigate if current locations are optimal - given fixed customer assignments:
    • Increase value of field Move_range of (some) predefined warehouses, and rerun.

  • Investigate if current customer assignments are optimal - given fixed warehouse locations:
    • Empty field Warehouse_ID of (some) customers, and rerun
    • Or uncheck constraint "Fixed customer-warehouse assignments" under section
      "Parameters & constraints"
      - subsection
      "Constraints"
      , and rerun.

  • Investigate where to open a next new warehouse:
    • Increase the number of Center-of-Gravity beyond the number of predefined warehouses, and rerun.
    • Make sure you allow (some) customers to get (re)assigned to this new warehouse.

Activate other types of constraints

Relaxing some constraints, you may want to control the solution by other types of constraints:
  • Limit warehouse throughput capacities:
    • Enter field Capacity in the Predefined warehouses table.
    • Check constraint "Capacity limits" under section
      "Parameters & constraints"
      - subsection
      "Constraints"
      , and rerun.
    • Keep in mind that current limits may not apply in future, if additional space can be rented or the owned facility expanded!

  • Group customers for single sourcing:
    To enforce all customers within a group to be assigned to the same, single warehouse:
    • Enter field Group in table Customers.
    • Activate constraint "Customer groups" under section
      "Parameters & constraints"
      - subsection
      "Constraints"
      , and rerun.

Intro

A Center-of-Gravity analysis focuses on the demand side with its relatively high transport costs and lead time requirements. But you can add suppliers (locations and supply quantities) to include supply transport costs in the optimization. Adding suppliers becomes more relevant if there are a few dominant supply locations (such as a large plant or entry harbour), in which case a warehouse should move towards that location.

Note that a supplier may pull all warehouses, whereas a customer only pulls one.

Suppliers

Enter suppliers - at least obligatory fields Supplier_ID, Latitude, Longitude, Supply - in input table Suppliers.

Supplier transport rate

Supplier shipments are usually larger than customer shipments, on average. This makes supplier transport relatively cheaper. The lower transport rate makes suppliers pull Center-of-Gravity relatively less than customers do.
Enter supplier and customer transport rate under section
"Parameters & Constraints"
- subsection
"Transport rates"
.

Supply flows

Check "Suppliers" under section
"Parameter & constraints"
- subsection
"Supply options"
.
Select 1 of the 4 supply options in the same subsection. The selected option determines how supply flows are constructed.
Non-unique products
  1. Each supplier delivers to closest warehouse* only
    i
  2. LP optimized supply flows - with auto-sized suppliers
    i
Unique products
  1. Each supplier delivers to each warehouse
    i
  2. Each supplier delivers to each warehouse via closest warehouse*
    i
* Closest warehouse can be manually overruled

Under options 2/3/4 each supplier - unlike a customer - pulls several/all warehouses.

Demand side only

Warehouses are pulled by customers only

Supply option 3

All warehouses are pulled towards a major supplier.

Supply option 4

All warehouses - but especially the closest warehouse - are pulled towards a major supplier.

Note that when activating supply, the picture may suddenly becomes much more complex.

Select a proper location for each Center-of-Gravity

Once the Centers-of-Gravity have been calculated (based on road distance estimations), select a proper warehouse location for each Center-of-Gravity.

Under Map Settings, select ESRI map and decrease Center-of-Gravity size factor or opacity to see the road network.

Consider locations within the 1%-costs-increase-range around the Center-of-Gravity - the visual outcome of the sensitivity analysis as described under step 1.

If the Center-of-Gravity sits on top of a dominant customer or supplier, then search for a highway/expressway junction close by. In this case, the 1%-costs-increase-range will be relatively small.
Else, search for a location where two expressways cross each other. At such crossing, transport in any direction will not cause a detour. Whereas if a location is only near an east-west expressway, then transport to the north or south means a detour to reach the north-south expressway. Moving the location to the crossing will remove that detour for 3 directions, but add it to 1 direction (east). If demand is almost equally divided across all 4 directions - which is usually true for a Center-of-Gravity - then this move lowers the sum of weighted road distances.
 
You may want to double check your selected location by testing also locations around it using actual road distances (instead of estimations). These can be retrieved with Batch Driving Distances Caclulator. Note that Google Maps returns the road distance of the fastest route, not shortest. Which is fine. But fastest route may depend on time of the day, day of the week, time of the year, roadworks, or vary between routes that are nearly-equivalent. So, even actual road distance might still be an estimation, to some extent.

Better would be to score your location against others by using transport tariffs that may capture macro-economic transport imbalances that cause transport in one direction to be less expensive per mile than in the opposite direction. But - most likely - it will be difficult to obtain all transport tariffs. This may (partly) be done via an RFQ/RFP in which you ask logistics service providers to quote for both the warehousing and transport operation.

The above does not yet take into account other/qualitative factors relevant for the warehouse location decision. And it may turn out there is no warehouse for rent/sale at the selected location.
If which warehouse(s) to keep and which to close? is the main question, then use Select best warehouses.

  • Enter your data in the input tables. Predefined warehouses is no longer optional input, but mandatory.
  • Specify the number of warehouse to be selected (per group) and make your solver selection from 3×3 matrix (as depicted below), then press button "Select best warehouses".

Optional

  • Enter warehouse capacity limits. Keep in mind that current limits may not apply in future, if additional space can be rented or the owned facility expanded!
  • Enter fixed customer-warehouse assignments, if some customers definitely need to be delivered from a specific warehouse.
  • You may override the transport costs (input) calculated by the software with your own transport costs based on your own costing method / on actual rate tables / on actual road distances that can be retrieved using Batch Driving Distances Calculator (Google Maps based).
    Transport rates for new warehouses may be unknown. Or transport rates from a current warehouse to customers that are currently delivered from another warehouse may be unknown. Unknown rates is often a cumbersome part in supply chain network design, and reason to use a simpler costing method that is - more or less - similar to the one embedded in this software.
  • Enter warehouse fixed/variable costs, so these can be taken into account as well in the optimization.
Kilometers
Miles
Distance circuity factor  
i
Color customers black if warehouse distance exceeds lead time distance of 
 km
i
Improve service level
i
Display city closest to Center-of-Gravity location
i
Only consider cities with a population larger than
Only consider cities within country  
i
Closest city is based on the underlying database that contains cities with a population larger than 15,000.

Display 

-costs-increase-areas around Center-of-Gravity

i

Randomize each demand quantity ± 

; using a  

 distribution

i
Non-unique products
1. Each supplier delivers to closest warehouse only
i

2. LP optimized supply flows - with auto-sized suppliers
i
Unique products
3. Each supplier delivers to each warehouse
i

4. Each supplier delivers to each warehouse via closest warehouse
i

Link suppliers to closest main warehouse (not satellite) - Applies to options 1 and 4

Auto-size shipments per individual customer

i
 
The below is meant to distinghuish between customer and supplier transport, if you activate suppliers.
Shipment sizes affect Center-of-Gravity locations, the cost/km (or cost/mile) value does not.
i
Shipment size

% FTL 
i
% FTL costs

Cost ratio
i
Costs/km
Costs/km/qty
Full Truck Load
Customer
Supplier
Interdepot
Center-of-Gravity positions depend on ratio supplier rate/customer rate = 
Transport costs curve
i
LTL cost factor as % FTL cost
Shipment size as %FTL
Point   X (as %)   Y (as %)  
Start point (P0)
Start control point (P1)
End control point (P2)
End point (P3)
Just a specific point on the curve
Animation of Bezier curve construction
You may also drag the red control points in chart itself.
  • Transport rates enable differentiation between relatively less expensive FTL-like transport (from suppliers) and relatively more expensive LTL-like transport (to customers).. It becomes most relevant if your model includes suppliers. To minimize transport costs a Center-of-Gravity should move closer towards a customer than towards a supplier, if their volumes would be equal. The ratio between supplier rate and customer rate is more important than rates as such. This ratio affects the Center-of-Gravity position, as shown in the animation below (and for more info and visuals, see section
    About Center-of-Gravity algorithms
    - subsection
    Including supply-side
    ).
  • By the way, a supplier may pull all warehouses, whereas a customer only pulls one, so the supply-side model involves more than a difference between customer and supplier transport rate.
  • Transport rates also enables differentiation between small and large customers, if shipment sizes are entered at individual customer level. However, the impact on Center-of-Gravity locations is often small, if smaller and larger customers are scattered all around.
  • Transport cost of a customer = demand × distance warehouse-customer × customer transport rate. The rate becomes customer specific if shipment size is specified in table Customers.
  • LTL transport being relatively more expensive than FTL transport is expressed in the transport cost curve as seen below. An LTL shipment size of 50% FTL brings 72% FTL costs, approximately. Thus, per each unit transported LTL transport is in that case 1.44 times more expensive than FTL transport.
  • Under map settings you can choose to display location sizes as transport-rated volumes (volume × rate ratio), instead of plain volumes. Suppliers will then appear relatively smaller than customers, which better reflects the 'pull force' of a supplier/customer.
Calculate Center-of-Gravity locations first, before using this section.

Own truck operation

i
Working days per year
i
Distribution hours per workday(s)
i
Unloading minutes per delivery
Average speed (km/hour)
Average speed (miles/hour)
Maximum speed (km/hour)
i
Truck fill rate
i
Sum of area size(s) (square km)
i
Area scanning level
i

Display area(s) on map


Avg Inter Drop Distance
i
Manual overrule IDD (km)
Manual overrule IDD (miles)
Avg deliveries per roundtrip
i
Avg roundtrip length
i
Sum of yearly roundtrip kilometers
Sum of yearly roundtrip miles
i
Demand beyond reach
Customers beyond reach
 
Above fields remain empty, because an infeasibility error is encountered at a warehouse.

If you want to calculate more precisely, on a daily basis (auto-generated or user entry), with actual roundtrips being constructed, then use Fleet Mileage Calculator
Centers-of-Gravity Calculator goal value assumes that transport costs are linearly, perfectly positive correlated to weighted distance, as if 1 customer delivery means 1 trip with 1 drop only, and as if costs are fully determined by distance driven. In reality, multiple drops are done in a single roundtrip, and trip costs are not only costs of driving, but also costs of loading and unloading (see picture on the right).

Centers-of-Gravity Calculator minimizes the sum of weighted distances. This is the same as minimizing the weighted average distance. That distance is the distance from warehouse to the first customer in a trip, and also from last customer back to warehouse. It does not equal the distance between customers on a trip. That inter-drop distance depends on the number of drops and delivery area size. So, trip length - and costs of driving - is only partly determined by weighted average distance. And costs of (un)loading is not related to distance. Because transport costs are only partly determined by weighted average distance, X% change of goal value does not mean X% change of transport costs. To estimate future scenario transport costs you may combine your actual baseline transport costs with goal value change and some dampening factor, as shown below.

BaselineFuture scenario
Baseline transport costs from your financialsUSD 12,000,000
Goal value Centers-of-Gravity Calculator10,000,0009,000,000
Goal value change (as %)-10%
Dampening factor (value assumed at 0.50)0.50
Goal value change × dampening factor-5%
Transport costs effect- USD     600,000
Future scenario costs  USD 11,400,000
Or use the sum of yearly transport kilometers of above section
"Own truck operation"
to estimate cost effects.
Predefined warehouses
Fixed customer-warehouse assignments
Fixed supplier-warehouse assignments
Capacity limits
LP optimization
i
Continuous optimization
Post-optimization only
Customer groups
i
Suppliers
Border crossing points
This section explains the links between constraints and input tables. Similar info is found in section
"Input tables"
- subsection
"About tables and fields"
.
This section also describes the contents of the demo data linked to a constraint.

Customers table

  • Check constraint "Fixed customer-warehouse assignments" to assign customers to a predefined warehouse.
    Demo: field Warehouse_IDs is set to "Birmingham" for all customers in UK/Ireland to assign them to the predefined Birmingham warehouse. It is set to "Madrid" for all customers in Spain/Portugal.
  • Check constraint "Customer groups" to have all customers within the same group delivered by the same single warehouse that can deliver the group against lowest transport costs (still calculated at individual customer level, see example in section
    "About Center-of-Gravity algorithms"
    - subsection
    "Customer grouping"
    ).
    Demo: field Group is filled with the applicable 2-letter ISO country code for all customers. So - in the demo - group stands for country. This prevents customers in Western France to get delivered by the UK warehouse.
  • Check constraint "Border crossing points" to activate border crossing points.
    Demo: field Border_group is filled for customers in UK, IE, Italy, and Iberia.

Predefined warehouses table (optional)

  • Check constraint "Predefined warehouses" to include predefined warehouses in the solution.
    Demo: contains one predefined main warehouse in Birmingham (UK) and one in Madrid (Spain), with field Move limit set to 0 for the Birmingham warehouse (it cannot move), and set to 200 for the Madrid warehouse (it can move within a 200 km range). Demo also contains several other main and satellite warehouses that can move freely around.
  • Check constraint "Capacity limits" to limit warehouse throughput capacities.
    Demo: field Capacity is set for both predefined warehouses Birmingham and Madrid.

Suppliers table (optional)

  • Check "Suppliers" to include suppliers.
    Demo: contains one supplier in Rotterdam (The Netherlands - Entry harbour supplying 71% total demand), and one in Bologna (Italy).
  • Flows from suppliers via warehouses to customers are constructed automatically, dependent on the selected Supply option as set in section
    "Parameters & constraints"
    - subsection
    "Supply options"
    .
  • Check constraint "Fixed customer-warehouse assignments" to assign suppliers to a predefined warehouse. It links to field Warehouse_ID. If filled, then the supplier will only supply this warehouse. And via this warehouse to each other warehouse, if supply option "Each supplier delivers to each warehouse via closest warehouse" is selected. (If field Warehouse_ID is filled, then a supplier will never supply all warehouses directly, even if supply option "Each supplier delivers to each warehouse directly" has been selected.)

Border crossing points table (optional)

  • Check constraint "Border crossing points" to activate border crossing points.
    Demo: field Border_group relates to the same field found in the customer table and specifies which border crossing points (if any) are applicable for which customers. The demo contains a limited amount of border crossing points in Italy, Iberia, UK/Ireland, just to show you how this concept works.
Centers-of-Gravity
i
runs
i
Minimum goal value    
i
Current goal value
Weighted distances    
i

Scenario 
i
Name
Scenario to reload
Show outcomes of Center-of-Gravity
Distance bin width (km)
10 20 25 50 100
 Distance    Demand cum   Demand  Customers cum  Customers   # Customers 
 
 
 
 
Copy chart
Copy reports
Tab separated
Decimal point
Semicolon separated
Decimal comma
Original input data and parameters are also copied in, at the end.

Summary

 
 
 
 
 
 
 
 
 
 
i
 
 
 
 
 
i
 
 
 
 
 
i

Centers-of-Gravity

i
i
i

Customer assignments

i
i

Service level distances

Goal value to be minimized is the sum of weighted distances. In a basic approach distances are weighted by quantities only. Centers‑of‑Gravity Calculator uses two weights. Distances are weighted by transport quantity (1st weight) × transport rate (2nd weight). The transport rate converts distances and quantities into costs. Primary reason for adding transport rate as a second weight is to make suppliers (FTL-like transport) pull Centers-of-Gravity relatively less than customers (LTL-like transport) do, rather than to come up with highly accurate transport costs.

Relative changes in minimum goal value between baseline and future scenario (expressed as % change) can be applied to your actual baseline costs (derived from your financial reports) to estimate the transport costs effect of a supply chain network change. Because transport costs partly consist of (un)loading costs that will not change, you may add some factor to dampen the costs effect.

BaselineFuture scenario
Baseline transport costs from your financialsUSD 12,000,000
Goal value Centers-of-Gravity Calculator10,000,0009,000,000
Goal value change (as %)-10%
Dampening factor (value assumed at 0.80)0.80
Goal value change × dampening factor-8%
Transport costs effect- USD     960,000
Future scenario costs  USD 11,040,000

For more info about rates and differentiation between customers and suppliers, see section
"Parameters & constraints"
- subsection
"Transport rates"
. By the way, a supplier may pull all warehouses, whereas a customer pulls only one warehouse, so the supply-side model involves more than only a difference between customer and supplier transport rate. (A supplier is not just a relatively smaller customer.)

In case of an owned truck operation, see section
"Parameters & Constraints"
- subsection
"Own truck operation"
. It offers functionality to estimate transport mileage. That mileage can be used to estimate the transport costs effects of a supply chain network change more precisely.

How to calculate Center-of-Gravity locations

This section explains in detail how Center-of-Gravity Calculator calculates Center-of-Gravity locations.

Center-of-Gravity locations are indicative warehouse locations that minimize transport costs

In fact, Center-of-Gravity locations are those locations that minimize the sum of weighted distances, given the amount of warehouses. Weighted distance is the distance from warehouse to customer multiplied by customer demand. If a customer has a demand of 10 and is located 25 kilometers from its warehouse, then its weighted distance is 250 kilometers. The sum of weighted distances of all customers acts as an indicator for transport costs.

Towards the algorithms - Introductory thoughts

Upfront: there exists no mathematical formula that can (simply) calculate the optimal warehouse position given customer locations and demand. So...

Imagine a case with two customers only. Customer A has a demand of 10 and customer B of 1. Where is the Center‑of‑Gravity? Somewhere on line A-B, closer to A?


Well, you could say that customer A pulls 10 times harder than customer B. If the 'Center‑of‑Gravity' * moves a distance d towards A the sum of weighted distances decreases (10 × d) – (1 × d) = 9 × d.
* If put between quotes then it refers to a location under investigation which is not yet the true Center‑of‑Gravity.


So, the Center‑of‑Gravity is right on top of customer A, not somewhere in between A and B!



The resultant pull force - sum of all customer pull forces - is leading. It always points in the direction that the 'Center‑of‑Gravity' should move into to decrease the sum of weighted distances. This resultant pull force is constructed by linking all customer pull forces together, head to tail.

However, the sum of weighted distances will only decrease if the 'Center‑of‑Gravity' moves the right distance! The resultant pull force does not tell how far to move. Move this far?


Or this far?



The smaller the move distance, the less chance of 'overshooting' the Center‑of‑Gravity, but the many more moves to be made. Therefore, it is better start with big moves. In case of 'extreme overshooting' the sum of weighted distances will have increased instead of decreased, and the resultant force arrow changed - or even completely reversed - its direction. By then, the move size needs to be reduced in order to get closer to the Center‑of‑Gravity. Else, the next move would end up at the previous position, followed by getting stuck in a loop of going back-and-forth without ever getting any closer. By reducing the move size each time the sum of weighted distances increased the 'Center‑of‑Gravity' ends up on top of the Center‑of‑Gravity.



Of course, the above was an extreme example. Usually, there is no single dominant customer, and the Center‑of‑Gravity will be somewhere in the center of all customers. Also then, the Center‑of‑Gravity is found by moving in the direction of the resultant pull force, but not too far. The resultant pull force becomes smaller the closer the location gets to the Center‑of‑Gravity (which implicates that the length of the resultant pull force somehow does relate to the distance to be moved). It becomes zero on top of the Center‑of‑Gravity, with all underlying pull forces (F) in a state of equilibrium in both x and y direction: ΣFx=0, ΣFy=0. All forces linked together start and finish at exactly the same location = zero resultant force.



Except if one dominant customer outweighs all other customers. Then the Center-of-Gravity is on top of this dominant customer, but the resultant force is not zero.
Another exceptional case, rather theoretical, is one in which there are only two customers, A and B, with equal demand. Then the resultant force is zero for all points between A and B on line A-B. Each of these points is Center‑of‑Gravity.

Single Center-of-Gravity location algorithm

There exists no mathematical formula that can calculate the Center‑of‑Gravity/optimal warehouse position, given customer locations and demand. It takes an iterative approach to determine the Center‑of‑Gravity.

The Single Center‑of‑Gravity algorithm works like this on an x,y plane:
  1. Initialization: locate the 'Center‑of‑Gravity' at an initial (random) position, and give the move distance a large value.
  2. Calculate the resultant pull force. Move the 'Center‑of‑Gravity' in that direction, at move distance.
  3. Calculate the sum of weighted distances. If it increased, then divide the move distance by two.
  4. Repeat steps 2 and 3 until the move distance becomes very small.
This algorithm will always find the global optimum with a single run. With this type of problem, there is no chance of getting stuck in local optimum. The algorithm relates to the gradient descent method (wikipedia), also used by Excel Solver's method GRG Nonlineair (GRG stands for Generalized Reduced Gradient).

Determining the Center‑of‑Gravity is like finding the x and y coordinate of the lowest point (x,y,z) in a bowl-shaped 3D‑chart - visualizing the sum of weighted distances z = f(x,y) for each x and y - by going into the direction of steepest descent as pointed to by the resultant pull force. During this descent the direction gets adjusted after each move made/step taken.

Wikipedia presents complex methods to determine a proper move distance (a.k.a. step size) per iteration. Luckily, there is no urgent need for those, because the method of step 3 works quite good!
The Single Center‑of‑Gravity algorithm works like this on an x,y plane:
  1. Initialization: locate the 'Center‑of‑Gravity' at an initial (random) position, and give the move distance a large value.
  2. Calculate the resultant pull force. Move the 'Center‑of‑Gravity' in that direction, at move distance.
  3. Calculate the sum of weighted distances. If it increased, then divide the move distance by two.
  4. Repeat steps 2 and 3 until the move distance becomes very small.

Steps more detailed

  1. Initialization: locate the 'Center‑of‑Gravity' at an initial (random) position, and give the move distance a large value.
    • A good initial position is the weighted average x and y coordinates of its customers. It is often near-optimal, but not the Center‑of‑Gravity, though you may have read elsewhere it is. Theoretically, it can be even 100% worse!
    • Often only 0-5% worse...
      Often, the sum of weighted distances of the weighted average x,y position versus that of the true Center‑of‑Gravity will be 0-5% worse, but more than 5% worse is also possible, as sometimes will happen/can be seen in the simulation further below.

      ...but theoretically even 100% worse is possible!
      Imagine a case with only two customers, customer A with demand 1000 at x,y position (0, 0) and B with demand 1 at position (100, 0). The weighted average x,y position is (0.0999, 0), with 0.0999 calculated as (1000×0 + 1×100)/(1000+1). If the 'Center‑of‑Gravity' moves a distance d towards customer A the goal value improves 1000×d (closer to A) − 1×d (further from B) = 999×d. So the Center‑of‑Gravity is on top of customer A, not at the initial weighted average x,y position! The Center‑of‑Gravity has a sum of weighted distances of 1000×0 (customer A) + 1×100 (customer B) = 100, whereas the initial position has a value of 1000×0.0999 (customer A) + 1×99.9 (customer B) = 199.8, which is 99.8% worse!

    • A random location within the customer cloud can be used just as well, as the remainder of the algorithm will always find the Center‑of‑Gravity, in almost equal time.

    • It is better to start with a bit too large move distance (100 kilometers) than with a bit too small, because if too small then it will take many iterations before the Center‑of‑Gravity is reached.

  2. Calculate the resultant pull force. Move the 'Center‑of‑Gravity' in that direction, at move distance.
    • Sum up all pull forces (vectors) to get the resultant pull force (vector) with a certain size (less relevant) and direction (most relevant) by summing up x and y components separately. For each customer pull force F: Fx = length demand vector × (customer_x − CoG_x)/(distance from customer to CoG), or shorter: Fx = demand × cosinus(angle F). Fy = demand × sinus(angle F).
    • Normalize this resultant pull force (a vector with origin at 0,0 and end point at x,y) by dividing x by its length √(x2 + y2) and y by its length. The vector keeps pointing in the same direction, but its length becomes 1, which makes it a unit vector.
    • Multiply x and y values of this unit vector with the step size to get the move vector representing move distance in x and y direction.
    • If the move vector's tail starts at the current 'Center‑of‑Gravity' position, then its head ends at the next 'Center‑of‑Gravity' position. So, add the move distance in x direction to the current x position of the 'Center‑of‑Gravity', and add distance in y direction to its current y position. This brings the next 'Center‑of‑Gravity' position.

  3. Calculate the sum of weighted distances. If it increased, then divide the move distance by two.
    • This approach originates from the binary search algorithm - a.k.a. half interval search - to find the position of a target value within a sorted array. See half-interval search (wikipedia).
    • Optional: move the 'Center‑of‑Gravity' back to its previous position if the sum increased, so with each 'accepted move' the solution always improves (or remains equal, but never worsens).

  4. Repeat steps 2 and 3 until the move distance becomes very small.
    • Then the Center‑of‑Gravity hardly changes anymore, and the sum of weighted distances converges.
    • The Center‑of‑Gravity may be in the middle of a lake or on top of a mountain.

Visual simulation

Press button Next process step to start the simulation.

Earth is a globe - Required adjustments

X,y on a flat plane (Chartesian coordinate system) becomes latitude,longitude on a globe (Spherical coordinate system). The algorithm involves summing up vectors with a length and an angle. The distance between two points on a globe is calculated with the Haversine formula, and the angle with a Bearing formula. Demand vectors are mapped to a flat tangent space before summing up, and the result is translated back to the globe - see also the picture of section 'Weiszfeld's algorithm as alternative'.
     
"No, it's not
a flat plane."
 
Latitudes and longitudes in both formulas need to be expressed in radians = degrees × 𝜋/180.

Haversine formula - in 2 steps
  1. a = sinus2((latitude_customer − latitude_Center-of-Gravity)/2) + cos(latitude_Center-of-Gravity) × cos(latitude_customer) × sinus2((longitude_customer − longitude_Center-of-Gravity)/2)
  2. As-the-crow-flies-distance = 2 × atan2(√a , √(1-a)) × 6371. 6371 kilometers is Earth's mean radius.
See Excel - As-the-crow-flies distance function for an Excel implementation. Excel's atan2 function takes its arguments in reversed order!

Bearing formula
Bearing = atan2(sinus(longitude_customer − longitude_Center-of-Gravity) × cosinus(latitude_customer) , cosinus(latitude_Center-of-Gravity) × sinus(latitude_customer) − sinus(latitude_Center-of-Gravity) × cosinus(latitude_customer) × cosinus(longitude_customer − longitude_Center-of-Gravity)

Bearing is measured against the vertical longitude axis, not the horizontal latitiude axis, so you need to swap the use of cosinus/sinus when calculating forces in x and y direction.

Weiszfeld's algorithm as alternative

Weiszfeld's algorithm - see also Geometric median (wikipedia) - works like this on an x,y plane:
  1. Initialization: locate the 'Center-of-Gravity' at an initial (random) position.
  2. Calculate each customer weight as demand divided by distance to 'Center-of-Gravity'.
  3. Calculate the weighted average x,y of customers as the next 'Center-of-Gravity'.
  4. Repeat steps 2 and 3 until the sum of weighted distances converges.
Applying Weiszfeld's algorithm to Earth is also done via a flat tangent space.

Source: section 2.3 "Weiszfeld Algorithm on a Riemannian Manifold" of scientific article
Generalized Weiszfeld Algorithms for Lq Optimization by K. Aftab, R. Hartley, J. Trumpf.

Differences between both algorithms

Major difference between Single Center-of-Gravity algorithm and Weiszfeld's algorithm is that the former uses an explicitly controlled move distance whereas - you could say - the latter has an implicit variable move distance of 1 ∕ Σ(demandi ∕ distancei), that is applied to a non-normalized resultant pull force vector.

This controlled move distance enables an advanced feature of Centers‑of‑Gravity Calculator: you can limit the move range of predefined warehouses. The optimal location may then be somewhere at the border of this limited range and Weiszfeld's algorithm cannot handle this. But this controlled move distance also means that, whereas under Weiszfeld's algorithm the sum of weighted distances decreases with each iteration, under the Single Center-of-Gravity algorithm it decreases only if the move distance did not result in 'extreme overshooting'.

Weiszfeld's algorithm converges approx. 10% faster. After 15 iterations the sum of weighted distances will have become less than 0.01% above absolute minimum. Weiszfeld's algorithm does not use a move distance, but the Single‑Center-of-Gravity algorithm does, and if the initial move distance is set too high, then the first few iterations will become useless 'extreme overshoots' (as can be seen in the chart), but if it is set too low it will take many more iterations to move to the Center-of-Gravity, so it's better to initialize it a bit too high.

Centers‑of‑Gravity Calculator uses both algorithms: the faster Weiszfeld's algorithm as its default, and Single‑Center-of-Gravity algorithm in case of predefined warehouses with limited move range. (Choice of algorithm can be case specific, and both algorithms used alternatingly also happens.)

Multiple Center-of-Gravity locations algorithm

Below, 'Center-of-Gravity' and warehouse are used interchangeably.

A single run of the Multiple Center-of-Gravity locations algorithm does the following:
  1. Initialization: locate each warehouse at a random location within the customer cloud.
  2. (Re)assign each customer to its closest warehouse.
  3. Move each warehouse to the Center-of-Gravity of its assigned customers.
    = apply Single Center-of-Gravity location algorithm / Weiszfeld's algorithm per warehouse
  4. Repeat steps 2 and 3 until the sum of weighted distances converges.
Multiple runs are done to find the global optimum, as a run may get stuck in a local optimum. The more runs, the more likely the global optimum is found. Usually, this global optimum will then have been found multiple times as best solution. The warehouse locations of the best solution found are considered to be the Center-of-Gravity. But - especially with a higher number of warehouses - it may happen that two different warehouse structures bring an almost similar sum of weighted distances.

Beware: a remote customer area at a very large distance from all other customers (e.g. an overseas island of a country), may cause one of the Centers-of-Gravity to end up in that remote area. Wanted? Only truck transport applicable? If not, then change the geocodes of these customers into exit harbour/airport geocodes. Or ignore demand completely, if marginal.

K-means Clustering

The above algorithm is similar to K-means Clustering (wikipedia) used for cluster analysis in data mining and machine learning, as depicted on the left.
K-means Clustering creates clusters that are purely distance based, just like each customer gets linked to its closest warehouse.
Expectation–Maximization (EM) algorithm creates clusters differently.
With Centers‑of‑Gravity Calculator you can group customers beforehand - like all dots in the yellow oval - if those need to be served by a single warehouse. The EM algorithm is useful for clustering analysis, not for Center-of-Gravity analysis.

Animations

The animations show what happens during a single run of the Multiple Center-of-Gravity locations algorithm. Customers are assigned to their closest warehouse, warehouses move to the Center-of-Gravity of their assigned customers, customer are reassigned, warehouses move, et cetera, until the final situation is reached where none of the customer assignments change anymore, and none of the warehouse positions.

Although each run starts with different random locations, the solution found (global optimum with a minimal sum of weighted distances) is the same in the first three run examples.

 Run 1 - global minimum  Run 2 - global minimum  Run 3 - global minimum

The example below shows a run that got stuck in a local optimum. Therefore, multiple runs need to be done to find the global optimum.

 Run 4 - local minimum

Underlying assumptions

A major underlying assumption is that transport cost = rate/kilometer × distance. This assumption is only partly valid. For instance, parcel rates are often distance independent within a region. Macro-economic imbalances cause direction-dependent LTL/FTL rates. Different transport companies may have different rates for the same route because they have a different customer base that may enable efficiencies (or not). From that perspective, it would be better to calculate with costs based on actual carrier rates. But most often you will not have transport rates for each and every possible warehouse location to every customer location. So then you have to rely on transport costs estimators.

Distances used are not actual road distances, but estimated road distances. Estimated road distance = as-the-crow-flies distances × distance circuity factor. An important reason for using as-the-crow-flies distances is because run-time would become too long when having to calculate (extremely) large amounts of road distances.
Note that from a cost perspective the fastest route is more relevant than the shortest route, as driver and truck cost are more time-related than distance-related. Google Maps retuns fastst route by default. Which is fine. But fastest route may depend on time of the day, day of the week, time of the year, roadworks, or vary between routes that are nearly-equivalent. So, even actual road distance might still be an estimation, to some extent.
Calculating Centers-of-Gravity is not so much about distances as it is about pull forces and directions, finding the spot where all forces summed up together become zero, as explained in the section about the Single Center-of-Gravity location algorithm.*
As distance estimation errors occur in each and every direction (one customer distance might be a bit too large, another a bit too small), errors tend to cancel each other out, and the Centers-of-Gravity (indicative warehouse locations) become pretty accurate. The use of as-the-crow-flies distance is usually not an issue, if the road network is dense. Approximations are acceptable, and commonly used in network design software.

* The exceptional case in which distances become "directly relevant" is a case in which a customer is located thousands of miles away from all others, on an overseas island that belongs/belonged to a country. Then a Center-of-Gravity may end up on top of that customer. But locating a warehouse over there would make no sense. So you better remove such customer from your input data. Even in such case, the use of estimated distances is not the issue.

Broader supply chain network design perspective

Of course, transport costs are only a part of supply chain costs. The optimal number of warehouses and their locations are driven by many quantitative and qualitative factors such as (future) transport and warehousing space and labor rates, future demand (and supply), lead time requirements, inventory effects, supply chain risk/redundancy, contractual obligations, taxes, distance to parcel/logistics hubs, workforce availability/public transport connections, et cetera.

Nevertheless, it is common practice to run a Center-of-Gravity analysis to get a view on which logical warehouse locations to consider in a supply chain network design.
A completely different alternative approach is one in which a large set of possible warehouse locations is pre-generated, after which the k best ones are selected (see Combination - wikipedia).

Advantages are that the warehouse-customer cost matrix can be based on various transport rate structures and using accurate road distances, and that it may take into account binary-fixed and variable warehousing costs as well.
Disadvantages are that it requires much more input. And still it has the risk that the set of predefined locations does not contain the optimal locations. Besides, runtime may become an issue.

See section
"Select best warehouses"
to apply this approach.
 

Add-ons

This section explains some additional functionality of Centers‑of‑Gravity Calculator.

LP optimization = Vogel's approximation + MODI + Stepping stone

If predefined warehouses have a limited capacity, a transportation problem arises. A transportation problem can be solved with the well-known Simplex method (LP). But it can be solved 50-100 times faster with a combination of Vogel's approximation + MODI + Stepping Stone method that generates an optimal solution. This combination has been implemented in the Centers‑of‑Gravity Calculator. Detailed descriptions of each separate method (standard as such) can be found on the internet. For a demo case that shows the speed difference, see Transportation problem solver

Note that if a customer receives from two warehouses in the optimal transportation problem solution (in which warehouse utilization never exceeds 100%), then this customer gets assigned in full to the warehouse that supplies the most, as Centers‑of‑Gravity Calculator is based on 'single sourcing'. This non-optimal, post-step may cause utilization to exceed 100%, usually less than 1%, as it involves a few customers only.

LP optimization ignores customer groups. But LP optimization will only get activated if warehouses still exceed capacity, after first having tried to solve capacity issues at group level if customer groups are applicable.

Superfast, greedy algorithm (if customer groups are relevant)

Centers‑of‑Gravity Calculator also contains a superfast, greedy algorithm as alternative that can be used if Vogel + MODI + Stepping Stone method runtime would become too long in case of an extremely large amount of customers and warehouses. As an extra, it will also try to keep customer groups intact. Roughly described, it works like this.
  • Assign customers to warehouses as if capacities are unlimited
  • Loop through all warehouse, and while the capacity of a warehouse is exceeded shift that customer to that other warehouse that will increase the costs the least (and only if the customer still fits in that warehouse if it is a warehouse earlier in the loop).
The solution may become sub-optimal.
Suppliers come with supplier transport costs. Including suppliers means that Center-of-Gravity locations should move towards suppliers. But only as long as total transport costs decrease.

Besides customers, suppliers also pull Center-of-Gravity locations, but in 'opposite' direction, and usually relatively less hard, as supplier transport is relatively less expensive than customer transport. See section
Parameters & Constraints
- subsection
Transport rates
.

Centers‑of‑Gravity Calculator supports 4 supply options that determine how supply flows are constructed.
  1. Each supplier delivers to closest warehouse only
    i
  2. LP optimized supply flows - with auto-sized suppliers
    i
  3. Each supplier delivers to each warehouse
    i
  4. Each supplier delivers to each warehouse via closest warehouse
    i

Each supplier causes (multiple) flows to warehouses. Each flow translates into a pull force (supplier or interdepot transport rate weighted) comparable to a customer pull force (customer tranport rate weighted) but pulling in 'opposite' direction. All forces are fed into the Single Center-of-Gravity algorithm that determines the position that minimizes total transport costs.

Besides, the customer assignment procedure of the Multiple Center-of-Gravity locations algorithm (step 2) takes into account (expected) supply-side transport costs when determining to which warehouse a customer gets assigned to.

Effect of ratio between supplier and customer transport cost rate on Center-of-Gravity

The highly simplified example on a Cartesian plane below shows the effect of including supply-side on a Center-of-Gravity, for varying ratio between supplier and customer transport rate.

  • Solver outcomes have been verified by geometry that brings a formula for the Center-of-Gravity x‑position.
    X‑position = max(0, 100 + 50 × F / √(1 - F2) ), with F = (1 - 3 × ratio)/2.
    F stands for pull force in horizontal direction - of both customer C1 and C3 - required to reach an equilibrium state.
  • X-position becomes exactly 100 at ratio 1/3 (0.333...), as supply quantity × 1/3 equals C2 quantity.
  • For a ratio ≥0.93 the supplier pull force outweighs customer pull forces, so the Center-of-Gravity ends up on top of the supplier. This 0.93 is in fact (1+2×1/√(12+0.52))/3 = (1+4/√5)/3 = 0.929618127...
A customer group is used to force all customers within a group to be delivered by a single warehouse only (single-sourcing). The group is assigned to the warehouse that comes with the lowest sum of weighted distances for this group of customers. Underlying cost calculation is still done at individual customer level.

What group stands for, is up to you to decide. For example, a group can be used to group customers per country, so each country is delivered from a single warehouse only.



A fixed customer-warehouse assignment takes precedence over a customer group. Warehouse capacity limits may cause a customer group to 'break'.
The "Select best warehouses" routine selects those predefined warehouses that minimize supplier plus customer transport costs + warehouse binary‑fixed costs + warehouse variable handling costs.

  • You may override the warehouse-customer transport costs (input) calculated by the software with your own transport costs based on your own costing method / on actual rate tables / on actual road distances that can be retrieved using Batch Driving Distances Calculator (Google Maps based).
  • Enter a C×W matrix (C customers top to bottom × W warehouses left to right) in below text area with each matrix cell containing the total transport costs to deliver the total demand of customer c from warehouse w.

  • Uncheck constraint "Fixed customer-warehouse assignments" if you no longer want to constrain customer assignments.
  • Clear textarea if you no longer want to override.
i
Must‑be‑included
  Warehouse group   a b c d e f g h i j
  Number of warehouses in group  
  Number of warehouses to select  
Warehouse combinations generation
K-means Clustering
  runs
i

Superfast Selection
solver
Enumeration
solver
Warehouse
capacities
      Ignore / n.a.
Greedy solver
i
LP solver      
i
For more info about above 3×3 options, read section
"About Select best warehouses algorithms"
.

Display selected warehouses only
i
Create "Top X" report, X =
i
Copy reports
Tab separated
Decimal point
Semicolon separated
Decimal comma

Summary

Selected warehouses

i

Customer assignments

Enumeration solver - Top X warehouse combinations


The "Select best warehouses" routine selects those predefined warehouses that minimize customer plus supplier transport costs + warehouse binary‑fixed costs + warehouse variable handling costs.
  • Customer transport cost if customer c is delivered from warehouse w = demand qty of customer c × as-the-crow-flies-distance between warehouse w and customer c × distance circuity factor × customer transport rate (= transport cost/distance unit/qty unit).
    • Distance is based on coordinates of the predefined warehouse, not final coordinates of Center-of-Gravity in case the warehouse was allowed to move, so you may want to copy those back into your predefined warehouse.
    • Distance includes detour via a border crossing point if applicable.
    • You can adjust cost input via section
      "Optional - Override warehouse-customer transport costs (input)"
      .
  • Supplier transport cost for each supplier = supply qty s × as-the-crow-flies-distance between warehouse w and supplier s × distance circuity factor × supplier transport rate * warehouse qty/total demand (conform supply option 3).
  • Warehouse binary-fixed costs of warehouse w are its fixed costs and apply only if warehouse w is opened.
  • Warehouse variable handling costs if customer c is delivered from warehouse w = productsum(customer c's whs quantities × warehouse w's variable rates). Note that customer field Demand (= transport qty) is irrelevant in this formula.

ConstraintSupportedHow to activate
Predefined warehousesyesAlways active (regardles constraint setting).
Fixed customer-warehouse assignmentsyesBy checking constraint in
"Parameters & Constraints"
- subsection
"Constraints"
Capacity limitsyesBy using Greedy solver or LP solver (not by checking constraint).
Customer groupsno
SuppliersyesBy checking constraint in
"Parameters & Constraints"
- subsection
"Constraints"
.
Supply option 3 is activated in background. Other options not supported.
Border crossing pointsyesBy checking constraint in
"Parameters & Constraints"
- subsection
"Constraints"
.
The selection of best warehouses is handled by two separate procedures.
  • One procedure that generates valid warehouse combinations = close/open decision (0/1) for each warehouse. The Enumeration solver simply generates all possible warehouse combinations, whereas the other two solvers generate only "promising" combinations (so run relatively much faster, but may miss out the optimal combination).
  • One procedure that handles warehouse capacity limits, given the close/open decisions. The Greedy solver runs quick, but may produce sub-optimal results. The LP solver runs relatively slow, but produces optimal results. Of course, if "ignore / n.a" is selected, then customers can simply be assigned to the open warehouse that brings the lowest costs (usually the closest warehouse), which requires no specific solver.
Those two procedures have each 3 (solver) options, resulting in 3×3 combinations you can select from.

Best is to run Enumerations Solver together with LP Solver (if warehouse capacity limits still apply in future). But if run time becomes too long - especially the LP Solver that handles capacity constraints is relatively slow - then stop the run and
  • use K-means Solver (and limit number of runs) or Superfast Selection Solver to generate warehouse combinations.
  • and/or use Greedy Solver to handle capacity constraints.

Warehouse combinations generation

Generates all possible valid warehouse combinations, so it will always find the optimum. But the higher the number of permutations, the longer the run time. It may even take hours. Reason to develop the other two solvers, that run quickly and will almost always find the optimal solution, however without guarantee. Because all combinations are generated and evaluated, the Enumeration Solver can produce a "top 20" list of warehouse combinations.
Problem-specific solver, invented by Stelling Consulting. Found optimal solutions in almost all tests, or else 0-2% worse. Roughly described, it works like this:
  • Open 1 by 1 the next best warehouse, until the amount of opened warehouses exceeds the amount to be opened with X. Then close X worst warehouses 1 by 1.
  • Swap N open warehouses with N closed ones (within 1 to N groups). Run for all possible swaps, enumeration-wise. Revert swap if solution got worse.
For example, it solved a 145 million combinations case optimally in 0.1 second, versus 5 minutes Enumeration Solver.
Problem-specific solver, custom developed by Stelling Consulting. Performs a K-means-Clustering-like procedure.

Single run
  • Initialisation: for each group, select a random warehouse within the group and open it, until the amount of warehouses to be opened for this group has been reached.
  • As long as costs still decrease, keep looping through all open warehouses, and
    • Close this open warehouse.
    • Find the closed warehouse within this group that will decrease costs the most (or increase the least), if it is opened.
    • Open that warehouse. (It might be the same warehouse as the one that just has been closed.)
Multiple runs
  • Perform the single run procedure multiple times (each starting with different randomly selected warehouses).
  • Often, this best solution will have been found in several times of those runs. (Just like the Center-of-Gravity calculation procedure that will find the same solution several times doing N runs.).
This solver found optimal solutions in almost all tests, or else 0-2% worse. The chance of missing out the optimum becomes higher, if the number of runs is set lower.

Speed is usually in the same ballpark as Superfast Selection Solver. But if a high number of warehouses and (relatively) high number to be opened is applicable, then the limit on number of runs makes it finish faster than Superfast Selection Solver.

Warehouse capacity limits handling

Greedy Solver runs a fast, greedy algorithm that works likes this:
  • Assign customers to warehouses as if capacities are unlimited
  • Loop through all warehouse, and while the capacity of a warehouse is exceeded shift that customer to that other warehouse that will increase the costs the least (and only if the customer still fits in that warehouse if it is a warehouse earlier in the loop).
The solution may become sub-optimal.
LP Solver runs Vogels' approximation + MODI + Stepping Stone a much faster equivalent of LP optimization by Simplex method. If predefined warehouses have a limited capacity, a transportation problem arises. A transportation problem can be solved with the well-known Simplex method (LP). But it can be solved 50-100 times faster with a combination of Vogel + MODI + Stepping Stone method that generates an optimal solution. This combination has been implemented. Detailed descriptions of each separate method (standard as such) can be found on the internet. For a demo case that shows the speed difference, see Transportation problem solver

Note that if a customer receives from two warehouses in the optimal transportation problem solution (in which warehouse utilization never exceeds 100%), then this customer gets assigned in full to the warehouse that supplies the most. This non-optimal, post-step may cause utilization to exceed 100%, usually less than 1%, as it will involve/apply to a few customers only.
 

You

You may want to save your current scenario first!
Reload the scenario you want to share. Press button Export scenario file. Email file to your coworker.




Coworker

You may want to save your current scenario first!
Save file as received by email from your coworker on your computer. Press button Import scenario file.
Imported data is not saved into local browser memory until you press button Save under section Calculate.
Then it will permanently overwrite previous scenario data.
Your e-mail address

Your e-mail address (again)


Your message / question / suggestion for improvement

"Suggestions are always welcomed!
Multiple customers have experienced that their suggestion for a new feature got realized."

Alrik Stelling - Owner
 

You want support to investigate your specific case?

Then go to section Collaborate, export a scenario file, and email that file with your question or description of your issue.

(Do not send a filled Excel template. It does not contain your parameter settings.)