def test_airline(self): # Create problem data. E = 6 C = 2 P = 6 u = numpy.random.randint(10, 20, E) p = numpy.random.rand(P) d_mu = 100 * numpy.ones(P) # Not used d_Sigma = 0.01 * numpy.eye(P) # Not used m = 10 # Num samples A = [self.get_A(i, E, P) for i in range(C)] # Create optimization variables. x = [NonNegative(E) for i in range(C)] y = NonNegative(P) # Create second stage problem. capacity = [A[i] * y <= x[i] for i in range(C)] d = RandomVariable(pymc.Lognormal(name="d", mu=0, tau=1, size=P)) p2 = Problem(Minimize(-y.T * p), [y <= d] + capacity) Q = partial_optimize(p2, [y], [x[0], x[1]]) # Create and solve first stage problem. p1 = Problem(Minimize(expectation(Q, m)), [sum(x) <= u]) p1.solve() self.assert_feas(p1)
def test_variable_repr(self): x = Variable(name='x') y = NonNegative(name='y') self.assertEqual(repr(x), "Variable(1, 1, 'x')") self.assertEqual(repr(y), "NonNegative(1, 1, 'y')") x = Variable() y = NonNegative() self.assertEqual(repr(x), "Variable(1, 1)") self.assertEqual(repr(y), "NonNegative(1, 1)")
def test_assign_var_value(self): """Test assigning a value to a variable. """ # Scalar variable. a = Variable() a.value = 1 self.assertEqual(a.value, 1) with self.assertRaises(Exception) as cm: a.value = [2, 1] self.assertEqual(str(cm.exception), "Invalid dimensions (2, 1) for Variable value.") # Test assigning None. a.value = 1 a.value = None assert a.value is None # Vector variable. x = Variable(2) x.value = [2, 1] self.assertItemsAlmostEqual(x.value, [2, 1]) # Matrix variable. A = Variable(3, 2) A.value = np.ones((3, 2)) self.assertItemsAlmostEqual(A.value, np.ones((3, 2))) # Test assigning negative val to nonnegative variable. x = NonNegative() with self.assertRaises(Exception) as cm: x.value = -2 self.assertEqual(str(cm.exception), "Invalid sign for NonNegative value.") # Small negative values are rounded to 0. x.value = -1e-8 self.assertEqual(x.value, 0)
def __init__(self, constr, num_samples, phi=Phi.HINGE): self.constr = constr self.num_samples = num_samples self.phi = phi if self.phi == Phi.HINGE: self.alpha = NonNegative(1)
def test_news_vendor(self): # Create problem data. c, s, r, b = 10, 25, 5, 150 d_probs = [0.5, 0.5] d_vals = [55, 139] d = CategoricalRandomVariable(d_vals, d_probs) # Create optimization variables. x = NonNegative() y, z = NonNegative(), NonNegative() # Create second stage problem. obj = -s * y - r * z constrs = [y + z <= x, z <= d] # Putting these constrs in breaks the test: # y<=d, z<=d p2 = Problem(Minimize(obj), constrs) Q = partial_optimize(p2, [y, z], [x]) # Create and solve first stage problem p1 = Problem(Minimize(c * x + expectation(Q, want_de=True)), [x <= b]) p1.solve() # Solve problem the old way (i.e., deterministic equivalent) as a check. x = Variable() y1 = Variable() y2 = Variable() z1 = Variable() z2 = Variable() p3 = Problem( Minimize(c * x + 0.5 * (-r * y1 - s * z1) + 0.5 * (-r * y2 - s * z2)), [ 0 <= x, x <= b, 0 <= y1, 0 <= z1, 0 <= y2, 0 <= z2, y1 + z1 <= x, y2 + z2 <= x ]) # Putting these constrs in breaks the test: # y1 <= 55, y2 <= 139, z1 <= 55, z2 <= 139 p3.solve() self.assertAlmostEqual(p1.value, p3.value, 4)
def test_robust_svm(self): # Create problem data. m = 100 # num train points m_pos = math.floor(m / 2) m_neg = m - m_pos n = 2 # num dimensions mu_pos = 2 * numpy.ones(n) mu_neg = -2 * numpy.ones(n) sigma = 1 X = numpy.matrix( numpy.vstack((mu_pos + sigma * numpy.random.randn(m_pos, n), mu_neg + sigma * numpy.random.randn(m_neg, n)))) y = numpy.hstack((numpy.ones(m_pos), -1 * numpy.ones(m_neg))) C = 1 # regularization trade-off parameter ns = 50 eta = 0.1 # Create and solve optimization problem. w, b, xi = Variable(n), Variable(), NonNegative(m) constr = [] Sigma = 0.1 * numpy.eye(n) for i in range(m): mu = numpy.array(X[i])[0] x = NormalRandomVariable(mu, Sigma) chance = prob(-y[i] * (w.T * x + b) >= (xi[i] - 1), ns) constr += [chance <= eta] p = Problem(Minimize(norm(w, 2) + C * sum_entries(xi)), constr) p.solve(verbose=True) w_new = w.value b_new = b.value # Create and solve the canonical SVM problem. constr = [] for i in range(m): constr += [y[i] * (X[i] * w + b) >= (1 - xi[i])] p2 = Problem(Minimize(norm(w, 2) + C * sum_entries(xi)), constr) p2.solve() w_old = w.value b_old = b.value self.assert_feas(p)
def test_cvar(self): # Create problem data. n = 10 pbar, Sigma = numpy.random.randn(n), numpy.eye(n) p = RandomVariableFactory().create_normal_rv(pbar, Sigma) u, eta, m = numpy.random.rand(), 0.95, 100 # Create optimization variables. x, beta = NonNegative(n), Variable() # Create and solve optimization problem. cvar = expectation(pos(-x.T * p - beta), m) cvar = beta + 1 / (1 - eta) * cvar prob = Problem(Minimize(expectation(-x.T * p, m)), [x.T * numpy.ones((n, 1)) == 1, cvar <= u]) prob.solve() self.assert_feas(prob)
def test_nonnegative_variable(self): x = NonNegative() p = Problem(Minimize(5+x),[x>=3]) p.solve() self.assertAlmostEqual(p.value,8) self.assertAlmostEqual(x.value,3)
def test_dc_power(self): # Load problem data. fp = "pf_dc/pf_dc.mat" data = scipy.io.loadmat(fp) A = data.get("A") n, E = A.shape gen_idxes = data.get("gen_idxes") wind_idxes = data.get("wind_idxes") load_idxes = data.get("load_idxes") num_gens = gen_idxes.size num_winds = wind_idxes.size num_loads = load_idxes.size gen_idxes = gen_idxes.reshape( num_gens) - 1 # "-1" to switch from Matlab to Python indexing wind_idxes = wind_idxes.reshape(num_winds) - 1 load_idxes = load_idxes.reshape(num_loads) - 1 c_g = data.get("c_g") temp = c_g[0] c_g[0] = c_g[1] c_g[1] = temp c_w = data.get("c_w") p = data.get("p").reshape(n) p_orig = p u_lines = 1 # Note: depending on the choice of this # (and the realizations of p_w below, the # problem may or may not be feasible, so be # careful u_gens = 1 m = 100 # Num samples # Create optimization variables. p_g1, p_g2 = NonNegative(), NonNegative() z = NonNegative(num_winds) p_lines = Variable(E) p_w = RandomVariable( pymc.Lognormal(name="p_w", mu=1, tau=1, size=num_winds)) # Create second stage problem. p_g = vstack(p_g1, p_g2) p = vstack(p_g1, p_g2, p[load_idxes[:-1]], p_w - z, p[load_idxes[-1]]) p2 = Problem(Minimize(p_g.T * c_g + z.T * c_w), [ A * p_lines == p, p_g <= u_gens, z <= p_w, abs(p_lines) <= u_lines ]) Q = partial_optimize(p2, [p_g2, z, p_lines], [p_g1]) # Create and solve first stage problem. p1 = Problem(Minimize(expectation(Q, m))) p1.solve() # Plot results. B_binary = data.get("B_binary") coords = data.get("coords") coords[0, 0] += 0.1 # Drawing was getting clipped in Python... # Draw edges between vertices. fig = pyplot.figure() for i in range(n - 1): for j in range(i + 1, n): if B_binary[i, j] == 1: pyplot.plot((coords[i, 0], coords[j, 0]), (coords[i, 1], coords[j, 1]), '-k') # Draw symbols and power generation/consumption for each vertex. lognorm_mean = math.exp(1 + pow(1, 2) / 2.0) fs = 16 shift_x = 0 shift_y = 0.125 for i in range(n): if i in gen_idxes: pyplot.plot(coords[i, 0], coords[i, 1], color="crimson", marker="s", markersize=12) if i == 0: pyplot.text(coords[i, 0] + shift_x, coords[i, 1] + shift_y, "{0:.2f}".format(p_g1.value), fontsize=fs) else: pyplot.text(coords[i, 0] + shift_x, coords[i, 1] + shift_y, "sec. stg.", fontsize=fs) elif i in wind_idxes: pyplot.plot(coords[i, 0], coords[i, 1], color="blue", marker="s", markersize=12) pyplot.text(coords[i, 0] + shift_x, coords[i, 1] + shift_y, "{0:.2f}".format(lognorm_mean), fontsize=fs) else: pyplot.plot(coords[i, 0], coords[i, 1], 'ko') pyplot.text(coords[i, 0] + shift_x, coords[i, 1] + shift_y, "{0:.2f}".format(p_orig[i]), fontsize=fs) # pyplot.axis([0, 4, 0, 3]) pyplot.axis("off") fig.savefig("grid.png", bbox_inches="tight") # Check results. self.assert_feas(p1)