Самый эффективный способ построения матрицы затрат для линейного назначения суммы? - PullRequest
1 голос
/ 20 апреля 2020

Предположим, что мы хотим решить линейное назначение суммы с помощью scipy, а стоимость задания может быть построена из евклидовых расстояний.

Таким образом, из m рабочих W=[j_1, ..., j_m] и n задач T=[t_1, ..., t_n], матрица затрат задается как

cost_matrix = np.array([
    [np.linalg.norm(x - y) for x in W] for y in T
])

Это выглядит тяжелым в вычислительном отношении и не очень эффективным. Есть ли какой-нибудь тупой / скучный способ сделать это лучше и быстрее?


Рабочий пример:

import numpy as np
from scipy.optimize import linear_sum_assignment

np.random.seed(0)

# define tasks 
t = np.random.rand(5)

# define workers
w = np.random.rand(3)

cost_matrix = np.array([[np.linalg.norm(x-y) for x in w] for y in t])  
>>> linear_sum_assignment(cost_matrix)
(array([1, 2, 4]), array([2, 0, 1]))

Ответы [ 2 ]

2 голосов
/ 20 апреля 2020

Я верю, что вы ищете cdist. Scipy cdist

Y = cdist(XA, XB, 'euclidean')

Вот ваш пример с рабочим кодом:

import numpy as np
from scipy.optimize import linear_sum_assignment
from scipy.spatial.distance import cdist

np.random.seed(0)

# define tasks 
t = np.random.rand(5)

# define workers
w = np.random.rand(3)

# cost_matrix = np.array([[np.linalg.norm(x-y) for x in w] for y in t])  
cost_matrix = cdist(np.array([t]).T, np.array([w]).T, 'euclidean')
linear_sum_assignment(cost_matrix)
1 голос
/ 20 апреля 2020

Это может быть не самый эффективный способ, но итерация передается numpy, поэтому это может быть быстрее:

import numpy as np
from scipy.optimize import linear_sum_assignment

np.random.seed(0)

# define tasks 
t = np.random.rand(5)

# define workers
w = np.random.rand(3)

W, T = np.meshgrid(w, t)
cost_matrix = abs(T-W)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...