PySCIPOpt  4.3.0
Python Interface for the SCIP Optimization Suite
even.py
Go to the documentation of this file.
1 
3 """
4 Public Domain, WTFNMFPL Public Licence
5 """
6 from pyscipopt import Model
7 from pprint import pformat as pfmt
8 
9 example_values = [
10  0,
11  1,
12  1.5,
13  "helloworld",
14  20,
15  25,
16  -101,
17  -15.,
18  -10,
19  -2**31,
20  -int(2**31),
21  "2**31-1",
22  int(2**31-1),
23  int(2**63)-1
24 ]
25 
26 verbose = False
27 #verbose = True # uncomment for additional info on variables!
28 sdic = {0: "even", 1: "odd"} # remainder to 2
29 
30 def parity(number):
31  """
32  Prints if a value is even/odd/neither per each value in a example list
33 
34  This example is made for newcomers and motivated by:
35  - modulus is unsupported for pyscipopt.scip.Variable and int
36  - variables are non-integer by default
37  Based on this: #172#issuecomment-394644046
38 
39  Args:
40  number: value which parity is checked
41 
42  Returns:
43  sval: 1 if number is odd, 0 if number is even, -1 if neither
44  """
45  sval = -1
46  if verbose:
47  print(80*"*")
48  try:
49  assert number == int(round(number))
50  m = Model()
51  m.hideOutput()
52 
53  # x and n are integer, s is binary
54  # Irrespective to their type, variables are non-negative by default
55  # since 0 is the default lb. To allow for negative values, give None
56  # as lower bound.
57  # (None means -infinity as lower bound and +infinity as upper bound)
58  x = m.addVar("x", vtype="I", lb=None, ub=None) #ub=None is default
59  n = m.addVar("n", vtype="I", lb=None)
60  s = m.addVar("s", vtype="B")
61  # CAVEAT: if number is negative, x's lower bound must be None
62  # if x is set by default as non-negative and number is negative:
63  # there is no feasible solution (trivial) but the program
64  # does not highlight which constraints conflict.
65 
66  m.addCons(x==number)
67 
68  # minimize the difference between the number and twice a natural number
69  m.addCons(s == x-2*n)
70  m.setObjective(s)
71  m.optimize()
72 
73  assert m.getStatus() == "optimal"
74  boolmod = m.getVal(s) == m.getVal(x)%2
75  if verbose:
76  for v in m.getVars():
77  print("%*s: %d" % (fmtlen, v,m.getVal(v)))
78  print("%*d%%2 == %d?" % (fmtlen, m.getVal(x), m.getVal(s)))
79  print("%*s" % (fmtlen, boolmod))
80 
81  xval = m.getVal(x)
82  sval = m.getVal(s)
83  sstr = sdic[sval]
84  print("%*d is %s" % (fmtlen, xval, sstr))
85  except (AssertionError, TypeError):
86  print("%*s is neither even nor odd!" % (fmtlen, number.__repr__()))
87  finally:
88  if verbose:
89  print(80*"*")
90  print("")
91  return sval
92 
93 if __name__ == "__main__":
94  """
95  If positional arguments are given:
96  the parity check is performed on each of them
97  Else:
98  the parity check is performed on each of the default example values
99  """
100  import sys
101  from ast import literal_eval as leval
102  try:
103  # check parity for each positional arguments
104  sys.argv[1]
105  values = sys.argv[1:]
106  except IndexError:
107  # check parity for each default example value
108  values = example_values
109  # format lenght, cosmetics
110  fmtlen = max([len(fmt) for fmt in pfmt(values,width=1).split('\n')])
111  for value in values:
112  try:
113  n = leval(value)
114  except (ValueError, SyntaxError): # for numbers or str w/ spaces
115  n = value
116  parity(n)
even.parity
def parity(number)
Definition: even.py:28