Centers‑of‑Gravity Calculator

  • Calculates Centers‑of‑Gravity - indicative warehouse locations that minimize transport costs - based on yearly demand per customer location (latitude/longitude) as main input.
  • Offers an advanced mode to go beyond a basic greenfield analysis: you can predefine existing warehouses (with or without capacity limit, fixed location or limited move range), link customers to warehouses, group customers for single sourcing, include supplier transport costs, run sensitivity analyses, ...
    •   New: LP post-optimization + border crossing points (user defined)
  • Produces a downloadable map, service level chart, and detailed reports that are easily copied into clipboard/Excel.
  • Try before you buy: you can run this fully functional web app, filled with demo data.
We have been using Centers‑of‑Gravity Calculator for years. It’s 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
 
After adjustment, a single Calculation is run to effectuate changes
Customer/supplier size factor 
⇐ Set it such that 1st legend value becomes  
i
Centers‑of‑Gravity size factor 
Flow size factor 
i


Customer/supplier opacity 
Center‑of‑Gravity opacity 
Center‑of‑Gravity color  
Label font size 
Display transport-rated volumes
i
Display Centers‑of‑Gravity as fixed-sized circles
i
 Differentiate demand map
i
Display customer flows
 
Display supplier flows
Supplier flows color  
Supplier flows arrow size 
i
Scale arrows
Distance based customer coloring from green at 0 km, to red at lead time distance limit, and black beyond.
Carto map
ESRI map
OpenStreetMap map
 
Save all map settings as   
  under button  
Save



Reload: click a button

1. ...
⇒ Your custom settings used at startup
2. ...
3. ...
4. ...
5. ...
6. ...
7. ...
8. ...
9. ...
10. ...
Use system default
i
Use key
i
 
  Center Latitude  
  Longitude  
  Zoom  
  Width  
  Height  
 

You need to enable javascript.

Basic Mode
Advanced Mode
i
Report kilometers
Report miles
Note that fields Customer_ID and Border_group (free format) have been added.
If logged in, you can click in text area to highlight a customer on the map displaying calculation outcomes.

CUSTOMERS
Customer_ID  |  Latitude  |  Longitude  |  Demand  |  Warehouse_ID (opt)  |  Group (opt)  |  Shipment_size (opt)  |  Lead_time_distance (opt)  |  Border_group (opt)
141.153320.16833430AL
246.633314.31284270AT
346.989415.58174200AT
447.25211.424690AT
547.578412.73053550AT
647.991113.887811530AT
748.067113.17753300AT
848.202516.41864600AT
948.204916.27346100AT
1048.229716.46922620AT
1148.365613.97713340AT
1243.331917.75135900BA
1343.878418.35932460BA
1450.24584.85192720BE
1550.37534.38193420BE
1650.41724.4473220BE
1750.45553.96623500BE
1850.4614.84982940BE
1950.47974.16984600BE
2050.5885.86022840BE
2150.58824.32533120BE
2250.593.39222960BE
2350.59425.43313200BE
2450.59786.13253280BE
2550.64735.58326550BE
2650.72374.55433140BE
2750.74163.22382420BE
2850.78864.86122980BE
2950.81375.20892460BE
3050.81853.27852440BE
3150.8494.42975360BE
3250.85215.68783520BE
3350.88324.35519200BE
3450.89034.73818200BE
3550.89894.3913200BE
3650.93165.33684880BE
3750.94063.11816900BE
3850.94394.04422920BE
3950.96765.48863160BE
4050.98364.8213280BE
4150.98943.51063380BE
4251.00773.3683080BE
4351.02934.0942540BE
4451.03534.46653280BE
4551.05323.63079480BE
4651.124.57342780BE
4751.14624.33834120BE
4851.164.82773440BE
4951.16954.16474240BE
5051.20625.37982480BE
5151.2124.46863670BE
5251.21472.9193280BE
5351.22114.36643130BE
5451.23293.21183610BE
5551.23845.19493280BE
5651.27064.50284450BE
5751.33693.32343850BE
5851.35314.7712780BE
5942.68723.32734660BG
6042.726623.315818640BG
6153.123226.57967000BY
6246.03388.97192940CH
6346.12587.22742620CH
6446.34076.19743670CH
6546.59026.67164600CH
6646.93747.43452700CH
6746.969.05525800CH
6846.96528.21832640CH
6947.19217.56153360CH
7047.30927.60314560CH
7147.34759.40812520CH
7247.37768.53815900CH
7347.40368.03742820CH
7447.55677.59793730CH
7547.57779.08993340CH
7635.030933.13745960CY
7749.181216.67692520CZ
7849.839718.32482800CZ
7949.88616.47112610CZ
8049.887914.65555000CZ
8150.044614.56167790CZ
8250.136814.46013000CZ
8350.22414.07762840CZ
8447.748710.4642420DE
8547.844112.20044060DE
8647.848411.28494480DE
8747.89488.07213700DE
8847.90839.54462560DE
8947.98218.68013240DE
9048.12511.60057370DE
9148.182711.54956400DE
9248.32548.95952620DE
9348.337110.84774870DE
9448.434212.41173240DE
9548.446110.11333880DE
9648.489111.56843560DE
9748.726413.06732800DE
9848.75579.18173520DE
9948.78759.84224630DE
10048.81839.35294300DE
10148.96868.29096120DE
10249.092912.35277240DE
10349.28429.50624300DE
10449.3417.11153370DE
10549.357810.95455520DE
10649.406910.99995080DE
10749.42511.9613380DE
10849.42888.92782440DE
10949.46198.50934750DE
11049.51317.9894630DE
11149.74778.76633260DE
11249.84577.71225360DE
11349.962210.016615520DE
11450.05649.06168740DE
11550.089111.92072960DE
11650.11311.00842500DE
11750.11528.65634800DE
11850.20848.19024600DE
11950.30197.53174840DE
12050.526110.69563180DE
12150.549812.40752980DE
12250.60646.92744900DE
12350.67819.74572800DE
12450.732811.70884840DE
12550.777413.12323940DE
12650.79868.68663480DE
12750.80856.28724160DE
12850.90016.75875900DE
12950.93157.99582860DE
13050.96097.38265360DE
13151.17536.47733520DE
13251.177313.78975600DE
13351.186810.83034840DE
13451.201914.52073280DE
13551.2146.81364280DE
13651.21619.19774360DE
13751.30137.59813100DE
13851.344112.93573840DE
13951.49428.01544630DE
14051.496712.02024360DE
14151.52459.92083520DE
14251.5327.36955800DE
14351.54346.38757500DE
14451.55577.13728980DE
14551.7176.59462400DE
14651.756814.03472780DE
14751.78988.68245400DE
14852.12357.43024200DE
14952.15958.82322760DE
15052.187510.6834420DE
15152.245514.01423250DE
15252.317912.78862740DE
15352.323510.0994060DE
15452.385111.64952560DE
15552.40139.69575000DE
15652.459413.48923220DE
15752.511713.40793370DE
15852.53167.72785700DE
15952.587813.33928560DE
16052.949313.16483280DE
16153.08998.84413060DE
16253.20829.35742500DE
16353.29347.76664900DE
16453.357411.48063360DE
16553.4569.8083520DE
16653.56259.99144540DE
16753.5913.33373060DE
16853.632710.08747780DE
16953.95510.9566050DE
17054.031812.42734570DE
17154.31679.89183550DE
17254.32569.12573340DE
17355.614712.31887300DK
17455.668912.553250DK
17559.221724.1876810EE
17635.2931-2.94922420MadridESIberia
17735.8917-5.33053000MadridESIberia
17836.1408-5.35362440MadridESIberia
17936.5295-5.755411200MadridESIberia
18036.8099-4.663212760MadridESIberia
18137.3103-2.34286040MadridESIberia
18237.3968-3.2311000MadridESIberia
18337.5034-6.79915800MadridESIberia
18437.5264-5.580714280MadridESIberia
18537.9667-3.34425800MadridESIberia
18637.9718-4.76917300MadridESIberia
18738.073-1.470212160MadridESIberia
18838.3649-0.423718480MadridESIberia
18938.7208-5.96838840MadridESIberia
19038.7359-1.8656000MadridESIberia
19138.979-3.79945700MadridESIberia
19239.3672-0.736125920MadridESIberia
19339.61782.90676920MadridESIberia
19439.7771-6.29814800MadridESIberia
19539.8069-4.11615000MadridESIberia
19639.9488-2.12172880MadridESIberia
19740.2532-0.13815300MadridESIberia
19840.5295-3.766977840MadridESIberia
19940.6066-0.72993320MadridESIberia
20040.6391-4.90622540MadridESIberia
20140.7418-2.50935250MadridESIberia
20240.7762-6.00964690MadridESIberia
20341.05360.92185000MadridESIberia
20441.1183-3.95733340MadridESIberia
20541.693-6.15063160MadridESIberia
20641.7153-4.64884600MadridESIberia
20741.7472.072357700MadridESIberia
20841.8449-0.866212800MadridESIberia
20942.06711.09734720MadridESIberia
21042.07342.50639820MadridESIberia
21142.1097-0.06372960MadridESIberia
21242.1882-7.52375000MadridESIberia
21342.2716-2.40016040MadridESIberia
21442.3387-3.57944520MadridESIberia
21542.3728-8.36898020MadridESIberia
21642.4117-4.48143480MadridESIberia
21742.6085-1.605411160MadridESIberia
21842.63-5.89456850MadridESIberia
21942.8386-2.74894840MadridESIberia
22043.0522-7.37175800MadridESIberia
22143.1264-3.99526100MadridESIberia
22243.1369-8.475715040MadridESIberia
22343.1534-2.15684600MadridESIberia
22443.2274-2.94127930MadridESIberia
22543.254-5.82557320MadridESIberia
22660.161624.484427040FI
22742.179.05962400FR
22842.63112.43883520FR
22943.03392.47543340FR
23043.13790.1642700FR
23143.1855-0.87787150FR
23243.31181.247911440FR
23343.41896.2955440FR
23443.54245.02877510FR
23543.59033.3636760FR
23643.78362.24932440FR
23743.90027.185810900FR
23843.9514.07743520FR
23943.99885.2163790FR
24044.0016-0.68423300FR
24144.06591.36962520FR
24244.29612.64162920FR
24344.35610.48153240FR
24444.72375.24952480FR
24544.8705-0.473115430FR
24645.12830.71132760FR
24745.28435.57254600FR
24845.33131.88353520FR
24945.48216.40612960FR
25045.66450.2512400FR
25145.707-0.60453160FR
25245.75174.24175480FR
25345.76483.19227250FR
25445.86674.71588040FR
25545.90051.26593640FR
25646.05965.46722520FR
25746.07016.42983160FR
25846.36153.12382760FR
25946.475-0.31323220FR
26046.58710.54763140FR
26146.66024.54322800FR
26246.6798-1.33153400FR
26346.76565.72513080FR
26446.80941.54973520FR
26547.01222.43472680FR
26647.05586.38973080FR
26747.21810.72644360FR
26847.3432-1.72856680FR
26947.3935-0.53693730FR
27047.46174.80034840FR
27147.62856.95872760FR
27247.66071.43622400FR
27347.8153-2.86753430FR
27447.85053.60843460FR
27547.8677.23163280FR
27647.91592.28664090FR
27748.01760.23634330FR
27848.142-0.63823580FR
27948.15486.31453240FR
28048.1559-1.63919960FR
28148.2314-4.0695840FR
28248.32114.1473440FR
28348.4526-2.77614090FR
28448.45571.39173020FR
28548.52862.26167000FR
28648.57210.07392920FR
28748.58157.59716350FR
28848.61382.96915050FR
28948.7631.84217840FR
29048.77312.45156700FR
29148.84092.23534540FR
29248.86082.32738740FR
29348.90572.451910500FR
29448.94595.98185760FR
29548.96844.24246850FR
29649.00865.38143340FR
29749.01456.79533250FR
29849.06631.07322500FR
29949.07292.10666200FR
30049.0903-1.33873580FR
30149.0927-0.35373910FR
30249.41292.42794600FR
30349.46573.60213400FR
30449.67140.93065650FR
30549.97462.30592980FR
30650.5313.164314560FR
30750.53752.35714750FR
30841.918644.36282940GE
30935.322525.02983490GR
31037.531923.34074760GR
31137.893523.77652640GR
31237.93823.71793360GR
31337.986723.72076160GR
31437.989423.73769750GR
31538.003823.6366160GR
31638.018223.86414640GR
31738.082923.83143300GR
31838.226421.81533340GR
31939.567920.84953520GR
32039.571622.46813020GR
32140.581123.01073480GR
32240.675222.93833340GR
32340.698623.29853700GR
32440.772522.98973580GR
32545.792116.02514600HR
32647.476819.13926220HU
32747.549219.00323700HU
32847.631619.38114360HU
32951.8969-8.48637960BirminghamIEIE
33052.2523-7.12723520BirminghamIEIE
33152.2713-9.69992800BirminghamIEIE
33252.6541-7.24482640BirminghamIEIE
33352.668-8.63054390BirminghamIEIE
33453.2706-9.05674150BirminghamIEIE
33553.3498-6.260325990BirminghamIEIE
33653.7179-6.35613200BirminghamIEIE
33754.2766-8.47612880BirminghamIEIE
33836.907814.68212600ITIT
33937.037215.08973520ITIT
34037.494214.84949080ITIT
34137.875112.78163260ITIT
34237.896913.66013920ITIT
34338.055114.9134600ITIT
34438.391716.11252860ITIT
34538.973616.65024560ITIT
34639.587216.37833370ITIT
34739.61139.00926530ITIT
34840.16418.17123960ITIT
34940.22839.09852460ITIT
35040.418715.1514510ITIT
35140.529815.89133120ITIT
35240.558317.26424090ITIT
35340.641117.75682680ITIT
35440.787714.45949910ITIT
35540.81848.90294390ITIT
35640.9915.08292860ITIT
35741.032816.66327930ITIT
35841.205914.1422420ITIT
35941.229614.77792540ITIT
36041.462113.19192460ITIT
36141.528115.59694280ITIT
36241.619813.48993320ITIT
36341.722514.54243380ITIT
36441.854812.501427680ITIT
36542.105714.46173480ITIT
36642.173813.64182820ITIT
36742.318714.00833240ITIT
36842.505511.97243500ITIT
36942.670612.40412820ITIT
37042.678713.74793600ITIT
37142.765711.23062960ITIT
37243.006513.54813480ITIT
37343.104812.64440ITIT
37443.16311.45314060ITIT
37543.169813.27723360ITIT
37643.476110.6229560ITIT
37743.487213.20562460ITIT
37843.524311.9193520ITIT
37943.692312.63693120ITIT
38043.828111.21395400ITIT
38143.95367.82983200ITIT
38244.032512.19917100ITIT
38344.22329.75942920ITIT
38444.25828.32523380ITIT
38544.344811.95494000ITIT
38644.44211.28985760ITIT
38744.4519.05724640ITIT
38844.46677.55914600ITIT
38944.54210.90654330ITIT
39044.604810.50673670ITIT
39144.69279.95673910ITIT
39244.754211.78222560ITIT
39344.82889.59743380ITIT
39444.83538.18882720ITIT
39544.85378.6473100ITIT
39644.967111.85373600ITIT
39745.02649.03484850ITIT
39845.135610.85013260ITIT
39945.17367.37912700ITIT
40045.19269.89364270ITIT
40145.392311.77876550ITIT
40245.42211.05678620ITIT
40345.458812.47544870ITIT
40445.48089.119723500ITIT
40545.55228.1964540ITIT
40645.617711.46493820ITIT
40745.73629.84214720ITIT
40845.757310.35167930ITIT
40945.779813.62453120ITIT
41045.809412.21133940ITIT
41145.85718.79994840ITIT
41245.86558.33884760ITIT
41345.93059.15723610ITIT
41446.129911.2022760ITIT
41546.13579.91823180ITIT
41646.193313.01437150ITIT
41746.290712.16462780ITIT
41846.664511.38933380ITIT
41954.891723.92212620LT
42055.150822.9553220LT
42155.169423.88134750LT
42255.930225.35593480LT
42356.987424.10594750LV
42449.81536.12963940LX
42547.025228.85093440MD
42641.987621.49023480MK
42735.937514.37546120MTIT
42850.88665.96193440NL
42951.10765.86265720NL
43051.37126.17112420NL
43151.42045.4013420NL
43251.43755.48173160NL
43351.49244.03783120NL
43451.58864.78132900NL
43551.5985.09232440NL
43651.6865.302713100NL
43751.80645.258512640NL
43851.84715.86354450NL
43951.91764.48873790NL
44051.98055.90592680NL
44152.0235.03614920NL
44252.0245.5572840NL
44352.07874.31724870NL
44452.08795.11622680NL
44552.13265.291313740NL
44652.15185.04512700NL
44752.15544.49162760NL
44852.22086.89932800NL
44952.22445.17647900NL
45052.30814.94424600NL
45152.37284.90676700NL
45252.51136.09032760NL
45352.63074.75053120NL
45452.73086.47235740NL
45552.78476.90092860NL
45653.2186.57072620NL
45759.732610.79136450NO
45859.934210.79947780NO
45950.21819.0024160PL
46051.813519.44510450PL
46152.107721.081529210PL
46252.265817.62522860PL
46352.28221.03863000PL
46437.0213-7.93382680MadridPTIberia
46538.525-8.89866120MadridPTIberia
46638.7367-9.133919060MadridPTIberia
46739.2322-8.6862620MadridPTIberia
46839.3999-8.22452720MadridPTIberia
46939.7425-8.80642760MadridPTIberia
47040.2108-8.42215640MadridPTIberia
47140.6266-8.64792840MadridPTIberia
47240.6447-7.30442780MadridPTIberia
47340.6592-7.91473460MadridPTIberia
47441.1515-8.605110180MadridPTIberia
47541.5453-8.41993940MadridPTIberia
47644.390226.116126080RO
47744.440326.03425960RO
47844.453126.12867580RO
47944.520726.13589080RO
48045.794525.22653040RO
48145.930324.304418170RO
48244.016521.005920720RS
48344.826220.45719300RS
48455.816837.4999145900RU
48557.38712.279222750SE
48646.056314.504710090SI
48746.556515.64994900SI
48848.049818.25323140SK
48948.066517.1553490SK
49048.197617.14784570SK
49148.67420.78493120SK
49248.753619.29415640SK
49349.135621.18673190SK
49436.730731.04362780TR
49537.036937.28752620TR
49637.286735.73333040TR
49737.869832.39944320TR
49838.48927.226122280TR
49938.709735.84096160TR
50039.624237.32572440TR
50139.919132.7538560TR
50240.191429.05552460TR
50340.368936.54313260TR
50440.907139.80052480TR
50541.010529.002555600TR
50641.200736.13772900TR
50748.379431.165624400UA
50848.437134.90454900UA
50950.442430.52217780UA
51049.2044-2.1372860BirminghamUKUK
51150.4536-3.70992960BirminghamUKUK
51250.4769-4.42834040BirminghamUKUK
51350.8499-0.941919360BirminghamUKUK
51450.8647-0.12392940BirminghamUKUK
51550.9034-3.79712820BirminghamUKUK
51650.9553-1.36834090BirminghamUKUK
51751.0893-0.29953180BirminghamUKUK
51851.0970.52012840BirminghamUKUK
51951.1703-0.75546450BirminghamUKUK
52051.3326-0.39053440BirminghamUKUK
52151.37750.08539240BirminghamUKUK
52251.41560.26932480BirminghamUKUK
52351.4249-2.65713160BirminghamUKUK
52451.4389-0.42693460BirminghamUKUK
52551.44770.01232800BirminghamUKUK
52651.4535-0.18934960BirminghamUKUK
52751.5144-0.17853140BirminghamUKUK
52851.5168-0.18053020BirminghamUKUK
52951.5313-0.02583100BirminghamUKUK
53051.5491-0.36383580BirminghamUKUK
53151.5559-0.11552600BirminghamUKUK
53251.56780.27253280BirminghamUKUK
53351.5699-0.10353280BirminghamUKUK
53451.5805-0.20733910BirminghamUKUK
53551.5844-0.34794120BirminghamUKUK
53651.60290.07713360BirminghamUKUK
53751.622-3.39928700BirminghamUKUK
53851.6633-0.38792740BirminghamUKUK
53951.7784-0.31568840BirminghamUKUK
54051.79240.48023440BirminghamUKUK
54151.8347-1.29953910BirminghamUKUK
54251.8808-4.43482780BirminghamUKUK
54351.96790.87492560BirminghamUKUK
54451.9687-0.1532660BirminghamUKUK
54552.0941-0.685148300BirminghamUKUK
54652.22520.23782400BirminghamUKUK
54752.273-0.86613060BirminghamUKUK
54852.3304-1.48212800BirminghamUKUK
54952.3767-1.83683520BirminghamUKUK
55052.4658-1.98793420BirminghamUKUK
55152.4664-1.888632500BirminghamUKUK
55252.6388-1.02364720BirminghamUKUK
55352.66391.233114430BirminghamUKUK
55452.72680.1283260BirminghamUKUK
55552.9482-3.814412840BirminghamUKUK
55653.0054-0.8013100BirminghamUKUK
55753.2034-3.03123340BirminghamUKUK
55853.2582-1.40472800BirminghamUKUK
55953.3608-1.46742600BirminghamUKUK
56053.374-2.54962720BirminghamUKUK
56153.4236-1.45763260BirminghamUKUK
56253.4301-1.40922420BirminghamUKUK
56353.4669-2.22383460BirminghamUKUK
56453.51-2.24273280BirminghamUKUK
56553.5178-1.46472940BirminghamUKUK
56653.5278-0.61532440BirminghamUKUK
56753.5478-2.65383400BirminghamUKUK
56853.6686-1.45811700BirminghamUKUK
56953.7526-0.30072760BirminghamUKUK
57053.7726-2.78522900BirminghamUKUK
57153.8316-2.98043340BirminghamUKUK
57253.8482-2.37867000BirminghamUKUK
57353.859-1.53863130BirminghamUKUK
57453.9762-2.01785920BirminghamUKUK
57554.1184-0.78913220BirminghamUKUK
57654.5486-1.12675760BirminghamUKUK
57754.7576-2.90546200BirminghamUKUK
57854.8088-1.77222820BirminghamUKUK
57954.8533-1.3942760BirminghamUKUK
58055.2237-2.02766250BirminghamUKUK
58155.3781-3.43616000BirminghamUKUK
58255.4331-4.5093020BirminghamUKUK
58355.6095-3.77233360BirminghamUKUK
58455.7945-4.20766600BirminghamUKUK
58555.8453-4.31126500BirminghamUKUK
58656.7077-2.75973040BirminghamUKUK
58757.2367-2.78212780BirminghamUKUK
58857.8682-4.44482620BirminghamUKUK


Create an account to run this fully functional web app with your own data instead of the demo data.

Download Excel template if you want to copy-paste from Excel file (tab separated). Or enter data semicolon separated. Do not copy-paste table headers, but data rows only. Decimal commas will be converted to decimal points, and thousands separators removed automatically.

Use Batch Geocoder (free) or Batch Geocoder (paid) or any other geocoder of your choice to retrieve latitudes/longitudes of location addresses, in case you have not done so yet.

Section Data preparation discusses field Demand, amongst others. Section About optional input fields and tables (Advanced Mode) explains all optional fields of the Customers table.
SUPPLIERS
Supplier_ID  |  Latitude  |  Longitude  |  Supply  |  Warehouse_ID (opt)  |  Shipment_size (opt)  |  Supply_option
PREDEFINED WAREHOUSES
Warehouse_ID  |  Latitude  |  Longitude  |  Move_limit (km)  |  Capacity (opt)  |  Transport_rate_index (opt)
BORDER CROSSING POINTS
Border_group  |  Latitude  |  Longitude
 

Customers

  • Warehouse_ID (= link to table Predefined warehouses) is used to assign a customer to a predefined warehouse. If left empty, the software decides to which Center‑of‑Gravity the customer will be assigned. If you specify Warehouse_ID, then the customer will be assigned to that warehouse, regardless Group.
  • Group - free format, for example "UK" - is used to force all customers within a group to be delivered by a single warehouse only , the one that comes with the lowest sum of weighted distances for this group of customers. What group means, is up to you - often used is country. Warehouse capacity constraints may cause some customers of a group to get reassigned to another warehouse. You can fill group for some customers (treated as group), and leave group blank for others (treated individually).
  • Shipment_size is used to calculate an individual customer transport rate.
    • Given two customers with equal demand, the customer with smaller shipments will pull the Center‑of‑Gravity harder than the customer with larger shipments, as transporting many small shipments is more expensive than tranporting a few large shipments. So, customers with smaller shipments will pull a Center‑of‑Gravity relatively less and vice versa.
    • The impact of individualized shipment sizes on Centers‑of‑Gravity locations will be marginal, if small and large (shipment) customers are scattered all around, which is usually the case. You can start without individualized shipment sizes.
    • Transport rates - including logic behind transforming shipment size into transport rate - are explained under section "Optional constraints and parameters".
  • Lead_time_distance (km) represents lead time requirement expressed as the maximum allowed distance from the warehouse. Customers are colored in black if warehouse distance exceeds leadtime distance. This provides a visual clue of where lead times are compromised. You can then decide to increase the number of warehouses, or to setup a predefined warehouse at a location closer to these customers (with a zero or limited move range), or accept that some customers will have a longer lead time (like in reality; a few small far-away customers should not be driving your supply chain network design!).
  • 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 within the bordered area (auto-detected for a warehouse, as it may enter or exit the area during the optimization process).

Suppliers

  • Warehouse_ID (= link to table Predefined warehouses) is used to assign a supplier to a warehouse. If left empty, the software decides which Center(s)-of-Gravity is/are supplied by the supplier. If set, then this supplier will not supply all warehouses directly, even if supply option "Each supplier delivers to each warehouse directly" has been selected.
  • Shipment_size is used to calculate a supplier specific transport rate. Transport rates are explained under section "Optional constraints and parameters".
  • Supply_option is used to overrule the generic supply option as selected under section "Optional constraints and parameters".
    1. Supply closest warehouse only
      i
    2. Supply each warehouse
      i
    3. Supply each warehouse via closest warehouse
      i

Predefined warehouses

  • 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).
  • Move_limit = 0 means a fixed location, whereas Move_limit > 0 (in km, not miles!) means a moveable location that may move within its Move limit around its coordinates.
  • Capacity is used to limit the demand that can be assigned to a warehouse. Capacity constraints may 'break' customer groups.
  • 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).

Border crossing points

Border crossing points can enhance routing accuracy. For example:
  • UK: the English Channel is crossed at a specific points.
  • Italy: merely surrounded by sea and trucks enter/exit via its north side. Border crossing points prevent that flows go directly from Italy into Albania/Croatia (or vice versa) crossing the Adriatic sea.

Border crossing points get activated:
  • if a warehouse is outside the area and supplies a customer within the area (entry)
  • if the warehouse is inside the area and supplies a cusomer outside the area (exit)

  • Border_group - free format - is the name of the bordered region (often a country) with its specific border crossing points as defined in this table. Field border_group is also found in the customers table, to link customers to the group. The customers define its shape.

The optimal border crossing point is auto-detected. To function properly at least some customers of a bordered area should be located within a 50 km range of the border point.
One border crossing per flow is supported, currently. A DC area exit point will take priority over a customer area entry point ("exit before entry").

The demo case contains just a few sample border crossing points to show you how it works. Feel free to adjust!
 
Centers‑of‑Gravity
 
runs
i
Activate border
crossing points
i
Sum of weighted distances
i
Current
Minimum 

Distance / lead time / service level

Factor to convert as-the-crow-flies-distance into fastest route road distance
i
 
 
Color customers black if warehouse distance exceeds lead time distance
 km
i
 
 Improve service level
i
 

Closest city name

 Display CoG closest city
i
Only consider cities with a population larger than
  • City name appears as Center-of-Gravity name on the map and in reports, if you have checked 'Display closest city name'.
    • But warehouse_ID is shown as name in case of a predefined immovable warehouse.
  • When determining closest city, only cities with a population larger than the population threshold are included.
  • The database contains cities that have a population larger than 15,000, as depicted below.



Sensitivity analysis

Display 

-costs-increase-areas around Centers‑of‑Gravity

i
 

Randomize each demand quantity ± 

; using a  

 distribution

i
 

Apply constraints

Predefined warehouse locations
Fixed customer-warehouse assignments
Fixed supplier-warehouse assignments
Capacity limits
Run LP post-optimization
i
Customer groups
i
 

Supply options

Activate supply
Each supplier delivers to closest warehouse only
i

Each supplier delivers to each warehouse
i

Each supplier delivers to each warehouse via closest warehouse

i
 

Transport rates

 

Auto-size shipments per individual customer

i
 
i
Shipment size

% FTL

% FTL costs

Cost ratio
i
Costs/km
i
Transport rate
FTL
Customer
Supplier
Interdepot
Ratio supplier rate/customer rate =  
Transport cost of a customer = demand × distance warehouse-customer × customer transport rate (that becomes
customer specific if shipment size is specified in customer table - same rate logic as shown above applicable).

  • Transport rates enable differentiation between relatively less expensive FTL-like (supplier) transport and relatively more expensive LTL-like (customer) transport.
  • In order 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 and customer transport rate is more important than the rates as such.
  • 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, thus properly reflecting the force with which a location pulls a Center‑of‑Gravity (though in case of a supplier, this force may be split across all warehouses, dependent on selected supply option).
  • You may even enter shipment size per individual customer, to differentiate transport rates between customers. However, impact on Centers-of-Gravity locations will be marginal, if small and large (shipment) customers are scattered all around.
  • LTL transport is relatively more expensive than FTL transport. An LTL shipment size of 50% FTL brings 72% FTL costs, approximately. Thus, per each unit transported LTL transport is 1.44 times more expensive than FTL transport.
Shipment costs curve
i
LTL cost factor as % FTL cost
Shipment size as %FTL
Point   X   Y  
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
 

Customers table

  • Check constraint "Fixed customer-warehouse assignments" to assign customers to a warehouse. Demo data: customers in UK/Ireland are assigned to the predefined Birmingham warehouse (field Warehouse_ID set to "Birmingham"), and customers in Spain/Portugal to the Madrid warehouse.
  • Check constraint "Customer groups" to have all customers within a group delivered by the same single warehouse. Demo data: all customers have field Group filled with a 2-letter ISO country code. In this case group means country: each country is delivered by one warehouse only.

Predefined warehouses table (optional)

  • Check constraint "Predefined warehouse locations" to activate predefined warehouses and include those in the solution. Demo data: there is one warehouse in Birmingham/UK (cannot move, field Move limit set to 0) and one in Madrid/Spain (can move within a 200 km range around Madrid, field Move limit set to 200).
  • Check constraint "Capacity limits" to limit warehouse throughput capacities. Demo date: field Capacity is set for both Birmingham and Madrid.

Suppliers table (optional)

  • Check parameter "Activate supply" to activate supply. Demo data: there is one supply location in harbour Rotterdam/The Netherlands (supplies 71% total demand volume), and one in Bologna/Italy (supplies 29% total demand volume).
  • Suppliers - like customers - pull Centers‑of‑Gravity which will tend to move towards suppliers, as supply volumes are usually high compared to individual customer demand volumes. However, supplier transport is - due to larger shipment sizes - relatively less expensive than customer transport. Transport rates express how much less. Supplier quantity × supplier transport rate = supplier pull force. Suppliers will appear relatively smaller on the map - reflecting pull force as used in the calculations - if you check Map Settings option "Display transport rated volumes".
  • Flows from suppliers to customers via warehouse(s) are constructed automatically. Under Supply options you can chose from three options. Option “each supplier delivers to each warehouse” is the default option, and means that the supplier volume to each warehouse is pro rata the customer demand assigned to each warehouse.
 
Show outcomes of Center-of-Gravity
Distance bin width (km)
10 20 25 50 100
 Distance    Demand cum   Demand   Customers cum   Customers   # Customers 
 

 
 
 
 
Tab separated
Semicolon separated
Decimal point
Decimal comma
Copy reports
CENTERS‑OF‑GRAVITY
CoG_ID  |  Latitude  |  Longitude  |  Capacity  |  Rate index  |  Demand  |  Total_demand_%  |  Utilization  |  Closest_city  |  Distance_to_Closest_city
i
CUSTOMER ASSIGNMENTS
Customer_ID  |  Latitude  |  Longitude  |  Demand  |  Warehouse_ID  |  Group  |  Ship_size  |  Leadtime_dist  |  CoG_ID  |  Distance  |  Transport_rate  |  Transport_costs  |  Latitude_border;  |  Longitude_border
SERVICE LEVEL DISTANCES
Distance  |  Demand_cum_%  |  Demand_%  |  Customers_cum_%  |  Customers_%  |  Number_of_customers
 


 

Current situation

0 optimization freedom
• All warehouses as is
• All customer assignments as is,
  so warehouse capacity constraints
  adhered to as well

Realistic scenario

Some optimization freedom
• Some warehouses as is
• Some warehouses closed
• Some warehouses extended
• Some warehouses newly added
• Some customers reassignable
• Some capacity constraints

Greenfield

100% optimization freedom
• Free amount of new warehouses
  at Centers-of-Gravity locations
• All customers reassignable
• No capacity constraints
100% ←- Optimization freedom -→0%

Create greenfield solution (Basic Mode)

  • Fill out input table Customers.
  • Select the number of Centers‑of‑Gravity, and press Calculate.
  • View map and other outputs. Then change the number of Centers‑of‑Gravity and see how it affects sum of weighted distances (transport costs indicator) and service level distances.

To understand how the software calculates you can read page How to determine Centers‑of‑Gravity.

Replicate current situation (Advanced Mode)

  • Fix warehouses at their current location by filling out table Predefined warehouse with field Move_range set to 0, and checking constraint "Predefined warehouse locations".
  • Assign customers to their current warehouse by entering field Warehouse_ID in the Customers table, and checking constraint "Fixed customer warehouse assignments".

You can quickly (un)check those constraints to see how those affect outcomes.

Create realistic future scenario (Advanced Mode)

Once you have replicated the current situation you can gradually allow more optimization freedom while keeping constraints activated.
  • Investigate if current locations are optimal - given fixed customer assignments - by increasing Move_range of (some) predefined warehouses.
  • Investigate if current customer assignments are optimal - given fixed warehouse locations - by removing Warehouse_ID of (some) customers, or by unchecking constraint "Fixed customer-warehouse assignments".
  • Investigate where to open a next new warehouse by increasing the number of Centers‑of‑Gravity beyond the number of predefined warehouses. Make sure you allow (some) customers to get (re)assigned to this new warehouse.

Relaxing some constraints, you may want to implement other types of constraints:
  • Limit warehouse capacities - to constrain demand volume that can be assigned to a warehouse - by filling field Capacity in the Predefined warehouses table and activating constraint "Capacity limits". Keep in mind that in the future capacity limits may not be applicable anymore, if additional space can be rented or the owned facility expanded.
  • Group customers for single sourcing to enforce all customers within a group (free format, what group stands for is up to you) to be assigned to a single warehouse, by filling field Group in the customers table (for some or all customers) and activating constraint "Customer groups". (In the demo group stands for country. Customers are grouped per country. Group is used to avoid that customers in the western part of France are delivered by a warehouse in the UK.)

Besides, you can run a sensitivity analysis that indicates how much transport costs increase if a warehouse is located outside the Center-of-Gravity. An area around the Center-of-Gravity is drawn. At the area border the transport costs of the warehouse would increase x%. The higher x is set, the larger the (irregularly shaped) area becomes.

Add supply side (Advanced Mode)

A Center‑of‑Gravity analysis usually focuses on the demand side with its relatively high transport costs and lead time requirements. But you can add the supply side to optimize supply transport costs as well. Adding the supply side becomes more relevant if there are a few major supply locations, such as a harbour, in which case a warehouse should move towards the harbour.

Because supplier shipments are larger than customer shipments - which makes supplier transport relatively cheaper - suppliers pull Centers‑of‑Gravity relatively less than customers. Differentation between customer and supplier transport rate is handled in subsection "Optional constraints and Parameters".

Flows from suppliers to customers are constructed automatically. You chan choose from 3 supply options:
  1. Each supplier delivers to closest warehouse* only
  2. Each supplier delivers to each warehouse
  3. Each supplier delivers to each warehouse via closest warehouse*
* Closest warehouse (auto-detected) can be overruled by specifying a predefined warehouse in the supplier table

Under option 1 each supplier - like a customer - pulls one warehouse (though relatively less).
Under options 2 and 3 each supplier - unlike a customer - pulls all warehouses.

Demand side only

Centers‑of‑Gravity are pulled by customers only

Supply option 2

All Centers‑of‑Gravity are pulled towards a major supplier.

Supply option 3

Especially the closest warehouse is pulled towards a major supplier.

You can quickly (de)activate the supply side and see how this affects the Centers‑of‑Gravity locations. Note that you can no longer directly compare the solution value to the value of a model without supply.

Run sensitivity analysis

The software supports:
  • the creation of an area around each Center-of-Gravity on the map that shows where it can be located before its transport costs would increase more than X%.
  • the randomization of the demand quantity of each customer with ±X%, after which you can investigate how it affects the solution.

Remark: broader supply chain network design perspective

Transport costs are only a part of supply chain costs, and the optimal number of warehouses and their locations are driven by many quantitative and qualitative factors, such as (future) transport and warehousing rates, future demand, lead time requirements, inventory effects, supply chain risk/redundancy, contractual obligations, distance to parcel/logistics hubs, workforce availability/public transport connections, et cetera.. Nevertheless, it is common practice to do a Center‑of‑Gravity-analysis in a supply chain network design, as it provides useful insights.

Collect customer adresses and demand quantities

Retrieve customer addresses and demand quantities and/or shipment data from your system. Ideally, express demand quantities in the main transport cost driver applicable for your business: weight, volume or volumetric weight.
  • Consider seasonality: take a full year of data if your business is seasonal.

  • Demand can be based on sales order quantities × item master dimensions. But most likely, your item master will not be 100% clean. It may contain items that accidentally got 'kilogram' instead of 'gram' as UoM. This may cause large errors when calculating volumes. So, if available, then collect shipment data with actual (pay)weight or volumes.

  • Validate your input data
    • Check for zero and empty values.
    • Check item master (sold products only). For example, does kilogram/m3 make sense?
    • Check for outliers. For example, calculated shipment sizes that exceed truck capacity.
    • Check completeness. For example, compare number of orderlines to a warehouse productivity report.
    • Check top-X customers list. Major customers missing? Unknown/small customers appearing?
    • Check demand map. Gaps? Unknown large locations?

  • Though not used as input by the Centers‑of‑Gravity Calculator, product groups and sales channels may become relevant when designing your supply chain network in more detail. Define relevant product groups/levels - related to your network design questions - before data collection.


Include growth projections

Design for the future: include growth projections if those are substantial and different (per product group) per region.

Geocode adresses (and aggregate demand)

Geocoding is the process of converting addresses (like a street address) into geographic coordinates (latitude and longitude). Those are used for creating locations and flows on the map, and in (distance) calculations. See Free Batch Geocoder or Batch Geocoder if you still need to retrieve latitudes and longitudes of locations.

Consider aggregating demand per latitude/longitude (using an Excel pivot table), especially when creating a demand map. Without aggregation customers with the same latitude/longitude are plotted on top of each other and a relatively small dot will appear on the map. After aggregation a bigger dot will appear, which better reflects underlying volumes.

Consider harbours

If far-away-customers are delivered via an exit harbour, then put the aggregated far-away-customers' demand on top of that harbour, instead of their original location in the demand country. The harbour may be located in opposite direction of the demand country, seen from a warehouse perspective, and a warehouse should be pulled in the right direction in the optimization process!

Consider regional setups

You may want to split your data set. For instance, if you already know that you will operate a warehouse/warehouses in the UK to deliver UK/IE customers only, then split your data set into 'UK data' and 'mainland Europe data' and run the model for both sets separately. If it is about a single UK warehouse only, then - alternatively - you can link UK/IE customers to a predefined UK warehouse (that is allowed to move), without having to split the data set.

Optional: Collect supplier adresses and supply quantities

You may want to add suppliers so supplier (and interdepot) transport costs are also taken into account when optimizing Centers‑of‑Gravity.

 

Stelling
 Consulting
Home page
Your e-mail address

Your e-mail address (again)


Your message

Feedback and suggestions for improvement are welcomed

Centers‑of‑Gravity Calculator explained • How to calculate Centers‑of‑Gravity

It is common practice to run a Center‑of‑Gravity analysis in supply chain network design.
Centers‑of‑Gravity Calculator determines indicative warehouse locations that minimize transport costs. How does it work? The section below explains the core algorithms of Center‑of‑Gravity‑Calculator. This explanation applies to any software that properly calculates Centers‑of‑Gravity.
 

Centers‑of‑Gravity are indicative warehouse locations that minimize transport costs

In fact, Centers‑of‑Gravity 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 resultant force never becomes 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 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.

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.
    • Often 0-5% worse. But worse is possible.
      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.

      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.
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!

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_cog)/2) + cos(latitude_cog) × cos(latitude_customer) × sinus2((longitude_customer − longitude_cog)/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_cog) × cosinus(latitude_customer) , cosinus(latitude_cog) × sinus(latitude_customer) − sinus(latitude_cog) × cosinus(latitude_customer) × cosinus(longitude_customer − longitude_cog)

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 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. The controlled move distance enables a feature of Centers‑of‑Gravity Calculator: allowing predefined warehouses to move within a limited range. They may need to end up somewhere at the border of this range and Weiszfeld's algorithm as such 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 an explicit move distance, so no need to worry about its initialization value. Under the Single‑Center‑of‑Gravity algorithm: 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 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.

Multiple‑Centers‑of‑Gravity algorithm

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

A single run of the Multiple‑Centers‑of‑Gravity 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 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 Centers‑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.

The algorithm resembles the k-means clustering algorithm (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 - that need to be served by a single warehouse.

Animations

The animations show what happens during a single run of this 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
 

A completely different approach

A completely different approach is one in which a set of hundreds or thousands of possible warehouse locations are pre-generated, after which the k best ones are selected (see Combination - wikipedia). Advantage is that the warehouse-customer cost matrix can be based on various transport rate structures and can capture warehousing costs. Disadvantages are that it requires many more inputs (and still has the risk that the set of predefined locations may not contain the optimal locations), and that the number of possible warehouse combinations - thus runtime - may grow exponentially.
Web app Warehouse Selection Optimizer facilitates this approach.

Underlying assumptions

A major underlying assumption is that transport cost = rate/kilometer × distance. This assumption is only partly valid. Parcel rates are often distance independent within a region, FTL pallet rate/kilometer is lower than LTL pallet rate/kilometer, macro-economic imbalances cause direction-dependent rates.

Besides, as-the-crow-flies distances × circuitry factor are used as approximation of road distances. What is meant with road distance? The distance of the fastest or the shortest route? The fastest route is usually more relevant, as driver and truck cost are more time-related than distance-related. But the fastest route may depend on the time of the day, and on the day of the week. Reality is complex. As the estimation errors will be more or less the same for each direction, approximations are acceptable, and commonly used in supply chain network design software.

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 rates, future demand (and supply), lead time requirements, inventory effects, supply chain risk/redundancy, contractual obligations, 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.

Web app Centers‑of‑Gravity Calculator

Web app Centers‑of‑Gravity Calculator (or simply scroll to the top of the page) uses a more advanced version of weighted distances, defined as distance × demand (1st weight) × transport rate (2nd weight). The transport rate enables differentiation between a demand volume transported in small shipments versus the same volume transported in large shipments, which is less expensive.

Besides, Centers‑of‑Gravity Calculator offers more advanced functionality to run a supply chain Center‑of‑Gravity analysis. For instance, you can predefine existing warehouse locations including capacity limits.