Python 如何计算「;AddAbsEquality“;或;AddMultiplicationEqualit“;使用谷歌&x27;s CP-SAT非线性优化求解器?

Python 如何计算「;AddAbsEquality“;或;AddMultiplicationEqualit“;使用谷歌&x27;s CP-SAT非线性优化求解器?,python,optimization,or-tools,cp-sat-solver,Python,Optimization,Or Tools,Cp Sat Solver,我的目标是根据预测的序列恢复数据序列。假设原始数据序列是xu org=[10,20,30,40,50],但我收到的随机数据是xu ran=[50,40,20,10,30]。现在,我的目标是通过保持模式最接近原始模式来恢复模式(最小化恢复损失) 我使用了一种与谷歌或谷歌工具网站上提供的“与工人团队一起分配任务”和“解决优化问题”几乎相似的方法[https://developers.google.com/optimization/assignment/assignment_teams]及[https

我的目标是根据预测的序列恢复数据序列。假设原始数据序列是xu org=[10,20,30,40,50],但我收到的随机数据是xu ran=[50,40,20,10,30]。现在,我的目标是通过保持模式最接近原始模式来恢复模式(最小化恢复损失)

我使用了一种与谷歌或谷歌工具网站上提供的“与工人团队一起分配任务”和“解决优化问题”几乎相似的方法[https://developers.google.com/optimization/assignment/assignment_teams]及[https://developers.google.com/optimization/cp/integer_opt_cp]

我可以最小化损失总和(误差),但不能计算平方和/绝对和


from ortools.sat.python import cp_model

x_org = [10, 20, 30, 40, 50]
x_ran = [50, 40, 20, 10, 30]
n = len(x_org)


model = cp_model.CpModel()

# Defidning recovered data
x_rec = [model.NewIntVar(0, 10000, 'x_rec_%i') for i in range(n)]

# Defidning recovery loss        
x_loss = [model.NewIntVar(0, 10000, 'x_loss_%i' % i) for i in range(n)]

# Defining a (recovery) mapping matrix 
M = {}
for i in range(n):
    for j in range(n):
        M[i, j] = model.NewBoolVar('M[%i,%i]' % (i, j)) 
    
# -----------------Constraints---------------%
# Each sensor is assigned one unique measurement.
for i in range(n):
    model.Add(sum([M[i, j] for j in range(n)]) == 1)

# Each measurement is assigned one unique sensor.
for j in range(n):
    model.Add(sum([M[i, j] for i in range(n)]) == 1)


# Recovering the remapped data x_rec=M*x_ran (like, Ax =b)
for i in range(n):   
    model.Add(x_rec[i] == sum([M[i,j]*x_ran[j] for j in range(n)]))

# Loss = orginal data - recovered data
for i in range(n):
    x_loss[i] = x_org[i] - x_rec[i]

    
# minimizing recovery loss
model.Minimize(sum(x_loss))

#--------------- Calling solver -------------%

# Solves and prints out the solution.
solver = cp_model.CpSolver()
status = solver.Solve(model)

print('Solve status: %s' % solver.StatusName(status))

if status == cp_model.OPTIMAL:
    print('Optimal objective value: %i' % solver.ObjectiveValue())
    for i in range(n):
        print('x_loss[%i] = %i' %(i,solver.Value(x_loss[i]))) 
则无绝对误差和的输出为:

Solve status: OPTIMAL
Optimal objective value: 0
x_loss[0] = -10
x_loss[1] = -30
x_loss[2] = 0
x_loss[3] = 30
x_loss[4] = 10

这表明即使损失之和为零,恢复也不正确。然而,当我试图添加另一个int变量来存储丢失的绝对值时(如下所示),编译器给出了一个错误

# Defidning abs recovery loss        
x_loss_abs = [model.NewIntVar(0, 10000, 'x_loss_abs_%i' % i) for i in range(n)] 
# Loss = orginal data - recovered data
for i in range(n):
    model.AddAbsEquality(x_loss_abs[i], x_loss[i])
    #model.AddMultiplicationEquality(x_loss_abs[i], [x_loss[i], x_loss[i]])
错误是回溯为:

TypeError                                 Traceback (most recent call last)
<ipython-input-42-2a043a8fef8b> in <module>
      3 # Loss = orginal data - recovered data
      4 for i in range(n):
----> 5     model.AddAbsEquality(x_loss_abs[i], x_loss[i])

~/anaconda3/envs/tensorgpu/lib/python3.7/site-packages/ortools/sat/python/cp_model.py in AddAbsEquality(self, target, var)
   1217         ct = Constraint(self.__model.constraints)
   1218         model_ct = self.__model.constraints[ct.Index()]
-> 1219         index = self.GetOrMakeIndex(var)
   1220         model_ct.int_max.vars.extend([index, -index - 1])
   1221         model_ct.int_max.target = self.GetOrMakeIndex(target)

~/anaconda3/envs/tensorgpu/lib/python3.7/site-packages/ortools/sat/python/cp_model.py in GetOrMakeIndex(self, arg)
   1397         else:
   1398             raise TypeError('NotSupported: model.GetOrMakeIndex(' + str(arg) +
-> 1399                             ')')
   1400 
   1401     def GetOrMakeBooleanIndex(self, arg):

TypeError: NotSupported: model.GetOrMakeIndex((-x_rec_%i + 10))
TypeError回溯(最近一次调用)
在里面
3#丢失=原始数据-恢复的数据
对于范围(n)内的i,为4:
---->5.模型添加平均值(x_损失_abs[i],x_损失[i])
AddAbsEquality(self、target、var)中的~/anaconda3/envs/tensorgpu/lib/python3.7/site-packages/ortools/sat/python/cp_model.py
1217 ct=约束(自身模型约束)
1218 model\u ct=self.\u model.constraints[ct.Index()]
->1219索引=self.GetOrMakeIndex(var)
1220型号ct.int\U最大变量扩展([index,-index-1])
1221 model_ct.int_max.target=self.GetOrMakeIndex(目标)
GetOrMakeIndex中的~/anaconda3/envs/tensorgpu/lib/python3.7/site-packages/ortools/sat/python/cp_model.py(self,arg)
1397其他:
1398 raise TypeError('不支持:model.GetOrMakeIndex('+str(arg))+
-> 1399                             ')')
1400
1401 def GetOrMakeBooleanIndex(自身,参数):
TypeError:不支持:model.GetOrMakeIndex(-x\u rec\u%i+10))

你能建议如何使恢复损失的绝对和/平方和最小化吗?谢谢。

AddAbsEquality
要求参数是变量(而不是表达式,如
x_org[i]-x_rec[i]
。因此,在使用它之前必须创建一个临时决策变量(此处为
v
)。以下操作似乎有效:

# ...
x_loss_abs = [model.NewIntVar(0, 10000, 'x_loss_abs_%i' % i) for i in range(n)]

# ...
for i in range(n):
   # x_loss[i] = x_org[i] - x_rec[i] # Original
   v = model.NewIntVar(-1000,1000,"v") # Temporary variable
   model.Add(v == x_org[i] - x_rec[i] )
   model.AddAbsEquality(x_loss_abs[i],v)

# ....
model.Minimize(sum(x_loss_abs))
然后解决方案是(我更改了输出):


AddAbsEquality
要求参数是变量(而不是像
x_org[i]-x_rec[i]
这样的表达式)。因此,在使用它之前必须创建一个临时决策变量(这里是
v
)。下面的方法似乎有效:

# ...
x_loss_abs = [model.NewIntVar(0, 10000, 'x_loss_abs_%i' % i) for i in range(n)]

# ...
for i in range(n):
   # x_loss[i] = x_org[i] - x_rec[i] # Original
   v = model.NewIntVar(-1000,1000,"v") # Temporary variable
   model.Add(v == x_org[i] - x_rec[i] )
   model.AddAbsEquality(x_loss_abs[i],v)

# ....
model.Minimize(sum(x_loss_abs))
然后解决方案是(我更改了输出):


在我看来,您最初计算的
x_损失
需要是绝对值。您试图最小化的错误量应该是无符号的。
x_损失[i]=abs(x_组织[i]-x_记录[i])
是的,这就是我试图做的,但在实现过程中出现了一个错误。@hakank的评论显示了如何实现绝对值。在我看来,您最初对x_损失的计算应该是绝对值。您试图最小化的错误量应该是无符号的。
x_损失[I]=abs(x_组织[I]-x_rec[i])
是的,这就是我试图做的,但在实现中出现了错误。现在,@hakank的注释显示了如何实现绝对值。