Python или инструменты минимизируют сумму квадратов различий

#python #python-3.x #or-tools

#python #python-3.x #или-инструменты

Вопрос:

Я новичок в Google ortools, и я пытаюсь использовать cp_model для решения этой проблемы:

У меня есть матрица «агенты» размером d x s (мои переменные решения), матрица перехода «shifts_coverage» размером s x p и объективная матрица «objective» размером d x p. Я хочу минимизировать

введите описание изображения здесь

где «*» обозначает умножение матрицы. Итак, я написал

 model.Minimize(sum(np.power([np.dot(agents, shifts_coverage) - objetive]),2))
  

агенты — это a model.NewIntVar , а «shifts_coverage» и «objective» являются фиксированными входными матрицами.

Однако я получаю сообщение об ошибке, в котором говорится TypeError: unsupported operand type(s) for ** or pow(): '_SumArray' and 'int' , что если я удалю np.power, ошибка есть is not a valid objective . Поэтому я не уверен, как следует определять эту объектную функцию, чтобы иметь ожидаемый формат от ortools. Я также видел что-то под названием model.AddAbsEquality , кажется, это связано, но я не смог успешно реализовать это в этой объектной функции

Спасибо!

РЕДАКТИРОВАТЬ: я пытался использовать промежуточные переменные, как было предложено, но поскольку я хочу минимизировать квадратную разницу, я попробовал что-то вроде этого

  • Выразите квадратную разницу как умножение абсолютных значений, поскольку мои матрицы являются положительными введите описание изображения здесь

  • Для термина агенты * shifts_coverage я добавил еще одну переменную с именем shifted_agents как

shifted_agents [d][p] = sum([agents[d][s] * shifts_coverage[s][p] for s in range(num_shifts)])

Помните, что shifts_coverage[s][p] — это просто bool, а агенты [d] [s] — это модель.NewIntVar (я думаю, это может быть проблемой)

  • Для абсолютного значения используется трюк с промежуточными переменными с
 abs_difference[d][p] = model.NewIntVar(0, 100, f'abs_difference_d{d}p{p}')
model.AddAbsEquality(abs_difference[d][p], shifted_agents[d][p] - objetive[d][p])
  

Идея после этого заключается в реализации AddMultiplicationEquality с abs_difference, но пока я получаю эту ошибку:

 TypeError('NotSupported: model.GetOrMakeIndex('   str(arg)  
TypeError: NotSupported: model.GetOrMakeIndex((((agents_d0s2))   -objetive_d0p0))
  

Примечание: я удалил циклы for, но оставил индексы, чтобы понять размеры матрицы

Ответ №1:

Плюс AddMultiplicationEquality для создания промежуточных переменных.

То есть

 model.Minimize(a**2   b**2) 
  

Это не будет работать напрямую, так как цель, а также добавляемые вами уравнения должны быть линейными.

 square_a = model.NewIntVar(0, max_a**2, 'square_a')
model.AddMultiplicationEquality(square_a, [a, a])
square_b = model.NewIntVar(0, max_b**2, 'square_b')
model.AddMultiplicationEquality(square_b, [b, b])
model.Minimize(square_a   square_b)
  

сделает свое дело.

Комментарии:

1. Спасибо Лорен за ваш ответ, не могли бы вы немного подробнее рассказать о том, как связаны эти методы и как их следует передавать? Это должно было бы добавить равенство для каждой «строки»?. Извините, я новичок в ortools и все еще пытаюсь понять, как все связано

2. Спасибо, Лоран, я попробую!

3. Привет, Лоран, я думаю, что знаю, как реализовать трюк с промежуточными переменными с помощью ortools, не могли бы вы взглянуть на мое оригинальное редактирование поста? Я думаю, что ошибка на самом деле заключается в умножении моих переменных решения на входную матрицу. Спасибо!

4. AddAbsEquality принимает две переменные. Вам нужно создать другую временную переменную difference == shifted_agents[d][p] - objetive[d][p] .

5. Я уже пытался создать эту временную переменную, но ошибка остается прежней. agents_abs_difference[d][s] = model.NewIntVar(0, max_relative_agents, f'agents_difference_d{d}s{s}') agents_difference[d][s] == agents[d][s] - objetive[d][s] #Также попытался сделать это NewIntVar и добавить вычитание в качестве ограничения. « модель. AddAbsEquality(agents_abs_difference [d] [s], agents_difference) «