Calculates the weighted centers of your customers and suppliers. Those Centers‑of‑Gravity indicate where to locate warehouses to minimize transport costs.
Shows how service distances are affected by the number of warehouses.
Offers extensive functionality: setup (semi-)fixed warehouse locations, limit capacities, group customers, model supply, location sensitivity analysis, and more.
Runs fast, especially in Google Chrome.
This web app - with demo data - is fully functional, so you can check out how it works. To run with your own data, you need to create an account.
“We have been using this 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.”
Head of Transport Solutions Design MLE MEA &
Network Design & Supply Chain Consulting Global Practice Lead DHL Supply Chain
Show map display settings
Show run options and parameters (linked to optional input data)
Show help text, login form, intro
Map display settings
Customer/supplier size - display factor
Centers-of-Gravity size - display factor
Flow size - display factor
Set to zero to deactivate flow scaling
Hide roads, et cetera
Display Centers-of-Gravity as fixed-sized circles, instead of volume-sized circles
Fixed-sized Centers-of-Gravity color
Display geodesic flows between Centers-of-Gravity and customers
Display geodesic flows between Centers-of-Gravity and suppliers
Supplier flows color
Supplier flows arrow size
Set to zero to hide arrows
Scale arrows to flow size
Distance based customer coloring From green at 0 km, to red at
km (beyond this distance, from dark red to black)
Map tiles by Carto
Map tiles by ESRI
Map tiles by OpenStreetMap
Apply constraints (linked to optional input data)
Predefined warehouse locations
Fixed customer-warehouse assignments
Fixed supplier-warehouse assignments
Supply parameters (linked to optional input data)
Supplier transport costs ratio
Show calculation aid transport costs ratio
Supplier transport (inbound) is - due to larger shipments - relatively less expensive than customer transport (outbound).
The supplier cost ratio expresses how much.
Supplier 'forces' pulling the Centers-of-Gravity are multiplied with this ratio.
On the map suppliers (white circles) appear relatively smaller than customers as well, as the same ratio is applied for circle sizes.
Formula LTL costs factor = %FTL costs = −0.7 × Shipmentsize2 + 1.63 × Shipmentsize + 0.078
Costs/km. No accurate input required as outcome is rate independent.
Expressed in KG, M3, pallet, loading metre, ...
Avg. shipment size
% FTL costs
Rate per qty
= Supplier rate per qty / Customer rate per qty
Each supplier delivers to its closest (or fixed) warehouse only (local-for-local)
Each supplier delivers to each warehouse
Each supplier delivers to each warehouse via its closest (or fixed) warehouse (2-echelon)
Location - Cost sensitivity analysis
-costs-increase-areas around each Center-of-Gravity (grey areas with dotted border) If a Center-of-Gravity is located at the area border, its inbound and outbound transport costs increase 5%
Number of Centers-of-Gravity
Present best solution out of N runs, with N is
Save and Reload: data and settings are saved in your local browser memory, so you can reload those when logged in next time.
Save and Load are not functional in demo mode.
Current sum of weighted distances
Lowest sum of weighted distances
Distance bin width (km)
Run scores chart
See also detailed output tables further below.
Data tables and run options
In demo mode this web app is fully functional (except buttons Save and Load) but you cannot enter your own data.
Create an account if you want to run with your own data.
About the demo data, and all run options
The demo data sits in the input tables below.
To cover all functionality, optional input fields/tables have been filled as well.
But optional data is only taken into account if constraints have been checked.
Just below the map, check "Show run options and parameters" to see all constraints settings and options.
Checking constraints will affect outcomes.
Obviously, adjusting the number of Centers-of-Gravity will affect outcomes as well.
Table predefined warehouses (optional)
This table contains two predefined warehouses, one in Birmingham/UK (cannot move, optional field Move_limit set to 0) and one in Madrid/Spain (can move within a 200km range, Move_limit set to 200).
These locations are only activated if you check constraint "predefined warehouse locations".
They have certain throughput capacities (optional field Capacity set to 482500 and 550000), which are adhered to if you check constraint "capacity limits".
This table contains 588 customer locations.
Customers in UK/Ireland are assigned to the Birmingham warehouse, customers in Spain/Portugal to the Madrid warehouse (optional field Warehouse_ID set to Birmingham or Madrid) if you check constraint "fixed customer-warehouse assignments".
All customers have optional field Group set to the code of the country they are located within (AL/AT/BE/CH/CZ/DE/..) effectively meaning all customers within the same country are assigned to a single warehouse only, if you check constraint "customer groups" .
Customers within a single group are not delivered from multiple warehouses (unless capacity constraints would get violated).
A group does not necessarily need to be a country.
It is up to you to define what field Group (free format text) will capture.
Table suppliers (optional)
This table contains two supply locations, one in Rotterdam/The Netherlands, and one in Bologna/Italy, which are only activated if you check "supply".
Suppliers pull warehouses, like customers, so Centers-of-Gravity will tend to move towards those locations, as supply volumes are high compared to individual demand volumes.
However, suppliers are also treated differently than customers.
Supplier transport is usually - due to larger shipment sizes - relatively less expensive than customer transport.
The Supply parameter "supplier transport costs ratio" expresses how much less. (The calculation aid helps you estimate this ratio.)
Supplier pull forces are multiplied with this ratio.
On the map suppliers will appear relatively smaller than customers, as the same ratio is applied to sizes.
Setting this ratio to 0 is effectively the same as unchecking "supply": Centers-of-Gravity will then be based on demand only.
Under Supply parameters you can chose from three options of how supply will flow via warehouses to meet demand.
Option “each supplier delivers to each warehouse” can be considered the default option: each supplier delivers to each warehouse, pro rata total customer demand assigned to a warehouse.
This means a supplier - unlike a customer - pulls all warehouses, and its total pull force (corrected with the supplier transport costs ratio) is divided over all warehouses pro rata, also meaning these individual supplier pull forces are unknown upfront.
Though not mandatory, it is advised to express quantities as rounded numbers without thousands or decimal separators, and to filter out all records with zero quantity.
Use decimal point - not decimal comma - as decimal separator. Any commas in your data will be removed automatically. You can enter your data semicolon or tab separated. Tab separated data will be converted to semicolon separated data automatically.
Use the Batch Geocoder if you still need to retrieve latitudes and longitudes of your locations (city/postal code, country).
Warehouse_ID: free format, e.g. "Birmingham". To assign a customer permanently to a warehouse enter the Warehouse_ID of a predefined warehouse location.
Group: free format, e.g. "UK". All customers with the same Group will be assigned to the same warehouse that comes with the lowest sum of weighted distance for this group of customers.
If you specify Warehouse_ID, the customer will be assigned to that warehouse, regardless Group. Leave Warehouse_ID empty if you want to specify Group only.
Suppliers (optional): optional field Warehouse_ID
Warehouse_ID: free format, e.g. "Birmingham". To assign a supplier permanently to a warehouse enter the Warehouse_ID of a predefined warehouse location. It also means this supplier will not assign pro rata customer demand to all warehouses - it overrules that option for this particular supplier.
Predefined warehouses (optional)
You can predefine warehouse locations as fixed locations or as seed locations.
Fixed location: set Move_limit to 0 (in km, not miles!). A fixed location cannot move.
Seed location: set Move_limit > 0 (in km, not miles!). A seed location may move within its Move_limit (around its specified coordinates).
Give each warehouse a Warehouse_ID and use this Warehouse_ID in the customer table and/or supplier table if you want to assign customers and/or suppliers to a warehouse.
Warehouse capacity: limits the amount of demand that can be assigned to a warehouse. Adhering to capacity constraints may ignore customer groupings. Fast greedy algorithm implemented.
Combining both options you can replicate your current network structure, and compare costs of the current structure to costs of alternative structures. Or determine the optimal location of a warehouse given its current customers.
If you already know you will operate a single warehouse in UK to deliver UK customers only, split your data into 'UK data' and 'mainland Europe data' and run the model for both sets separately.
Outcomes may vary, due to initial random locations. Run several times to check if a solution reappears and/or to see alternatives.
No restrictions apply in the 'warehouse-moving-process': warehouses may end up in the middle of the sea.
Minimizing transport costs by locating warehouses in demand Centers-of-Gravity
Demand Centers-of-Gravity are those locations that minimize the sum of weighted distances. Weighted distance is the as-the-crow-flies-distance from warehouse to customer multiplied by demand. E.g. if customer A has a demand of 10 and is located 25 km from its warehouse the weighted distance is 250 km. Summing over all customers gives the sum of weighted distances as an indicator for transport costs. It is a relative figure, not an absolute cost figure. The Centers-of-Gravity algorithm minimizes its value by moving warehouses.
Implicit assumption: transport cost = rate/km × distance. So minimal transport kilometers come with minimal transport costs (and minimal Green House Gas emissions). This assumption is partly valid. E.g. parcel rates are distance independent within a country, FTL pallet rate/km is lower than LTL pallet rate (you may adjust demands for this in your input), macro-economic imbalance cause direction-dependent rates, et cetera.
The sum of weighted distances belonging to the current warehouse setup and customer assignments can be compared to the sum of weighted distances of alternative setups. The ratio between those indicators combined with a current customer transport costs figure will provide a rough estimation of how much can be saved on customer transport by changing the supply chain network structure.
Broader supply chain network design perspective
Customer transportation costs are only a (substantial) part of total costs.
The optimal number of warehouses and locations are driven by many quantitative and qualitative factors: (future) transport and warehouse rates, tax rates, demand growth/decline, lead time requirements, inventories, supply chain risk/redundancy, law (for example, in some European countries the warehouse of medical supplies has to be located in the customer country itself).
Nevertheless, it is standard practice to run a Centers-of-Gravity-analysis to get an indication how many and what warehouse locations to consider, when doing a supply chain network design project.
Quality of core algorithms & speed
The quality of the algorithms of this Centers-of-Gravity Calculator equals that of Excel Solver and Llamasoft.
This web app runs much faster than Excel Solver (test 2018) and Llamasoft (test 2017), if running in Google Chrome.
Customer A has a demand of 10 and customer B a demand of 1.
Where is the CoG? Somewhere on line A-B, closer to A?
Well, customer A pulls 10 times harder than customer B.
If the CoG moves a distance d towards A the sum of weighted distances decreases (10 x d) – (1 x d).
So, the CoG is right on top of customer A, not somewhere in between A and B!
Though the goal value is the sum of weighted distances, distances itself are (kind of) irrelevant when figuring out in what direction to move the CoG.
The overall demand force is leading. In the example it has a length of 9 and points towards customer A.
The overall demand force points the right direction, but does not tell how far to move the CoG.
Or this far?
How to determine multiple Centers-of-Gravity?
The Multiple-Centers-of-Gravity algorithm
A single run of this algorithm does the following:
Step 1: locate warehouses at a random location (randomly selected customer location)
Step 2: (re)assign each customer to the closest warehouse
Step 3: move each warehouse to the Center-of-Gravity of its customers = apply Single-Center-of-Gravity algorithm (described below)
Repeat steps 2 and 3 until the goal value, the sum of weighted distances (see formula below) does not improve anymore.
Multiple runs are done, each run starting with different random locations. The best solution out of those runs is presented as final outcome. The higher the number of runs, the more likely the optimum solution will be found.
Goal value = sum of weighted distances = ∑i Di.Qi
Qi is the demand of customer i
Di is the distance between customer i and the warehouse this customer is assigned to.
The animation shows what happens during a single run of this algorithm: customers (circles) are assigned to the closest warehouse (triangles), warehouses move to their center-of-gravity, customer are reassigned, warehouses move, et cetera, until the final situation is reached where none of the asssignments and warehouse positions change any more.
On a side note, the problem and algorithm are comparable to k-means clustering: cluster analysis performed in data mining, and used in machine learning.
How to determine a single Center-of-Gravity?
The Single-Center-of-Gravity algorithm (= step 3 of the Multiple-Centers-of-Gravity algorithm)
Initial Center-of-Gravity position
The Center-of-Gravity is initially positioned at the weighted average X and Y coordinates:
X_cog = ∑i Xi .Qi / ∑i Qi
Y_cog = ∑i Yi .Qi / ∑i Qi
Xi = x-coordinate of customer i
Yi = y-coordinate of customer i
Qi = Demand quantity of customer i
This inital Center-of-Gravity is often presented as optimal, but this is not true!
Imagine there are only two customers, customer A with demand 10 at position (0 , 0) and B with demand 1 at position (100 , 0). If the Center-of-Gravity moves a distance d towards customer A the goal value improves 10 × d (closer to A) − 1 × d (further from B) = 9 × d. So the optimal position is on top of customer A, not at (9.09 , 0) as given by the formula. The optimal Center-of-Gravity has a goal value of (0×10+100×1) = 100, whereas the initial Center-of-Gravity at (9.09 , 0) has a much higher value of (9.09×10+90.91×1)=182, so 82% higher costs. In realistic situations with multiple customers, the relative difference will be much smaller - less than 5% - as also can be seen in the visual simulation further below.
Though the goal function contains distances, these are (kind of) irrelevant when determining the optimal Center-of-Gravity.
To optimize 'demand forces' pulling the Center-of-Gravity need to be calculated:
FX = force in x-direction = ∑i (Qi.(X_cog − Xi)/Di) on a flat surface, or ∑i (Qi.cosinus(anglei)) in general
FY = force in y-direction = ∑i (Qi.(Y_cog − Yi)/Di) on a flat surface, or ∑i (Qi.sinus(anglei)) in general.
The above applies for a flat surface. The Earth is a globe. The geographical translation is as follows:
Xi = longitude (expressed in radians when used in formula)
Yi = latitude (expressed in radians when used in formula)
Di is the as-the-crow-flies-distance, the shortest distance over the earth's surface. It is calculated using the Haversine formula (in 3 steps):
Because bearing compares to an angle between a line and the Y-axis, instead of X-axis:
Flat = ∑i (Qi.sinus(bearingi))
Flon = ∑i (Qi.cosinus(bearingi))
Moving the Center-of-Gravity in force direction will decrease the sum of weighted distances, if moved the right distance
Moving the warehouse in the x and y direction of the force - first normalized by dividing it by its own length - lowers the goal value. The distance to move in that direction - initiated at a large value - is halved each time the new position would result in a worse goal value (a case of 'overtargetting').
Single Center-of-Gravity algorithm
Step 1: locate Center-of-Gravity at its initial position, and initialize step_distance at a large value (e.g. 100km)
Step 2: update Latitudecog to Latitudecog + Flat / √(Flat2 +Flon2) .step_distance, and update Longitudecog to Longitudecog + Flon / √(Flat2 +Flon2) .step_distance
Step 3: calculate the goal value. If it increases, then move back to the previous position, and update step_distance to step_distance/2.
Repeat steps 2 and 3 until step_distance has become sufficiently small (e.g. 1 meter - in most cases the force will then be almost zero).