def bounds_on_box(a, x, b):
    Bounds, n = [None, None], len(a)
    s = pywraplp.Solver('Box', pywraplp.Solver.GLOP_LINEAR_PROGRAMMING)
    xx = [s.NumVar(x[i].Lb(), x[i].Ub(), '') for i in range(n)]
    S = s.Sum([-b] + [a[i] * xx[i] for i in range(n)])
    s.Maximize(S)
    rc = s.Solve()
    Bounds[1] = None if rc != 0 else ObjVal(s)
    s.Minimize(S)
    s.Solve()
    Bounds[0] = None if rc != 0 else ObjVal(s)
    return Bounds
Beispiel #2
0
def solve_model(Teams, params):
    (nbIntra, nbInter, nbPerWeek, nbWeeks) = params
    nbTeams = sum([1 for sub in Teams for e in sub])
    nbDiv, Cal = len(Teams), []
    s = newSolver('Sports schedule', True)
    x = [[[s.IntVar(0, 1, '') if i < j else None for _ in range(nbWeeks)]
          for j in range(nbTeams)] for i in range(nbTeams - 1)]
    for Div in Teams:
        for i in Div:
            for j in Div:
                if i < j:
                    s.Add(sum(x[i][j][w] for w in range(nbWeeks)) == nbIntra)
    for d in range(nbDiv - 1):
        for e in range(d + 1, nbDiv):
            for i in Teams[d]:
                for j in Teams[e]:
                    s.Add(sum(x[i][j][w] for w in range(nbWeeks)) == nbInter)
    for w in range(nbWeeks):
        for i in range(nbTeams):
            s.Add(sum(x[i][j][w] for j in range(nbTeams) if i<j) +
                  sum(x[j][i][w] for j in range(nbTeams) if j<i )\
                  <=nbPerWeek)
    Value=[x[i][j][w] for Div in Teams for i in Div for j in Div \
        for w in range(nbWeeks-len(Div)*nbIntra//nbPerWeek,nbWeeks)\
        if i<j]
    s.Maximize(sum(Value))
    rc = s.Solve()
    if rc == 0:
        Cal=[[(i,j) \
              for i in range(nbTeams-1) for j in range(i+1,nbTeams)\
              if SolVal(x[i][j][w])>0] for w in range(nbWeeks)]
    return rc, ObjVal(s), Cal
def solve_model(Part, Target, Cost, Inventory, D, SC, SL):
    s = newSolver('Multi-period soap blending problem')
    Oils = range(len(Part))
    Periods, Acids = range(len(Cost[0])), range(len(Part[0]))
    Buy = [[s.NumVar(0, D, '') for _ in Periods] for _ in Oils]
    Blnd = [[s.NumVar(0, D, '') for _ in Periods] for _ in Oils]
    Hold = [[s.NumVar(0, D, '') for _ in Periods] for _ in Oils]
    Prod = [s.NumVar(0, D, '') for _ in Periods]
    CostP = [s.NumVar(0, D * 1000, '') for _ in Periods]
    CostS = [s.NumVar(0, D * 1000, '') for _ in Periods]
    Acid = [[s.NumVar(0, D * D, '') for _ in Periods] for _ in Acids]
    for i in Oils:
        s.Add(Hold[i][0] == Inventory[i][0])
    for j in Periods:
        s.Add(Prod[j] == sum(Blnd[i][j] for i in Oils))
        s.Add(Prod[j] >= D)
        if j < Periods[-1]:
            for i in Oils:
                s.Add(Hold[i][j] + Buy[i][j] - Blnd[i][j] == Hold[i][j + 1])
        s.Add(sum(Hold[i][j] for i in Oils) >= SL[0])
        s.Add(sum(Hold[i][j] for i in Oils) <= SL[1])
        for k in Acids:
            s.Add(Acid[k][j] == sum(Blnd[i][j] * Part[i][k] for i in Oils))
            s.Add(Acid[k][j] >= Target[0][k] * Prod[j])
            s.Add(Acid[k][j] <= Target[1][k] * Prod[j])
        s.Add(CostP[j] == sum(Buy[i][j] * Cost[i][j] for i in Oils))
        s.Add(CostS[j] == sum(Hold[i][j] * SC for i in Oils))
    Cost_product = s.Sum(CostP[j] for j in Periods)
    Cost_storage = s.Sum(CostS[j] for j in Periods)
    s.Minimize(Cost_product + Cost_storage)
    rc = s.Solve()
    B, L, H, A = SolVal(Buy), SolVal(Blnd), SolVal(Hold), SolVal(Acid)
    CP, CS, P = SolVal(CostP), SolVal(CostS), SolVal(Prod)
    return rc, ObjVal(s), B, L, H, P, A, CP, CS
def solve_model(S, I, R, P):
    s = newSolver('Staff Scheduling', True)
    nbS, nbI, nbSets, nbPairs = len(S), len(I), len(R), len(P)
    nbC, nbT = S[-1][1] + 1, 1 + max(e[2] for e in S)
    x = [[s.IntVar(0, 1, '') for _ in range(nbS)] for _ in range(nbI)]
    z=[[[s.IntVar(0,1,'') for _ in range(len(P[p][1]))] \
          for p in range(nbPairs)] for _ in range(nbI)]
    for j in range(nbS):
        k_out_of_n(s, 1, [x[i][j] for i in range(nbI)], '<=')
    for i in range(nbI):
        s.Add(sum(x[i][j] for j in range(nbS)) >= I[i][1][0])
        s.Add(sum(x[i][j] for j in range(nbS)) <= I[i][1][1])
        for t in range(nbT):
            k_out_of_n(s, 1, [x[i][j] for j in range(nbS) if S[j][2] == t],
                       '<=')
    WC=sum(x[i][j] * I[i][2][c] for i in range(nbI) \
       for j in range(nbS) for c in range(nbC) if S[j][1] == c)
    WR=sum(I[i][3][r] * sum(x[i][j] for j in R[r][1]) \
       for r in range(nbSets) for i in range(nbI))
    for i in range(nbI):
        for p in range(nbPairs):
            if I[i][4][p] != 0:
                for k in range(len(P[p][1])):
                    xip1k0, xip1k1 = x[i][P[p][1][k][0]], x[i][P[p][1][k][1]]
                    reify(s, [1, 1], [xip1k0, xip1k1], 2, z[i][p][k], '>=')
    WP = sum(z[i][p][k]*I[i][4][p] for i in range(nbI) \
             for p in range(nbPairs) for k in range(len(P[p][1])) \
             if I[i][4][p] != 0)
    s.Maximize(WC + WR + WP)
    rc, xs = s.Solve(), ss_ret(x, z, nbI, nbSets, nbS, nbPairs, I, S, R, P)
    return rc, SolVal(x), xs, ObjVal(s)
Beispiel #5
0
def solve_model(D,Start=None, End=None):
  s,n = newSolver('Shortest path problem'),len(D)
  if Start is None: 
    Start,End = 0,len(D)-1
  G = [[s.NumVar(0,1 if D[i][j] else 0,'') for j in range(n)] for i in range(n)]
  for i in range(n): 
    if i == Start:
      s.Add(1 == sum(G[Start][j] for j in range(n))) 
      s.Add(0 == sum(G[j][Start] for j in range(n))) 
    elif i == End:
      s.Add(1 == sum(G[j][End] for j in range(n))) 
      s.Add(0 == sum(G[End][j] for j in range(n))) 
    else:
      s.Add(sum(G[i][j] for j in range(n))==sum(G[j][i] for j in range(n))) 
  Distance = s.Sum(G[i][j]*D[i][j] for i in range(n) for j in range(n)) 
  s.Minimize(Distance)
  rc = s.Solve()
  Path,Cost,Cumul,node=[Start],[0],[0],Start
  while rc == 0 and node != End and len(Path)<n:
    next = [i for i in range(n) if SolVal(G[node][i]) == 1][0]
    Path.append(next)
    Cost.append(D[node][next])
    Cumul.append(Cumul[-1]+Cost[-1])
    node = next
  return rc,ObjVal(s),Path,Cost,Cumul
def get_new_pattern(l, w):
    s = newSolver('Cutting stock slave', True)
    n = len(l)
    a = [s.IntVar(0, 100, '') for i in range(n)]
    Cost = sum(l[i] * a[i] for i in range(n))
    s.Maximize(Cost)
    s.Add(sum(w[i] * a[i] for i in range(n)) <= 100)
    rc = s.Solve()
    return SolVal(a), ObjVal(s)
def solve_diet(N):
  s = newSolver('Diet')
  nbF,nbN = len(N)-2, len(N[0])-3                          
  FMin,FMax,FCost,NMin,NMax = nbN,nbN+1,nbN+2,nbF,nbF+1                           
  f = [s.NumVar(N[i][FMin], N[i][FMax],'') for i in range(nbF)] 
  for j in range(nbN):                                    
    s.Add(N[NMin][j]<=s.Sum([f[i]*N[i][j] for i in range(nbF)]))
    s.Add(s.Sum([f[i]*N[i][j] for i in range(nbF)])<=N[NMax][j])
  s.Minimize(s.Sum([f[i]*N[i][FCost] for i in range(nbF)]))        
  rc = s.Solve()
  return rc,ObjVal(s),SolVal(f)
Beispiel #8
0
def solve_model(D):
    s = newSolver('Transshipment problem')
    n = len(D[0]) - 1
    B = sum([D[-1][j] for j in range(n)])
    G = [[s.NumVar(0,B if D[i][j] else 0,'') \
        for j in range(n)] for i in range(n)]
    for i in range(n):
        s.Add(D[i][-1] - D[-1][i] ==  \
        sum(G[i][j] for j in range(n))-sum(G[j][i]for j in range(n)))
    Cost = s.Sum(G[i][j] * D[i][j] for i in range(n) for j in range(n))
    s.Minimize(Cost)
    rc = s.Solve()
    return rc, ObjVal(s), SolVal(G)
def solve_model(D, C=None):
    t = 'Set Cover'
    s = pywraplp.Solver(t, pywraplp.Solver.CBC_MIXED_INTEGER_PROGRAMMING)
    nbSup = len(D)
    nbParts = max([e for d in D for e in d]) + 1
    S = [s.IntVar(0, 1, '') for i in range(nbSup)]
    for j in range(nbParts):
        s.Add(1 <= sum(S[i] for i in range(nbSup) if j in D[i]))
    s.Minimize(s.Sum(S[i] * (1 if C is None else C[i]) for i in range(nbSup)))
    rc = s.Solve()
    Suppliers = [i for i in range(nbSup) if SolVal(S[i]) > 0]
    Parts = [[i for i in range(nbSup) if j in D[i] and SolVal(S[i]) > 0]
             for j in range(nbParts)]
    return rc, ObjVal(s), Suppliers, Parts
Beispiel #10
0
def solve_model(D):
    s = newSolver('Mincost flow problem')
    m, n = len(D) - 1, len(D[0]) - 1
    B = sum([D[-1][j] for j in range(n)])
    G = [[s.NumVar(0,B if D[i][j] else 0,'') for j in range(n)] \
         for i in range(m)]
    for i in range(m):
        s.Add(D[i][-1] >= sum(G[i][j] for j in range(n)))
    for j in range(n):
        s.Add(D[-1][j] == sum(G[i][j] for i in range(m)))
    Cost = s.Sum(G[i][j] * D[i][j] for i in range(m) for j in range(n))
    s.Minimize(Cost)
    rc = s.Solve()
    return rc, ObjVal(s), SolVal(G)
def solve_classification(A,B):
  n,ma,mb=len(A[0]),len(A),len(B)
  s = newSolver('Classification')
  ya = [s.NumVar(0,99,'') for _ in range(ma)] 
  yb = [s.NumVar(0,99,'') for _ in range(mb)] 
  a = [s.NumVar(-99,99,'') for _ in range(n+1)] 
  for i in range(ma):
    s.Add(ya[i] >= a[n]+1-s.Sum(a[j]*A[i][j] for j in range(n))) 
  for i in range(mb):
    s.Add(yb[i] >= s.Sum(a[j]*B[i][j] for j in range(n))-a[n]+1 ) 
  Agap = s.Sum(ya[i] for i in range(ma))
  Bgap = s.Sum(yb[i] for i in range(mb))
  s.Minimize(Agap+Bgap)
  rc = s.Solve()
  return rc,ObjVal(s),SolVal(a)
Beispiel #12
0
def solve_tree_model(D,Start=None):
  s,n = newSolver('Shortest paths tree problem'),len(D)
  Start = 0 if Start is None else Start 
  G = [[s.NumVar(0,min(n,D[i][j]),'') for j in range(n)] for i in range(n)]
  for i in range(n):
    if i == Start:
      s.Add(n-1 == sum(G[Start][j] for j in range(n))) 
      s.Add(0 == sum(G[j][Start] for j in range(n))) 
    else:
      s.Add(sum(G[j][i] for j in range(n))-sum(G[i][j] for j in range(n))==1) 
  Distance = s.Sum(G[i][j]*D[i][j] for i in range(n) for j in range(n)) 
  s.Minimize(Distance)
  rc = s.Solve()
  Tree = [[i,j, D[i][j]] for i in range(n) for j in range(n) if SolVal(G[i][j])>0]
  return rc,ObjVal(s),Tree
def solve_model_eliminate(D, Subtours=[]):
    s, n = newSolver('TSP', True), len(D)
    x = [[s.IntVar(0,0 if D[i][j] is None else 1,'') \
          for j in range(n)] for i in range(n)]
    for i in range(n):
        s.Add(1 == sum(x[i][j] for j in range(n)))
        s.Add(1 == sum(x[j][i] for j in range(n)))
        s.Add(0 == x[i][i])
    for sub in Subtours:
        K = [x[sub[i]][sub[j]]+x[sub[j]][sub[i]]\
             for i in range(len(sub)-1) for j in range(i+1,len(sub))]
        s.Add(len(sub) - 1 >= sum(K))
    s.Minimize(s.Sum(x[i][j]*(0 if D[i][j] is None else D[i][j]) \
                     for i in range(n) for j in range(n)))
    rc = s.Solve()
    tours = extract_tours(SolVal(x), n)
    return rc, ObjVal(s), tours
Beispiel #14
0
def solve_model_big(Teams,params):
  (nbIntra,nbInter,nbPerWeek,nbWeeks) = params
  nbTeams = sum([1 for sub in Teams for e in sub])
  nbDiv,cuts = len(Teams),[]
  for iter in range(2): 
    s = newSolver('Sports schedule', False)
    x = [[[s.NumVar(0,1,'') if i<j else None
          for _ in range(nbWeeks)] 
          for j in range(nbTeams)] for i in range(nbTeams-1)]
    basic_model(s,Teams,nbTeams,nbWeeks,nbPerWeek,nbIntra,\
                nbDiv,nbInter,cuts,x) 
    rc = s.Solve()
    bounds = {(3,1):1, (4,1):2, (5,1):2, (5,3):7}
    if nbPerWeek <= 3:
      for w in range(nbWeeks):
        for i in range(nbTeams-2):
          for j in range(i+1,nbTeams-1):
            for k in range(j+1,nbTeams):
              b = bounds.get((3,nbPerWeek),1000)
              if sum([SolVal(x[p[0]][p[1]][w]) \
                      for p in pairs([i,j,k],[])])>b:
                cuts.append([[i,j,k],[w,b]])
                for l in range(k+1,nbTeams):
                  b = bounds.get((4,nbPerWeek),1000)
                  if sum([SolVal(x[p[0]][p[1]][w]) \
                          for p in pairs([i,j,k,l],[])])>b:                  
                    cuts.append([[i,j,k,l],[w,b]])
                  for m in range(l+1, nbTeams):
                    b = bounds.get((5,nbPerWeek),1000)                    
                    if sum([SolVal(x[p[0]][p[1]][w]) \
                            for p in pairs([i,j,k,l,m],[])])>b:
                      cuts.append([[i,j,k,l,m],[w,b]])
    else:
      break
  s = newSolver('Sports schedule', True) 
  x = [[[s.IntVar(0,1,'') if i<j else None 
        for _ in range(nbWeeks)]
        for j in range(nbTeams)] for i in range(nbTeams-1)]
  basic_model(s,Teams,nbTeams,nbWeeks,nbPerWeek,nbIntra,\
              nbDiv,nbInter,cuts,x)
  rc,Cal = s.Solve(),[]
  if rc == 0:
    Cal=[[(i,j) \
          for i in range(nbTeams-1) for j in range(i+1,nbTeams)\
          if SolVal(x[i][j][w])>0] for w in range(nbWeeks)]
  return rc,ObjVal(s),Cal
Beispiel #15
0
def solve_model(D, W, symmetry_break=False, knapsack=True):
    s = newSolver('Bin Packing', True)
    nbC, nbP = len(D), sum([P[0] for P in D])
    w = [e for sub in [[d[1]] * d[0] for d in D] for e in sub]
    nbT, nbTmin = bound_trucks(w, W)
    x = [[[s.IntVar(0,1,'')  for _ in range(nbT)] \
        for _ in range(d[0])] for d in D]
    y = [s.IntVar(0, 1, '') for _ in range(nbT)]
    for k in range(nbT):
        sxk = sum(D[i][1]*x[i][j][k] \
                  for i in range(nbC) for j in range(D[i][0]))
        s.Add(sxk <= W * y[k])
    for i in range(nbC):
        for j in range(D[i][0]):
            s.Add(sum([x[i][j][k] for k in range(nbT)]) == 1)
    if symmetry_break:
        for k in range(nbT - 1):
            s.Add(y[k] >= y[k + 1])
        for i in range(nbC):
            for j in range(D[i][0]):
                for k in range(nbT):
                    for jj in range(max(0, j - 1), j):
                        s.Add(sum(x[i][jj][kk] \
                          for kk in range(k+1)) >= x[i][j][k])
                    for jj in range(j + 1, min(j + 2, D[i][0])):
                        s.Add(sum(x[i][jj][kk] \
                          for kk in range(k,nbT))>=x[i][j][k])
    if knapsack:
        s.Add(sum(W * y[i] for i in range(nbT)) >= sum(w))
    s.Add(sum(y[k] for k in range(nbT)) >= nbTmin)
    s.Minimize(sum(y[k] for k in range(nbT)))
    rc = s.Solve()
    P2T = [[
        D[i][1],
        [
            k for j in range(D[i][0]) for k in range(nbT)
            if SolVal(x[i][j][k]) > 0
        ]
    ] for i in range(nbC)]
    T2P=[[k, [(i,j,D[i][1]) \
      for i in range(nbC) for j in range(D[i][0])\
              if SolVal(x[i][j][k])>0]] for k in range(nbT)]
    return rc, ObjVal(s), P2T, T2P
Beispiel #16
0
def solve_model(M, nf, Q=None, P=None, no_part=False):
    s = newSolver('Staffing', True)
    nbt, n = len(M) - 1, len(M[0]) - 1
    B = sum(M[t][-1] for t in range(len(M) - 1))
    x = [s.IntVar(0, B, '') for i in range(n)]
    for t in range(nbt):
        s.Add(sum([M[t][i] * x[i] for i in range(n)]) >= M[t][-1])
    if Q:
        for i in range(n):
            s.Add(x[i] >= Q[i])
    if P:
        s.Add(sum(x[i] for i in range(nf)) >= P)
    if no_part:
        for t in range(nbt):
            s.Add(B*sum([M[t][i] * x[i] for i in range(nf)]) \
                  >= sum([M[t][i] * x[i] for i in range(nf,n)]))
    s.Minimize(sum(x[i] * M[-1][i] for i in range(n)))
    rc = s.Solve()
    return rc, ObjVal(s), SolVal(x)
def solve_model(D, F):
    s = newSolver('Facility location problem', True)
    m, n = len(D) - 1, len(D[0]) - 1
    B = sum(D[-1][j]*max(D[i][j] \
      for i in range(m)) for j in range(n))
    x = [[s.NumVar(0,D[i][-1],'') for j in range(n)] \
        for i in range(m)]
    y = [s.IntVar(0, 1, '') for i in range(m)]
    Fcost, Dcost = s.NumVar(0, B, ''), s.NumVar(0, B, '')
    for i in range(m):
        s.Add(D[i][-1] * y[i] >= sum(x[i][j] for j in range(n)))
    for j in range(n):
        s.Add(D[-1][j] == sum(x[i][j] for i in range(m)))
    s.Add(sum(y[i] * F[i] for i in range(m)) == Fcost)
    s.Add(sum(x[i][j]*D[i][j] \
          for i in range(m) for j in range(n)) == Dcost)
    s.Minimize(Dcost + Fcost)
    rc = s.Solve()
    return rc,ObjVal(s),SolVal(x),SolVal(y),\
           SolVal(Fcost),SolVal(Dcost)
Beispiel #18
0
def solve_model(D,deg=1,objective=0):
  s,n = newSolver('Polynomial fitting'),len(D)
  b = s.infinity()
  a = [s.NumVar(-b,b,'a[%i]' % i) for i in range(1+deg)]  
  u = [s.NumVar(0,b,'u[%i]' % i) for i in range(n)]       
  v = [s.NumVar(0,b,'v[%i]' % i) for i in range(n)]       
  e = s.NumVar(0,b,'e')                                 
  for i in range(n):                              
    s.Add(D[i][1]==u[i]-v[i]+sum(a[j]*D[i][0]**j \
                                 for j in range(1+deg)))
  for i in range(n):                                     
    s.Add(u[i] <= e)
    s.Add(v[i] <= e)
  if objective:
    Cost = e                                               
  else:
    Cost = sum(u[i]+v[i] for i in range(n))                
  s.Minimize(Cost)
  rc = s.Solve()
  return rc,ObjVal(s),SolVal(a)
Beispiel #19
0
def solve_gas(C, D):
    s = newSolver('Gas blending problem')
    nR, nF = len(C), len(D)
    Roc, Rmax, Rcost = 0, 1, 2
    Foc, Fmin, Fmax, Fprice = 0, 1, 2, 3
    G = [[s.NumVar(0.0, 10000, '') for j in range(nF)] for i in range(nR)]
    R = [s.NumVar(0, C[i][Rmax], '') for i in range(nR)]
    F = [s.NumVar(D[j][Fmin], D[j][Fmax], '') for j in range(nF)]
    for i in range(nR):
        s.Add(R[i] == sum(G[i][j] for j in range(nF)))
    for j in range(nF):
        s.Add(F[j] == sum(G[i][j] for i in range(nR)))
    for j in range(nF):
        s.Add(F[j] *
              D[j][Foc] == s.Sum([G[i][j] * C[i][Roc] for i in range(nR)]))
    Cost = s.Sum(R[i] * C[i][Rcost] for i in range(nR))
    Price = s.Sum(F[j] * D[j][Fprice] for j in range(nF))
    s.Maximize(Price - Cost)
    rc = s.Solve()
    return rc, ObjVal(s), SolVal(G)
Beispiel #20
0
def solve_model(C,D=None,Z=False):
  s = newSolver('Multi-commodity mincost flow problem', Z)
  K,n = len(C),len(C[0])-1,
  B = [sum(C[k][-1][j] for j in range(n)) for k in range(K)]
  x = [[[s.IntVar(0,B[k] if C[k][i][j] else 0,'') \
         if Z else s.NumVar(0,B[k] if C[k][i][j] else 0,'') \
         for j in range(n)] for i in range(n)] for k in range(K)]  
  for k in range(K): 
    for i in range(n): 
      s.Add(C[k][i][-1] - C[k][-1][i] == 
            sum(x[k][i][j] for j in range(n)) - \
            sum(x[k][j][i] for j in range(n)))
  if D:
    for i in range(n):
      for j in range(n):
        s.Add(sum(x[k][i][j] for k in range(K)) <= \
              D if type(D) in [int,float] else D[i][j])
  Cost = s.Sum(C[k][i][j]*x[k][i][j] if C[k][i][j] else 0\
         for i in range(n) for j in range(n) for k in range(K)) 
  s.Minimize(Cost)
  rc = s.Solve()
  return rc,ObjVal(s),SolVal(x)
def main():
    # Test force
    bounds = []
    s = pywraplp.Solver('', pywraplp.Solver.CBC_MIXED_INTEGER_PROGRAMMING)
    a = [[0, 1], [1, 0]]
    b = [4, 5]
    x = [s.IntVar(0, 10, 'x[%i]' % i) for i in range(2)]
    bounds, delta, gamma = [], [], []
    for j in range(len(a)):
        bounds.append(bounds_on_box(a[j], x, b[j]))
        d = reify_force(s, a[j], x, b[j], rel='==')
        delta.append(d)
    s.Maximize(x[0] + x[1])
    rc = s.Solve()
    if rc == 0:
        print(rc == 0,
              ObjVal(s) == 20,
              SolVal(delta) == [0, 0],
              SolVal(x) == [10, 10])
    else:
        print(rc)
    s.Add(delta[0] == 1)
    rc = s.Solve()
    if rc == 0:
        print(rc == 0,
              ObjVal(s) == 14,
              SolVal(delta) == [1, 0],
              SolVal(x) == [10, 4])
    else:
        print(rc)
    s.Add(delta[1] == 1)
    #s.Add(a[0][0]*x[0]+a[0][1]*x[1] == b[0])
    #s.Add(a[1][0]*x[0]+a[1][1]*x[1] == b[1])
    rc = s.Solve()
    if rc == 0:
        print(rc == 0,
              ObjVal(s) == 9,
              SolVal(delta) == [1, 1],
              SolVal(x) == [5, 4])
    else:
        print(rc)

    # Test raise
    s = pywraplp.Solver('', pywraplp.Solver.CBC_MIXED_INTEGER_PROGRAMMING)
    a = [[0, 1], [1, 0]]
    b = [4, 5]
    x = [s.IntVar(0, 10, 'x[%i]' % i) for i in range(2)]
    bounds, delta, gamma = [], [], []
    for j in range(len(a)):
        bounds.append(bounds_on_box(a[j], x, b[j]))
        d = reify_raise(s, a[j], x, b[j], rel='==')
        delta.append(d)
    s.Minimize(x[0] + x[1] + delta[0] + delta[1])
    rc = s.Solve()
    if rc == 0:
        #print rc,ObjVal(s),SolVal(delta),SolVal(x)
        print(rc == 0,
              ObjVal(s) == 0,
              SolVal(delta) == [0, 0],
              SolVal(x) == [0, 0])
    else:
        print(rc)
    s.Add(a[0][0] * x[0] + a[0][1] * x[1] == b[0])
    #s.Add(delta[0] == 1)
    rc = s.Solve()
    if rc == 0:
        #print rc,ObjVal(s),SolVal(delta),SolVal(x)
        print(rc == 0,
              ObjVal(s) == 5,
              SolVal(delta) == [1, 0],
              SolVal(x) == [0, 4])
    else:
        print(rc)
    #s.Add(delta[1] == 1)
    s.Add(a[1][0] * x[0] + a[1][1] * x[1] == b[1])
    rc = s.Solve()
    if rc == 0:
        #print rc,ObjVal(s),SolVal(delta),SolVal(x)
        print(rc == 0,
              ObjVal(s) == 11,
              SolVal(delta) == [1, 1],
              SolVal(x) == [5, 4])
    else:
        print(rc)

    # Test iff
    s = pywraplp.Solver('', pywraplp.Solver.CBC_MIXED_INTEGER_PROGRAMMING)
    a = [[0, 1], [1, 0]]
    b = [4, 5]
    x = [s.IntVar(0, 10, 'x[%i]' % i) for i in range(2)]
    q = [s.IntVar(0, 1, '') for _ in range(2)]
    bounds, delta, gamma = [], [], []
    for j in range(len(a)):
        bounds.append(bounds_on_box(a[j], x, b[j]))
        d = reify(s, a[j], x, b[j], rel='==')
        delta.append(d)
    s.Minimize(x[0] + x[1])
    sosn(s, 1, q, '==')
    rc = s.Solve()
    if rc == 0:
        #print rc,ObjVal(s),SolVal(delta),SolVal(x)
        print(rc == 0,
              ObjVal(s) == 0,
              SolVal(delta) == [0, 0],
              SolVal(x) == [0, 0],
              sum(SolVal(q)) == 1)
    else:
        print(rc)
    s.Add(a[0][0] * x[0] + a[0][1] * x[1] == b[0])
    #s.Add(delta[0] == 1)
    rc = s.Solve()
    if rc == 0:
        #print rc,ObjVal(s),SolVal(delta),SolVal(x)
        print(rc == 0,
              ObjVal(s) == 4,
              SolVal(delta) == [1, 0],
              SolVal(x) == [0, 4])
    else:
        print(rc)
    #s.Add(delta[1] == 1)
    s.Add(a[1][0] * x[0] + a[1][1] * x[1] == b[1])
    rc = s.Solve()
    if rc == 0:
        #print rc,ObjVal(s),SolVal(delta),SolVal(x)
        print(rc == 0,
              ObjVal(s) == 9,
              SolVal(delta) == [1, 1],
              SolVal(x) == [5, 4])
    else:
        print(rc)