source: mystic/examples2/olympic.py @ 855

Revision 855, 3.4 KB checked in by mmckerns, 5 months ago (diff)

updated copyright to 2016

Line 
1#!/usr/bin/env python
2#
3# Problem definition:
4# Example in google/or-tools
5# https://github.com/google/or-tools/blob/master/examples/python/olympic.py
6# with Copyright 2010 Hakan Kjellerstrand hakank@bonetmail.com
7# and disclamer as stated at the above reference link.
8#
9# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
10# Copyright (c) 1997-2016 California Institute of Technology.
11# License: 3-clause BSD.  The full license text is available at:
12#  - http://mmckerns.github.io/project/mystic/browser/mystic/LICENSE
13"""
14  Olympic puzzle in Google CP Solver.
15
16  Prolog benchmark problem
17  '''
18  Name   : olympic.pl
19  Author : Neng-Fa
20  Date   : 1993
21
22  Purpose: solve a puzzle taken from Olympic Arithmetic Contest
23
24  Given ten variables with the following configuration:
25
26                 X7   X8   X9   X10
27
28                    X4   X5   X6
29
30                       X2   X3
31
32                          X1
33
34  We already know that X1 is equal to 3 and want to assign each variable
35  with a different integer from {1,2,...,10} such that for any three
36  variables
37                        Xi   Xj
38
39                           Xk
40  the following constraint is satisfied:
41
42                      |Xi-Xj| = Xk
43  '''
44"""
45
46def objective(x):
47    return 0.0
48
49n = 10
50
51bounds = [(1,n)]*n
52# with penalty='penalty' applied, solution is:
53xs = [[3, 7, 4, 2, 9, 5, 8, 10, 1, 6],
54      [3, 7, 4, 2, 8, 5, 10, 9, 1, 6],
55      [3, 2, 5, 7, 9, 4, 8, 1, 10, 6],
56      [3, 5, 2, 4, 9, 7, 6, 10, 1, 8],
57      [3, 4, 7, 5, 1, 8, 6, 10, 9, 2],
58      [3, 4, 7, 5, 8, 1, 6, 2, 10, 9],
59      [3, 4, 7, 5, 9, 2, 6, 1, 10, 8]]
60ys = 0.0
61
62# constraints
63def penalty1(x): # == 0
64    return x[0] - 3
65
66def penalty2(x): # == 0
67    return abs(x[1] - x[2]) - x[0]
68
69def penalty3(x): # == 0
70    return abs(x[3] - x[4]) - x[1]
71
72def penalty4(x): # == 0
73    return abs(x[4] - x[5]) - x[2]
74
75def penalty5(x): # == 0
76    return abs(x[6] - x[7]) - x[3]
77
78def penalty6(x): # == 0
79    return abs(x[7] - x[8]) - x[4]
80
81def penalty7(x): # == 0
82    return abs(x[8] - x[9]) - x[5]
83
84
85from mystic.penalty import quadratic_equality
86from mystic.constraints import as_constraint
87
88@quadratic_equality(penalty1)
89@quadratic_equality(penalty2)
90@quadratic_equality(penalty3)
91@quadratic_equality(penalty4)
92@quadratic_equality(penalty5)
93@quadratic_equality(penalty6)
94@quadratic_equality(penalty7)
95def penalty(x):
96    return 0.0
97
98solver = as_constraint(penalty)
99
100
101from mystic.constraints import unique
102
103from numpy import round, hstack, clip
104def constraint(x):
105    x = round(x).astype(int) # force round and convert type to int
106    x = clip(x, 1,n)         #XXX: impose bounds
107    x = unique(x, range(1,n+1))
108    return x
109
110
111if __name__ == '__main__':
112
113    from mystic.solvers import diffev2
114    from mystic.math import almostEqual
115    from mystic.monitors import Monitor, VerboseMonitor
116    mon = VerboseMonitor(10)#,10)
117
118    result = diffev2(objective, x0=bounds, bounds=bounds, penalty=penalty, constraints=constraint, npop=50, ftol=1e-8, gtol=200, disp=True, full_output=True, cross=0.1, scale=0.9, itermon=mon)
119
120    print result[0]
121    assert almostEqual(result[0], xs[0], tol=1e-8) \
122        or almostEqual(result[0], xs[1], tol=1e-8) \
123        or almostEqual(result[0], xs[2], tol=1e-8) \
124        or almostEqual(result[0], xs[3], tol=1e-8) \
125        or almostEqual(result[0], xs[4], tol=1e-8) \
126        or almostEqual(result[0], xs[-1], tol=1e-8)
127    assert almostEqual(result[1], ys, tol=1e-4)
128
129
130# EOF
Note: See TracBrowser for help on using the repository browser.