Commit 91340630 by Michael Keller

### Proof savepoint

parent 9eb9696d
 import cvxpy as cp # X = 5 # Y = 5 # R = lambda a, b: [[-1, 0, 0.5, -0.5, 1, 0, 0.5, 1, 0.5, 0], # [0, -1, 0, 1, 0, 0, 0.5, 0.5, 0.5, 0], # [0.5, 0, -1, 0, 0, 0, 0.5, 0.5, 0, -0.5], # [-0.5, 1, 0, -1, 0, 0, -1, 0.5, 0.5, 0.5], # [0, 0, 0, 0, -1, 0, 0, 0, 0, 0], # [0, 0, 0, 0, 0, -1, 1, 0.5, 0, 0], # [0.5, 0.5, 0.5, -0.5, 0, 0.5, -1, 0.5, 0.5, 0.5], # [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], # [0.5, 0.5, 0, 1, 0, 0, 0.5, 0.5, -1, 0], # [0, 0, -0.5, 0.5, 0, 0, 1, 0.5, 0.5, -1]][a][b] # dist = [2,2,2,2,2,3,3,3,3,3] X = 1 Y = 4 R = lambda a, b: 1 dist = [2,2] def get_ind(p, c): return numb_crops * p + c def get_neighbors(p): neighbors = [] for n1 in range(-1, 2): for n2 in range(-1, 2): if n1 == 0 and n2 == 0: continue n = (p[0] + n1, p[1] + n2) if 0 <= n[0] and 0 <= n[1] and n[0] < X and n[1] < Y: neighbors.append(n) return neighbors numb_crops = len(dist) pixels = [(i, j) for i in range(X) for j in range(Y)] def main(): x = cp.Variable(shape=(X * Y * numb_crops,), pos=True, name="x") constraints = [] # constrain crop amounts in a pixel for p in range(X * Y): monomial = 1 for c in range(numb_crops): monomial *= x[p * numb_crops + c] constraints.append(x[p * numb_crops + c] <= 1) constraints.append(monomial == 1) # constrain global crop amounts for c in range(numb_crops): constr = 0 for p in range(X * Y): constr += x[p * numb_crops + c] constraints.append(constr <= dist[c]) # objective function obj = 0 for i, pA in enumerate(pixels): neighbors = get_neighbors(pA) for pB in neighbors: j = neighbors.index(pB) for cA in range(numb_crops): for cB in range(numb_crops): obj += x[get_ind(i, cA)] * x[get_ind(j, cB)] * R(cA, cB + 0.01) constraints.append(obj <= 0.000001) problem = cp.Problem(cp.Maximize(x[0]), constraints) problem.solve(gp=True) print("Optimal value:", problem.value) print(x, ":", x.value) main() \ No newline at end of file
This diff is collapsed.
 import numpy as np import gurobipy as gp from gurobipy import GRB # test if the quadratic constraint is spd A = np.array([[9,7],[6,14]]) R = lambda a, b: [[-1, 0, 0.5, -0.5, 1, 0, 0.5, 1, 0.5, 0], [0, -1, 0, 1, 0, 0, 0.5, 0.5, 0.5, 0], [0.5, 0, -1, 0, 0, 0, 0.5, 0.5, 0, -0.5], [-0.5, 1, 0, -1, 0, 0, -1, 0.5, 0.5, 0.5], [0, 0, 0, 0, -1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, -1, 1, 0.5, 0, 0], [0.5, 0.5, 0.5, -0.5, 0, 0.5, -1, 0.5, 0.5, 0.5], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0.5, 0.5, 0, 1, 0, 0, 0.5, 0.5, -1, 0], [0, 0, -0.5, 0.5, 0, 0, 1, 0.5, 0.5, -1]][a][b] # auto calculate some vars numb_crops = len(dist) pixels = [(i, j) for i in range(X) for j in range(Y)] Rnew = lambda a, b: R(i, j) + 99999999999999999 # print(np.linalg.eigvals(A) >= -0.000001) # # Helper functions # def get_ind(p, c): return numb_crops * p + c def get_neighbors(p): neighbors = [] for n1 in range(-1, 2): for n2 in range(-1, 2): if n1 == 0 and n2 == 0: continue n = (p[0] + n1, p[1] + n2) if 0 <= n[0] and 0 <= n[1] and n[0] < X and n[1] < Y: neighbors.append(n) return neighbors # # The interesting stuff # def main(): # define the score function obj = [] ind = 0 for pA in pixels: neighbors = get_neighbors(pA) for pB in neighbors: for cA in range(numb_crops): for cB in range(numb_crops): if get_ind(pA, pB, cA, cB) is None: obj.append(-(R(cA, cB) + R(cB, cA))) obj = np.array(obj) n = len(obj) # Build the QP m = gp.Model("qp") x = m.addMVar(n, lb=[0.0 for _ in obj], ub=[1.0 for _ in obj]) m.setObjective(obj @ x) np.all(np.linalg.eigvals(A) >= 0) \ No newline at end of file main() \ No newline at end of file
 ... ... @@ -129,5 +129,201 @@ statement with a condition on $R$ might be helpful: met to ensure that swapping in either direction even among neighboring pixels is never detrimental. l Let us consider the change in the score function when swapping $c_\alpha, c_\beta \in \Cps$ between two neighboring pixels $u$ and $v$. Let $F$ denote the field before the swap and $F'$ after. Further let $p_c$ denote the amount of crop $c$ within pixel $p$ in the field before the swap. $p'_c$ is defined analogously for the field after the swap. Lastly let $N(p)$ denote the set containing all of pixel $p$'s neighbors. \begin{align*} \Delta S &= S(F', R) - S(F, R)\\ &= \sum_{x \in F} \sum_{y \in N(x)} \sum_{c_i \in \Cps} \sum_{c_j \in \Cps} R(c_i, c_j) \cdot x'_{c_i} \cdot y'_{c_j}\\ &- \sum_{x \in F} \sum_{y \in N(x)} \sum_{c_i \in \Cps} \sum_{c_j \in \Cps} R(c_i, c_j) \cdot x_{c_i} \cdot y_{c_j}\\ &= \sum_{x \in F} \sum_{y \in N(x)} \sum_{c_i \in \Cps} \sum_{j \in \Cps} R(c_i, c_j) \cdot (x'_{c_i} \cdot y'_{c_j} - x_{c_i} \cdot y_{c_j}) \end{align*} Because we are only swapping between two pixels, we can drop the terms where $p'_c = p_c$ as these are $0$. We therefore only need to sum up the relationships involving at least one of either $u$ or $v$: \begin{align*} \Delta S &= \sum_{y \in N(u)} \sum_{c_i \in \Cps} \sum_{c_j \in \Cps} (R(c_i, c_j) + R(c_j, c_i)) \cdot (u'_{c_i} \cdot y'_{c_j} - u_{c_i} \cdot y_{c_j})\\ &+ \sum_{y \in N(v) \setminus x} \sum_{c_i \in \Cps} \sum_{c_j \in \Cps} (R(c_i, c_j) + R(c_j, c_i)) \cdot (v'_{c_i} \cdot y'_{c_j} - v_{c_i} \cdot y_{c_j}) \end{align*} In a next step we separate out the crops we are swapping from the sum: $c_\alpha$ and $c_\beta$. Of particular interest in these long formulas are mainly the sets over which we are summing. \begin{align*} \Delta S &= \sum_{y \in N(u)} \ \sum_{c_i \in \{c_\alpha, c_\beta\}} \ \sum_{c_j \in \{c_\alpha, c_\beta\}} \ (R(c_i, c_j) + R(c_j, c_i)) \cdot (u'_{c_i} \cdot y'_{c_j} - u_{c_i} \cdot y_{c_j})\\ &+ \sum_{y \in N(u)} \ \sum_{c_i \in \{c_\alpha, c_\beta\}} \ \sum_{c_j \in \Cps \setminus \{c_\alpha, c_\beta\}} \ (R(c_i, c_j) + R(c_j, c_i)) \cdot (u'_{c_i} \cdot y'_{c_j} - u_{c_i} \cdot y_{c_j})\\ &+ \sum_{y \in N(v) \setminus x} \ \sum_{c_i \in \{c_\alpha, c_\beta\}} \ \sum_{c_j \in \{c_\alpha, c_\beta\}} \ (R(c_i, c_j) + R(c_j, c_i)) \cdot (v'_{c_i} \cdot y'_{c_j} - v_{c_i} \cdot y_{c_j}) \\ &+ \sum_{y \in N(v) \setminus x} \ \sum_{c_i \in \{c_\alpha, c_\beta\}} \ \sum_{c_j \in \Cps \setminus \{c_\alpha, c_\beta\}} \ (R(c_i, c_j) + R(c_j, c_i)) \cdot (v'_{c_i} \cdot y'_{c_j} - v_{c_i} \cdot y_{c_j}) \end{align*} Which lets us simplify even further some variables that stay the same: \begin{align*} \Delta S &= \sum_{y \in N(u)} \ \sum_{c_i \in \{c_\alpha, c_\beta\}} \ \sum_{c_j \in \{c_\alpha, c_\beta\}} \ (R(c_i, c_j) + R(c_j, c_i)) \cdot (u'_{c_i} \cdot y'_{c_j} - u_{c_i} \cdot y_{c_j})\\ &+ \sum_{y \in N(u)} \ \sum_{c_i \in \{c_\alpha, c_\beta\}} \ \sum_{c_j \in \Cps \setminus \{c_\alpha, c_\beta\}} \ (R(c_i, c_j) + R(c_j, c_i)) \cdot ((u'_{c_i} - u_{c_i}) \cdot y_{c_j})\\ &+ \sum_{y \in N(v) \setminus x} \ \sum_{c_i \in \{c_\alpha, c_\beta\}} \ \sum_{c_j \in \{c_\alpha, c_\beta\}} \ (R(c_i, c_j) + R(c_j, c_i)) \cdot (v'_{c_i} \cdot y'_{c_j} - v_{c_i} \cdot y_{c_j}) \\ &+ \sum_{y \in N(v) \setminus x} \ \sum_{c_i \in \{c_\alpha, c_\beta\}} \ \sum_{c_j \in \Cps \setminus \{c_\alpha, c_\beta\}} \ (R(c_i, c_j) + R(c_j, c_i)) \cdot ((v'_{c_i} - v_{c_i}) \cdot y_{c_j}) \end{align*} And from the way we shift crops we know: \begin{align*} u'_{c_\alpha} &= u_{c_\alpha} - \lambda & u'_{c_\beta} &= u_{c_\beta} + \lambda\\ v'_{c_\alpha} &= v_{c_\alpha} + \lambda & v'_{c_\beta} &= v_{c_\beta} - \lambda \end{align*} Therefore we can conclude that the second and fourth term are linear functions in $\lambda$. Next we further split up the $c_\alpha, c_\beta$ sums to be able to apply our $p'$ definitions from above: \begin{align*} \Delta S &= \sum_{y \in N(u)} \ \sum_{c_j \in \{c_\alpha, c_\beta\}} \ (R(c_\alpha, c_j) + R(c_j, c_\alpha)) \cdot (u'_{c_\alpha} \cdot y'_{c_j} - u_{c_\alpha} \cdot y_{c_j})\\