0

我正在尝试添加一个约束,该约束指定在优化中,求解器必须在设定的持续时间内选择 u 的值,并且只能在设定的时间后切换。例如,假设我有一个只能每 10 秒切换一次输入值的机械设备。然后,我希望优化器考虑到这一点。我将在这里附上代码:

        for it_i in range(0, N-1, equivalence_samples):

            print("N: {}".format(N))

            for it_j in range(0, equivalence_samples - 1):

                if (it_i + it_j + 1) > N-1:
                    print("Breaking")
                    break
                else:
                    constraint_u0 = prog.AddConstraint(u[0, it_i + it_j] == u[0, it_i + it_j + 1]) # add equivalence constraints
                    constraint_u1 = prog.AddConstraint(u[1, it_i + it_j] == u[1, it_i + it_j + 1]) # add equivalence constraints
                    print('Constraint_u_PE: {}'.format(constraint_u0))
                    print('Constraint_u_NI: {}'.format(constraint_u1))

我已经实现了这一点,我希望这是一个可行的解决方案。有时它似乎在工作,而其他时候却没有。

我将展示一些输出约束的照片,然后是一个不工作的例子。

示例约束第 1 部分

示例约束第 2 部分

然后,这里的图表清楚地表明切换时间之间存在一些界限,但这些值并不相等。我也附上了生成这个图的代码。

几乎相等的输入!!

        u_sol = result.GetSolution(u)
        u_time = np.linspace(0, N-1, num = N)
        # u_sol_trajectory = PiecewisePolynomial.ZeroOrderHold(u_time, u_sol)

        plt.figure()
        plt.plot(u_time, u_sol[0, :], 'o')
        plt.plot(u_time, u_sol[1, :], 'o')
        plt.xlabel('time steps')
        plt.ylabel('u [mcg/min]')
        plt.legend(['u_PE', 'u_NI'])
4

1 回答 1

1

在这种情况下使用的特定求解器是 OSQP 求解器。尽管在理想的求解器世界中,我在上面的代码中指定了正确的约束(输入 1 == 输入 2、输入 2 == 输入 3 等),但我没有考虑求解器具有与他们试图维护这些限制。

我可以通过更新求解器的准确性(如https://osqp.discourse.group/t/constraints-violated/143建议的那样)或输入更明确的约束来解决此问题。我用第二个选项解决了这个问题。现在,我不仅要指定如下模式的约束:

输入 1 == 输入 2,输入 2 == 输入 3,等等。

但我也包括如下模式的约束:

输入 1 == 输入 3,输入 1 == 输入 4,输入 1 == 输入 5

输入 2 == 输入 4,输入 2 == 输入 5 等等。

通过更明确,我的求解器现在正在做我所要求的,与约束的偏差很小。但是,对于我的应用程序来说,小的偏差是可以接受的!它有点慢,但这对我目前使用它来说不是问题。这是我更新的代码:


        for it_i in range(0, N-1, equivalence_samples):
            
            for it_j in range(0, equivalence_samples - 1):

                for it_f in range(1, equivalence_samples - it_j):

                    if (it_i + it_j + it_f) > N-1:
                        print("Breaking")
                        break
                    else:
                        con_0 = eq(u[:, it_i + it_j], u[:, it_i + it_j + it_f])
                        constraint_u = prog.AddConstraint(con_0) # add equivalence constraints
                        print('Constraint_u: {}'.format(constraint_u))

不是世界上最漂亮的代码,但它确实有效。

于 2020-07-31T18:27:25.663 回答