Streamlined Travel Planning

I have a problem to solve.

Problem Statement :

I have about 5,000 stores with geo-coordinates. Each store must be visited once to collect an order from the store.

This will be done by the seller.

I want to generate N optimized travel plans so that every seller can cover the maximum. stores within 8 hours .

In terms of travel, the time taken to visit all stores should not exceed 8 hours.

and no seller should visit the same store.

Once shopping should not be visited again in another travel plan.

In this case, the number of generated travel plans is indirectly zero. from sellers.

Desired end result :

Minimize the number. travel plan to cover all stores

What I have:

Matrix storage distance to the store. which has remote coverage and time between each store

Challange : I do not have any information about the seller (I have no geographic locations), which makes it difficult to choose a starting point for each Travel Plan.

My initial thoughts:

I am going to divide stores into different regions using clustering. and then make a travel plan for each cluster (for an optimized route).

I will develop this in python.

Any ideas on what would be the best way to try and get started on such a problem.

+4
source share
1 answer

Here is a heuristic idea:

  • . (, ), , 0 .
  • , s1 s2, t.
  • a1 a2, s1 s2. ​​ ( , s1 s2 - ), 2.
  • t_sum , a1, , a2 t. t_sum t, (8 ), 2.
  • a1 a2 . , . , a1 s1 a2 s2, , a1 s1 a2 s2, () a1, . t_sum.
  • 2. , .

. , , , , a1 a2, / . , :

  • a1 a2 s1 s2, a1 a2. , 1 2, [1, 3, 4] [2] ( [2, 1, 3, 4] [4, 3, 1, 2]), 1, , 2, .
  • a1 a2, T - t_sum < t, ( t), "" ", , , ( ), a1 a2 3.
  • , , , t "" t, "" , .

EDIT:

Python. NumPy , , , , .

def make_journeys(dists, max_dist):
    n = len(dists)
    ds = sorted((dists[i][j], i, j) for i in range(n) for j in range(i + 1, n))
    starts = list(range(n))
    ends = list(range(n))
    salesmen = [([i], 0) for i in range(n)]
    for d, i, j in ds:
        if starts[i] is not None and starts[j] is not None:
            si, sj = starts[i], starts[j]
            reverse_i, reverse_j = True, False
        elif starts[i] is not None and ends[j] is not None:
            si, sj = starts[i], ends[j]
            reverse_i, reverse_j = True, True
        elif ends[i] is not None and starts[j] is not None:
            si, sj = ends[i], starts[j]
            reverse_i, reverse_j = False, False
        elif ends[i] is not None and ends[j] is not None:
            si, sj = ends[i], ends[j]
            reverse_i, reverse_j = False, True
        else:
            continue
        if si == sj:
            continue
        (pi, di) = salesmen[si]
        (pj, dj) = salesmen[sj]
        dt = d + di + dj
        if dt > max_dist:
            continue
        starts[pi[0]] = None
        ends[pi[-1]] = None
        starts[pj[0]] = None
        ends[pj[-1]] = None
        if reverse_i:
            pi = list(reversed(pi))
        if reverse_j:
            pj = list(reversed(pj))
        pt = pi + pj
        starts[pt[0]] = si
        ends[pt[-1]] = si
        salesmen[si] = (pt, dt)
        salesmen[sj] = None
    return [s for s in salesmen if s]

. :

def random_symmetric(N, min, max):
    # Build a random symmetric matrix
    dists = [[random.randint(1, 9) if i != j else 0 for j in range(N)] for i in range(N)]
    return [[(dists[i][j] + dists[j][i]) // 2 for j in range(N)] for i in range(N)]

random.seed(100)

# This takes long!
distances = random_symmetric(5000, 1, 9)
max_distance = 100

journeys = make_journeys(distances, max_distance)
print('{} journeys computed.'.format(len(journeys)))

:

50 journeys computed.

( NumPy). make_journeys ~ 16 . , YMMV, .

0

Source: https://habr.com/ru/post/1694959/


All Articles