Input tables
You have not logged in. You can adjust inputs and parameters, and run the software. See demo guide.
Changes to customers demo data are ignored. To run with your own customers data, you need to buy a license.
Changes to customers demo data are ignored. To run with your own customers data, you need to buy a license.
Or click button I-E (found above each table), paste data (tab or semicolon separated) into textarea, click I-E again. Or type directly within table.
Customers
Highlight customer on map by clicking on a table cell. In Map settings you can set customer size factor.
Only fields Customer_ID, Latitude, Longitude, Demand are mandatory. All fields are explained in user manual section Customers.
Aggregate customers in the rare case runtime becomes an issue (see tool below).
Aggregate customers in the rare case runtime becomes an issue (see tool below).
Customers aggregation tool
Constraints settings determine if the following fields are included in the aggregation:
→ Check constraint fixed customer-warehouse assignments
→ Check constraint customer groups
→ Check constraint border crossing points
Note: tight warehouse capacity limits might be a valid reason for not aggregating data - it is easier to match those limits more closely having many small customers that can be (re)assigned than having only a few big aggregated customers.
Predefined warehouses (optional)
All fields are explained in user manual section Warehouses.
Suppliers (optional)
All fields are explained in user manual section Suppliers.
Border crossing points (optional)
All fields are explained in user manual section Border crossing points.
Parameters
Distance
i
Service level
i
i
i
Closest city
i
i
Closest city is based on a database containing cities with at least 15,000 inhabitants.
Sensitivity analysis
Display
i
using a
i
Supply options
Read user manual section Logical steps - Add suppliers for more info. Options 1/3/4 can be mixed if set at individual supplier level.
Non-unique products
Unique products
Also set Transportation rates
Transportation rates
Read user manual section Transportation rates for more info.
i
|
i
Shipment size
|
% FTL |
See curve
% FTL costs |
Cost ratio |
i
|
Costs/km/qty
|
|
|
| Full Truck Load | |||||||
| Customer | |||||||
| Supplier | |||||||
| Inter-warehouse | |||||||
| Centers of Gravity depend on ratio supplier rate/customer rate = | |||||||
|
Transportation costs curve i
|
|
| Cost factor as % FTL cost | |
| Shipment size as %FTL | |
Cost curve settings
| Point | X (as %) | Y (as %) |
| Start point (P0) | ||
| Start control point (P1) | ||
| End control point (P2) | ||
| End point (P3) | ||
| Some point on the curve | ||
|
Animation of Bezier curve construction
|
||
| Or drag the red control points in chart. | ||
Constraints
Read user manual section Constraints for more info.
→ Also select supply option
Calculate Centers of Gravity
|
|
Customers aggregation tool
Initialization options
Options help to find the (near) minimum goal value quicker, on average. More info
| Minimum goal value | i |
|
| Current goal value | ||
| Weighted distances | i |
|
Create backup scenario file
Output − Service level distance metrics
Improve service level
Service level distance metrics
| Parameter | Value |
|---|---|
| Center of Gravity filter (include) | |
| Weighted avg. customer distance | |
| Min. customer distance | |
| Avg. customer distance | |
| Max. customer distance | |
| Number of customers assigned | |
| • Lead time distance limit (generic) | |
| • Customers within lead time distance | |
| • Demand within lead time distance |
Service level distance table
Distance bin width (km)
10
20
25
50
100
Service level metrics and table are also found in the output reports.
Service level distance chart
Distance = estimated road distance = as-the-crow-flies distance x circuity factor, set in section Parameters - Distance.
Output − Reports
|
Tab separated
|
Decimal point
|
|
|
Semicolon separated
|
Decimal comma
|
Summary
| i |
| i |
| i |
Centers of Gravity
i |
i |
i |
i |
i Country codes |
|---|
Customer assignments
i |
i |
i |
|---|
Service level distance metrics
Own transportation operation - Estimator of mileage and costs
Why this estimator - Center of Gravity model versus own transportation reality

Centers of Gravity Calculator minimizes weighted average distance which is the same as minimizing the sum of weighted distances. That distance is comparable to the distance between the warehouse and the first/last customer of a roundtrip. Neither the distance between customers on a roundtrip, nor costs of (un)loading are affected by weighted average distance. So, if weighted average distance changes X%, own transportation mileage and costs change less than X% (whereas if transportation is outsourced and distance based rate tables are applicable, costs will almost change X%). Hence, this estimator. It helps to determine how much own transportation mileage and costs will change, given the current and new supply chain network design, based on the construction of an average roundtrip, as explained in the next section.
How this estimator works & how to use it
- For each warehouse its delivery area shape is created, based on its customer locations - only those that can be reached within the maximum duration of a roundtrip. This shape is translated into the delivery area size.
- Customer demand divided by customer shipment size brings the number of deliveries per customer. Those are summed per warehouse, given customer assignments. Division by number of transportation days brings the number of daily deliveries.
- The delivery area size is divided by the number of daily deliveries. The square root of that number is the average inter-drop distance.
- An average roundtrip is constructed, based on average warehouse-customer distance, inter-drop distance, and other transportation parameters. This brings the number of deliveries per roundtrip, roundtrip length and duration.
- The total number of deliveries divided by the number of deliveries per roundtrip brings the number of roundtrips. Multiplying by roundtrip length and duration brings mileage and hours. Summing over all warehouses brings total mileage and hours. Multiplying by rates brings costs. Summing - and adding loading costs - brings total transportation costs.
Instead of using transportation costs outcomes directly as absolute figures, it is advised to do as follows:
- Replicate the current supply chain network (see user manual logical step 2) and run Centers of Gravity calculation. Use this estimator to calculate the total transportation cost of the current supply chain network (= CC).
- Create the future supply chain network (see user manual logical step 3) and run Centers of Gravity calculation. Use this estimator to calculate the total transportation cost of the future supply chain network (= FC).
- Estimate future costs as FC/CC × actual current costs (as taken from your financial reports), instead of directly using FC as future costs. Using actual current costs as basis is a way of calibrating model outcomes.
First, calculate Centers of Gravity. Center of Gravity locations and the resulting customer assignments are input for this estimator.
i
i
i
i
Customers beyond reach
i
Demand beyond reach
i
Full truck load
Set in Transportation ratesi
i
Sum of area size(s) (square km)
i
i
Weighted avg. distance
i
Avg. inter-drop distance
i
i
Avg. delivery size
i
Avg. deliveries per roundtrip
i
Avg. roundtrip length
i
Avg. roundtrip duration (hours)
| Total |
Rate i
|
Costs | |
|
Kilometers
Mileage
|
i ×
|
= | |
|
Hours
|
i ×
|
= | |
| Costs of loading (constant) | + | ||
| Total costs during number of transportation days | |||
Above fields remain empty, because an infeasibility error is encountered at a warehouse.
Select warehouses
How to activate constraints
| Constraint | How to activate |
|---|---|
| Predefined warehouses | Always active, regardles constraint setting. |
| Fixed customer-warehouse assignments | By checking constraint in section Constraints |
| Fixed supplier-warehouse assignments | Not supported |
| Capacity limits | By using Greedy solver or LP solver, see below (not by checking constraint). |
| Customer groups | Not supported |
| Suppliers | By checking constraint in section Constraints. Supply option 3 is activated in background, other options are not supported. |
| Border crossing points | By checking constraint in section Constraints. |
Create 24 demo warehouses
Number of warehouses to select |
||||||||||
| Warehouse group | a | b | c | d | e | f | g | h | i | j = must‑be‑included |
| Number of warehouses in group | ||||||||||
| Number of warehouses to select | ||||||||||
Number of possible warehouse combinations = ...
Solvers selectionUse Enumeration solver if runtime is acceptable. For more info, read Select warehouses algorithms. |
Warehouse combination generation (open/close decisions) | |||
| Enumeration solver | K‑means clustering solver |
|||
| Warehouse capacities (customer assignment) |
Ignore / not applicable | |||
| Greedy solver | ||||
|
LP solver+
|
||||
Override transportation costs input (optional)
- You may override warehouse-customer transportation costs as calculated by the software (see info next to button) with your own transportation costs based on actual rate tables.
- Enter a C × W matrix (C customers top to bottom × W warehouses left to right) in below text area with each cell containing total transportion costs to deliver the demand of customer C from warehouse W.
Override warehouse-supplier transportation costs
- You may override warehouse-supplier transportation costs. Only relevant if supply is activated via Constraints settings.
- Enter a S × W matrix (S suppliers top to bottom × W warehouses left to right) in below text area with each cell containing total transportion costs to deliver the supply of supplier S to warehouse W.
i
i
i
Improve service level
Output − Service level distance metrics
Improve service level
Service level distance metrics
| Parameter | Value |
|---|---|
| Warehouse filter filter (include) | |
| Weighted avg. customer distance | |
| Min. customer distance | |
| Avg. customer distance | |
| Max. customer distance | |
| Number of customers assigned | |
| • Lead time distance limit (generic) | |
| • Customers within lead time distance | |
| • Demand within lead time distance |
Service level distance table
Distance bin width (km)
10
20
25
50
100
Service level metrics and table are also found in the output reports.
Service level distance chart
Distance = estimated road distance = as-the-crow-flies distance x circuity factor, set in section Parameters - Distance.
Reports appear after running.
Output - Reports
|
Tab separated
|
Decimal point
|
|
|
Semicolon separated
|
Decimal comma
|
Summary
Selected warehouses
i
Customer assignments
Enumeration solver - top-X list of warehouse networks
* Total costs including penalties
i
Service level distance metrics
Reports appear after running.
Collaborate
Export scenario file
Press Export button. Email file to coworker.Import scenario file
Save file from coworker on your computer. Press Import button.Press Save in section Calculate to save imported data in memory.
Support
If you want Support to investigate your case, open section Collaborate,
export scenario file, and email scenario file to:
Do not email Excel template. It does not contain your parameter settings!
export scenario file, and email scenario file to:
Do not email Excel template. It does not contain your parameter settings!
Demo guide
Calculate Centers of Gravity
- Open section Calculate Centers of Gravity. Press Calculate. See map above, reports, and service level distance metrics. Change the number of Centers of Gravity. Rerun. Review new outcomes.
-
Activate sensitivity analysis, with each demand randomized ±X%. Rerun. Does it still bring similar locations?
Each rerun demand is randomized again, so rerun and view map a couple of times to check solution robustness thoroughly.
-
You can activate several constraints. But first, deactivate sensitivity analysis, and set the number of Centers of Gravity back to 3.
- Activate constraint Predefined warehouses. Rerun. Two predefined warehouses become part of the solution, one in Birmingham (UK), one in Madrid (Spain) that is allowed to move 200 kilometers and ends up near Guadalajara/Azuqueca. See how this affects the location and size of the 3rd warehouse.
- Activate constraint Suppliers as well. Rerun. Each of both suppliers pulls all warehouses (which is the default supply option). The warehouse in Spain moves northwards to Soria, the 3rd warehouse westwards. Supply flows make the map look more complex. Under Map settings you can uncheck their display.
- Activate constraint Capacity limits as well. Rerun. Warehouse Birmingham throughput drops from 976,680 to 482,460 (capacity = 482,500). The warehouse in Spain also becomes slightly smaller due to its capacity limit. So, the 3rd warehouse must grow. It takes over customers in the west, so moves westwards, as shown in below animation.
Select warehouses
For this part of the demo, 24 predefined warehouses will be created automatically.
-
Deactivate constraints. Open section Select warehouses. Press Read input data, press Select warehouses. The best 3 out of 24 warehouses are selected. Their locations resemble Centers of Gravity (because fixed and variable warehousing cost parameters are kept equal for all warehouses). Total warehousing plus transportation costs are 939676. The transportation costs of 468867 (Output - Reports - Summary) exceed 464757 (Center of Gravity minimum goal value), because the 24 warehouses are not ideally located, and the selection routine does not relocate. The Enumeration solver will have generated a top-X list of warehouse networks. The second best solution brings 940735 total costs.
The more predefined warehouses to select from, the lower transportation costs can become. If loaded with 588 warehouses that have the same geocodes as the 588 customers (bringing 33.7 million possible combinations of 3 warehouses), transportation costs decrease to 466478. Which is still slightly higher than the minimum goal value of 3 optimized Centers of Gravity. The k-means clustering solver will find the optimal solution within a minute. - The selection changes if warehousing costs become differentiated. Increase fixed costs of Madrid - in table predefined warehouses - to at least 106140 and it will no longer get selected. Differentiated fixed/variable warehousing costs may make the map look less "logical".
Learn more
To learn more about the software and its other functionality, read the user manual, starting with Using the software - Logical steps.Still have a question? You can always contact Support.
User manual
The user manual describes how to use Centers of Gravity Calculator and explains input data and parameters. See table of contents (clickable) for an overview of its contents. Local help information is provided if you hover over
i
symbols, buttons, or some of the input fields.
For a basic greenfield Center of Gravity analysis, you only need to enter customers with location and demand. Skip all sections and read User input - Customers for a jump-start.Using the software - Logical steps
If your main question is where to locate warehouses, use Calculate Centers of Gravity. This routine moves (virtual) warehouses to locations that minimize transportation costs, thus determining Centers of Gravity. It does not consider warehousing costs.
Calculate Centers of Gravity - Summary of steps
- Step 1 is running a greenfield Center of Gravity analysis. You only need to enter demand.
- Step 2 is replicating the current situation, to get figures to compare scenarios 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 transportation costs in the optimization.
- Step 5 is choosing a proper warehouse location for each Center of Gravity, once calculated.
1. Greenfield analysis 100% optimization freedom
|
3. Realistic scenario Some optimization freedom
|
2. Current situation Zero optimization freedom
|
100% ←------ Optimization freedom ------→ 0% |
Step 1. Run a greenfield Center of Gravity analysis
A first run
- Fill out table Customers in section Input tables - Customers.
- You can start with only the 4 obligatory fields filled: Customer_ID, Latitude, Longitude, Demand. All fields are explained in user manual section Customers.
- Select the number of Centers of Gravity in section Calculate Centers of Gravity
- Press Calculate to run the greenfield Center of Gravity analysis. That's it! Main output - including Centers of Gravity - is found in report section Output - Reports.
- Always validate your input data! For example, does the map show extremely large customers, or large unknown customers, or gaps where you expected to see customers? Invalid input = invalid output!
Assess service levels
- See service level distance metrics in report section Output - Service level distance metrics showing percentage of demand and customers reached within a certain distance (estimated road distance between warehouse and customer). This indicates whether more warehouses should be opened, or some could be closed.
-
Activate "distance-based customer coloring" in section Map settings. Customers beyond acceptable lead time distance (set in section Parameters - 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!
- Activate "Improve service level" in section Parameters - Service level and rerun. Service level will be improved at the expense of increased transportation costs.
Run sensitivity analyses
- Go to section Parameters - Sensitivity analysis.
- Activate "Display cost-increase-areas" and rerun. The map will show green areas around each Center of Gravity consisting of 10 bands, each band representing a 1% costs increase range. It also draws a dotted line, representing your selected % (X). If a Center of Gravity were located somewhere on the dotted line, its inbound and outbound transportation costs would increase X%. If a current warehouse falls well within acceptable-costs-increase-range, you may decide to stick with the current warehouse (enter it as a predefined warehouse), instead of opening a new one at the Center of Gravity.
- Activate "Randomize each demand quantity" and rerun. Each customer demand temporarily changes between −X% and +X%. Check how much it affects Centers of Gravity.
Step 2. Replicate the current situation
Enter current warehouses
- To enter current warehouses:
- Fill input table Predefined warehouses with current warehouses.
- Set field Move_limit to 0 or leave field empty, to fix the warehouse location.
- Activate constraint "Predefined warehouses" in section Parameters - Constraints to include predefined warehouses, and rerun.
Fix customer-warehouse assignments
- To assign customers to their current warehouse:
- Enter field Warehouse_ID in table Customers
- Activate constraint "Fixed customer warehouse assignments" in section Parameters - Constraints, and rerun.
- Displaying current warehouse-customer links may already reveal 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 field Capacity in Predefined warehouses table, yet.
Step 3. Create a realistic future scenario
Gradually relax some constraints
- Investigate if current locations are optimal - given fixed customer assignments:
- Increase value of field Move_limit 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 deactivate constraint "Fixed customer-warehouse assignments" in section Parameters - Constraints, and rerun.
- Investigate where to open a next new warehouse:
- Increase the number of Centers 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
- Limit warehouse capacities:
- Enter field Capacity in the Predefined warehouses table.
- Activate constraint "Capacity limits" in section Parameters - 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 force all customers within a group to be assigned to the same, single warehouse:
- Enter field Group in table Customers.
- Activate constraint "Customer groups" in section Parameters - Constraints, and rerun.
Step 4. Add suppliers (optional)
Intro
A Center of Gravity analysis focuses on the demand side with its relatively high transportation costs and lead time requirements. But you can add suppliers to include supply transportation costs. Adding suppliers becomes more relevant in a Center of Gravity analysis if there are a few dominant supply locations (such as a large plant or entry harbor), in which case a warehouse should move towards that location. Note that a supplier may pull all warehouses, whereas a customer only pulls one.Enter suppliers
Enter suppliers - at least obligatory fields Supplier_ID, Latitude, Longitude, Supply - in input table Suppliers.Enter supplier transportation rate
Supplier shipments are usually larger than customer shipments, on average. This makes supplier transportation relatively cheaper. The lower transportation rate makes suppliers pull Center of Gravity relatively less than customers do.Enter supplier transportation rate in section Parameters - Transportation rates.
Activate suppliers
Activate constraint "Suppliers" in section Parameters - Constraints.Select supply option
Select 1 out of 4 supply options in section Parameters - Supply options. It determines how supply flows are constructed.Non-unique products
- Option 1: Each supplier delivers to closest warehouse only
Used for a scenario in which local suppliers supply non-unique products to local warehouses. Closest warehouse (auto-detected) can be overridden by specifying a predefined warehouse in the supplier table. This option will neither create inter-warehouse flows nor rescale supply, to balance supply with demand, as it gives the user full control over supplier-warehouse flows. - Option 2: LP optimized supply flows - with auto-sized suppliers
Used for a scenario in which suppliers supply non-unique products to warehouses. This Linear Programming procedure creates supplier-warehouse flows that minimize supplier-warehouse transportation costs, while adhering to available supply quantities (and fixed supplier-warehouse assignments**). You may give suppliers "infinite" supply, as this LP procedure makes supply match demand exactly. It auto-sizes suppliers.
** If fixed supplier-warehouse assignments make it impossible for supply to reach demand, these assignments are (partly) ignored. A supplier will then also supply warehouses other than the one you assigned it to. This causes a cost penalty. The LP procedure avoids penalties, as long as possible. If a penalty was unavoidable, you will get a message. Penalties are excluded from costs outcomes as reported.
Unique products
- Option 3: Each supplier delivers to each warehouse (default option)
Used for a scenario in which suppliers supply their unique products to each warehouse directly. The supplier volume to each warehouse is pro rata the customer demand assigned to each warehouse. - Option 4: Each supplier delivers to each warehouse via closest warehouse
Used for a scenario in which suppliers supply their unique products to each warehouse - via the closest warehouse (2-echelon) - pro rata demand assigned.
Closest warehouse (auto-detected) can be overridden by specifying a predefined warehouse in the supplier table.
Remarks
- You can specify the supply option at individual supplier level. It will override the generic setting. This way you can create a mix of options 1/3/4. Option 2 cannot be combined with other options.
- If you have specified a fixed warehouse at a supplier (= supply single warehouse) but also selected option 3 (= supply all warehouses), this causes a logical inconsistency. In that case, option 3 is converted into option 4 'in background'.
- Under options 2/3/4 each supplier - unlike a customer - pulls several/all warehouses.
|
Demand side only
Only customers pull warehouses.
|
Supply option 3
Customers pull warehouses. Also, each supplier pulls all warehouses.
|
Supply option 4
Customers pull warehouses. Also, each supplier pulls all warehouses, and especially the closest one.
|
|
|
|
Revisit step 2 and 3
Of course, to keep comparisons apples-to-apples, you need to revisit steps 2 and/or 3 and rerun with suppliers activated in those steps as well.Step 5. Choose a proper warehouse location for each Center of Gravity
Once calculated, choose a proper warehouse location for each Center of Gravity (that may have ended up on top of a mountain or in the middle of a lake).
In 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, 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, transportation in any direction will not cause a detour. Whereas if a location is only near an east-west expressway, transportation 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 equally divided across all 4 directions, this move lowers the sum of weighted road distances.
In 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, 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, transportation in any direction will not cause a detour. Whereas if a location is only near an east-west expressway, transportation 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 equally divided across all 4 directions, this move lowers the sum of weighted road distances.

If your main question is which warehouses to open/close, use Select warehouses. This routine selects those warehouses that minimize transportation plus fixed and variable warehousing costs given a set of warehouses to select from. It does not move warehouses.
Select warehouses
Mandatory
- Enter your data into the input tables. Predefined warehouses are no longer optional, but mandatory.
- Open section Select warehouses: Press button "Read input data". Specify the number of warehouses to be selected (per group) and select solvers. Press button "Select 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 need to be delivered from a specific warehouse.
- You may override the transportation costs matrices as calculated by the software with your own transportation costs input based on your own costing method / actual rate tables / actual road distances that can be retrieved using Batch Driving Distances Calculator. Transportation rates for new warehouses may be unknown. Or transportation rates from a current warehouse to customers that are currently delivered from another warehouse may be unknown. Rates being unknown is often a cumbersome part in supply chain network design, and reason to use a simpler costing method like the one embedded in this software.
- Enter warehouse fixed/variable costs, so these are taken into account as well in the optimization.
How to activate constraints
| Constraint | How to activate |
|---|---|
| Predefined warehouses | Always active, regardles constraint setting. |
| Fixed customer-warehouse assignments | By checking constraint in section Constraints |
| Fixed supplier-warehouse assignments | Not supported |
| Capacity limits | By using Greedy solver or LP solver (not by checking constraint). |
| Customer groups | Not supported |
| Suppliers | By checking constraint in section Constraints. Supply option 3 is activated in background, other options are not supported. |
| Border crossing points | By checking constraint in section Constraints. |
User input
Customers
Mandatory fields
- Customer_ID is a free format identifier.
- Latitude and Longitude are both decimal numbers and the result of converting a textual ship-to address (not sold-to address) into geographic coordinates - a process called geocoding. You can use:
- Batch Geocoder - Free (OpenStreetMap based)
- Batch Geocoder - Paid (Google Maps based)
- Excel interfaces with Google Maps / TomTom / BING geocoding api
- or any other geocoder
- City names may not be unique (or misspelled), so use postal codes as well to geocode as otherwise you may end up with demand at the wrong location.
- Double check postal codes on missing leading zeroes. For example, if you see German postal codes with only 4 digits, a leading zero is missing. If working in Excel: do not forget to set the column to type "text" before loading postal codes into it otherwise leading zeroes get lost! Batch Geocoder - Paid (based on Google Maps api) autocorrects if a proper city name has been supplied as well, and reports the corrected postal code.
- Put aggregated demand of far-away-customers delivered by sea/air (on overseas island) on exit harbor/airport (latitude/longitude), to ensure that Centers of Gravity are pulled in the right direction, and to avoid that a Center of Gravity ends up in such remote area. Or simply delete them, if their demand is marginal. Or check remote filter in Initialization options.

- Demand = total yearly future demand of a customer (as you are designing for the future), ideally expressed in your transportation cost driver: volume or (volumetric) weight.
- Collect a full year of demand data if your business is highly seasonal. Otherwise, one month × 12 may do.
- Design for the future: include demand growth percentages.
- If available, use shipment data with volumes or weights. Otherwise, demand can be calculated based on sales order quantities × item dimensions. But beware: item masters are often not 100% clean, which may cause large calculation errors. Check at least for shipments that exceed truck capacity or that are extremely small.
- If a sales budget is the only info (new market entry), use demographics to create a geographical demand proxy.
- Though not obligatory, it is advised to enter demand figures as whole numbers, as these are easier to read.
- If shipment volumes/weights are impossible to obtain, use financial sales per customer as demand.
- To model demand at product group level: split a customer into sub-customers, and link each sub-customer to the subset of warehouses holding the applicable product group. See field Warehouse_IDs.
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, no fixed assignment applies.
- Create a fixed assignment by entering a single warehouse_ID.
- Create a semi-fixed assignment by entering a subset of warehouse_IDs that the solver is allowed to select from.
Use / as separator between warehouse_IDs. For example, Birmingham/Madrid/WH05.
Activate constraint "Fixed customer-warehouse assignments"in section Parameters - 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. Read user manual section Center of Gravity algorithms - Customer grouping for more info.
A fixed customer-warehouse assignment takes precedence over a customer group. Warehouse capacity limits may cause a customer group to 'break'.Activate constraint "Customer groups"in section Parameters - Constraints. - Shipment_size translates into an individual customer transportation rate. If specified, it overrides the general customer shipment size. Read user manual section Transportation rates for more info. Make sure it does not exceed truck capacity. Shipment size can be expressed in KG, M3, pallets, loading metres, ... which - of course - should relate to how you have expressed demand.
- Lead_time_distance is the individual maximum allowed distance from the warehouse. If specified, it overrides the general lead time distance as set in section Parameters - Service level. Customers are colored black if the lead time distance is exceeded, showing where service is compromised. Enter the distance in the correct distance unit, miles or kilometers, as you have selected in section Parameters - 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. Activate constraint "Border crossing points"in section Parameters - Constraints.
Optional fields for "Select 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 for yourself what each qty stands for.
Various remarks
- After having entered the 4 obligatory fields you can run a first Center of Gravity analysis. Go to Calculate Centers of Gravity and press Calculate.
- 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?
- Default customer opacity is 0.9 to make customers behind each other visible. Small customers are plotted on top of large. But still. Customers with the same latitude/longitude are plotted on top of each other. Only a relatively small dot will be seen that does not properly reflect total demand. By checking 'Display aggregated demand', you might get a more insightful demand map.
Aggregation of customers
Running with 100,000 customers is possible, but does not make sense. Most models contain (far) less than 5,000 customers. If you have several thousands of customers, aggregation can likely reduce this number significantly while maintaining model validity (see case examples below), making your model run (much) faster. First, run without aggregation, to check if run time is an issue at all. Thecustomers aggregation tool
can be used to enhance the demand map or to replace original customer data.Customers aggregation suggestions
Suggestion 1
You may round customer latitudes and longitudes to two decimals, then aggregate demand per rounded-latitude-and-longitude-key. By rounding a customer may shift 0.78 km (0.5 mile) from its original position, at most. This 0.78 km is the as-the-crow-flies distance between (latitude, longitude) point (0.000, 0.000) and (0.005, 0.005). The further away from the Equator, the smaller this maximum shift becomes. At a 'European' latitude of 44.000 it is 0.68 km, at most. On average, customers shift approx. 0.37 km (0.2 mile), which is unnoticeable on the map. Moreover, all customer shifts together will largely counterbalance each other, so Centers of Gravity shift a negligible 0.0-0.1 km.The customers aggregation tool applies a more precise variant, as explained in a next separate section.
Suggestion 2
You may aggregate demand per 2-digit postal code, per country if creating a supply chain model for total Europe. Each country becomes 100 customers, at most. For example, customer DE-13 stands for all German customers with postal code 13XXX (ISO 3166-1 alpha-2 country code for Germany is DE). On a side note: transportation rate tables often use aggregated postal code zones, so they are only accurate to that level as well.Add 2-digit postal code to each customer. Create a pivot table to sum demand per 2-digit postal code. Use geocodes of largest customer with that 2-digit postal code to locate aggregated demand (no need to geocode all customers). Or use geocodes from (use file at your own risk).
If your case is about a single country, aggregating at 3-digit postal code level may be more appropriate. This will result in a model with 1000 customers per country, at most.
Customers aggregation case examples
Example 1: US case, aggregate all customers, rounding lats/lons to 0.1, or to 1
Rounding to 0.1: 3252 customers become 2239 aggregated customers (31% reduction).
- With 1 Center of Gravity: location shifts 0.0 mi.
- With 5 Centers of Gravity: largest shift 0.3 mi.
Rounding to 1: 3252 customers become 469 aggregated customers (86% reduction).
- With 1 Center of Gravity: location shifts 0.2 mi.
- With 5 Centers of Gravity: largest shift 18.4 mi, Gainsville becomes Oakleaf Plantation (FL), second largest 9.7 mi, which is marginal.
US aggregated - 5 Centers of Gravity - animation
Example 2: EU demo case. Aggregating customers in The Netherlands
The demo case is on a European scale. The Netherlands is a small European country. Aggregating 29 customers in The Netherlands (field Group = NL) into 1 customer (with a total demand of 136890 and located at 51.9795, 5.3627) has almost zero effect on outcomes.
- With 1 Center of Gravity: location shifts 0.3 km.
- With 3 Centers of Gravity: location differences are only noticeable if animated. Location Asse (BE) that supplies NL customers shifts 2.3 km. Azuqueca de Henares (ES) 'steals' 1 customer from Asse, shifts 7.6 km, and becomes Guadalajara (ES). Szekszárd (HU) does not shift.
NL aggregated - 3 Centers of Gravity - animation
Original demo - 3 Centers of Gravity
Goal value: 464757
Goal value: 464757
| Closest_city | Latitude | Longitude | Customers |
|---|---|---|---|
| Asse (BE) | 50.915034 | 4.141259 | 334 |
| Szekszárd (HU) | 46.440946 | 18.551507 | 174 |
| Azuqueca de Henares (ES) | 40.636589 | -3.345402 | 80 |
NL aggregated - 3 Centers of Gravity
Goal value: 464494 (99.94%)
Goal value: 464494 (99.94%)
| Closest_city | Latitude | Longitude | Customers | Shift (km) |
|---|---|---|---|---|
| Asse (BE) | 50.933775 | 4.154013 | 305 | 2.3 |
| Szekszárd (HU) | 46.440947 | 18.551512 | 174 | 0.0 |
| Guadalajara (ES) | 40.660535 | -3.261011 | 81 | 7.6 |
Example 3: EU demo case. Aggregating all customers, rounding lats/lons to 1
You can check this case for yourself. Reload page, to reload demo case. Run customers aggregation tool with round latitudes/longitude set to 1. Press its button Import. Open section Calculate Centers of Gravity. Set number of runs to 200. Press Calculate. You should now see a map and a goal value as presented below.
588 customers become 317 aggregated customers (46% reduction, with all constraints deactivated).
- With 1 Center of Gravity: location shifts 0.5 km which is unnoticeable on the map.
- With 3 Centers of Gravity: location differences are still hardly noticeable unless animated. Asse (BE) shifts 11.9 km and becomes Lebbeke (BE). Azuqueca de Henares (ES) shifts 2.0 km. Szekszárd (HU) shifts 41 km westward and becomes Dombóvár (HU). It turns out that using those 3 new locations as predefined warehouses in the original case with 588 customers increases the goal value by 0.02% only. So, this solution is an alternative equivalent for the original case solution.
All aggregated - 3 Centers of Gravity - animation
All aggregated - 3 Centers of Gravity
Sensitivity analysis shows that Dombóvár (red dot) is located
well within the 0.05%‑costs‑increase‑range around Szekszárd.

| Both solutions are equivalent | Goal value | Index |
|---|---|---|
| Original case with 588 customers | 464,757 | 100.00% |
| 3 aggregated-case-warehouses forced upon original case | 464,835 | 100.02% |
| Aggregated case with 317 customers | 463,979 | 100.00% |
| 3 original-case-warehouses forced upon aggregated case | 464,102 | 100.03% |
well within the 0.05%‑costs‑increase‑range around Szekszárd.

Of course, with 588 customers only, there is no real need to aggregate data. But even then, using a rather crude level of aggregation, outcomes remained valid. Besides, the whole exercise can also be seen as an additional sensitivity analysis, as future customers may also be located slightly elsewhere than current customers. If you have more than 5,000 customers, aggregation can likely reduce this number significantly while maintaining model validity.
How the customers aggregation tool calculates aggregated customer coordinates
- Round latitude and longitude of each customer to 0.01 and concatenate those as aggregation category, for example "lat_41.15_lon_20.17".
- For each aggregation category calculate the weighted average latitude and longitude of customers within that category as aggregated customer coordinates (instead of simply using 41.15, 20.17), and aggregate demand.
- Besides being more precise, it also means that if there is only one location within a category, that location will not shift at all.
- (In fact, other optional text-fields also become part of the aggregation category key. So, if field Group differs between two customers, they will never become part of the same aggregated customer.)
Instead of rounding to 0.01 (very conservative), you can choose to round to 0.025, 0.05, 0.1 (suggested), 0.25, 0.5, or even 1.0. Of course, the higher this number, the less accurate the aggregation becomes. The appropriate level of aggregation depends on geographical scale and average warehouse-customer distances. The larger the scale, the longer the distance, the larger the aggregation range may become. And vice versa.
How the customers aggregation tool calculates aggregated shipment sizes
The customers aggregation tool calculates aggregated shipment size as follows (given the customers per aggregation category):
- Calculate the weighted average shipment rate for these customers = Σ(demandi × ratei)/Σ(demandi).
- Iteratively determine the shipment size that corresponds with that weighted average shipment rate, which involves reverse interpolation of the transport costs curve. The bisection method - a type of half-interval search - is used to iterate.
- Of course, if you have not entered individual customer shipment sizes, the calculated aggregated shipment sizes will equal the generic customer shipment size.
Predefined warehouses (optional)
Mandatory fields
- Activate constraint "Predefined warehouses"in section Parameters - Constraints to include predefined warehouses in the solution.
- 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 in section Parameters - Distance. Note: Select warehouses routine ignores Move_limit, always uses 0.
- Capacity is used to limit warehouse throughput, with throughput being demand assigned to the warehouse (in case of a main warehouse not including demand assigned to its satellites). It is not storage capacity. Warehouse capacity limits may cause customer groups to 'break'. Activate constraint "Capacity limits"in section Parameters - Constraints.
- Transport_rate_index is used to adjust customer transportation rates of all customers supplied from this warehouse. An index below 100 means transportation from this warehouse to customers is relatively cheaper, an index larger than 100 means more expensive. Customer transportation rates are multiplied by the warehouse Transportation 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 in a demand-only model main→satellite warehouse flows are generated.
- MainWarehouse_ID is used to assign a satellite warehouse to a main warehouse. If left empty, the satellite warehouse gets linked to its closest main warehouse.
- Color overwrites the default warehouse color. Format: #rrggbb (red, green, blue hexadecimal values)
Pick color → Color =
Optional fields for "Select 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 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, the variable costs of this customer X at warehouse Y are 10×2.50 + 5×3.75.
Suppliers (optional)
Mandatory fields
- Activate constraint "Suppliers"in section Parameters - Constraints to include suppliers.
- 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, this supplier will not supply all warehouses directly, even if supply option "Each supplier delivers to each warehouse directly" has been selected. Activate constraint "Fixed customer-warehouse assignments"in section Parameters - Constraints.
- Shipment_size translates into an individual supplier transportation rate.
- Supply_option (1, 3, or 4) can be set to override the general supply option (1, 3, or 4) as selected in section Parameters - Supply options. General supply option 2 (LP optimized supply flows) can not be overridden at individual supplier level (individual settings are ignored).
- Border_group links the supplier 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 supplier to a warehouse will go via one of the border crossing points, unless the warehouse and supplier are both inside the bordered area. Leave field empty if you want this functionality to be ignored for a particular supplier. Border crossing points for suppliers only work with default supply option 3. Activate constraint "Border crossing points"in section Parameters - Constraints.
For more info about suppliers, transportation rates, and supply options, read user manual section Logical steps - Step 4. Add suppliers
Border crossing points (optional)
Mandatory fields
- Activate constraint "Border crossing points"in section Parameters - 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 transportation flow must 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 close to the border point (within a 50 km range).
- In the picture on the right the border crossing points in the northern part of Italy prevent shortcuts across the Adriatic Sea. If ferries are a valid transportation option, you may remove all border crossing points or add ferry harbors 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". A warehouse area entry point takes priority over a supplier area exit point.
Border crossing points are not meant for modeling flows via sea/airports
As described in section Customers, demand of far away regions reached by air/sea should be put at exit port, instead of far away region itself (and especially if no warehouse should end up in that region). Similarly, supply coming from far away regions should be put at entry port. Sea/air lanes can neither be entered nor optimized with the software (not its purpose), hence these lanes should be excluded. Any sea/air lane would be considered trucking lane, and the selected border crossing point would be (partly) based on sea/air lane distance. This would make no sense, as truck rates do not compare to sea/air rates. It would cause false optimization..The only valid reason for wanting to include sea/air lanes would be for "picture only". For "picture only": see also Map Maker, a free app providing full manual control over locations and flows to be depicted.
Constraints
Intro
By (de)activating constraints (optional) in section Parameters - Constraints you (de)activate parts of your input data, so you can quickly investigate how a constraint affects goal value and supply chain network structure.The following explains the links between constraints and input tables. Similar info is provided in previous sections. But this section is more focused. It also describes demo data, so you can check how a constraint is set up.
Predefined warehouses table
- Ad 1. Activate constraint "Predefined warehouses" to include predefined warehouses in the solution.
Demo: contains one predefined 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). If the number of Centers of Gravity is set higher than two, these two locations will be part of the solution (Birmingham remains Birmingham, Madrid is moved to Guadalajara if running for 3 Centers of Gravity). If you make Madrid's Move_limit 0, it will remain Madrid. - Ad 4. Activate constraint "Capacity limits" to limit total customer demand that can be assigned to the warehouse.
Demo: field Capacity is set for both predefined warehouses Birmingham and Madrid. - Ad 5. For more info about capacity limits and LP optimization, read user manual section Center of Gravity algorithms - Warehouse capacity limits.
Customers table
- Ad 2. Activate constraint "Fixed customer-warehouse assignments" to assign customers to a predefined warehouse or subset of predefined warehouses.
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. - Ad 6. Activate constraint "Customer groups" to have all customers within the same group delivered by the same single warehouse that can deliver to the group against lowest transportation costs. These costs are still calculated at individual customer level, see example in user manual section Center of Gravity algorithms - Customer grouping.
Demo: field Group is filled with the applicable ISO 3166-1 alpha-2 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. - Ad 8. Activate constraint "Border crossing points" to include border crossing points.
Demo: field Border_group is filled for customers in UK, IE, Italy, and Iberia.
Suppliers table
- Ad 7. Activate "Suppliers" to include suppliers. Also select a supply option.
Demo: contains one supplier in Rotterdam (The Netherlands - Entry harbor supplying 71% total demand), and one in Bologna (Italy). - Ad 3. Activate constraint "Fixed customer-warehouse assignments" to assign suppliers to a predefined warehouse. It links to field Warehouse_ID. If filled, 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.
Note that if field Warehouse_ID is filled, 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
- Ad 8. Activate constraint "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 number of border crossing points in Italy, Iberia, UK/Ireland, just to show you how this concept works.
Transportation rates
Intro
In section Parameters - Transportation rates you set transportation rates to differentiate between customer and supplier transport. You may also adjust the cost curve that expresses how much - relatively - more expensive smaller shipments (LTL-like transport) are compared to larger shipments (FTL-like transport).Transportation costs curve
Smaller shipments being relatively more expensive than larger shipments is expressed in the transportation costs curve. The default cost curve shows that a shipment size of 50% FTL brings 72.4% FTL costs, meaning that - per each unit transported - it is 1.45 times more expensive than FTL transport. You can adjust the curve by dragging control point handles or entering control point values in the cost curve settings below the chart.
Small customer shipments versus large supplier shipments
Smaller shipments to customers are relatively more expensive than larger shipments from suppliers. Average customer and supplier shipment sizes - as set in the transportation rates table - are translated into rates by applying the cost curve.Shipment size can be expressed in KG, M3, pallets, loading metres, ... It should relate to how you have expressed customer demand, as a single transportation unit of measurement applies to the whole model.

The ratio supplier/customer rate is important as it expresses how relatively less suppliers pull warehouses than customers do. This ratio is independent of cost/km. Therefore, high accuracy of cost/km is of lesser importance.
Ratio supplier rate/customer rate
The ratio supplier rate/customer rate expresses how relatively less suppliers pull warehouses than customers do. To minimize transportation costs, a Center of Gravity should move closer towards a customer than towards a supplier, if their total transportation volumes would be equal, regardless of distance!Animated calculation of how ratio affects Center of Gravity

- Above chart can be verified by geometry that brings the following formula for the Center of Gravity 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.
- It is easy to understand that x‑position becomes exactly 100 at ratio 1/3, as supply quantity of 3 × 1/3 balances with C2 quantity of 1, and C1 and C3 then pull it to 100.
- 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.9296...
Keep in mind that a supplier is not just a small customer as they can pull all warehouses. Read user manual section Logical steps - Step 4. Add suppliers for more info.
Small customer shipments versus large customer shipments
Similarly, shipments to small customers are relatively more expensive than shipments to large customers. To differentiate you can enter individual shipment sizes at individual customer (and also at individual supplier level). The impact of individual shipment size on Centers of Gravity may be small, if smaller and larger customers are scattered all around.Auto-sizing shipments per individual customer
Calculates individual shipment sizes, replacing the average customer shipment size as set in transportation costs table, assuming shipments to larger customers are larger and shipments to smaller customers are smaller. The chart shows the assumed relation between demand volume and shipment size.
As this method is rough, it is better to enter actual individual shipment sizes in the customer table than to activate auto-sizing.
Displaying transport-rated volumes on the map
In section Map settings you can choose to display location sizes as transport-rated volumes (volume × rate ratio), instead of plain volumes (default setting). Suppliers will then appear relatively smaller than customers, which better reflects the Center of Gravity 'pull forces' of suppliers and customers.Inter-warehouse flows
But you can also model: (suppliers →) warehouses → warehouses → customers
There are two options to model inter-warehouse flows.
- In a model with suppliers: Select supply option "Each supplier delivers to each warehouse via closest warehouse".
Closest warehouse can be overridden by specifying a predefined warehouse in field Warehouse_IDs of the supplier table. Supply quantities (that are related to demand quantities) determine warehouse-warehouse flow quantities. - In a model without suppliers: Set up predefined warehouses, some as main warehouse (field IsSatellite=0), some as satellite (IsSatellite=1).
Each satellite gets supplied by its closest warehouse. Satellite demand quantities determine warehouse-warehouse flow quantities.
You can combine it with forcing a link between a customer/supplier and a (subset of) warehouse(s) by entering field Warehouse_IDs.
In general, try to keep your model simple. Its purpose is to help answer questions. That does not necessarily mean it should reflect reality as closely as possible. For example, if all suppliers deliver to a single plant (main warehouse), and the plant delivers to warehouses that deliver to customers, you can create a 2-echelon model with plant (main warehouse) → warehouses. But if that plant location is fixed, there is no possibility to optimize suppliers→plant flows. So, you may consider replacing all suppliers and plant with a single fake supplier at (previously) plant location, and revert to a simple 1-echelon model.
Note: "Select warehouses" routine does not support inter-warehouse flows.
Explanation of Center of Gravity algorithms
Goal value
Demand can be used as weight (this is often seen on internet). But should a customer with 17 deliveries of 2 pallets have equal weight as one with 2 deliveries of 17 pallets? Number of deliveries can be used as weight. But should a customer with 17 deliveries of 2 pallets have equal weight as one with 17 deliveries of 13 pallets?
Centers of Gravity Calculator uses two weights. Goal value to be minimized is the sum of double weighted distances. Distances are weighted by transportation quantity (1st weight) × transportation rate (2nd weight). The transportation rate converts distances and quantities into costs. Transportation rate depends on shipment size, captured by a transportation costs curve (adjustable). Main reason for adding transportation rate as a second weight is to make suppliers - that come with relatively less expensive transportation - pull Centers of Gravity relatively less than customers do, rather than to come up with highly accurate transportation costs. Section Transportation rates provides more info about transportation rate differentiation between customers and suppliers.
Regardless of how weight is defined, algorithms remain the same, given the weights. So, in the next sections, this second weight (transportation rate), is ignored, as it is not relevant for explaining the algorithms as such. So, for readability, the next sections use demand for weight.
Algorithms
Single Center of Gravity algorithm
Upfront: it takes an iterative algorithm to calculate a Center of Gravity properly
The weighted arithmetic mean formula (Wikipedia) in applied form:
| Weighted average x = | (demand of customer 1 × x of customer 1 + .... + demand of customer N × x of customer N) |
| (demand of customer 1 + .... + demand of customer N) | |
| Weighted average y = | (demand of customer 1 × y of customer 1 + .... + demand of customer N × y of customer N) |
| (demand of customer 1 + .... + demand of customer N) |
The weighted average position brings a sum of weighted distances that is often only 0-5% worse than that of the true Center of Gravity, sometimes 5%-10% worse, and theoretically even 100% worse is possible (see example below). The small realtime random examples of section Animated explanation often show 0-10% worse.
100% worse theoretical example - weighted average position versus true Center of Gravity
Customer A has a demand of 1000 and is located at (0, 0).
Customer B has a demand of 1 and is located at (100, 0).
Weighted average x = (1000×0 + 1×100) / (1000+1) = 0.0999.
Weighted average y = (1000×0 + 1×0) / (1000+1) = 0.
The weighted average position brings a sum of weighted distances of 1000×0.0999 (A) + 1×99.9 (B) = 199.8.
If the weighted average position is moved a small distance d towards customer A, the sum of weighted distances decreases 1000×d (closer to A) − 1×d (further from B) = 999×d. So, the Center of Gravity is on top of customer A, at (0, 0), not at (0.0999, 0)
The Center of Gravity brings a sum of weighted distances of 1000×0 (A) + 1×100 (B) = 100.
The weighted average position brings a sum of weighted distances of 199.8 (see above) which is 100% worse.
Customer A has a demand of 1000 and is located at (0, 0).
Customer B has a demand of 1 and is located at (100, 0).
Weighted average x = (1000×0 + 1×100) / (1000+1) = 0.0999.
Weighted average y = (1000×0 + 1×0) / (1000+1) = 0.
The weighted average position brings a sum of weighted distances of 1000×0.0999 (A) + 1×99.9 (B) = 199.8.
If the weighted average position is moved a small distance d towards customer A, the sum of weighted distances decreases 1000×d (closer to A) − 1×d (further from B) = 999×d. So, the Center of Gravity is on top of customer A, at (0, 0), not at (0.0999, 0)
The Center of Gravity brings a sum of weighted distances of 1000×0 (A) + 1×100 (B) = 100.
The weighted average position brings a sum of weighted distances of 199.8 (see above) which is 100% worse.
Introductory thoughts
Well, you could say that customer A pulls 10 times harder than customer B. If the 'Center of Gravity'* moves a distance d towards customer 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 customer A and customer 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?
If the move distance is set extremely small, you will for sure end up on top of the Center of Gravity, but it will take an extremely large number of moves before the Center of Gravity is finally reached. Therefore, it is better start with big moves. Which then will cause 'overshooting' (after some steps). In case of 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.
|
Using a variable step size speeds up the algorithm drastically. Given a search range of 1024 miles (= 210 miles) it takes 10 steps only to reach the Center of Gravity within 1 mile precision (11 steps brings 0.5 mile precision, 12 steps 0.25 mile). Whereas using a small, fixed step size of 1 mile would take on average 500 steps to reach the Center of Gravity, and worse case 1000 steps. |

** 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. And 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.
Strangely, minimizing the sum of weighted distances is not directly related to distances as such, but to pull forces and directions. Shown below are four customers with equal demand. Obviously, the Center of Gravity is located in the center.
The Center of Gravity will not change if customer B is moved further away, as long as the direction CoG-B does not change. Distance is irrelevant! This also makes it clear why it is impossible to calculate a Center of Gravity in a single step with a simple formula (different input should bring the same output).
Algorithm
- 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 coordinate of its customers, as discussed in section Upfront that also presents the weighted average formula.
- 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 it is too small then it will take many iterations before the Center of Gravity is reached.
- 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 × cosine(angle F). Fy = demand × sine(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, 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.
- Calculate the sum of weighted distances. If it increased, 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).
- Repeat steps 2 and 3 until the move distance becomes exceedingly small.
- Then the Center of Gravity hardly changes anymore, and the sum of weighted distances converges.
- This Center of Gravity may be in the middle of a lake or on top of a mountain, as it is a theoretical calculation without constraints.
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 Nonlinear (GRG stands for Generalized Reduced Gradient), but is more tailored to the problem, using 'physics' to determine which direction to move.
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.

There are methods to determine a proper move distance (a.k.a. step size) per iteration. But these are rather complex and (thus) time-consuming. Luckily, there is no urgent need for those, because the method of step 3 works and is fast.
Animated explanation by real-time simulation
Process step by step
Press button Next process step to start the simulation.
Percentual difference of the sum of weighted distances between weighted average position versus true Center of Gravity
The animation shows the percentual difference of the sum of weighted distances between initial position (white dot, as calculated by weighted average formula) versus true Center of Gravity (large grey circle) with a percentage cost improvement.Translating Cartesian into Spherical coordinate system
|
X,y on a flat plane (Cartesian 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 an Initial Bearing formula. |
"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
See Excel - As-the-crow-flies distance function for an Excel implementation. Excel's atan2 function takes its arguments in reversed order!
Initial Bearing formula
Initial Bearing = atan2(sine(longitude_customer − longitude_Center of Gravity) × cosine(latitude_customer) , cosine(latitude_Center of Gravity) × sine(latitude_customer) − sine(latitude_Center of Gravity) × cosine(latitude_customer) × cosine(longitude_customer − longitude_Center of Gravity)
Initial Bearing is measured against the vertical longitude axis (with 0 degrees = North), not the horizontal latitude axis, so you need to swap the use of cosine/sine when calculating forces in x and y direction.
See Excel - Initial Bearing function for an Excel implementation. Excel's atan2 function takes its arguments in reversed order!
|
||
Applying the algorithm to Earth is done via a flat tangent space.
The globe with current 'Center of Gravity' location (white) and customer pull forces are transformed to a tangent space - a flat plane that touches the globe at the current 'Center of Gravity' location - respecting pull force lengths and angles. The next 'Center of Gravity' location (green) is computed on the tangent space applying the algorithm. This next location is mapped back to the globe. This green location then becomes white current location, and the process is repeated (until the final location has been reached).
The globe with current 'Center of Gravity' location (white) and customer pull forces are transformed to a tangent space - a flat plane that touches the globe at the current 'Center of Gravity' location - respecting pull force lengths and angles. The next 'Center of Gravity' location (green) is computed on the tangent space applying the algorithm. This next location is mapped back to the globe. This green location then becomes white current location, and the process is repeated (until the final location has been reached).Weiszfeld's algorithm as alternative
Algorithm
Weiszfeld's algorithm - see also Geometric median (Wikipedia) - is simpler (but less intuitive) and works like this on an x,y plane:- Initialization: locate the 'Center of Gravity' at an initial (random) position.
- Calculate each customer weight as demand divided by distance to 'Center of Gravity'.
- Calculate the weighted average x,y of customers as the next 'Center of Gravity'.
- Repeat steps 2 and 3 until the sum of weighted distances converges.
Differences between Single Center of Gravity and Weiszfeld's algorithm
Major difference between Single Center of Gravity algorithm and Weiszfeld's algorithm is that the Single Center of Gravity algorithm uses an explicitly controlled move distance that - indirectly - enables an advanced feature: you can limit the move range of predefined warehouses. The optimal location may then be somewhere exactly at the border of this limited range and Weiszfeld's algorithm cannot handle this.
That difference is also the reason that Weiszfeld's algorithm converges approx. 10% faster. Because, if the initial move distance used by the Single Center of Gravity algorithm is set too low, it will take many iterations to move a Center of Gravity to its final destination, so it is better to initialize it too high. But as a result, the first few iterations will often be useless overshoots (ignored - after which step size is divided by two - and then it quickly catches up with Weiszfeld's algorithm).

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, and some other specific cases.
Multiple Centers of Gravity algorithm
Algorithm
Below, 'Center of Gravity' and warehouse are used interchangeably.A single run of the Multiple Centers of Gravity algorithm does the following:
- Initialization: locate each warehouse at a random location within the customer cloud.
If many Centers of Gravity, initialize with k-means++ (Wikipedia). More info is found at the end of this section. - (Re)assign each customer to its closest warehouse.
- Move each warehouse to the Center of Gravity of its assigned customers.
= apply Single Center of Gravity algorithm / Weiszfeld's algorithm per warehouse - Repeat steps 2 and 3 until the sum of weighted distances converges.
Most important: 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 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 above algorithm is similar to k‑means clustering (Wikipedia) used for cluster analysis in data mining and machine learning.
In supply chain network design, customer clusters will overlap. K-means iterations will work reasonably well, regardless of the initialization, as concluded in this scientific article How much can k-means be improved by using better initialization and repeats?.
UK and mainland Europe is an example where there is less overlap. If you know upfront that a warehouse in the UK is required to meet customer lead times, Centers of Gravity Calculator offers the functionality to set up a predefined warehouse in the UK with limited move range (so it can still optimize its position), and/or to link customers in UK to it, and/or group all UK customers for single sourcing. Or you can simply run the Center of Gravity analysis separately for the UK.
Algorithm - Simultaneous version
In case of main and satellite warehouses that interact with each other, the algorithm optimizes all Centers of Gravity simultaneously instead of sequentially (step 3 is done somewhat differently).Animated explanation
The animations show what happens during a single run of the Multiple Centers of Gravity 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 - in the first three examples below - each run starts with different initial random locations, the solution found is the global optimum with a minimal sum of weighted distances.
| Run 1 - global optimum | Run 2 - global optimum | Run 3 - global optimum |
![]() |
![]() |
![]() |
| But a run may get stuck in a local optimum, as shown below. Therefore, multiple runs need to be done to find the global optimum. | ||
| Run 4 - local optimum | ||
![]() |
||
Real-time animated simulation
Below you see a real-time animated simulation of the multiple Centers of Gravity algorithm. It shows 10 runs for the same random case. Above each picture it shows the sum of weighted distances, and between brackets the cost index compared to the best solution (so far).If a run does not further improve, it is marked light grey (its sum of weighted distances will not change anymore, but its cost index may still increase). When all 10 runs have finished, each best solution - having index 100.0000 - is highlighted. A new random case is created - with the number of warehouses looping through 2,3,4 - and the process is endlessly repeated.
Beware of an overseas customer, far, far away
As seen before, calculating a Center of Gravity is not so much about distances as such, as it is about pull forces and directions, finding the spot where all forces summed up together become zero.An exceptional Centers of Gravity case in which distances may become "directly relevant" is a case in which one larger customer is located thousands of miles away from all others, on some overseas island that belongs/belonged to a country. Then one of the Centers of Gravity may end up on top of that customer (in random initialization phase, after which it will simply stay there as it will not get linked to any other customer, so will not get pulled away). But locating a warehouse over there probably makes no sense. So, you better remove such customer from your input data, or else relocate it to exit harbor or airport.
K‑means++ as alternative initialization method
K‑means++ disperses initial Centers of Gravity better, which is especially helpful if the number of Centers of Gravity is high. K‑means++ will not lower the goal value per se, if a large number of runs is done. But at a high number of Centers of Gravity the percentage of runs within +0.01% from minimum goal value will increase, compared to pure random initialization. On average, the minimum is found quicker. On average, because randomness is involved. It can happen that run number 1 finds the global optimum, with or without k‑means++.K‑means++ may perform slightly worse at a low number of Centers of Gravity, because it puts initial Centers of Gravity in remote areas with high probability, whereas those few locations should end up in major customer areas.
Overseas customers, far, far away, cause more of an issue for k‑means++, so you are advised to relocate those at exit harbor or airport, or simply delete those, if their demand is marginal. And/or use the remote filter. Remote customers are only ignored in the initialization phase, and not permanently deleted.
Add-ons
Warehouse capacity limits
Default: Greedy algorithm
Centers of Gravity Calculator's default algorithm (by Stelling Consulting) to handle capacity constraints is a superfast, greedy algorithm. Roughly described, it works like this.- Assign each customer (group) to a warehouse as if warehouse capacities are unlimited
- Loop through all warehouse, and while the capacity of a warehouse is exceeded shift that customer (group) to that other warehouse that will increase the costs the least - and only if the customer (group) still fits in that warehouse if it is a warehouse earlier in the loop.
Greedy means that the solution may be sub-optimal, cost-wise. Capacities will not exceed 100% unless all are set super-tight without any small customers that can easily be reassigned.
Optional: LP optimization
LP optimization sets up and solves a transportation problem in which demand should be met by supply against minimal costs. A transportation problem can be solved with the Simplex method, but much faster with a combination of Vogel's approximation + MODI + Stepping Stone method, bringing a cost-optimal solution in which capacities never exceed 100%. For more info and a real-time demo, see Transportation problem solverHowever, that cost-optimal solution needs post-processing, because demand got assigned, not customers. In its solution a few customers may have been assigned to multiple warehouses. This happens if the demand of a customer could only be partly supplied from a warehouse, because its utilization reached 100%. Another warehouse will then supply the remainder to this customer.
Center of Gravity Calculator assumes single sourcing. Each 'split' customer gets assigned in full to the warehouse that supplied the major portion of its demand. This may cause utilization to (slightly) exceed 100% and costs to (slightly) deviate from the transportation problem solution costs. The Greedy algorithm solution can be superior, but LP optimization often brings a solution with 0%-3% lower costs in less run time, especially if all warehouses have tight capacity constraints.
LP optimization ignores customer groups, but will only get activated if warehouses still exceed capacity, after first having tried to solve capacity issues at group level (done by Greedy algorithm).
The Select warehouses routine reports separately the transportation problem solution itself, details about split customers, and cost effects of post-processing. You may want to replicate your Centers of Gravity solution using the Select warehouses routine, to generate that more detailed report. To do so, set the number of warehouses to select equal to the number of Centers of Gravity.
Continuous LP optimization or post-optimization only
You can choose between:
| Continuous optimization: | LP continuously active, during whole process, for all runs. May increase total run time considerably. |
| Post‑optimization only: | LP applied for best run only, afterwards. It will not affect Centers of Gravity, but may prevent illogical customer flows. |
Run with and without LP optimization and compare outcomes
Of course, you can simply run with and without LP optimization, and compare solutions. Usually, they do not differ that much.Including supply-side
Besides customers, suppliers also pull Centers of Gravity, but in 'opposite' direction, and usually relatively less hard, as supplier transportation is relatively less expensive than customer transport. See section Parameters - Transportation rates.
Centers of Gravity Calculator supports 4 supply options that determine how supply flows are constructed.
- Each supplier delivers to closest warehouse onlyi
- LP optimized supply flows - with auto-sized suppliersi
- Each supplier delivers to each warehousei
- Each supplier delivers to each warehouse via closest warehousei
Each supplier causes (multiple) flows to warehouses. Each flow translates into a pull force (supplier or inter-warehouse transportation rate weighted) comparable to a customer pull force (customer transport 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 transportation costs.
Besides, the customer assignment procedure of the Multiple Centers of Gravity algorithm (step 2) takes into account (expected) supply-side transportation costs when determining to which warehouse a customer gets assigned to.
Customer grouping
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'.
Underlying assumptions
Of course, it would be better to use actual transportation rates. But - most likely - you will not have transportation rates for every possible warehouse location to every customer location, so you will have to rely on approximations.
Minor assumption is that estimated road distances resemble actual road distance. The software calculates with estimated road distances. Estimated road distance = as-the-crow-flies distances × distance circuity factor. An important reason for using estimated road distances is that run-time would become too long when having to calculate (extremely) large numbers of actual road distances (still an approximation to some extent - see note at end of this section). Also, calculating Centers of Gravity is not so much about distances as such (see example below) as it is about pull forces and directions, finding the spot where all forces summed up together become zero (equilibrium), as explained in section Single Center of Gravity algorithm. As distance estimation errors occur in each 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 become pretty accurate. The use of as-the-crow-flies distance × circuity factor as an estimator for actual road distance is usually not an issue, if the road network is dense. Approximations are acceptable, and commonly used in supply chain network design software.
Shown below are four customers with equal demand. Obviously, the Center of Gravity is located in the center.
The Center of Gravity will not change if customer B is moved further away, as long as the direction CoG-B does not change. Distance is irrelevant! This also makes it clear why it is impossible to calculate a Center of Gravity in a single step with a simple formula (different input should bring the same output).
The Center of Gravity will not change if customer B is moved further away, as long as the direction CoG-B does not change. Distance is irrelevant! This also makes it clear why it is impossible to calculate a Center of Gravity in a single step with a simple formula (different input should bring the same output).
Note
Google Maps returns fastest route by default, not shortest route. Which is fine, because driver and truck cost relate more to time than distance. 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. Besides, new roads may open in the near future. Even actual road distance is an estimation to some extent.
Google Maps returns fastest route by default, not shortest route. Which is fine, because driver and truck cost relate more to time than distance. 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. Besides, new roads may open in the near future. Even actual road distance is an estimation to some extent.
Broader supply chain network design perspective
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 Center of Gravity analysis is only part of a supply chain network design project, which typically looks like this:
Supply chain network design - Project phases and activities
|
|||||
PROJECT KICK-OFF
|
CURRENT BASELINE
|
FUTURE BASELINE
|
FUTURE SCENARIOS
|
SELECTION & ROADMAP
|
|
| 1 week lead time | 3-5 weeks lead time | 1-2 weeks lead time | 2-4 weeks lead time | 2-3 weeks lead time | |
A completely different algorithmic approach - Towards Select warehouses
+ Advantages are that the warehouse-customer cost matrix (and warehouse-supplier costs matrix) can be based on various transportation rate structures and accurate road distances, and that it can take into account binary-fixed and variable warehousing costs.
− Disadvantages are that (much) more input is required, and that the set of possible warehouse locations may not contain the true optimal locations.
The Select warehouses routine (see next section) is based on the above approach.
Explanation of Select warehouses algorithms
Goal value
- Customer transportation 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 transportation rate (= transportation cost/distance unit/qty unit).
- Distance is based on coordinates of the predefined warehouse. (So, not the coordinates of Center of Gravity in case a warehouse was allowed to move. You may want to copy Center of Gravity coordinates back into your predefined warehouse table.)
- Distance includes detour via a border crossing point if applicable.
- You can adjust cost input via section "Override warehouse-customer transportation costs input (optional)".
- Supplier transportation cost (optional) for each supplier S = supply qty of supplier S × as-the-crow-flies-distance between warehouse W and supplier S × distance circuity factor × supplier transportation rate * warehouse qty/total demand. This is conform supply option 3.
- Warehouse binary-fixed costs (optional) of warehouse W are its fixed costs and apply only if warehouse W is opened.
- Warehouse variable handling costs (optional) if customer C is delivered from warehouse W = productsum(customer C's whs quantities × warehouse W's variable rates). Note that customer field Demand (= transportation qty) is irrelevant in this formula.
Algorithms
Two independent main procedures
The selection of best warehouses is handled by a combination of two independent main procedures, each having solver options.Main procedure 1 - Warehouse combinations generation
Generates valid warehouse combinations, by making an open/close decision for each warehouse, with valid meaning that the number of warehouses to select is respected and each must-be-included warehouse is included.
- Enumeration solver: generates all possible valid warehouse combinations, solves relatively slowly, but optimally (guaranteed).
- K‑means clustering solver: generates only "promising" warehouse combinations, solves fast, but may bring sub-optimal decisions.
Main procedure 2 - Customer assignment while respecting warehouse capacities
Given open/close decisions of main procedure 1, main procedure 2 assigns each customer to an open warehouse.
- If warehouse capacities are not applicable, each customer can simply be assigned to the warehouse that brings lowest costs.
- Greedy solver: respects warehouse capacities, assigns fast, but may produce sub-optimal assignments, with costs not truly minimized.
- LP solver: respects warehouse capacities, assigns customer demand (not customers) relatively slowly, with costs truly minimized. In a non-optimal final step, each customer then gets assigned to the warehouse that supplies most (single sourcing).
Use Enumeration solver with LP solver (if warehouse capacities apply) if run time is acceptable
But for a first quick result - that most often brings the optimal warehouse selection - use other solvers.Using Enumeration solver with LP solver run time will increase and behave non-linear. For example, if running the demo case and selecting three warehouses, the process starts relatively slowly, because the first two warehouses out of 24 have capacity limits, so a transportation problem needs to be solved if the warehouse combination of three warehouses contains one or both of those two constrained warehouses. Once none of those two is part of a warehouse combination of three then the run speeds up drastically, because customers can simply be assigned to the cheapest warehouse without having to solve a transportation problem, so the run is suddenly finished within the blink of an eye. This "fast forward" happens when 23.9% of 2024 combinations have been processed, with 1540 combinations of 3 warehouses out of the last 22 unconstrained warehouses on the list still to be processed. (After having optimized programming code for speed, this example now takes less than 2 seconds, and the "non-linear" run time is only noticeable if running at a higher number of warehouses to select.)
If a run takes too long, simply stop it - and ignore outcome if Enumeration solver is used as that solver lacks an internal mechanism to steer towards the best combination of warehouses - and use another combination of solvers.
Warehouse combinations generation
Enumeration solver
K‑means clustering solver
Single run
- Initialization: for each group, select a random warehouse within the group and open it, until the number 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 several times in 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.
Customer assignment while respecting warehouse capacities
Ignore / not applicable
Greedy solver
- Assign each customer (group) to a warehouse as if warehouse capacities are unlimited
- Loop through all warehouse, and while the capacity of a warehouse is exceeded shift that customer (group) to that other warehouse that will increase the costs the least - and only if the customer (group) still fits in that warehouse if it is a warehouse earlier in the loop.
Greedy means that the solution may be sub-optimal, cost-wise. Capacities will not exceed 100% unless all are set super-tight without any small customers that can easily be reassigned.
LP solver
However, that cost-optimal solution needs post-processing, because demand got assigned, not customers. In its solution a few customers may have been assigned to multiple warehouses. This happens if the demand of a customer could only be partly supplied from a warehouse, because its utilization reached 100%. Another warehouse will then supply the remainder to this customer.
Center of Gravity Calculator assumes single sourcing. Each 'split' customer gets assigned in full to the warehouse that supplied the major portion of its demand. This may cause utilization to (slightly) exceed 100% and costs to (slightly) deviate from the transportation problem solution costs. The Greedy algorithm solution can be superior, but LP optimization often brings a solution with 0%-3% lower costs in less run time, especially if all warehouses have tight capacity constraints.
Table of contents



