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