示例#1
0
 def test(self):
     x = cp.Variable(10)
     x.value = np.zeros(10)
     expr = cp.sum_squares(x)
     with self.assertRaises(AssertionError):
         sccf.minimum(-expr, 1.0)
     min_expr = sccf.minimum(expr, 1.0)
     self.assertEqual(min_expr.value, 0.0)
     x.value = np.ones(10)
     self.assertEqual(min_expr.value, 1.0)
示例#2
0
 def test(self):
     x = cp.Variable(1)
     x.value = 2 * np.ones(1)
     expr1 = sccf.minimum(cp.sum(cp.huber(x)), 1.0)
     expr2 = sccf.minimum(cp.sum(cp.huber(x - 1.0)), 1.0)
     obj = expr1 + expr2
     starting = obj.value
     prob = sccf.Problem(obj)
     ending = prob.solve()
     self.assertLessEqual(ending["final_objective_value"], starting)
示例#3
0
 def test(self):
     x = cp.Variable(10)
     x.value = np.zeros(10)
     expr1 = sccf.minimum(cp.sum_squares(x), 1.0)
     expr2 = sccf.minimum(cp.sum_squares(x - 1), 1.0)
     sum_exprs = expr1 + expr2
     self.assertEqual(len(sum_exprs.min_exprs), 2)
     self.assertEqual(sum_exprs.value, 1.0)
     sum_exprs += 1.0
     self.assertEqual(sum_exprs.value, 2.0)
     sum_exprs += cp.sum_squares(x - 1)
     self.assertEqual(sum_exprs.value, 12.0)
示例#4
0
文件: subset_sum.py 项目: cvxgrp/sccf
import cvxpy as cp
import sccf
import numpy as np

np.random.seed(3) # fishy?
a = np.random.randint(-50, 50, size=5)
idx = np.random.choice(np.arange(5), size=3, replace=False)
a = np.append(
    a,
    -int(np.sum(a[idx]))
)
n = a.size

print("a =", a)

x = cp.Variable(n)
objective = 0.0
for i in range(n):
    objective += sccf.minimum(cp.square(x[i]), 0.25)
    objective += sccf.minimum(cp.square(x[i] - 1.0), 0.25)
objective += cp.square(a*x) - n/4
constraints = [cp.sum(x) >= 1.0]

prob = sccf.Problem(objective, constraints)
print("Alternating minimization:")
result = prob.solve(maxiter=50, verbose=True, warm_start_lam=np.random.uniform(0.0, 1.0, size=2*n+2), solver=cp.MOSEK)

print("objective value = %.3f" % result["final_objective_value"])
print("x =", np.around(x.value))
示例#5
0
def main(show):
    # generate data
    np.random.seed(243)
    m, n = 5, 1
    n_outliers = 1
    eta = 0.1
    alpha = 0.5
    A = np.random.randn(m, n)
    x_true = np.random.randn(n)
    b = A @ x_true + 1e-1 * np.random.randn(m)
    b[np.random.choice(np.arange(m), replace=False, size=n_outliers)] *= -1.

    # alternating
    x_alternating = cp.Variable(n)
    objective = 0.0
    for i in range(m):
        objective += sccf.minimum(cp.square(A[i]@x_alternating-b[i]), alpha)
    objective += eta * cp.sum_squares(x_alternating)
    prob = sccf.Problem(objective)
    prob.solve()

    # solve relaxed problem
    x_relaxed = cp.Variable(n)
    z = [cp.Variable(n) for _ in range(m)]
    s = cp.Variable(m)
    objective = 0.0
    constraints = [0 <= s, s <= 1]
    for i in range(m):
        objective += cp.quad_over_lin(A[i, :] @ z[i] - b[i] * s[i], s[i]) + (1.0 - s[i]) * alpha  + \
                    eta / m * (cp.quad_over_lin(x_relaxed - z[i], 1.0 - s[i]) + eta / m * cp.quad_over_lin(z[i], s[i]))
    prob = cp.Problem(cp.Minimize(objective), constraints)
    result = prob.solve(solver=cp.MOSEK)

    # alternating w/ relaxed initialization
    x_alternating_perspective = cp.Variable(n)
    x_alternating_perspective.value = x_relaxed.value
    objective = 0.0
    for i in range(m):
        objective += sccf.minimum(cp.square(A[i]@x_alternating_perspective-b[i]), alpha)
    objective += eta * cp.sum_squares(x_alternating_perspective)
    prob = sccf.Problem(objective)
    prob.solve(warm_start=True)

    # brute force evaluate function and perspective
    xs = np.linspace(-5, 5, 100)
    f = np.sum(np.minimum(np.square(A * xs - b[:, None]), alpha), axis=0) + eta*xs**2
    f_persp = []
    for x in xs:
        z = [cp.Variable(n) for _ in range(m)]
        s = cp.Variable(m)

        objective = 0.0
        constraints = [0 <= s, s <= 1]
        for i in range(m):
            objective += cp.quad_over_lin(A[i, :] @ z[i] - b[i] * s[i], s[i]) + (1.0 - s[i]) * alpha + \
                        eta / m * (cp.quad_over_lin(x - z[i], 1.0 - s[i]) + eta / m * cp.quad_over_lin(z[i], s[i]))
        prob = cp.Problem(cp.Minimize(objective), constraints)
        result = prob.solve(solver=cp.MOSEK)
        f_persp.append(result)

    def find_nearest(array, value):
        array = np.asarray(array)
        idx = (np.abs(array - value)).argmin()
        return idx 

    # plot
    latexify(fig_width=6, fig_height=4)
    plt.plot(xs, f, '-', label="$L(x)$", c='k')
    plt.plot(xs, f_persp, '--', label="perspective", c='k')
    plt.plot(x_alternating.value[0], )
    plt.scatter(x_alternating.value[0], f[find_nearest(xs, x_alternating.value[0])], marker='o', label="sccf (no init)", c='k')
    plt.scatter(x_alternating_perspective.value[0], f[find_nearest(xs, x_alternating_perspective.value[0])], marker='*', label="sccf (persp init)", c='k')
    plt.legend()
    plt.xlabel("$x$")
    plt.savefig("figs/perspective.pdf")
    if show:
        plt.show()
示例#6
0
def main(show=False):
    margin = .05  # margin for drawing box

    initial_pos = 1
    final_pos = 1

    n = 100

    all_pos = np.linspace(0, 1, n)

    # Complicated lane example

    box_size = .18
    box_pos = [.2, .5, .8]
    box_orientation = [-1, 1, -1]

    x = cp.Variable(n)

    cons = [x[0] == initial_pos, -2 <= x, x <= 2, x[-1] == -1]

    obj = 0.0

    for i, pos in enumerate(all_pos):
        obj += sccf.minimum(cp.square(x[i] + 1), 1)
        obj += sccf.minimum(cp.square(x[i] - 1), 1)

        for b_pos, b_or in zip(box_pos, box_orientation):
            if b_pos <= pos and pos <= b_pos + box_size:
                cons.append(x[i] >= 0 if b_or > 0 else x[i] <= 0)

    for idx, weight in enumerate([10, 1, .1]):
        obj += weight * cp.sum_squares(cp.diff(x, k=idx + 1))

    prob = sccf.Problem(obj, cons)
    tic = time.time()
    result = prob.solve()
    toc = time.time()

    print("lane change 2:", obj.value)
    print("time:", toc - tic)
    print("iters:", result["iters"])

    latexify(fig_width=7, fig_height=2)
    plt.plot(all_pos * 100, x.value, c='black')
    plt.ylim(-2, 2)
    for pos, orientation in zip(box_pos, box_orientation):
        plt.gca().add_patch(
            Rectangle((pos * 100, .25 if orientation < 0 else -1.75),
                      (box_size - margin) * 100,
                      1.5,
                      facecolor='none',
                      edgecolor='k'))
    plt.axhline(0, ls='--', c='k')
    plt.savefig("figs/lane_changing.pdf")
    if show:
        plt.show()

    # Lower bound
    obj = 0

    z_top = [cp.Variable(n) for _ in range(n)]
    z_bottom = [cp.Variable(n) for _ in range(n)]

    x = cp.Variable(n)
    cons = [x[0] == initial_pos, -2 <= x, x <= 2, x[-1] == -1]

    lam_top = cp.Variable(n)
    lam_bottom = cp.Variable(n)
    cons.append(0 <= lam_top)
    cons.append(0 <= lam_bottom)
    cons.append(lam_top <= 1)
    cons.append(lam_bottom <= 1)

    for z, lam in zip(z_top + z_bottom, lam_top + lam_bottom):
        cons.append(z[0] == initial_pos * lam)
        cons.append(-2 * lam <= z)
        cons.append(z <= 2 * lam)
        cons.append(z[-1] == -1 * lam)

    for i, pos in enumerate(all_pos):
        obj += cp.quad_over_lin(z_top[i][i] + lam_top[i],
                                lam_top[i]) + (1 - lam_top[i])
        obj += cp.quad_over_lin(z_bottom[i][i] - lam_bottom[i],
                                lam_bottom[i]) + (1 - lam_bottom[i])

        for b_pos, b_or in zip(box_pos, box_orientation):
            if b_pos <= pos and pos <= b_pos + box_size:
                for z in z_top + z_bottom + [x]:
                    cons.append(z[i] >= 0 if b_or > 0 else z[i] <= 0)

    for idx, weight in enumerate([10, 1, .1]):
        for z, lam in zip(z_top + z_bottom, lam_top + lam_bottom):
            obj += weight * cp.quad_over_lin(cp.diff(z, k=idx + 1),
                                             lam) / (2 * n)
            obj += weight * cp.quad_over_lin(cp.diff(x - z, k=idx + 1),
                                             1 - lam) / (2 * n)

    prob = cp.Problem(cp.Minimize(obj), cons)
    obj_value = prob.solve(solver=cp.MOSEK)

    print("lane change lower bound:", obj_value)

    # MICP
    obj = 0

    z_top = [cp.Variable(n) for _ in range(n)]
    z_bottom = [cp.Variable(n) for _ in range(n)]

    x = cp.Variable(n)
    cons = [x[0] == initial_pos, -2 <= x, x <= 2, x[-1] == -1]

    lam_top = cp.Variable(n, boolean=True)
    lam_bottom = cp.Variable(n, boolean=True)

    for z, lam in zip(z_top + z_bottom, lam_top + lam_bottom):
        cons.append(z[0] == initial_pos * lam)
        cons.append(-2 * lam <= z)
        cons.append(z <= 2 * lam)
        cons.append(z[-1] == -1 * lam)

    for i, pos in enumerate(all_pos):
        obj += cp.quad_over_lin(z_top[i][i] + lam_top[i],
                                lam_top[i]) + (1 - lam_top[i])
        obj += cp.quad_over_lin(z_bottom[i][i] - lam_bottom[i],
                                lam_bottom[i]) + (1 - lam_bottom[i])

        for b_pos, b_or in zip(box_pos, box_orientation):
            if b_pos <= pos and pos <= b_pos + box_size:
                for z in z_top + z_bottom + [x]:
                    cons.append(z[i] >= 0 if b_or > 0 else z[i] <= 0)

    for idx, weight in enumerate([10, 1, .1]):
        for z, lam in zip(z_top + z_bottom, lam_top + lam_bottom):
            obj += weight * cp.quad_over_lin(cp.diff(z, k=idx + 1),
                                             lam) / (2 * n)
            obj += weight * cp.quad_over_lin(cp.diff(x - z, k=idx + 1),
                                             1 - lam) / (2 * n)

    prob = cp.Problem(cp.Minimize(obj), cons)
    import sys
    while True:
        answer = input(
            "Are you sure you would like to solve the MICP (y/n) ").lower()

        if answer == "y":
            break
        elif answer == "n":
            return
        else:
            print("Invalid answer.")
            continue

    obj_value = prob.solve(solver=cp.MOSEK, verbose=True)

    print("global optimum:", obj_value)