API – custom distance matrix

In your requests you can provide a custom distance matrix, or selected parts of the distance matrix. This is how it works. First, straight line distances are computed between each pair of locations (Agents and Facilities). Then, if you provided an optional Distances field, this field is parsed and the straight line distances in the original distance matrix are overwritten with the values you provided. If you provide a special -1 distance value, then the corresponding existing distance value is not modified (see examples below).

It is even better if you can provide reliable travelling times instead of distances. In this case, as distance equals time multiplied by speed, convert your times into distances by multiplying them by AgentSpeed that you also provided in your json request.

The Distances field is a sequence that consists of any number of sections, with each section describing distances between a subset of locations. Each section consists of four parts:
[number of locations,assume symmetric? 0 or 1,indexes of locations,distance values].

For nonsymmetric (0) distances, OptiFacility expects number of locations * (number of locations − 1) distance values. If you say that the distances are symmetric (1), then you only need to provide half of the number of nonsymmetric distance values.

Let's consider a few illustrative examples. We will assume there are 12 locations (agents+facilities) so the full distance matrix (row index=from, column index=to) looks like this:

0 1 2 3 4 5 6 7 8 9 10 11
0 0,00,10,20,30,40,50,60,70,80,90,100,11
1 1,01,11,21,31,41,51,61,71,81,91,101,11
2 2,02,12,22,32,42,52,62,72,82,92,102,11
3 3,03,13,23,33,43,53,63,73,83,93,103,11
4 4,04,14,24,34,44,54,64,74,84,94,104,11
5 5,05,15,25,35,45,55,65,75,85,95,105,11
6 6,06,16,26,36,46,56,66,76,86,96,106,11
7 7,07,17,27,37,47,57,67,77,87,97,107,11
8 8,08,18,28,38,48,58,68,78,88,98,108,11
9 9,09,19,29,39,49,59,69,79,89,99,109,11
10 10,010,110,210,310,410,510,610,710,810,910,1010,11
11 11,011,111,211,311,411,511,611,711,811,911,1011,11



Let's analyze the following sequence:
"Distances":[3, 0, 5, 6, 7, 51, 52, 53, 54, 55, 56]

This entire sequence consists of only one section: [3,0,5,6,7,51,52,53,54,55,56].

    It mentions 3 indexes: 5,6,7.
    The value of 0 means the assumption that all distances provided in this section are NOT symmetric, so OptiFacility expects that you provided 6 distance values.
    distances[5,6]= 51
    distances[5,7]= 52
    distances[6,5]= 53
    distances[6,7]= 54
    distances[7,5]= 55
    distances[7,6]= 56

After applying this sequence, the following distances are modified in the matrix:

0 1 2 3 4 5 6 7 8 9 10 11
0 0,00,10,20,30,40,50,60,70,80,90,100,11
1 1,01,11,21,31,41,51,61,71,81,91,101,11
2 2,02,12,22,32,42,52,62,72,82,92,102,11
3 3,03,13,23,33,43,53,63,73,83,93,103,11
4 4,04,14,24,34,44,54,64,74,84,94,104,11
5 5,05,15,25,35,45,551525,85,95,105,11
6 6,06,16,26,36,4536,6546,86,96,106,11
7 7,07,17,27,37,455567,77,87,97,107,11
8 8,08,18,28,38,48,58,68,78,88,98,108,11
9 9,09,19,29,39,49,59,69,79,89,99,109,11
10 10,010,110,210,310,410,510,610,710,810,910,1010,11
11 11,011,111,211,311,411,511,611,711,811,911,1011,11



Now almost identical sequence, but the order of indexes is random (not really useful, just for illustration of how this influences the result):
"Distances":[3, 0, 7, 5, 6, 51, 52, 53, 54, 55, 56]

This entire sequence consists of only one section: [3,0,7,5,6,51,52,53,54,55,56].

    It mentions 3 indexes: 7,5,6.
    The value of 0 means the assumption that all distances provided in this section are NOT symmetric, so OptiFacility expects that you provided 6 distance values.
    distances[7,5]= 51
    distances[7,6]= 52
    distances[5,7]= 53
    distances[5,6]= 54
    distances[6,7]= 55
    distances[6,5]= 56

After applying this sequence, the following distances are modified in the matrix:

0 1 2 3 4 5 6 7 8 9 10 11
0 0,00,10,20,30,40,50,60,70,80,90,100,11
1 1,01,11,21,31,41,51,61,71,81,91,101,11
2 2,02,12,22,32,42,52,62,72,82,92,102,11
3 3,03,13,23,33,43,53,63,73,83,93,103,11
4 4,04,14,24,34,44,54,64,74,84,94,104,11
5 5,05,15,25,35,45,554535,85,95,105,11
6 6,06,16,26,36,4566,6556,86,96,106,11
7 7,07,17,27,37,451527,77,87,97,107,11
8 8,08,18,28,38,48,58,68,78,88,98,108,11
9 9,09,19,29,39,49,59,69,79,89,99,109,11
10 10,010,110,210,310,410,510,610,710,810,910,1010,11
11 11,011,111,211,311,411,511,611,711,811,911,1011,11



Let's now analyze this simple sequence:
"Distances":[2, 0, 5, 8, 51, 52]

This entire sequence consists of only one section: [2,0,5,8,51,52].

    It mentions 2 indexes: 5,8.
    The value of 0 means the assumption that all distances provided in this section are NOT symmetric, so OptiFacility expects that you provided 2 distance values.
    distances[5,8]= 51
    distances[8,5]= 52

After applying this sequence, the following distances are modified in the matrix:

0 1 2 3 4 5 6 7 8 9 10 11
0 0,00,10,20,30,40,50,60,70,80,90,100,11
1 1,01,11,21,31,41,51,61,71,81,91,101,11
2 2,02,12,22,32,42,52,62,72,82,92,102,11
3 3,03,13,23,33,43,53,63,73,83,93,103,11
4 4,04,14,24,34,44,54,64,74,84,94,104,11
5 5,05,15,25,35,45,55,65,7515,95,105,11
6 6,06,16,26,36,46,56,66,76,86,96,106,11
7 7,07,17,27,37,47,57,67,77,87,97,107,11
8 8,08,18,28,38,4528,68,78,88,98,108,11
9 9,09,19,29,39,49,59,69,79,89,99,109,11
10 10,010,110,210,310,410,510,610,710,810,910,1010,11
11 11,011,111,211,311,411,511,611,711,811,911,1011,11



Let's analyze another simple sequence:
"Distances":[2, 1, 5, 8, 51]

This entire sequence consists of only one section: [2,1,5,8,51].

    It mentions 2 indexes: 5,8.
    The value of 1 means the assumption that all distances provided in this section are symmetric, so OptiFacility expects that you provided 1 distance value.
    distances[5,8]= 51
    distances[8,5]= 51

After applying this sequence, the following distances are modified in the matrix:

0 1 2 3 4 5 6 7 8 9 10 11
0 0,00,10,20,30,40,50,60,70,80,90,100,11
1 1,01,11,21,31,41,51,61,71,81,91,101,11
2 2,02,12,22,32,42,52,62,72,82,92,102,11
3 3,03,13,23,33,43,53,63,73,83,93,103,11
4 4,04,14,24,34,44,54,64,74,84,94,104,11
5 5,05,15,25,35,45,55,65,7515,95,105,11
6 6,06,16,26,36,46,56,66,76,86,96,106,11
7 7,07,17,27,37,47,57,67,77,87,97,107,11
8 8,08,18,28,38,4518,68,78,88,98,108,11
9 9,09,19,29,39,49,59,69,79,89,99,109,11
10 10,010,110,210,310,410,510,610,710,810,910,1010,11
11 11,011,111,211,311,411,511,611,711,811,911,1011,11



Now let's see the following sequence:
"Distances":[4, 1, 2, 5, 9, 10, 51, 52, 53, 54, -1, 56]

This entire sequence consists of only one section: [4,1,2,5,9,10,51,52,53,54,-1,56].

    It mentions 4 indexes: 2,5,9,10.
    The value of 1 means the assumption that all distances provided in this section are symmetric, so OptiFacility expects that you provided 6 distance values.
    distances[2,5]= 51
    distances[5,2]= 51
    distances[2,9]= 52
    distances[9,2]= 52
    distances[2,10]= 53
    distances[10,2]= 53
    distances[5,9]= 54
    distances[9,5]= 54
    distances[5,10]= unchanged (-1)
    distances[10,5]= unchanged (-1)
    distances[9,10]= 56
    distances[10,9]= 56

After applying this sequence, the following distances are modified in the matrix:

0 1 2 3 4 5 6 7 8 9 10 11
0 0,00,10,20,30,40,50,60,70,80,90,100,11
1 1,01,11,21,31,41,51,61,71,81,91,101,11
2 2,02,12,22,32,4512,62,72,852532,11
3 3,03,13,23,33,43,53,63,73,83,93,103,11
4 4,04,14,24,34,44,54,64,74,84,94,104,11
5 5,05,1515,35,45,55,65,75,8545,105,11
6 6,06,16,26,36,46,56,66,76,86,96,106,11
7 7,07,17,27,37,47,57,67,77,87,97,107,11
8 8,08,18,28,38,48,58,68,78,88,98,108,11
9 9,09,1529,39,4549,69,79,89,9569,11
10 10,010,15310,310,410,510,610,710,85610,1010,11
11 11,011,111,211,311,411,511,611,711,811,911,1011,11



Finally, let's investigate a sequence with 4 merged sections:
"Distances":[4, 1, 1, 2, 3, 4, 51, 52, -1, 54, 55, 56, 2, 0, 8, 9, 101, -1, 2, 0, 9, 10, 103, 104, 2, 1, 10, 8, 105]

Section 1 is [4,1,1,2,3,4,51,52,-1,54,55,56].

    It mentions 4 indexes: 1,2,3,4.
    The value of 1 means the assumption that all distances provided in this section are symmetric, so OptiFacility expects that you provided 6 distance values.
    distances[1,2]= 51
    distances[2,1]= 51
    distances[1,3]= 52
    distances[3,1]= 52
    distances[1,4]= unchanged (-1)
    distances[4,1]= unchanged (-1)
    distances[2,3]= 54
    distances[3,2]= 54
    distances[2,4]= 55
    distances[4,2]= 55
    distances[3,4]= 56
    distances[4,3]= 56

Section 2 is [2,0,8,9,101,-1].

    It mentions 2 indexes: 8,9.
    The value of 0 means the assumption that all distances provided in this section are NOT symmetric, so OptiFacility expects that you provided 2 distance values.
    distances[8,9]= 101
    distances[9,8]= unchanged (-1)

Section 3 is [2,0,9,10,103,104].

    It mentions 2 indexes: 9,10.
    The value of 0 means the assumption that all distances provided in this section are NOT symmetric, so OptiFacility expects that you provided 2 distance values.
    distances[9,10]= 103
    distances[10,9]= 104

Section 4 is [2,1,10,8,105].

    It mentions 2 indexes: 10,8.
    The value of 1 means the assumption that all distances provided in this section are symmetric, so OptiFacility expects that you provided 1 distance value.
    distances[8,10]= 105
    distances[10,8]= 105

After applying this sequence, the following distances are modified in the matrix:

0 1 2 3 4 5 6 7 8 9 10 11
0 0,00,10,20,30,40,50,60,70,80,90,100,11
1 1,01,151521,41,51,61,71,81,91,101,11
2 2,0512,254552,52,62,72,82,92,102,11
3 3,052543,3563,53,63,73,83,93,103,11
4 4,04,155564,44,54,64,74,84,94,104,11
5 5,05,15,25,35,45,55,65,75,85,95,105,11
6 6,06,16,26,36,46,56,66,76,86,96,106,11
7 7,07,17,27,37,47,57,67,77,87,97,107,11
8 8,08,18,28,38,48,58,68,78,81011058,11
9 9,09,19,29,39,49,59,69,79,89,91039,11
10 10,010,110,210,310,410,510,610,710510410,1010,11
11 11,011,111,211,311,411,511,611,711,811,911,1011,11





In most of the examples above, indexes were sorted in each section of a sequence. This is not a requirement. However, unordered indexes do not provide any advantages over ordered indexes, yet they make the effects of applying the sequence less intuitive, as one of the examples showed.

The sections can describe parts of the matrix that overlap, but this is rarely needed.

Developers may find this sample source code in java helpful.