#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) «