diff --git "a/sample_submission.jsonl" "b/sample_submission.jsonl" new file mode 100644--- /dev/null +++ "b/sample_submission.jsonl" @@ -0,0 +1,141 @@ +{"id": "csplib__csplib_001_car_sequencing", "model": "# Data\nat_most = [1, 2, 2, 2, 1] # The amount of times a property can be present\n# in a group of consecutive timeslots (see next variable)\nper_slots = [2, 3, 3, 5, 5] # The amount of consecutive timeslots\ndemand = [1, 1, 2, 2, 2, 2] # The demand per type of car\nrequires = [[1, 0, 1, 1, 0],\n [0, 0, 0, 1, 0],\n [0, 1, 0, 0, 1],\n [0, 1, 0, 1, 0],\n [1, 0, 1, 0, 0],\n [1, 1, 0, 0, 0]] # The properties per type of car\n# End of data\n\n# Import libraries\nfrom cpmpy import *\nimport json\n\n# Parameters\nn_cars = sum(demand) # The amount of cars to sequence\nn_options = len(at_most) # The amount of different options\nn_types = len(demand) # The amount of different car types\nrequires = cpm_array(requires) # For element constraint\n\n# Decision Variables\nsequence = intvar(0, n_types - 1, shape=n_cars, name=\"sequence\") # The sequence of car types\nsetup = boolvar(shape=(n_cars, n_options), name=\"setup\") # Sequence of different options based on the car type\n\n# Model\nmodel = Model()\n\n# The amount of each type of car in the sequence has to be equal to the demand for that type\nmodel += [sum(sequence == t) == demand[t] for t in range(n_types)]\n\n# Make sure that the options in the setup table correspond to those of the car type\nfor s in range(n_cars):\n model += [setup[s, o] == requires[sequence[s], o] for o in range(n_options)]\n\n# Check that no more than \"at most\" car options are used per \"per_slots\" slots\nfor o in range(n_options):\n for s in range(n_cars - per_slots[o]):\n slot_range = range(s, s + per_slots[o])\n model += (sum(setup[slot_range, o]) <= at_most[o])\n\n# Solve\nmodel.solve()\n\n# Print\nsolution = {\"sequence\": sequence.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "csplib__csplib_002_template_design", "model": "# Data\nn_slots = 9 # The amount of slots on a template\nn_templates = 2 # The amount of templates\nn_var = 7 # The amount of different variations\ndemand = [250, 255, 260, 500, 500, 800, 1100] # The demand per variation\n# End of data\n\n# Import libraries\nfrom cpmpy import *\nimport json\n\n# Parameters\nub = max(demand) # The upper bound for the production\n\n# create model\nmodel = Model()\n\n# decision variables\nproduction = intvar(1, ub, shape=n_templates, name=\"production\")\nlayout = intvar(0, n_var, shape=(n_templates, n_var), name=\"layout\")\n\n# all slots are populated in a template\nmodel += all(sum(layout[i]) == n_slots for i in range(n_templates))\n\n# meet demand\nfor var in range(n_var):\n model += sum(production * layout[:, var]) >= demand[var]\n\n# break symmetry\n# equal demand\nfor i in range(n_var - 1):\n if demand[i] == demand[i + 1]:\n model += layout[0, i] <= layout[0, i + 1]\n for j in range(n_templates - 1):\n model += (layout[j, i] == layout[j, i + 1]).implies(layout[j + 1, i] <= layout[j + 1, i + 1])\n\n# distinguish templates\nfor i in range(n_templates - 1):\n model += production[i] <= production[i + 1]\n\n# static symmetry\nfor i in range(n_var - 1):\n if demand[i] < demand[i + 1]:\n model += sum(production * layout[:, i]) <= sum(production * layout[:, i + 1])\n\n# minimize number of printed sheets\nmodel.minimize(sum(production))\n\n# Solve\nmodel.solve()\n\n# Print\nsolution = {\"production\": production.value().tolist(), \"layout\": layout.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "csplib__csplib_005_autocorrelation", "model": "# Data\nn = 10 # Length of the binary sequence\n# End of data\n\n# Import libraries\nfrom cpmpy import *\nimport numpy as np\nimport json\n\n\n# periodic auto correlation\ndef PAF(arr, s):\n # roll the array 's' indices\n return sum(arr * np.roll(arr, -s))\n\n\n# Decision Variables\nsequence = intvar(-1, 1, shape=n, name=\"sequence\") # binary sequence\nE = sum([PAF(sequence, s) ** 2 for s in range(1, n)]) # energy value\n\nmodel = Model()\n\n# exclude 0\nmodel += sequence != 0\n\n# minimize sum of squares\nmodel.minimize(E)\n\n# Solve\nmodel.solve()\n\n# Print\nsolution = {\"sequence\": sequence.value().tolist(), \"E\": E.value()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "csplib__csplib_006_golomb_rulers", "model": "# Data\nsize = 10 # Number of marks on the Golomb ruler\n# End of data\n\n# Import libraries\nfrom cpmpy import *\nimport json\n\n# Decision variables\nmarks = intvar(0, size * size, shape=size, name=\"marks\")\nlength = marks[-1]\n\n# Model\nmodel = Model()\n\n# first mark is 0\nmodel += (marks[0] == 0)\n\n# marks must be increasing\nmodel += marks[:-1] < marks[1:]\n\n# golomb constraint\ndiffs = [marks[j] - marks[i] for i in range(0, size - 1) for j in range(i + 1, size)]\nmodel += AllDifferent(diffs)\n\n# Symmetry breaking\nmodel += (marks[size - 1] - marks[size - 2] > marks[1] - marks[0])\nmodel += (diffs[0] < diffs[size - 1])\n\n# find optimal ruler\nmodel.minimize(length)\n\n# Solve\nmodel.solve()\n\n# Print\nsolution = {\"marks\": marks.value().tolist(), \"length\": length.value()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "csplib__csplib_007_all_interval", "model": "# Data\nn = 12 # Number of pitch-classes\n# End of data\n\n# Import libraries\nfrom cpmpy import *\nimport numpy as np\nimport json\n\n# Create the solver\nmodel = Model()\n\n# Declare variables\nx = intvar(0, n - 1, shape=n, name=\"x\") # Pitch-classes\ndiffs = intvar(1, n - 1, shape=n - 1, name=\"diffs\") # Intervals\n\n# Constraints\nmodel += [AllDifferent(x),\n AllDifferent(diffs)]\n\n# Differences between successive values\nmodel += diffs == np.abs(x[1:] - x[:-1])\n\n# Symmetry breaking\nmodel += [x[0] < x[-1]] # Mirroring array is equivalent solution\nmodel += [diffs[0] < diffs[1]] # Further symmetry breaking\n\n# Solve\nmodel.solve()\n\n# Print\nsolution = {\"x\": x.value().tolist(), \"diffs\": diffs.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "csplib__csplib_008_vessel_loading", "model": "# Data\ndeck_width = 5 # Width of the deck\ndeck_length = 5 # Length of the deck\nn_containers = 3 # Number of containers\nwidth = [5, 2, 3] # Widths of containers\nlength = [1, 4, 4] # Lengths of containers\nclasses = [1, 1, 1] # Classes of containers\nseparation = [ # Separation constraints between classes\n [0, 0],\n [0, 0]\n]\n# End of data\n\n# Import libraries\nfrom cpmpy import *\nimport json\nfrom cpmpy.expressions.utils import all_pairs\n\n# Create the model\nmodel = Model()\n\n# Declare variables\nleft = intvar(0, deck_width, shape=n_containers, name=\"left\")\nright = intvar(0, deck_width, shape=n_containers, name=\"right\")\ntop = intvar(0, deck_length, shape=n_containers, name=\"top\")\nbottom = intvar(0, deck_length, shape=n_containers, name=\"bottom\")\n\n# Set shape of containers\nfor i in range(n_containers):\n model += ((right[i] - left[i] == width[i]) & (top[i] - bottom[i] == length[i])) | \\\n ((right[i] - left[i] == length[i]) & (top[i] - bottom[i] == width[i]))\n\n# No overlap between containers\nfor x, y in all_pairs(range(n_containers)):\n c1, c2 = classes[x], classes[y]\n sep = separation[c1 - 1][c2 - 1]\n model += (\n (right[x] + sep <= left[y]) | # x at least sep left of y or\n (left[x] >= right[y] + sep) | # x at least sep right of y or\n (top[x] + sep <= bottom[y]) | # x at least sep under y or\n (bottom[x] >= top[y] + sep) # x at least sep above y\n )\n\n# Solve\nmodel.solve()\n\n# Print\nsolution = {\n \"left\": left.value().tolist(),\n \"right\": right.value().tolist(),\n \"top\": top.value().tolist(),\n \"bottom\": bottom.value().tolist()\n}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "csplib__csplib_009_perfect_square_placement", "model": "# Data\nbase = 6 # Side length of the large square\nsides = [3, 3, 3, 2, 1, 1, 1, 1, 1] # Side lengths of the smaller squares\n# End of data\n\n# Import libraries\nimport json\nimport numpy as np\nfrom cpmpy import *\nfrom cpmpy.expressions.utils import all_pairs\n\ndef perfect_squares(base, sides):\n model = Model()\n sides = np.array(sides)\n\n squares = range(len(sides))\n\n # Ensure that the squares cover the base exactly\n assert np.square(sides).sum() == base ** 2, \"Squares do not cover the base exactly!\"\n\n # Variables\n x_coords = intvar(0, base, shape=len(squares), name=\"x_coords\")\n y_coords = intvar(0, base, shape=len(squares), name=\"y_coords\")\n\n # Squares must be in bounds of big square\n model += x_coords + sides <= base\n model += y_coords + sides <= base\n\n # No overlap between squares\n for a, b in all_pairs(squares):\n model += (\n (x_coords[a] + sides[a] <= x_coords[b]) |\n (x_coords[b] + sides[b] <= x_coords[a]) |\n (y_coords[a] + sides[a] <= y_coords[b]) |\n (y_coords[b] + sides[b] <= y_coords[a])\n )\n\n return model, (x_coords, y_coords)\n\n# Example usage\nmodel, (x_coords, y_coords) = perfect_squares(base, sides)\n\n# Solve\nmodel.solve()\n\n# Print\nsolution = {\n \"x_coords\": x_coords.value().tolist(),\n \"y_coords\": y_coords.value().tolist()\n}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "csplib__csplib_010_social_golfers_problem", "model": "# Data\nn_weeks = 4 # Number of weeks\nn_groups = 3 # Number of groups\ngroup_size = 3 # Size of each group\n# End of data\n\n# Import libraries\nfrom cpmpy import *\nfrom cpmpy.expressions.utils import all_pairs\nimport numpy as np\nimport json\n\n\ndef social_golfers(n_weeks, n_groups, group_size):\n\n n_golfers = n_groups * group_size\n golfers = np.arange(n_golfers)\n weeks = np.arange(n_weeks)\n groups = np.arange(n_groups)\n\n # Possible configurations\n assign = intvar(0, n_groups - 1, shape=(n_golfers, n_weeks), name=\"assign\")\n\n model = Model()\n\n # C1: Each group has exactly group_size players\n for gr in groups:\n for w in weeks:\n model += sum(assign[:, w] == gr) == group_size\n\n # C2: Each pair of players only meets at most once\n for g1, g2 in all_pairs(golfers):\n model += sum(assign[g1] == assign[g2]) <= 1\n\n # SBSA: Symmetry-breaking by selective assignment\n # On the first week, the first group_size golfers play in group 1, the\n # second group_size golfers play in group 2, etc. On the second week,\n # golfer 1 plays in group 1, golfer 2 plays in group 2, etc.\n # model += [assign[:, 0] == (golfers // group_size)]\n\n for g in golfers:\n if g < group_size:\n model += [assign[g, 1] == g]\n\n # First golfer always in group 0\n model += [assign[0, :] == 0]\n\n return model, assign\n\n# Example usage\nmodel, assign = social_golfers(n_weeks, n_groups, group_size)\n\n# Solve\nmodel.solve()\n\n# Print\nsolution = {\n \"assign\": assign.value().tolist()\n}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "csplib__csplib_011_acc_basketball_schedule", "model": "# Data\nn_teams = 9\nn_days = 18\n# End of data\n\n# Import libraries\nfrom cpmpy import *\nimport numpy as np\nimport json\n\n\ndef basketball_schedule():\n n_teams = 9\n n_days = 18\n\n # Teams\n teams = np.arange(n_teams)\n CLEM, DUKE, FSU, GT, UMD, UNC, NCSt, UVA, WAKE = teams\n rivals = [GT, UNC, FSU, CLEM, UVA, DUKE, WAKE, UMD, NCSt]\n\n # Days\n days = np.arange(n_days)\n weekdays = np.where(days % 2 == 0)[0]\n weekends = np.where(days % 2 == 1)[0]\n\n # matrix indicating which teams play against each other at what date\n # config[d,i] == j iff team i plays team j on day d of the tournament\n # config[d,i] == i iff team i plays bye on day d of the tournament\n config = intvar(0, n_teams - 1, shape=(n_days, n_teams), name=\"config\")\n # home[d,i] == True iff team i plays home on day d of the tournament\n where = intvar(0, 2, shape=(n_days, n_teams), name=\"where\")\n HOME, BYE, AWAY = 0, 1, 2\n\n model = Model()\n\n # a team cannot have different opponents on the same day\n for day_conf in config:\n model += AllDifferent(day_conf)\n\n # team plays itself when playing BYE\n for day in range(n_days):\n model += (config[day] == teams) == (where[day] == BYE)\n\n # symmetry\n for day in range(n_days):\n for t in range(n_teams):\n model += config[day, config[day, t]] == t\n\n # 1. mirroring constraint\n scheme = np.array([7, 8, 11, 12, 13, 14, 15, 0, 1, 16, 17, 2, 3, 4, 5, 6, 9, 10])\n model += config == config[scheme]\n model += where == (2 - where[scheme])\n\n # 2. no two final days away\n for t in range(n_teams):\n model += sum(where[-2:, t] == AWAY) <= 1\n\n # 3. home/away/bye pattern constraint\n for t in teams:\n for d in days[:-3]:\n # No team may have more than two home matches in a row\n model += sum(where[d:d + 3, t] == HOME) <= 2\n # No team may have more than two away matches in a row\n model += sum(where[d:d + 3, t] == AWAY) <= 2\n\n for d in days[:-4]:\n # No team may have more than three away matches or byes in a row\n model += sum((where[d:d + 4, t] == AWAY) |\n (where[d:d + 4, t] == BYE)) <= 3\n\n for d in days[:-5]:\n # No team may have more than four home matches or byes in a row.\n model += sum((where[d:d + 5, t] == HOME) |\n (where[d:d + 5, t] == BYE)) <= 4\n\n # 4. weekend pattern constraint\n # Of the weekends, each team plays four at home, four away, and one bye.\n for t in range(n_teams):\n model += sum(where[weekends, t] == HOME) == 4\n model += sum(where[weekends, t] == AWAY) == 4\n model += sum(where[weekends, t] == BYE) == 1\n\n # 5. first weekends constraint\n # Each team must have home matches or byes at least on two of the first five weekends.\n for t in range(n_teams):\n model += (sum(where[weekends[:5], t] == HOME) +\n sum(where[weekends[:5], t] == BYE)) >= 2\n\n # 6. rival matches constraint\n # In the last date, every team except FSU plays against its rival, unless it plays against FSU or has a bye.\n for t in teams:\n if t != FSU:\n model += (config[-1, t] == rivals[t]) | \\\n (config[-1, t] == FSU) | \\\n (where[-1, t] == BYE)\n\n # 7. Constrained matches\n # The following pairings must occur at least once in dates 11 to 18:\n # Wake-UNC, Wake-Duke, GT-UNC, and GT-Duke.\n model += sum(config[10:, WAKE] == UNC) >= 1\n model += sum(config[10:, WAKE] == DUKE) >= 1\n model += sum(config[10:, GT] == UNC) >= 1\n model += sum(config[10:, GT] == DUKE) >= 1\n\n # 8. Opponent Sequence constraints\n for t in teams:\n for d in days[:-2]:\n if t != DUKE and t != UNC:\n # No team plays in two consecutive dates away against UNC and Duke\n model += ((config[d, t] == UNC) & (where[d, t] == AWAY) &\n (config[d + 1, t] == DUKE) & (where[d + 1, t] == AWAY)).implies(False)\n model += ((config[d, t] == DUKE) & (where[d, t] == AWAY) &\n (config[d + 1, t] == UNC) & (where[d + 1, t] == AWAY)).implies(False)\n for d in days[:-3]:\n if t not in [UNC, DUKE, WAKE]:\n # No team plays in three consecutive dates against UNC, Duke and Wake (independent of home/away).\n model += ((config[d, t] == UNC) & (config[d + 1, t] == DUKE) & (config[d + 2, t] == WAKE)).implies(\n False)\n model += ((config[d, t] == UNC) & (config[d + 1, t] == WAKE) & (config[d + 2, t] == DUKE)).implies(\n False)\n model += ((config[d, t] == DUKE) & (config[d + 1, t] == UNC) & (config[d + 2, t] == WAKE)).implies(\n False)\n model += ((config[d, t] == DUKE) & (config[d + 1, t] == WAKE) & (config[d + 2, t] == UNC)).implies(\n False)\n model += ((config[d, t] == WAKE) & (config[d + 1, t] == UNC) & (config[d + 2, t] == DUKE)).implies(\n False)\n model += ((config[d, t] == WAKE) & (config[d + 1, t] == DUKE) & (config[d + 2, t] == UNC)).implies(\n False)\n\n # 9. Other constraints\n # UNC plays its rival Duke in the last date and in date 11\n model += config[10, UNC] == DUKE\n model += config[-1, UNC] == DUKE\n # UNC plays Clem in the second date\n model += config[1, UNC] == CLEM\n # Duke has a bye in date 16\n model += where[15, DUKE] == BYE\n # Wake does not play home in date 17\n model += where[16, WAKE] != HOME\n # Wake has a bye in the first date\n model += where[0, WAKE] == BYE\n # Clem, Duke, UMD and Wake do not play away in the last date\n model += where[-1, [CLEM, DUKE, UMD, WAKE]] != AWAY\n # Clem, FSU, GT and Wake do not play away in the first date\n model += where[0, [CLEM, FSU, GT, WAKE]] != AWAY\n # Neither FSU nor NCSt have a bye in last date\n model += where[-1, [FSU, NCSt]] != BYE\n # UNC does not have a bye in the first date.\n model += where[0, UNC] != BYE\n\n return model, (config, where)\n\n\n# Example usage\nmodel, (config, where) = basketball_schedule()\n\n# Solve\nmodel.solve()\n\n# Print\nsolution = {\n \"config\": config.value().tolist(),\n \"where\": where.value().tolist()\n}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "csplib__csplib_012_nonogram", "model": "# Data\nrows = 8 # Number of rows\nrow_rule_len = 2 # Maximum length of row rules\nrow_rules = [\n [0, 1],\n [0, 2],\n [4, 4],\n [0, 12],\n [0, 8],\n [0, 9],\n [3, 4],\n [2, 2]\n] # Rules for rows\ncols = 13 # Number of columns\ncol_rule_len = 2 # Maximum length of column rules\ncol_rules = [\n [0, 2],\n [2, 1],\n [3, 2],\n [0, 6],\n [1, 4],\n [0, 3],\n [0, 4],\n [0, 4],\n [0, 4],\n [0, 5],\n [0, 4],\n [1, 3],\n [0, 2]\n] # Rules for columns\n# End of data\n\n# Import libraries\nimport json\nfrom cpmpy import *\n\n\ndef nonogram(row_rules, col_rules, **kwargs):\n solver = SolverLookup.get(\"ortools\")\n n_rows, n_cols = len(row_rules), len(col_rules)\n board = intvar(0, 1, shape=(n_rows, n_cols), name=\"board\")\n solver.user_vars.update(set(board.flatten()))\n\n # Patterns of each row must be correct\n for r, pattern in enumerate(row_rules):\n automaton_func, final_states = transition_function(pattern)\n solver.ort_model.AddAutomaton(\n solver.solver_vars(board[r]),\n starting_state=0, final_states=final_states,\n transition_triples=automaton_func\n )\n\n # Patterns of each column must be correct\n for c, pattern in enumerate(col_rules):\n automaton_func, final_states = transition_function(pattern)\n solver.ort_model.AddAutomaton(\n solver.solver_vars(board[:, c]),\n starting_state=0, final_states=final_states,\n transition_triples=automaton_func\n )\n\n return solver, (board,)\n\n\ndef transition_function(pattern):\n \"\"\"\n Pattern is a vector containing the lengths of blocks with value 1\n \"\"\"\n func = []\n n_states = 0\n for block_length in pattern:\n if block_length == 0:\n continue\n func += [(n_states, 0, n_states)]\n for _ in range(block_length):\n func += [(n_states, 1, n_states + 1)]\n n_states += 1\n\n func += [(n_states, 0, n_states + 1)]\n n_states += 1\n\n func += [(n_states, 0, n_states)]\n # Line can end with 0 or 1\n return func, [n_states - 1, n_states]\n\n\n# Example usage\nmodel, (board,) = nonogram(row_rules, col_rules)\n\n# Solve\nmodel.solve()\n\n# Print\nsolution = {\"board\": board.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "csplib__csplib_013_progressive_party_problem", "model": "# Data\nn_boats = 5 # Number of boats\nn_periods = 4 # Number of periods\ncapacity = [6, 8, 12, 12, 12] # Capacities of the boats\ncrew_size = [2, 2, 2, 2, 4] # Crew sizes of the boats\n# End of data\n\n# Import libraries\nimport json\nfrom cpmpy import *\nfrom cpmpy.expressions.utils import all_pairs\n\n\ndef progressive_party(n_boats, n_periods, capacity, crew_size, **kwargs):\n is_host = boolvar(shape=n_boats, name=\"is_host\")\n visits = intvar(0, n_boats - 1, shape=(n_periods, n_boats), name=\"visits\")\n\n model = Model()\n\n # Crews of host boats stay on boat\n for boat in range(n_boats):\n model += (is_host[boat]).implies((visits[:, boat] == boat).all())\n\n # Number of visitors can never exceed capacity of boat\n for slot in range(n_periods):\n for boat in range(n_boats):\n model += sum((visits[slot] == boat) * crew_size) + crew_size[boat] * is_host[boat] <= capacity[boat]\n\n # Guests cannot visit a boat twice\n for boat in range(n_boats):\n model += (~is_host[boat]).implies(AllDifferent(visits[:, boat]))\n\n # Non-host boats cannot be visited\n for boat in range(n_boats):\n model += (~is_host[boat]).implies((visits != boat).all())\n\n # Crews cannot meet more than once\n for c1, c2 in all_pairs(range(n_boats)):\n model += sum(visits[:, c1] == visits[:, c2]) <= 1\n\n # Minimize number of hosts needed\n model.minimize(sum(is_host))\n\n return model, (visits, is_host)\n\n\n# Example usage\nmodel, (visits, is_host) = progressive_party(n_boats, n_periods, capacity, crew_size)\nmodel.solve()\n\n# Print\nsolution = {\n \"visits\": visits.value().tolist(),\n \"is_host\": is_host.value().tolist()\n}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "csplib__csplib_015_schurs_lemma", "model": "# Data\nn = 13 # Number of balls\nc = 3 # Number of boxes\n# End of data\n\n# Import libraries\nimport json\nfrom cpmpy import *\n\n\ndef shur_lemma(n, c):\n # balls[i] = j iff ball i is in box j\n balls = intvar(1, c, shape=n, name=\"balls\")\n\n model = Model()\n\n # Ensure each triple (x, y, z) with x + y = z are not in the same box\n for x in range(1, n):\n for y in range(1, n - x + 1):\n z = x + y\n if z <= n:\n model += (balls[x - 1] != balls[y - 1]) | \\\n (balls[x - 1] != balls[z - 1]) | \\\n (balls[y - 1] != balls[z - 1])\n\n return model, (balls,)\n\n\n# Example usage\nmodel, (balls,) = shur_lemma(n, c)\nmodel.solve()\n\n# Print\nsolution = {\"balls\": balls.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "csplib__csplib_019_magic_squares_and_sequences", "model": "# Data\nn = 12 # Length of the magic sequence\n# End of data\n\n# Import libraries\nimport json\nimport numpy as np\nfrom cpmpy import *\n\ndef magic_sequence(n):\n model = Model()\n\n x = intvar(0, n - 1, shape=n, name=\"x\")\n\n # Constraints\n for i in range(n):\n model += x[i] == sum(x == i)\n\n # Speedup search\n model += sum(x) == n\n model += sum(x * np.arange(n)) == n\n\n return model, (x,)\n\n# Example usage\nmodel, (x,) = magic_sequence(n)\nmodel.solve()\n\n# Print\nsolution = {\"x\": x.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "csplib__csplib_021_crossfigures", "model": "# Import libraries\nimport math\nfrom cpmpy import *\nimport json\n\n\ndef member_of(x, val):\n \"\"\"\n member_of(x, val)\n\n Ensures that the value `val` is in the array `x`.\n \"\"\"\n n = len(x)\n # cc = intvar(0,n)\n # constraints = [count(x, val, cc), cc > 0]\n constraints = [sum([x[i] == val for i in range(n)]) > 0]\n return constraints\n\n\ndef is_prime(n):\n \"\"\"\n is_prime(n)\n\n Returns True if the number n is a prime number, otherwise return False.\n \"\"\"\n if n < 2: return False\n if n == 2: return True\n if not n & 1:\n return False\n for i in range(3, 1 + int(math.sqrt(n)), 2):\n if n % i == 0:\n return False\n return True\n\n\ndef to_num(a, n, base):\n \"\"\"\n to_num(a, n, base)\n\n Ensure that the digits in array `a` corresponds to the number `n` in base `base`.\n \"\"\"\n tlen = len(a)\n return n == sum([(base ** (tlen - i - 1)) * a[i] for i in range(tlen)])\n\n\n#\n# across(Matrix, Across, Len, Row, Col)\n# Constrains 'Across' to be equal to the number represented by the\n# 'Len' digits starting at position (Row, Col) of the array 'Matrix'\n# and proceeding across.\n#\ndef across(Matrix, Across, Len, Row, Col):\n Row -= 1\n Col -= 1\n tmp = intvar(0, 9999, shape=Len)\n constraints = []\n constraints += [to_num(tmp, Across, 10)]\n for i in range(Len):\n constraints += [Matrix[Row, Col + i] == tmp[i]]\n return constraints\n\n\n#\n# down(Matrix, Down, Len, Row, Col):\n#\tConstrains 'Down' to be equal to the number represented by the\n#\t'Len' digits starting at position (Row, Col) of the array 'Matrix'\n#\tand proceeding down.\n#\ndef down(Matrix, Down, Len, Row, Col):\n Row -= 1\n Col -= 1\n tmp = intvar(0, 9999, shape=Len)\n constraints = []\n constraints += [to_num(tmp, Down, 10)]\n for i in range(Len):\n constraints += [Matrix[Row + i, Col] == tmp[i]]\n return constraints\n\n\nmodel = Model()\nn = 9\n\nD = 9999 # the max length of the numbers in this problem is 4\nprimes = [i for i in range(2, D + 1) if is_prime(i)]\nsquares = [i ** 2 for i in range(1, 1 + math.ceil(math.sqrt(D)))]\n\nZ = -1\nB = -2 # Black box\n# The valid squares (or rather the invalid are marked as B)\nValid = [[Z, Z, Z, Z, B, Z, Z, Z, Z],\n [Z, Z, B, Z, Z, Z, B, Z, Z],\n [Z, B, Z, Z, B, Z, Z, B, Z],\n [Z, Z, Z, Z, B, Z, Z, Z, Z],\n [B, Z, B, B, B, B, B, Z, B],\n [Z, Z, Z, Z, B, Z, Z, Z, Z],\n [Z, B, Z, Z, B, Z, Z, B, Z],\n [Z, Z, B, Z, Z, Z, B, Z, Z],\n [Z, Z, Z, Z, B, Z, Z, Z, Z]]\n\nM = intvar(0, 9, shape=(n, n), name=\"M\") # The matrix\n\nfor i in range(n):\n for j in range(n):\n if Valid[i][j] == B:\n model += (M[i, j] == 0)\n\nA1 = intvar(0, D, name=\"A1\")\nA4 = intvar(0, D, name=\"A4\")\nA7 = intvar(0, D, name=\"A7\")\nA8 = intvar(0, D, name=\"A8\")\nA9 = intvar(0, D, name=\"A9\")\nA10 = intvar(0, D, name=\"A10\")\nA11 = intvar(0, D, name=\"A11\")\nA13 = intvar(0, D, name=\"A13\")\nA15 = intvar(0, D, name=\"A15\")\nA17 = intvar(0, D, name=\"A17\")\nA20 = intvar(0, D, name=\"A20\")\nA23 = intvar(0, D, name=\"A23\")\nA24 = intvar(0, D, name=\"A24\")\nA25 = intvar(0, D, name=\"A25\")\nA27 = intvar(0, D, name=\"A27\")\nA28 = intvar(0, D, name=\"A28\")\nA29 = intvar(0, D, name=\"A29\")\nA30 = intvar(0, D, name=\"A30\")\n\nAList = [A1, A4, A7, A8, A9, A10, A11, A13, A15, A17, A20, A23, A24, A25, A27, A28, A29, A30]\n\nD1 = intvar(0, D, name=\"D1\")\nD2 = intvar(0, D, name=\"D2\")\nD3 = intvar(0, D, name=\"D3\")\nD4 = intvar(0, D, name=\"D4\")\nD5 = intvar(0, D, name=\"D5\")\nD6 = intvar(0, D, name=\"D6\")\nD10 = intvar(0, D, name=\"D10\")\nD12 = intvar(0, D, name=\"D12\")\nD14 = intvar(0, D, name=\"D14\")\nD16 = intvar(0, D, name=\"D16\")\nD17 = intvar(0, D, name=\"D17\")\nD18 = intvar(0, D, name=\"D18\")\nD19 = intvar(0, D, name=\"D19\")\nD20 = intvar(0, D, name=\"D20\")\nD21 = intvar(0, D, name=\"D21\")\nD22 = intvar(0, D, name=\"D22\")\nD26 = intvar(0, D, name=\"D26\")\nD28 = intvar(0, D, name=\"D28\")\nDList = [D1, D2, D3, D4, D5, D6, D10, D12, D14, D17, D18, D19, D20, D21, D22, D26, D28]\n\n# Set up the constraints between the matrix elements and the\n# clue numbers.\n#\n# Note: Row/Col are adjusted to base-0 in the\n# across and down methods.\n#\nmodel += (across(M, A1, 4, 1, 1))\nmodel += (across(M, A4, 4, 1, 6))\nmodel += (across(M, A7, 2, 2, 1))\nmodel += (across(M, A8, 3, 2, 4))\nmodel += (across(M, A9, 2, 2, 8))\nmodel += (across(M, A10, 2, 3, 3))\nmodel += (across(M, A11, 2, 3, 6))\nmodel += (across(M, A13, 4, 4, 1))\nmodel += (across(M, A15, 4, 4, 6))\nmodel += (across(M, A17, 4, 6, 1))\nmodel += (across(M, A20, 4, 6, 6))\nmodel += (across(M, A23, 2, 7, 3))\nmodel += (across(M, A24, 2, 7, 6))\nmodel += (across(M, A25, 2, 8, 1))\nmodel += (across(M, A27, 3, 8, 4))\nmodel += (across(M, A28, 2, 8, 8))\nmodel += (across(M, A29, 4, 9, 1))\nmodel += (across(M, A30, 4, 9, 6))\n\nmodel += (down(M, D1, 4, 1, 1))\nmodel += (down(M, D2, 2, 1, 2))\nmodel += (down(M, D3, 4, 1, 4))\nmodel += (down(M, D4, 4, 1, 6))\nmodel += (down(M, D5, 2, 1, 8))\nmodel += (down(M, D6, 4, 1, 9))\nmodel += (down(M, D10, 2, 3, 3))\nmodel += (down(M, D12, 2, 3, 7))\nmodel += (down(M, D14, 3, 4, 2))\nmodel += (down(M, D16, 3, 4, 8))\nmodel += (down(M, D17, 4, 6, 1))\nmodel += (down(M, D18, 2, 6, 3))\nmodel += (down(M, D19, 4, 6, 4))\nmodel += (down(M, D20, 4, 6, 6))\nmodel += (down(M, D21, 2, 6, 7))\nmodel += (down(M, D22, 4, 6, 9))\nmodel += (down(M, D26, 2, 8, 2))\nmodel += (down(M, D28, 2, 8, 8))\n\n# Set up the clue constraints.\n# Across\n# 1 27 across times two\n# 4 4 down plus seventy-one\n# 7 18 down plus four\n# 8 6 down divided by sixteen\n# 9 2 down minus eighteen\n# 10 Dozen in six gross\n# 11 5 down minus seventy\n# 13 26 down times 23 across\n# 15 6 down minus 350\n# 17 25 across times 23 across\n# 20 A square number\n# 23 A prime number\n# 24 A square number\n# 25 20 across divided by seventeen\n# 27 6 down divided by four\n# 28 Four dozen\n# 29 Seven gross\n# 30 22 down plus 450\n\nmodel += (A1 == 2 * A27)\nmodel += (A4 == D4 + 71)\nmodel += (A7 == D18 + 4)\n# model += (A8 == D6 / 16)\nmodel += (16 * A8 == D6)\nmodel += (A9 == D2 - 18)\n# model += (A10 == 6 * 144 / 12)\nmodel += (12 * A10 == 6 * 144)\nmodel += (A11 == D5 - 70)\nmodel += (A13 == D26 * A23)\nmodel += (A15 == D6 - 350)\nmodel += (A17 == A25 * A23)\n# model += (square(A20))\nmodel += (member_of(squares, A20))\n# model += (is_prime(A23))\nmodel += (member_of(primes, A23))\n# model += (square(A24))\nmodel += (member_of(squares, A24))\n# model += (A25 == A20 / 17)\nmodel += (17 * A25 == A20)\n# model += (A27 == D6 / 4)\nmodel += (4 * A27 == D6)\nmodel += (A28 == 4 * 12)\nmodel += (A29 == 7 * 144)\nmodel += (A30 == D22 + 450)\n\n# Down\n#\n# 1 1 across plus twenty-seven\n# 2 Five dozen\n# 3 30 across plus 888\n# 4 Two times 17 across\n# 5 29 across divided by twelve\n# 6 28 across times 23 across\n# 10 10 across plus four\n# 12 Three times 24 across\n# 14 13 across divided by sixteen\n# 16 28 down times fifteen\n# 17 13 across minus 399\n# 18 29 across divided by eighteen\n# 19 22 down minus ninety-four\n# 20 20 across minus nine\n# 21 25 across minus fifty-two\n# 22 20 down times six\n# 26 Five times 24 across\n# 28 21 down plus twenty-seven\n\nmodel += (D1 == A1 + 27)\nmodel += (D2 == 5 * 12)\nmodel += (D3 == A30 + 888)\nmodel += (D4 == 2 * A17)\n# model += (D5 == A29 / 12)\nmodel += (12 * D5 == A29)\nmodel += (D6 == A28 * A23)\nmodel += (D10 == A10 + 4)\nmodel += (D12 == A24 * 3)\n# model += (D14 == A13 / 16)\nmodel += (16 * D14 == A13)\nmodel += (D16 == 15 * D28)\nmodel += (D17 == A13 - 399)\n# model += (D18 == A29 / 18)\nmodel += (18 * D18 == A29)\nmodel += (D19 == D22 - 94)\nmodel += (D20 == A20 - 9)\nmodel += (D21 == A25 - 52)\nmodel += (D22 == 6 * D20)\nmodel += (D26 == 5 * A24)\nmodel += (D28 == D21 + 27)\n\nmodel.solve()\n\n# Print the solution\nsolution = {\"M\": M.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "csplib__csplib_024_langford", "model": "# Data\nk = 4 # Number of sets\n# End of data\n\n# Import libraries\nimport json\nfrom cpmpy import *\n\n\ndef langford(k):\n model = Model()\n\n if not (k % 4 == 0 or k % 4 == 3):\n print(\"There is no solution for K unless K mod 4 == 0 or K mod 4 == 3\")\n return None, None\n\n # Variables\n position = intvar(0, 2 * k - 1, shape=2 * k, name=\"position\")\n solution = intvar(1, k, shape=2 * k, name=\"solution\")\n\n # Constraints\n model += [AllDifferent(position)]\n\n for i in range(1, k + 1):\n model += [position[i + k - 1] == position[i - 1] + i + 1]\n model += [i == solution[position[i - 1]]]\n model += [i == solution[position[k + i - 1]]]\n\n # Symmetry breaking\n model += [solution[0] < solution[2 * k - 1]]\n\n return model, (position, solution)\n\n\n# Example usage\nmodel, (position, solution) = langford(k)\nif model:\n model.solve()\n\n # Print\n solution_dict = {\n \"position\": position.value().tolist(),\n \"solution\": solution.value().tolist()\n }\n print(json.dumps(solution_dict))\n# End of CPMPy script"} +{"id": "csplib__csplib_026_sports_tournament_scheduling", "model": "# Data\nn_teams = 8 # Number of teams\n# End of data\n\n# Import libraries\nimport json\nfrom cpmpy import *\nfrom cpmpy.expressions.utils import all_pairs\nimport numpy as np\n\n\ndef sport_scheduling(n_teams):\n n_weeks, n_periods, n_matches = n_teams - 1, n_teams // 2, (n_teams - 1) * n_teams // 2\n\n home = intvar(1, n_teams, shape=(n_weeks, n_periods), name=\"home\")\n away = intvar(1, n_teams, shape=(n_weeks, n_periods), name=\"away\")\n\n model = Model()\n\n # teams cannot play each other\n model += home != away\n\n # every teams plays once a week\n # can be written cleaner, see issue #117\n # model += AllDifferent(np.append(home, away, axis=1), axis=0)\n for w in range(n_weeks):\n model += AllDifferent(np.append(home[w], away[w]))\n\n # every team plays each other\n for t1, t2 in all_pairs(range(1, n_teams + 1)):\n model += (sum((home == t1) & (away == t2)) + sum((home == t2) & (away == t1))) >= 1\n\n # every team plays at most twice in the same period\n for t in range(1, n_teams + 1):\n # can be written cleaner, see issue #117\n # sum((home == t) | (away == t), axis=1) <= 2\n for p in range(n_periods):\n model += sum((home[p] == t) | (away[p] == t)) <= 2\n\n return model, (home, away)\n\n\n# Example usage\nmodel, (home, away) = sport_scheduling(n_teams)\nmodel.solve()\n\n# Print\nsolution = {\n \"home\": home.value().tolist(),\n \"away\": away.value().tolist()\n}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "csplib__csplib_028_bibd", "model": "# Data\nv = 9 # Number of distinct objects\nb = 12 # Number of blocks\nr = 4 # Number of blocks each object occurs in\nk = 3 # Number of objects each block contains\nl = 1 # Number of blocks in which each pair of distinct objects occurs together\n# End of data\n\n# Import libraries\nimport json\nimport numpy as np\nfrom cpmpy import *\nfrom cpmpy.expressions.utils import all_pairs\n\ndef bibd(v, b, r, k, l):\n matrix = boolvar(shape=(v, b), name=\"matrix\")\n\n model = Model()\n\n # Every row adds up to r\n model += [sum(row) == r for row in matrix]\n # Every column adds up to k\n model += [sum(col) == k for col in matrix.T]\n\n # The scalar product of every pair of columns adds up to l\n model += [np.dot(row_i, row_j) == l for row_i, row_j in all_pairs(matrix)]\n\n # Break symmetry\n # Lexicographic ordering of rows\n for r in range(v - 1):\n bvar = boolvar(shape=(b + 1))\n model += bvar[0] == 1\n model += bvar == ((matrix[r] <= matrix[r + 1]) &\n ((matrix[r] < matrix[r + 1]) | (bvar[1:] == 1)))\n model += bvar[-1] == 0\n # Lexicographic ordering of columns\n for c in range(b - 1):\n bvar = boolvar(shape=(v + 1))\n model += bvar[0] == 1\n model += bvar == ((matrix.T[c] <= matrix.T[c + 1]) &\n ((matrix.T[c] < matrix.T[c + 1]) | (bvar[1:] == 1)))\n model += bvar[-1] == 0\n\n return model, (matrix,)\n\n# Example usage\nmodel, (matrix,) = bibd(v, b, r, k, l)\nmodel.solve()\n\n# Print\nsolution = {\"matrix\": matrix.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "csplib__csplib_033_word_design", "model": "# Data\nn = 8 # Number of words to find\n# End of data\n\n# Import libraries\nimport json\nfrom cpmpy import *\nfrom cpmpy.expressions.utils import all_pairs\n\ndef word_design(n=2):\n A, C, G, T = 1, 2, 3, 4\n\n # words[i,j] is the j'th letter of the i'th word\n words = intvar(A, T, shape=(n, 8), name=\"words\")\n\n model = Model()\n\n # 4 symbols from {C,G}\n for w in words:\n model += sum((w == C) | (w == G)) >= 4\n\n # Each pair of distinct words differ in at least 4 positions\n for x, y in all_pairs(words):\n model += (sum(x != y) >= 4)\n\n # Each pair of words x and y (where x and y may be identical)\n # are such that x^R and y^C differ in at least 4 positions\n for y in words:\n y_c = 5 - y # Watson-Crick complement\n for x in words:\n x_r = x[::-1] # reversed x\n model += sum(x_r != y_c) >= 4\n\n # Break symmetry\n for r in range(n - 1):\n b = boolvar(shape=(9,))\n model += b[0] == 1\n model += b == ((words[r] <= words[r + 1]) &\n ((words[r] < words[r + 1]) | (b[1:] == 1)))\n model += b[-1] == 0\n\n return model, (words,)\n\n# Example usage\nmodel, (words,) = word_design(n)\nmodel.solve()\n\n# Print\nsolution = {\"words\": words.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "csplib__csplib_044_steiner", "model": "# Data\nn = 9 # Order of the Steiner Triple System\n# End of data\n\n# Import libraries\nimport json\nfrom cpmpy import *\nfrom cpmpy.expressions.utils import all_pairs\n\ndef steiner(n=15):\n assert n % 6 == 1 or n % 6 == 3, \"N must be (1|3) modulo 6\"\n\n n_sets = int(n * (n - 1) // 6)\n\n model = Model()\n\n # boolean representation of sets\n # sets[i,j] = true iff item j is part of set i\n sets = boolvar(shape=(n_sets, n), name=\"sets\")\n\n # cardinality of set if 3\n # can be written cleaner, see issue #117\n # model += sum(sets, axis=0) == 3\n model += [sum(s) == 3 for s in sets]\n\n # cardinality of intersection <= 1\n for s1, s2 in all_pairs(sets):\n model += sum(s1 & s2) <= 1\n\n # symmetry breaking\n model += (sets[(0, 0)] == 1)\n\n return model, (sets,)\n\n# Example usage\nmodel, (sets,) = steiner(n)\nmodel.solve()\n\n# Print\nsolution = {\"sets\": sets.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "csplib__csplib_049_number_partitioning", "model": "# Data\nn = 12 # The number N\n# End of data\n\n# Import libraries\nimport json\nimport numpy as np\nfrom cpmpy import *\n\ndef number_partitioning(n=8):\n assert n % 2 == 0, \"The value of n must be even\"\n\n # x[i] is the ith value of the first set\n x = intvar(1, n, shape=n // 2)\n\n # y[i] is the ith value of the second set\n y = intvar(1, n, shape=n // 2)\n\n model = Model()\n\n model += AllDifferent(np.append(x, y))\n\n # sum of numbers is equal in both sets\n model += sum(x) == sum(y)\n\n # sum of squares is equal in both sets\n model += sum(x ** 2) == sum(y ** 2)\n\n # break symmetry\n model += x[:-1] <= x[1:]\n model += y[:-1] <= x[1:]\n\n return model, (x,y)\n\n# Example usage\nmodel, (x, y) = number_partitioning(n)\nmodel.solve()\n\nA = x\nB = y\n\n# Print\nsolution = {\"A\": x.value().tolist(), \"B\": y.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "csplib__csplib_050_diamond_free", "model": "# Data\nN = 10 # Number of vertices in the graph\n# End of data\n\n# Import libraries\nimport json\nimport numpy as np\nfrom cpmpy import *\nfrom itertools import combinations\n\ndef diamond_free(N=10):\n # By definition a and b will have the same cardinality:\n matrix = boolvar(shape=(N, N), name=\"matrix\")\n\n model = Model()\n\n # No rows contain just zeroes.\n model += [sum(row) > 0 for row in matrix] # can be written cleaner, see issue #117\n # Every row has a sum modulo 3.\n model += [sum(row) % 3 == 0 for row in matrix]\n # The sum of the matrix is modulo 12.\n model += sum(matrix) % 12 == 0\n # No row R contains a 1 in its Rth column.\n model += [matrix[np.diag_indices(N)] == 0]\n\n # Every grouping of 4 rows can have at most a sum of 4 between them.\n for a, b, c, d in combinations(range(N), 4):\n model += sum([matrix[a][b], matrix[a][c], matrix[a][d],\n matrix[b][c], matrix[b][d], matrix[c][d]]) <= 4\n\n # Undirected graph\n model += matrix == matrix.T\n\n # Symmetry breaking\n # lexicographic ordering of rows\n for r in range(N - 1):\n b = boolvar(N + 1)\n model += b[0] == 1\n model += b == ((matrix[r] <= matrix[r + 1]) &\n ((matrix[r] < matrix[r + 1]) | b[1:] == 1))\n model += b[-1] == 0\n # lexicographic ordering of cols\n for c in range(N - 1):\n b = boolvar(N + 1)\n model += b[0] == 1\n model += b == ((matrix.T[c] <= matrix.T[c + 1]) &\n ((matrix.T[c] < matrix.T[c + 1]) | b[1:] == 1))\n model += b[-1] == 0\n\n return model, matrix\n\n# Example usage\nmodel, matrix = diamond_free(N)\nmodel.solve()\n\n# Print\nsolution = {\"matrix\": matrix.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "csplib__csplib_053_graceful_graphs", "model": "# Data\nm = 16 # Number of edges in the graph\nn = 8 # Number of nodes in the graph\ngraph = [[0, 1], [0, 2], [0, 3], [1, 2], [1, 3], [2, 3],\n [4, 5], [4, 6], [4, 7], [5, 6], [5, 7], [6, 7],\n [0, 4], [1, 5], [2, 6], [3, 7]] # Edges of the graph\n# End of data\n\n# Import libraries\nimport json\nfrom cpmpy import *\nimport numpy as np\n\n\ndef graceful_graphs(m, n, graph):\n graph = np.array(graph)\n\n model = Model()\n\n # variables\n nodes = intvar(0, m, shape=n, name=\"nodes\")\n edges = intvar(1, m, shape=m, name=\"edges\")\n\n # constraints\n model += np.abs(nodes[graph[:, 0]] - nodes[graph[:, 1]]) == edges\n\n model += (AllDifferent(edges))\n model += (AllDifferent(nodes))\n\n return model, (nodes, edges)\n\n\n# Example usage\nmodel, (nodes, edges) = graceful_graphs(m, n, graph)\nmodel.solve()\n\n# Print\nsolution = {\"nodes\": nodes.value().tolist(), \"edges\": edges.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "csplib__csplib_054_n_queens", "model": "# Data\nn = 10 # Size of the chessboard and number of queens\n# End of data\n\n# Import libraries\nimport json\nimport numpy as np\nfrom cpmpy import *\n\ndef n_queens(n=8):\n\n queens = intvar(1, n, shape=n, name=\"queens\")\n\n # Constraints on columns and left/right diagonal\n model = Model([\n AllDifferent(queens),\n AllDifferent(queens - np.arange(n)),\n AllDifferent(queens + np.arange(n)),\n ])\n\n return model, (queens,)\n\n# Example usage\nmodel, (queens,) = n_queens(n)\nmodel.solve()\n\n# Print\nsolution = {\"queens\": queens.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "csplib__csplib_076_costas_arrays", "model": "# Data\nn = 8 # Size of the Costas array\n# End of data\n\n# Import libraries\nimport json\nimport numpy as np\nfrom cpmpy import *\n\ndef costas_array(n=6):\n model = Model()\n\n # Declare variables\n costas = intvar(1, n, shape=n, name=\"costas\")\n differences = intvar(-n + 1, n - 1, shape=(n, n), name=\"differences\")\n\n tril_idx = np.tril_indices(n, -1)\n triu_idx = np.triu_indices(n, 1)\n\n # Constraints\n # Fix the values in the lower triangle in the difference matrix to -n+1.\n model += differences[tril_idx] == -n + 1\n\n model += [AllDifferent(costas)]\n\n # Define the differences\n for i, j in zip(*triu_idx):\n model += [differences[i, j] == costas[j] - costas[j - i - 1]]\n\n # All entries in a particular row of the difference triangle must be distinct\n for i in range(n - 2):\n model += [AllDifferent([differences[i, j] for j in range(n) if j > i])]\n\n # Additional constraints to speed up the search\n model += differences[triu_idx] != 0\n for k, l in zip(*triu_idx):\n if k < 2 or l < 2:\n continue\n model += [differences[k - 2, l - 1] + differences[k, l] ==\n differences[k - 1, l - 1] + differences[k - 1, l]]\n\n return model, (costas, differences)\n\n# Example usage\nmodel, (costas, differences) = costas_array(n)\nmodel.solve()\n\n# Print\nsolution = {\n \"costas\": costas.value().tolist()\n}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "csplib__csplib_084_hadamard_matrix", "model": "# Data\nl = 9 # Value of l (must be an odd positive integer)\n# End of data\n\n# Import libraries\nimport json\nimport numpy as np\nfrom cpmpy import *\n\ndef PAF(arr, s):\n return sum(arr * np.roll(arr,-s))\n\ndef hadamard_matrix(l=5):\n\n m = int((l - 1) / 2)\n\n a = intvar(-1,1, shape=l, name=\"a\")\n b = intvar(-1,1, shape=l, name=\"b\")\n\n model = Model()\n\n model += a != 0 # exclude 0 from dom\n model += b != 0 # exclude 0 from dom\n\n model += sum(a) == 1\n model += sum(b) == 1\n\n for s in range(1,m+1):\n model += (PAF(a,s) + PAF(b,s)) == -2\n\n return model, (a,b)\n\n\n# Example usage\nmodel, (a, b) = hadamard_matrix(l)\nmodel.solve()\n\n# Print\nsolution = {\"a\": a.value().tolist(), \"b\": b.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__abbots_puzzle", "model": "# Import libraries\nfrom cpmpy import *\nimport json\n\n# Decision variables\nmen = intvar(0, 100, name=\"men\")\nwomen = intvar(0, 100, name=\"women\")\nchildren = intvar(0, 100, name=\"children\")\n\n# Model\nmodel = Model([\n men + women + children == 100, # Total number of people\n men * 6 + women * 4 + children == 200, # Total bushels of corn\n men * 5 == women # Five times as many women as men\n])\n\n# Solve the model\nmodel.solve()\n\n# Print the solution\nsolution = {\n \"men\": men.value(),\n \"women\": women.value(),\n \"children\": children.value()\n}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__added_corners", "model": "# Import libraries\nfrom cpmpy import *\nimport json\n\n# Parameters\nn = 8 # Number of digits\n\n# Decision variables\npositions = intvar(1, n, shape=n, name=\"positions\")\na, b, c, d, e, f, g, h = positions\n\n# Model\nmodel = Model([\n AllDifferent(positions),\n b == a + c,\n d == a + f,\n e == c + h,\n g == f + h\n])\n\n# Solve the model\nmodel.solve()\n\n# Print the solution\nsolution = {\"positions\": positions.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__ages_of_the_sons", "model": "# Import libraries\nfrom cpmpy import *\nimport json\n\n\nA1 = intvar(0, 36, name=\"A1\") # oldest son\nA2 = intvar(0, 36, name=\"A2\")\nA3 = intvar(0, 36, name=\"A3\")\n\nB1 = intvar(0, 36, name=\"B1\")\nB2 = intvar(0, 36, name=\"B2\")\nB3 = intvar(0, 36, name=\"B3\")\nAS = intvar(0, 1000, name=\"AS\")\nBS = intvar(0, 1000, name=\"BS\")\n\nmodel = Model([A1 > A2,\n A2 >= A3,\n 36 == A1 * A2 * A3,\n\n B1 >= B2,\n B2 >= B3,\n A1 != B1,\n\n 36 == B1 * B2 * B3,\n AS == A1 + A2 + A3,\n BS == B1 + B2 + B3,\n AS == BS\n ])\n\n# Solve\nmodel.solve()\n\n# Print the solution\nsolution = {\"A1\": A1.value(), \"A2\": A2.value(), \"A3\": A3.value()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__age_changing", "model": "# Import libraries\nfrom cpmpy import *\nimport json\n\ndef check(perm, old, new):\n return [\n (perm == 0).implies(new == old + 2),\n # (perm == 1).implies(new == old / 8), # This give a lot of bad solutions\n (perm == 1).implies(8*new == old), # This works\n (perm == 2).implies(new == old - 3),\n (perm == 3).implies(new == old * 7)\n ]\n\nn = 4\n\nperms = [\"+2\", \"/8\", \"-3\", \"*7\"]\n\n# ages 16..120\nage_low = 16\nage_high = 120\n\n# variables\nm = intvar(age_low, age_high, name=\"m\") # my age\nh = intvar(age_low, age_high, name=\"h\") # my age\n\nperm1 = intvar(0, n - 1, shape=n, name=\"perm1\")\nperm2 = intvar(0, n - 1, shape=n, name=\"perm2\")\n\n# for calculating my age and husband's age\nmlist = intvar(1, 1000, shape=n + 1, name=\"mlist\")\nhlist = intvar(1, 1000, shape=n + 1, name=\"hlist\")\n\n# constraints\nmodel = Model([AllDifferent(perm1),\n AllDifferent(perm2),\n\n # same operations in different order\n sum([perm1[i] != perm2[i] for i in range(n)]) > 0,\n\n # find husbands age, start with my age\n hlist[0] == m,\n\n # husband's age is last in hlist\n h == hlist[n],\n\n # checking my age, start with husband's age\n mlist[0] == h,\n\n # my age is last in mlist\n m == mlist[n],\n\n # check the operations\n [check(perm1[i], hlist[i], hlist[i + 1]) for i in range(n)],\n [check(perm2[i], mlist[i], mlist[i + 1]) for i in range(n)],\n\n # Symmetry breaking: I'm younger than husband\n # m < h\n ])\n\n# Solve\nmodel.solve()\n\n# Print the solution\nsolution = {\n \"m\": m.value(),\n \"h\": h.value()\n}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__allergy", "model": "# Import libraries\nfrom cpmpy import *\nimport json\n\nn = 4\nfriends = Debra, Janet, Hugh, Rick = list(range(n))\nfriends_s = [\"Debra\", \"Janet\", \"Hugh\", \"Rick\"]\n\n# foods[i] is the friend allergic to the ith food\neggs, mold, nuts, ragweed = foods = intvar(0, n - 1, shape=n, name=\"foods\")\nfoods_s = [\"eggs\", \"mold\", \"nuts\", \"ragweed\"]\n\n# surnames[i] is the friend with the ith surname\nbaxter, lemon, malone, fleet = surnames = intvar(0, n - 1, shape=n, name=\"surnames\")\nsurnames_s = [\"baxter\", \"lemon\", \"malone\", \"fleet\"]\n\nmodel = Model([AllDifferent(foods),\n AllDifferent(surnames),\n\n mold != Rick,\n eggs == baxter,\n lemon != Hugh,\n fleet != Hugh,\n ragweed == Debra,\n lemon != Janet,\n eggs != Janet,\n mold != Janet])\n\n# Solve\nmodel.solve()\n\n# Print the solution\nsolution = {\"eggs\": eggs.value(), \"mold\": mold.value(), \"nuts\": nuts.value(), \"ragweed\": ragweed.value(),\n \"baxter\": baxter.value(), \"lemon\": lemon.value(), \"malone\": malone.value(), \"fleet\": fleet.value()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__among", "model": "# Data\nn = 5 # Length of x\nm = 3 # Number of values\nv = [1, 5, 8] # Values to be among in x\n# End of data\n\n# Import libraries\nfrom cpmpy import *\nimport json\n\n\ndef among(m,x,v):\n \"\"\"\n among(m,x,v)\n\n Requires exactly m variables in x to take one of the values in v.\n \"\"\"\n return [m == sum([x[i] == j for i in range(len(x)) for j in v])]\n\n\n# Decision variables\nx = intvar(1, 8, shape=n, name=\"x\")\n\n# Model\nmodel = Model([\n among(m, x, v)\n])\n\n# Solve the model\nmodel.solve()\n\n# Print the solution\nsolution = {\"x\": x.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__appointment_scheduling", "model": "# Data\nm = [\n [1, 1, 1, 1],\n [0, 1, 1, 0],\n [1, 0, 0, 1],\n [1, 0, 0, 1]\n] # Matrix representing the free-busy schedules\n# End of data\n\n# Import libraries\nfrom cpmpy import *\nimport json\nimport random\n\nmodel = Model()\n\nn = len(m)\n\n# decision variables\n\n# the assignment of persons to a slot (appointment number 0..n)\nx = boolvar(shape=(n, n), name=\"x\")\n\n# constraints\n\nfor i in range(n):\n # ensure a free slot\n model += (sum([m[i][j] * x[(i, j)] for j in range(n)]) == 1)\n\n # ensure one assignment per slot\n model += (sum([x[(i, j)] for j in range(n)]) == 1)\n model += (sum([x[(j, i)] for j in range(n)]) == 1)\n# Solve the model\nmodel.solve()\n\n# Print the solution\nsolution = {\"x\": x.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__archery_puzzle", "model": "# Import libraries\nfrom cpmpy import *\nimport json\n\n# Parameters\ntargets = [16, 17, 23, 24, 39, 40]\nn = len(targets)\ntarget_score = 100\n\n# Decision variables\nhits = intvar(0, 100, shape=n, name=\"hits\")\nscore = intvar(0, 100, name=\"score\")\ndeviation = intvar(0, 100, name=\"deviation\")\n\n# Model\nmodel = Model([\n score == sum(hits * targets),\n deviation == abs(target_score - score)\n])\n\n# Objective\nmodel.minimize(deviation)\n\n# Solve the model\nmodel.solve()\n\n# Print the solution\nsolution = {\"hits\": hits.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__arch_friends", "model": "# Import libraries\nfrom cpmpy import *\nimport numpy as np\nimport json\n\n\nn = 4\nmodel = Model()\n\nshoes = intvar(1, n, shape=n, name=\"shoes\")\necruespadrilles, fuchsiaflats, purplepumps, suedesandals = shoes\n\nstore = intvar(1, n, shape=n, name=\"store\")\nfootfarm, heelsinahandcart, theshoepalace, tootsies = store\n\nmodel += [AllDifferent(shoes),\n AllDifferent(store),\n\n # 1. Harriet bought fuchsia flats at Heels in a Handcart.\n fuchsiaflats == heelsinahandcart,\n\n # 2. The store she visited just after buying her purple pumps was not\n # Tootsies.\n purplepumps + 1 != tootsies,\n\n # 3. The Foot Farm was Harriet's second stop.\n footfarm == 2,\n\n # 4. Two stops after leaving The Shoe Place, Harriet bought her suede\n # sandals.\n theshoepalace + 2 == suedesandals\n ]\n\nmodel.solve()\n\n# Print\nsolution = {\"ecruespadrilles\": ecruespadrilles.value(),\n \"fuchsiaflats\": fuchsiaflats.value(),\n \"purplepumps\": purplepumps.value(),\n \"suedesandals\": suedesandals.value(),\n \"footfarm\": footfarm.value(),\n \"heelsinahandcart\": heelsinahandcart.value(),\n \"theshoepalace\": theshoepalace.value(),\n \"tootsies\": tootsies.value()\n }\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__assignment_costs", "model": "# Data\ncost = [ # Cost matrix, rows are tasks, columns are people\n [14, 5, 8, 7, 15],\n [2, 12, 6, 5, 3],\n [7, 8, 3, 9, 7],\n [2, 4, 6, 10, 1]\n] # Cost matrix\n# End of data\n\n# Import libraries\nfrom cpmpy import *\nimport numpy as np\nimport json\n\n# Parameters\nrows = len(cost)\ncols = len(cost[0])\n\n# Decision variables\nmax_cost = np.sum(np.array(cost))\n\ntotal_cost = intvar(0, max_cost, name='cost')\nx = boolvar(shape=(rows, cols), name=\"x\")\n\nmodel = Model(\n total_cost >= 0,\n total_cost == np.sum([x_row * cost_row for (x_row, cost_row) in zip(x, cost)]),\n\n # exacly one assignment per row, all rows (tasks) must be assigned.\n [sum(row) == 1 for row in x],\n\n # zero or one assignments per column (people)\n [sum(col) <= 1 for col in x.transpose()],\n)\n\n# Objective\nmodel.minimize(total_cost)\n\n# Solve the model\nmodel.solve()\n\n# Print the solution\nsolution = {\"x\": x.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__autoref", "model": "# Data\nn = 27\nm = 5\n# End of data\n\n# Import libraries\nfrom cpmpy import *\nimport json\n\n\ndef count(a, val, c):\n \"\"\"\n count(a,val,c)\n\n c is the number of occurrences of val in array a.\n \"\"\"\n return [c == sum([a[i] == val for i in range(len(a))])]\n\n\ndef global_cardinality_count(a, gcc):\n \"\"\"\n global_cardinality_count(a, gcc)\n\n Global cardinality count: Collect the number of occurrences of each value 0..a.ub\n in gcc. The array gcc must be of length 0..ub.\n \"\"\"\n n = len(a)\n ub = max([a[i].ub for i in range(n)])\n constraints = []\n for i in range(ub + 1):\n constraints += [count(a, i, gcc[i])]\n\n return constraints\n\n\ndef autoref(s):\n \"\"\"\n autoref(s)\n Ensure that the number of occurrences of i in s is s[i].\n s should be an array of 0..n+1\n \"\"\"\n return [global_cardinality_count(s, s)]\n\n\n# Decision Variables\ns = intvar(0, n, shape=n + 2, name=\"s\")\n\n# Model\nmodel = Model(s[n + 1] == m, autoref(s))\n\n# Solve the model\nmodel.solve()\n\n# Print the solution\nsolution = {\"s\": s.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__bales_of_hay", "model": "# Import libraries\nfrom cpmpy import *\nimport json\n\n# Parameters\nn = 5\nweights = [80, 82, 83, 84, 85, 86, 87, 88, 90, 91]\n\n# variables\nbales = intvar(0, 50, shape=n, name=\"bales\")\n\nmodel = Model()\n\n\ndef increasing(args):\n \"\"\"\n Ensure that the values in args are increasing.\n \"\"\"\n return [args[i - 1] <= args[i] for i in range(1, len(args))]\n\n\n# constraints\nmodel += [increasing(bales)]\n\nfor w in weights:\n i = intvar(0, n - 1)\n j = intvar(0, n - 1)\n model += [i < j]\n model += [w == bales[i] + bales[j]]\n\n# Solve the model\nmodel.solve()\n\n# Print the solution\nsolution = {\"bales\": bales.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__bananas", "model": "# Import libraries\nfrom cpmpy import *\nimport json\n\nx = intvar(1, 100, shape=4, name=\"x\")\nbananas, oranges, mangoes, apples = x\n\nthe_sum = intvar(1, 2000, name=\"the_sum\")\n\nmodel = Model([the_sum == bananas + apples,\n # This don't work since \"/\" does integer division\n # 3*bananas/5 + 5*oranges/7 + 7*mangoes/9 + 9*apples/3 == 100,\n # we multiply with 3*5*7*9=945 on both sides to weed out the divisions\n 3 * bananas * 189 + 5 * oranges * 135 + 7 * mangoes * 105 + 9 * apples * 315 == 100 * 945,\n sum(x) == 100\n ])\n\nmodel.minimize(the_sum)\n\n# Solve the model\nmodel.solve()\n\n# Print the solution\nsolution = {\n \"bananas\": bananas.value(),\n \"oranges\": oranges.value(),\n \"mangoes\": mangoes.value(),\n \"apples\": apples.value()\n}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__best_host", "model": "# Import libraries\nfrom cpmpy import *\nimport json\n\n\ndef member_of(x, val):\n \"\"\"\n member_of(x, val)\n\n Ensures that the value `val` is in the array `x`.\n \"\"\"\n n = len(x)\n # cc = intvar(0,n)\n # constraints = [count(x, val, cc), cc > 0]\n constraints = [sum([x[i] == val for i in range(n)]) > 0]\n return constraints\n\n\nmodel = Model()\n\nn = 6\n\nAndrew = 0\nBetty = 1\nCara = 2\nDave = 3\nErica = 4\nFrank = 5\n\nprefs = cpm_array([\n [Dave, Frank], # Andrew\n [Cara, Erica], # Betty\n [Betty, Frank], # Cara\n [Andrew, Erica], # Dave\n [Betty, Dave], # Erica\n [Andrew, Cara] # Frank\n])\n\n# declare variables\nx = intvar(0, n - 1, shape=n, name=\"x\")\n\n#\n# constraints\n#\nmodel += (AllDifferent(x))\n\n# symmetry breaking\nmodel += (x[0] == Andrew)\n\nfor i in range(n):\n # This don't work:\n # TypeError: object of type 'Element' has no len()\n # model += [member_of(prefs[x[i]], x[(i-1) % n])]\n # model += [member_of(prefs[x[i]], x[(i+1) % n])]\n\n # It works if we expand the array:\n model += [member_of([prefs[x[i], j] for j in range(2)], x[(i - 1) % n])]\n model += [member_of([prefs[x[i], j] for j in range(2)], x[(i + 1) % n])]\n\n # Another approach that works\n # model += [sum([prefs[x[i],j] == x[(i-1) % n] for j in range(2)])>0]\n # model += [sum([prefs[x[i],j] == x[(i+1) % n] for j in range(2)])>0]\n\n# Solve the model\nmodel.solve()\n\n# Print the solution\nsolution = {\"x\": x.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__big_bang2", "model": "# Import libraries\nfrom cpmpy import *\nimport json\n\n\ndef increasing(args):\n \"\"\"\n Ensure that the values in args are increasing.\n \"\"\"\n return [args[i - 1] <= args[i] for i in range(1, len(args))]\n\n\nrock = 0\npaper = 1\nscissors = 2\nlizard = 3\nspock = 4\n\nm = 5 # number of dice\nn = 8 # number of faces of each die\nf = 2 * n # max face value of dice\nk = 10 # number of competitions\nedge = [\n [rock, scissors],\n [rock, lizard],\n [paper, rock],\n [paper, spock],\n [scissors, paper],\n [scissors, lizard],\n [lizard, paper],\n [lizard, spock],\n [spock, rock],\n [spock, scissors]\n]\n\n#\n# declare variables\n#\n\ndice = intvar(1, f, shape=(m, n), name=\"dice\")\ncomp = intvar(0, n * n, shape=(k, 2), name=\"comp\")\nmax_val = intvar(0, f, name=\"max_val\")\n\nmodel = Model()\n#\n# constraints\n#\nmodel += (max_val == max(dice))\n\n# Symmetry breaking\n# order of the number of each die, lowest first\nmodel += [increasing(dice[i]) for i in range(m)]\n# This is faster but yield max_val = 11 instead of the correct 9!\n# model += [lex_less(dice[i],dice[i+1]) for i in range(m-1)]\nmodel += [dice[0, 0] == 1]\nmodel += [AllDifferent([dice[i, 0] for i in range(m)])]\n\n# and now we roll...\nfor c in range(k):\n model += (comp[c, 0] == sum([dice[edge[c][0], r1] > dice[edge[c][1], r2]\n for r1 in range(n) for r2 in range(n)]))\n\n model += (comp[c, 1] == sum([dice[edge[c][1], r1] > dice[edge[c][0], r2]\n for r1 in range(n) for r2 in range(n)]))\n\n model += (comp[c, 0] > comp[c, 1])\n\n # added later by Thore:\n model += (comp[c, 0] + comp[c, 1] == n * n) # make sure there are no ties\n\n# Solve the model\nmodel.solve()\n\n# Print the solution\nsolution = {\"dice\": dice.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__bin_packing", "model": "# Data\nweights = [4, 3, 1, 3, 2, 5, 2]\ncapacity = 5\nnum_bins = 5\n# End of data\n\n# Import libraries\nfrom cpmpy import *\nimport json\n\n# Parameters\nn = len(weights)\n\n# Decision variables\nbins = intvar(0, num_bins - 1, shape=n, name=\"bins\") # Which bin each item is assigned to\n\n# Model\nmodel = Model([\n [sum(weights[j] * (bins[j] == i) for j in range(n)) <= capacity for i in range(n)]\n])\n\n# Solve the model\nmodel.solve()\n\n# Print the solution\nsolution = {\"bins\": bins.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__birthday_coins", "model": "# Import libraries\nfrom cpmpy import *\nimport json\n\n# Parameters\ncoin_types = 3\nvalues = [30, 12, 6] # Values in pence for half-crowns, shillings, and sixpences\ntotal_value = 240 + 5 * 12 + 6 # Total value in pence\ntotal_coins = 15 # Total number of coins\n\n# Decision variables\ncoins = intvar(1, 15, shape=coin_types, name=\"coins\")\nhalf_crowns = coins[0]\n\n# Model\nmodel = Model([\n sum(values[i] * coins[i] for i in range(coin_types)) == total_value,\n sum(coins) == total_coins\n])\n\n# Solve the model\nmodel.solve()\n\n# Print the solution\nsolution = {\n \"half_crowns\": half_crowns.value(),\n}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__bowls_and_oranges", "model": "# Import libraries\nfrom cpmpy import *\nimport json\n\n# Parameters\nn = 40 # Number of bowls\nm = 9 # Number of oranges\n\n# Decision variables\nx = intvar(1, n, shape=m, name=\"x\")\n\n\ndef increasing(args):\n \"\"\"\n Ensure that the values in args are increasing.\n \"\"\"\n return [args[i - 1] <= args[i] for i in range(1, len(args))]\n\n\n# Model\nmodel = Model([\n AllDifferent(x),\n increasing(x)\n])\n\n# Constraint to ensure no three oranges A, B, and C have equal distances\nfor i in range(m):\n for j in range(m):\n for k in range(m):\n if i < j < k:\n model += ((x[j] - x[i]) != (x[k] - x[j]))\n\n# Solve the model\nmodel.solve()\n\n# Print the solution\nsolution = {\"x\": x.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__broken_weights", "model": "# Import libraries\nfrom cpmpy import *\nimport json\n\n\ndef increasing_strict(args):\n \"\"\"\n Ensure that the values in args are strict increasing.\n \"\"\"\n return [args[i - 1] < args[i] for i in range(1, len(args))]\n\n\n# Parameters\nm = 40\nn = 4\n\n# variables\nweights = intvar(1, m, shape=n, name=\"weights\")\nx = intvar(-1, 1, shape=(m, n), name=\"x\")\n\nmodel = Model(minimize=weights[-1])\n# model = Model()\n\n# constraints\n\nmodel += [AllDifferent(weights)]\nmodel += [sum(weights) == m]\n\n# Check that all weights from 1 to 40 can be made.\n#\n# Since all weights can be on either side\n# of the side of the scale we allow either\n# -1, 0, or 1 of the weights, assuming that\n# -1 is the weights on the left and 1 is on the right.\n#\nfor i in range(m):\n model += [sum([weights[j] * x[i, j] for j in range(n)]) == i + 1]\n # model += [i+1 == sum(weights * x[i])] # using numpy's magic\n\n# symmetry breaking\n# for j in range(1, n):\n# model += [weights[j-1] < weights[j]]\nmodel += [increasing_strict(weights)]\nmodel.solve()\n\n# Print the solution\nsolution = {\"weights\": weights.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__building_blocks", "model": "# Import libraries\nfrom cpmpy import *\nimport json\nimport numpy as np\n\n\ndef count(a, val, c):\n \"\"\"\n count(a,val,c)\n\n c is the number of occurrences of val in array a.\n \"\"\"\n return [c == sum([a[i] == val for i in range(len(a))])]\n\n\ndef global_cardinality_count(a, gcc):\n \"\"\"\n global_cardinality_count(a,gcc)\n\n Global cardinality count: Collect the number of occurrences of each value 0..a.ub\n in gcc. The array gcc must be of length 0..ub.\n \"\"\"\n n = len(a)\n ub = max([a[i].ub for i in range(n)])\n constraints = []\n for i in range(ub + 1):\n constraints += [count(a, i, gcc[i])]\n\n return constraints\n\n\nn = 4\nnum_words = 12\nm = 24\n\n# Index 1 based (adjusted below)\nA = 1;\nB = 2;\nC = 3;\nD = 4;\nE = 5;\nF = 6;\nG = 7;\nH = 8;\nI = 9;\nJ = 10;\nK = 11;\nL = 12;\nM = 13;\nN = 14;\nO = 15;\nP = 16;\nR = 17;\nS = 18;\nT = 19;\nU = 20;\nV = 21;\nW = 22;\nX = 23;\nY = 24;\n\nalpha = [\"A\", \"B\", \"C\", \"D\", \"E\", \"F\", \"G\", \"H\", \"I\", \"J\", \"K\", \"L\", \"M\",\n \"N\", \"O\", \"P\", \"R\", \"S\", \"T\", \"U\", \"V\", \"W\", \"X\", \"Y\"];\n\nwords = np.array([[B, A, K, E],\n [O, N, Y, X],\n [E, C, H, O],\n [O, V, A, L],\n [G, I, R, D],\n [S, M, U, G],\n [J, U, M, P],\n [T, O, R, N],\n [L, U, C, K],\n [V, I, N, Y],\n [L, U, S, H],\n [W, R, A, P]])\n\ndice = intvar(0, n - 1, shape=m, name=\"dice\")\n\nmodel = Model()\n\n# the letters in a word must be on a different die\nfor word in range(num_words):\n # Also, adjust for 1-based\n model += (AllDifferent([dice[words[word] - 1]]))\n\n# there must be exactly 6 letters of each die\nmodel += (global_cardinality_count(dice, [6 for i in range(n)]))\n\n# symmetry breaking (first word is placed)\nmodel += (dice[0] <= dice[6])\nmodel += (dice[6] <= dice[12])\n\nmodel.solve()\n\n# Print the solution\nsolution = {\"dice\": dice.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__cabling", "model": "# Import libraries\nfrom cpmpy import *\nimport json\n\n# Parameters\nn = 8\n\nmodel = Model()\n\n# A <--- 1 cable ---> H\n# A <--- 2 cables ---> E\n# B <--- 4 cables ---> F\n# C <--- 1 cable ---> G\n# C <--- 1 cable ---> D\n# C <--- 1 cable ---> E\n# D <--- 3 cables ---> H\n# G <--- 1 cable ---> H\nA, B, C, D, E, F, G, H = list(range(n))\n\ncable_struct = [[A, H, 1],\n [A, E, 2],\n [B, F, 4],\n [C, G, 1],\n [C, D, 1],\n [C, E, 1],\n [D, H, 3],\n [G, H, 1]]\n\nx = intvar(0, n - 1, shape=n, name=\"x\") # position of the device in the rack\nt = intvar(1, n * n, shape=len(cable_struct), name=\"t\") # cable lengths\nfinal_sum = intvar(0, n * n, name=\"final_sum\") # sum of all cable lengths\n\n# all \"devices\" has distinct positions in rack:\nmodel += [AllDifferent(x),\n final_sum == sum(t)]\n\nfor i in range(len(cable_struct)):\n a, b, num = cable_struct[i]\n model += [t[i] == abs(x[a] - x[b]) * num]\n\nmodel.minimize(final_sum)\n\n# Solve\nmodel.solve()\n\n# Print the solution\nsolution = {\"final_sum\": final_sum.value()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__calvin_puzzle", "model": "# Data\nn = 5\n# End of data\n\n# Import libraries\nfrom cpmpy import *\nimport json\n\n# Decision variables\nx = intvar(1, n * n, shape=(n, n), name=\"x\")\n\nx_flat = [x[i, j] for i in range(n) for j in range(n)]\n\nmodel = Model(AllDifferent(x_flat))\nmodel += (x[0, 0] == 1)\n\nfor k in range(1, n * n):\n i = intvar(0, n - 1, name=f\"i_{k}\")\n j = intvar(0, n - 1, name=f\"j_{k}\")\n a = intvar(-3, 3, name=f\"a_{k}\")\n b = intvar(-3, 3, name=f\"b_{k}\")\n\n # Ensure that we are in the square\n model += [i + a >= 0, i + a <= n - 1, j + b >= 0, j + b <= n - 1]\n\n # model += [a != -1, a != 1, b != -1, b != 1]\n\n model += [((abs(a) == 3) & (b == 0)) |\n ((abs(b) == 3) & (a == 0)) |\n ((abs(a) == 2) & (abs(b) == 2))\n ]\n\n # Valid moved\n # model += [ ((a == 3) & (b == 0)) |\n # ((a == -3) & (b == 0)) |\n\n # ((b == 3) & (a == 0)) |\n # ((b == -3) & (a == 0)) |\n\n # ((a == 2) & (b == 2)) |\n # ((a == 2) & (b == -2)) |\n # ((a == -2) & (b == 2)) |\n # ((a == -2) & (b == -2))\n # ]\n\n # 1) First: fix this k, i.e.\n model += [k == Element(x_flat, (i * n) + j)]\n\n # 2) Then, find the position of the next value, i.e.\n model += [(k + 1) == Element(x_flat, ((i + a) * n) + (j + b))]\n\n# Solve the model\nmodel.solve()\n\n# Print the solution\nsolution = {\"x\": x.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__candies", "model": "# Data\nratings = [2, 3, 4, 4, 4, 2, 1, 3, 4] # Ratings of the children\n# End of data\n\n# Import libraries\nfrom cpmpy import *\nimport json\n\n# Parameters\nn = len(ratings)\n\n# variables\nx = intvar(1, n, shape=n, name=\"x\") # number of candies for each child\nz = intvar(1, n * n, name=\"z\") # total number of candies\n\n# constraints\nmodel = Model([z == sum(x),\n z >= n])\n\nfor i in range(1, n):\n if ratings[i - 1] > ratings[i]:\n model += (x[i - 1] > x[i])\n elif ratings[i - 1] < ratings[i]:\n model += (x[i - 1] < x[i])\n\nmodel.minimize(z)\n# Solve the model\nmodel.solve()\n\n# Print the solution\nsolution = {\"z\": z.value(), \"x\": x.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__capital_budget", "model": "# Import libraries\nfrom cpmpy import *\nimport json\n\n# Parameters\nbudget = 14\nnpv = [16, 22, 12, 8]\ncash_flow = [5, 7, 4, 3]\nn = 4\n\n# variables\nx = boolvar(shape=n, name=\"x\") # x[i] = 1 if investments i\nz = intvar(0, 1000, name=\"z\") # total NPV in thousands of dollars\n\n# constraints\nmodel = Model([\n # the sum of all choosen investments must be less than the budget\n sum(x * cash_flow) <= budget,\n z == sum(x * npv)\n])\n\n# Objective: maximize the NPV\nmodel.maximize(z)\n\n# Solve the model\nmodel.solve()\n\n# Print the solution\nsolution = {\"z\": z.value(), \"x\": x.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__chess_set", "model": "# Import libraries\nfrom cpmpy import *\nimport json\n\n# Decision variables\nsmall_set = intvar(0, 100, name=\"small_set\")\nlarge_set = intvar(0, 100, name=\"large_set\")\nmax_profit = intvar(0, 10000, name=\"max_profit\")\n\n# Model\nmodel = Model([\n small_set + 3 * large_set <= 200, # Boxwood constraint\n 3 * small_set + 2 * large_set <= 160, # Lathe-hours constraint\n max_profit == 5 * small_set + 20 * large_set # Profit calculation\n])\n\n# Objective: maximize the profit\nmodel.maximize(max_profit)\n\n# Solve the model\nmodel.solve()\n\n# Print the solution\nsolution = {\n \"small_set\": small_set.value(),\n \"large_set\": large_set.value(),\n \"max_profit\": max_profit.value()\n}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__circling_squares", "model": "# Import libraries\nfrom cpmpy import *\nimport json\n\n\ndef s(x1, x2, y1, y2):\n return x1 * x1 + x2 * x2 == y1 * y1 + y2 * y2\n\n\nn = 10\n\n# variables\nx = intvar(1, 99, shape=n, name=\"x\")\nA, B, C, D, E, F, G, H, I, K = x\n\n# constraints\nmodel = Model([AllDifferent(x),\n A == 16,\n B == 2,\n F == 8,\n G == 14,\n\n s(A, B, F, G),\n s(B, C, G, H),\n s(C, D, H, I),\n s(D, E, I, K),\n s(E, F, K, A),\n ])\n# End of CPMPy script\n\n# Solve\nmodel.solve()\n\n# Print the solution\nsolution = {\"A\": A.value(), \"B\": B.value(), \"C\": C.value(), \"D\": D.value(), \"E\": E.value(),\n \"F\": F.value(), \"G\": G.value(), \"H\": H.value(), \"I\": I.value(), \"K\": K.value()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__circular_table_averbach_1_2", "model": "# Import libraries\nfrom cpmpy import *\nimport json\n\n\n# a is right to b\ndef right_to(a, b):\n # return ((a == b+1) | (a == b-2) )\n return (a == (b + 1) % 3)\n\n\n# a is left to b\ndef left_to(a, b):\n return [right_to(b, a)]\n\n\nn = 3\n\n# variables\nplayers = intvar(0, 2, shape=n, name=\"players\")\nx, y, z = players\n\nnationalities = intvar(0, 2, shape=n, name=\"women\")\namerican, english, french = nationalities\n\nmodel = Model([AllDifferent(players),\n AllDifferent([american, english, french]),\n right_to(y, american),\n left_to(x, french),\n\n # symmetry breaking\n x == 0\n ])\n\nmodel.solve()\n\n# Print the solution\nsolution = {\"x\": x.value(), \"y\": y.value(), \"z\": z.value(), \"american\": american.value(), \"english\": english.value(),\n \"french\": french.value()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__clock_triplets", "model": "# Import libraries\nfrom cpmpy import *\nimport json\n\n# Parameters\nn = 12\n\n# variables\nx = intvar(1, n, shape=n, name=\"x\") # The numbers on the clock\ntriplet_sum = intvar(0, 21, name=\"triplet_sum\")\n\n# constraints\nmodel = Model([AllDifferent(x),\n x[0] == 12,\n x[1] > x[11],\n [(x[i % 12] + x[(i % 12) - 1] + x[(i % 12) - 2]) <= triplet_sum for i in range(n)],\n ])\n\n# Solve\nmodel.solve()\n\n# Print the solution\nsolution = {\"x\": x.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__cmo_2012", "model": "# Import libraries\nfrom cpmpy import *\nimport json\nfrom math import sqrt\n\n\ndef is_prime(n):\n \"\"\"Return True if n is prime, False otherwise\"\"\"\n if n < 2:\n return False\n for i in range(2, int(sqrt(n)) + 1):\n if n % i == 0:\n return False\n return True\n\n\ndef primes(n):\n \"\"\"Return a list of primes less than n\"\"\"\n primes = []\n for i in range(2, n):\n if is_prime(i):\n primes.append(i)\n return primes\n\n\nmax_val = 10000\nprime_list = primes(2012)\n\na = intvar(2012, max_val, name=\"a\")\nb = intvar(2, 2012, name=\"b\")\nn = intvar(2, 2012, name=\"n\")\n# p can only take primes (reduced below).\n# How do one create a list of specific domain in cpmpy?\np = intvar(2, 2012, name=\"p\")\n\nmodel = Model(minimize=a)\n\nfor i in range(max(prime_list)):\n # if not i in prime_list:\n # model += [p != i]\n if not is_prime(i):\n model += [p != i]\n\nmodel += [a >= b]\nmodel += [p == a - b]\nmodel += [a * b == n * n]\n\nmodel.solve()\n\nsolution = {\"a\": a.value(), \"b\": b.value(), \"n\": n.value(), \"p\": p.value()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__coin3_application", "model": "# Import libraries\nfrom cpmpy import *\nimport json\n\n# Parameters\ndenominations = [1, 2, 5, 10, 20, 50] # Euro cent denominations\nn = len(denominations)\n\n# declare variables\nx = intvar(0, 99, shape=n, name=\"x\") # The number of each type of coin used\nnum_coins = intvar(0, 99, name=\"num_coins\") # The total number of coins used\n\nmodel = Model(minimize=num_coins)\n\n# constraints\n\n# number of used coins, to be minimized\nmodel += [num_coins == sum(x)]\n\n# Check that all changes from 1 to 99 can be made.\nfor j in range(1, 100):\n tmp = intvar(0, 99, shape=n)\n model += [sum(tmp * denominations) == j]\n model += [tmp[i] <= x[i] for i in range(n)]\n\n# Solve the model\nmodel.solve()\n\n# Print the solution\nsolution = {\"x\": x.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__coins_grid", "model": "# Import libraries\nfrom cpmpy import *\nimport json\nimport numpy as np\n\n# Parameters\nn = 31\nc = 14\n\n# variables\nx = intvar(0, 1, shape=(n, n), name=\"x\") # The coins on the grid (1 if a coin is placed, 0 otherwise)\nz = intvar(0, 1000000, name=\"z\") # The sum of the quadratic horizontal distance from the main diagonal\n\nmodel = Model([\n # every row adds up to c\n [sum(row) == c for row in x],\n\n # every col adds up to c\n [sum(col) == c for col in x.transpose()],\n\n # quadratic horizonal distance\n z == sum([x[i, j] * abs(i - j) * abs(i - j) for i in range(0, n) for j in range(0, n)]),\n\n], minimize=z\n)\n\n# Solve the model\nmodel.solve()\n\n# Print the solution\nsolution = {\"x\": x.value().tolist(), \"z\": z.value()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__contracting_costs", "model": "# Import libraries\nfrom cpmpy import *\nimport json\n\nn = 6\nx = intvar(1, 5300, shape=n, name=\"x\")\npaper_hanger, painter, plumber, electrician, carpenter, mason = x\n\ncosts = [[paper_hanger, painter, 1100],\n [painter, plumber, 1700],\n [plumber, electrician, 1100],\n [electrician, carpenter, 3300],\n [carpenter, mason, 5300],\n [mason, painter, 3200],\n ]\n\n# model = Model([1100 == paper_hanger + painter,\n# 1700 == painter + plumber,\n# 1100 == plumber + electrician,\n# 3300 == electrician + carpenter,\n# 5300 == carpenter + mason,\n# 3200 == mason + painter,\n# ])\n\n# Alternative encoding:\nmodel = Model([sum(costs[i][:2]) == costs[i][2] for i in range(n)])\n\n# Solve\nmodel.solve()\n\n# Print the solution\nsolution = {\"paper_hanger\": paper_hanger.value(), \"painter\": painter.value(), \"plumber\": plumber.value(),\n \"electrician\": electrician.value(), \"carpenter\": carpenter.value(), \"mason\": mason.value()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__covering_opl", "model": "# Data\nnb_workers = 32 # Number of workers\nnum_tasks = 15 # Number of tasks\nQualified = [ # Which worker is qualified for each task (1-based indexing)\n [1, 9, 19, 22, 25, 28, 31],\n [2, 12, 15, 19, 21, 23, 27, 29, 30, 31, 32],\n [3, 10, 19, 24, 26, 30, 32], [4, 21, 25, 28, 32],\n [5, 11, 16, 22, 23, 27, 31], [6, 20, 24, 26, 30, 32],\n [7, 12, 17, 25, 30, 31], [8, 17, 20, 22, 23],\n [9, 13, 14, 26, 29, 30, 31], [10, 21, 25, 31, 32],\n [14, 15, 18, 23, 24, 27, 30, 32], [18, 19, 22, 24, 26, 29, 31],\n [11, 20, 25, 28, 30, 32], [16, 19, 23, 31],\n [9, 18, 26, 28, 31, 32]]\nCost = [ # Cost of hiring each worker\n 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5,\n 5, 6, 6, 6, 7, 8, 9\n]\n# End of data\n\n# Import libraries\nfrom cpmpy import *\nimport json\n\n# Parameters\nWorkers = list(range(nb_workers))\nTasks = list(range(num_tasks))\n\n#\n# variables\n#\nworkers = boolvar(shape=nb_workers, name=\"workers\") # 1 if the worker is hired, 0 otherwise\ntotal_cost = intvar(0, nb_workers * sum(Cost), name=\"total_cost\") # Total cost of hiring the workers\n\nmodel = Model(minimize=total_cost)\n\n#\n# constraints\n#\nmodel += [total_cost == sum(workers * Cost)]\n\nfor j in Tasks:\n # Sum the cost for hiring the qualified workers\n # (also, make 0-base)\n model += [sum([workers[c - 1] for c in Qualified[j]]) >= 1]\n\n# Solve the model\nmodel.solve()\n\n# Print the solution\nsolution = {\"total_cost\": total_cost.value(), \"workers\": workers.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__crew", "model": "# Data\nattributes = [\n # steward, hostess, french, spanish, german\n [1, 0, 0, 0, 1], # Tom = 1\n [1, 0, 0, 0, 0], # David = 2\n [1, 0, 0, 0, 1], # Jeremy = 3\n [1, 0, 0, 0, 0], # Ron = 4\n [1, 0, 0, 1, 0], # Joe = 5\n [1, 0, 1, 1, 0], # Bill = 6\n [1, 0, 0, 1, 0], # Fred = 7\n [1, 0, 0, 0, 0], # Bob = 8\n [1, 0, 0, 1, 1], # Mario = 9\n [1, 0, 0, 0, 0], # Ed = 10\n [0, 1, 0, 0, 0], # Carol = 11\n [0, 1, 0, 0, 0], # Janet = 12\n [0, 1, 0, 0, 0], # Tracy = 13\n [0, 1, 0, 1, 1], # Marilyn = 14\n [0, 1, 0, 0, 0], # Carolyn = 15\n [0, 1, 0, 0, 0], # Cathy = 16\n [0, 1, 1, 1, 1], # Inez = 17\n [0, 1, 1, 0, 0], # Jean = 18\n [0, 1, 0, 1, 1], # Heather = 19\n [0, 1, 1, 0, 0] # Juliet = 20\n]\n\n# The columns are in the following order:\n# staff : Overall number of cabin crew needed\n# stewards : How many stewards are required\n# hostesses : How many hostesses are required\n# french : How many French speaking employees are required\n# spanish : How many Spanish speaking employees are required\n# german : How many German speaking employees are required\nrequired_crew = [\n [4, 1, 1, 1, 1, 1], # Flight 1\n [5, 1, 1, 1, 1, 1], # Flight 2\n [5, 1, 1, 1, 1, 1], # ..\n [6, 2, 2, 1, 1, 1],\n [7, 3, 3, 1, 1, 1],\n [4, 1, 1, 1, 1, 1],\n [5, 1, 1, 1, 1, 1],\n [6, 1, 1, 1, 1, 1],\n [6, 2, 2, 1, 1, 1], # ...\n [7, 3, 3, 1, 1, 1] # Flight 10\n]\n# End of data\n\n# Import libraries\nfrom cpmpy import *\nimport json\n\n\n# Parameters\nnum_persons = len(attributes) # number of persons\nnum_flights = len(required_crew) # number of flights\n\n#\n# declare variables\n#\ncrew = boolvar(shape=(num_flights, num_persons), name=\"crew\")\n\n# number of working persons\nnum_working = intvar(1, num_persons, name=\"num_working\")\n\n#\n# constraints\n#\nmodel = Model()\n\n# number of working persons\nmodel += [num_working == sum([sum([crew[(f, p)] for f in range(num_flights)]) >= 1\n for p in range(num_persons)])]\n\nfor f in range(num_flights):\n # size of crew\n tmp = [crew[(f, i)] for i in range(num_persons)]\n model += [sum(tmp) == required_crew[f][0]]\n\n # attributes and requirements\n for j in range(5):\n tmp = [attributes[i][j] * crew[(f, i)] for i in range(num_persons)]\n model += [sum(tmp) >= required_crew[f][j + 1]]\n\n# after a flight, break for at least two flights\nfor f in range(num_flights - 2):\n for i in range(num_persons):\n model += [crew[f, i] + crew[f + 1, i] + crew[f + 2, i] <= 1]\n\n# extra contraint: all must work at least two of the flights\n# for i in range(num_persons):\n# model += [sum([crew[f,i] for f in range(num_flights)]) >= 2]\n\n# Solve the model\nmodel.solve()\n\n# Print the solution\nsolution = {\"crew\": crew.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__crossword", "model": "# Import libraries\nfrom cpmpy import *\nimport json\n\na = 1;\nb = 2;\nc = 3;\nd = 4;\ne = 5;\nf = 6;\ng = 7;\nh = 8;\ni = 9;\nj = 10;\nk = 11;\nl = 12;\nm = 13;\nn = 14;\no = 15;\np = 16;\nq = 17;\nr = 18;\ns = 19;\nt = 20;\nu = 21;\nv = 22;\nw = 23;\nx = 24;\ny = 25;\nz = 26;\n\nAA = [\n [h, o, s, e, s], # HOSES\n [l, a, s, e, r], # LASER\n [s, a, i, l, s], # SAILS\n [s, h, e, e, t], # SHEET\n [s, t, e, e, r], # STEER\n [h, e, e, l, 0], # HEEL\n [h, i, k, e, 0], # HIKE\n [k, e, e, l, 0], # KEEL\n [k, n, o, t, 0], # KNOT\n [l, i, n, e, 0], # LINE\n [a, f, t, 0, 0], # AFT\n [a, l, e, 0, 0], # ALE\n [e, e, l, 0, 0], # EEL\n [l, e, e, 0, 0], # LEE\n [t, i, e, 0, 0] # TIE\n]\nword_len = 5\nnum_words = len(AA)\n\nnum_overlapping = 12\noverlapping = [\n [0, 2, 1, 0], # s\n [0, 4, 2, 0], # s\n\n [3, 1, 1, 2], # i\n [3, 2, 4, 0], # k\n [3, 3, 2, 2], # e\n\n [6, 0, 1, 3], # l\n [6, 1, 4, 1], # e\n [6, 2, 2, 3], # e\n\n [7, 0, 5, 1], # l\n [7, 2, 1, 4], # s\n [7, 3, 4, 2], # e\n [7, 4, 2, 4] # r\n]\n\nA = intvar(0, 26, shape=(num_words, word_len), name=\"A\")\n\nn = 8\nE = intvar(0, num_words, shape=n, name=\"E\") # The selected words for each slot\n\nmodel = Model()\n\nfor I in range(num_words):\n for J in range(word_len):\n model += [A[I, J] == AA[I][J]]\n\nmodel += [AllDifferent(E)]\n\nfor I in range(num_overlapping):\n model += [A[E[overlapping[I][0]], overlapping[I][1]] == A[E[overlapping[I][2]], overlapping[I][3]]]\n\nmodel.solve()\n\n# Print the solution\nsolution = {\"E\": E.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__crypta", "model": "# Import libraries\nfrom cpmpy import *\nimport json\n\nmodel = Model()\n\n# variables\nLD = intvar(0, 9, shape=10, name=\"LD\")\nA, B, C, D, E, F, G, H, I, J = LD\n\nSr1 = intvar(0, 1, name=\"Sr1\")\nSr2 = intvar(0, 1, name=\"Sr2\")\n\n#\n# constraints\n#\nmodel += [AllDifferent(LD)]\nmodel += [B >= 1]\nmodel += [D >= 1]\nmodel += [G >= 1]\n\nmodel += [A + 10 * E + 100 * J + 1000 * B + 10000 * B + 100000 * E +\n 1000000 * F + E + 10 * J + 100 * E + 1000 * F + 10000 * G +\n 100000 * A + 1000000 * F == F + 10 * E + 100 * E + 1000 * H +\n 10000 * I + 100000 * F + 1000000 * B + 10000000 * Sr1]\n\nmodel += [C + 10 * F + 100 * H + 1000 * A + 10000 * I + 100000 * I +\n 1000000 * J + F + 10 * I + 100 * B + 1000 * D + 10000 * I +\n 100000 * D + 1000000 * C + Sr1 == J + 10 * F + 100 * A + 1000 * F +\n 10000 * H + 100000 * D + 1000000 * D + 10000000 * Sr2]\n\nmodel += [A + 10 * J + 100 * J + 1000 * I + 10000 * A + 100000 * B + B +\n 10 * A + 100 * G + 1000 * F + 10000 * H + 100000 * D + Sr2 == C +\n 10 * A + 100 * G + 1000 * E + 10000 * J + 100000 * G]\n\n# Solve the model\nmodel.solve()\n\n# Print the solution\nsolution = {\"A\": A.value(), \"B\": B.value(), \"C\": C.value(), \"D\": D.value(), \"E\": E.value(), \"F\": F.value(),\n \"G\": G.value(), \"H\": H.value(), \"I\": I.value(), \"J\": J.value()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__curious_set_of_integers", "model": "# Import libraries\nfrom cpmpy import *\nimport json\n\n\nmodel = Model()\n\n# data\nn = 5\nmax_val = 10000\n\n# variables\nx = intvar(0, max_val, shape=n)\nnumber = x[-1]\n\n# constraints\nmodel += [AllDifferent(x)]\nmodel += x[0] == 1\nmodel += x[1] == 3\nmodel += x[2] == 8\nmodel += x[3] == 120\n\nfor i in range(n):\n for j in range(n):\n if i != j:\n p = intvar(0, max_val) # the root of the product of x[i] and x[j] plus one\n model += [p * p == x[i] * x[j] + 1] # the product of any two integers is one less than a perfect square\n\n# Solve the model\nmodel.solve()\n\n# Print the solution\nsolution = {\"number\": number.value()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__cur_num", "model": "# Import libraries\nfrom cpmpy import *\nimport json\n\npeculiar, a, b, c, d, e = intvar(1, 2_000_000, shape=6) # number, number + 1, its square root, number/2, number/2 + 1, its square root\n\nmodel = Model([\n peculiar != 48, # 48 is already known\n\n peculiar + 1 == a, # if you add 1 to it\n a == b * b, # the result is a square number\n\n peculiar == 2 * c, # if you to its half\n c + 1 == d, # add 1\n d == e * e, # you also get a square number\n])\n\n# Solve the model\nmodel.solve()\n\n# Print the solution\nsolution = {\"peculiar\": peculiar.value()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__devils_word", "model": "# Data\narr = [72, 229, 107, 97, 110, 32, 75, 106, 101, 108, 108, 101, 114, 115, 116, 114, 97, 110, 100]\ntotal = 666\n# End of data\n\n# Import libraries\nfrom cpmpy import *\nimport json\n\nmodel = Model()\n\nn = len(arr)\nmax_val = max(arr)\n\n# variables\nplus = boolvar(shape=n, name=\"plus\") # is the number arr[i] to be added\nminus = boolvar(shape=n, name=\"minus\") # or is it to be subtracted?\n\n# array with the number with correct sign\nresult = intvar(-max_val, max_val, shape=n, name=\"result\")\n\n# constraints\nfor i in range(n):\n # either plus or minus\n model += [plus[i] + minus[i] == 1]\n # calculate the result array\n model += [result[i] == arr[i] * plus[i] + (-arr[i]) * minus[i]]\n\n# calculate the sum of the numbers in arr\nmodel += [total == sum([result[i] for i in range(n)])]\n\n# Solve the model\nmodel.solve()\n\n# Print the solution\nsolution = {\"result\": result.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__de_bruijn_sequence", "model": "# Import libraries\nfrom cpmpy import *\nimport json\n\nbase = 2\nn = 4\nm = base ** n\n\nx = intvar(0, (base ** n) - 1, shape=m) # all possible numbers\nbinary = intvar(0, base - 1, shape=(m, n))\nde_bruijn = intvar(0, base - 1, shape=m) # the de Bruijn sequence\n\nmodel = Model()\n\nmodel += [AllDifferent(x)]\n\n# convert x[i] <-> binary[i,..]\nmodel += [[x[i] == sum([binary[i][j] * (base ** (n - j - 1)) for j in range(n)]) for i in range(m)]]\n\n# de Bruijn property for the nodes\nmodel += [[binary[i - 1][j] == binary[i][j - 1] for j in range(1, n) for i in range(1, m)]]\n\n# ... and around the corner\nmodel += [[binary[m - 1][j] == binary[0][j - 1] for j in range(1, n)]]\n\n# convert binary -> de_bruijn\nmodel += [[de_bruijn[i] == binary[i][0] for i in range(m)]]\n\n# symmetry breaking: x[1] is the minimum number\n# model += [[x[0] < x[i] for i in range(1, m)]]\n\n# Solve the model\nmodel.solve()\n\n# Print the solution\nsolution = {\"de_bruijn\": de_bruijn.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__diet", "model": "# Data\nn = 4\nprice = [50, 20, 30, 80] # in cents\nlimits = [500, 6, 10, 8] # requirements for each nutrition type\n# End of data\n\n# Import libraries\nfrom cpmpy import *\nimport json\n\n\n# macros for each food\ncalories = [400, 200, 150, 500]\nchocolate = [3, 2, 0, 0]\nsugar = [2, 2, 4, 4]\nfat = [2, 4, 1, 5]\n\nx = intvar(0, 10000, shape=n)\ncost = intvar(0, 1000, name=\"cost\")\nmodel = Model(\n [\n sum(x * calories) >= limits[0],\n sum(x * chocolate) >= limits[1],\n sum(x * sugar) >= limits[2],\n sum(x * fat) >= limits[3],\n cost == sum(x * price),\n ],\n minimize=cost\n)\n\n# Solve and print the solution\nmodel.solve()\n\n# Print the solution\nsolution = {\"cost\": cost.value()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__dinner", "model": "# Import libraries\nfrom cpmpy import *\nimport json\n\n\n# variables\n# \"We're going out to dinner taking 1-6 grandparents, 1-10 parents and/or 1-40 children\"\ngrandparents = intvar(1, 6, name=\"grandparents\")\nparents = intvar(1, 10, name=\"parents\")\nchildren = intvar(1, 40, name=\"children\")\n\nmodel = Model([\n # \"Grandparents cost $3 for dinner, parents $2 and children $0.50\"\n # \"There must be 20 total people at dinner ...\n grandparents * 6 + parents * 4 + children * 1 == 20 * 2, # multiplied by 2 to not have decimals\n # ... and it must cost $20\"\n grandparents + parents + children == 20\n])\n\n# Solve and print the solution\nmodel.solve()\n\nsolution = {\n \"grandparents\": grandparents.value(),\n \"parents\": parents.value(),\n \"children\": children.value()\n}\nprint(json.dumps(solution, indent=4))\n# End of CPMPy script"} +{"id": "hakan_examples__discrete_tomography", "model": "# Data\nrow_sums = [0, 0, 8, 2, 6, 4, 5, 3, 7, 0, 0] # Each number represents the number of 1s in the row\ncol_sums = [0, 0, 7, 1, 6, 3, 4, 5, 2, 7, 0, 0] # Each number represents the number of 1s in the column\n# End of data\n\n# Import libraries\nfrom cpmpy import *\nimport json\n\nr = len(row_sums)\nc = len(col_sums)\nmatrix = intvar(0, 1, shape=(r, c), name=\"x\")\n\nmodel = Model([\n [sum(row) == row_sums[i] for (row, i) in zip(matrix, range(r))],\n [sum(col) == col_sums[j] for (col, j) in zip(matrix.transpose(), range(c))]\n])\n\n# Solve and print the solution\nmodel.solve()\n\nsolution = {\n \"matrix\": matrix.value().tolist()\n}\nprint(json.dumps(solution, indent=4))\n# End of CPMPy script"} +{"id": "hakan_examples__divisible_by_1_through_9", "model": "# Import libraries\nfrom cpmpy import *\nimport json\n\n# Decision Variables\nx = intvar(0, 9, shape=10) # The 10 digits\nt = intvar(0, 10**10, shape=10) # The 10 numbers formed by the first n digits\nnumber = t[9]\n\nmodel = Model()\n\n# Constraints\nmodel += AllDifferent(x)\nfor i in range(10):\n # find current number at position i\n cur_num = sum([x[j] * (10 ** (i-j)) for j in range(i+1)])\n model += t[i] == cur_num\n\n # current number must be divisible by i+1\n model += t[i] % (i+1) == 0\n\n# solve\nmodel.solve()\n\n# print\nsolution = {\"number\": number.value()}\nprint(json.dumps(solution, indent=4))\n# End of CPMPy script"} +{"id": "hakan_examples__dudeney_numbers", "model": "# Import libraries\nfrom cpmpy import *\nimport json\n\n# max number of digits\nn = 6\n\n# Decision Variables\nnumber_digits = intvar(0, 9, shape=n)\nnumber = intvar(0, 10 ** n - 1)\ncube_root = intvar(1, 9 * n)\n\nmodel = Model()\n\n# Constraints\nmodel += number == cube_root * cube_root * cube_root\nmodel += cube_root == sum(number_digits)\nmodel += number == sum([number_digits[i] * (10 ** (n - i - 1)) for i in range(n)])\nmodel += number > 1\n\n# solve\nmodel.solve()\n\n# print\nsolution = {\"number\": number.value()}\nprint(json.dumps(solution, indent=4))\n# End of CPMPy script"} +{"id": "hakan_examples__eighteen_hole_golf", "model": "# Import libraries\nfrom cpmpy import *\nimport json\n\n# Parameters\nnum_holes = 18 # Number of holes\ntotal_length = 72 # Total length of the course\nhole_lengths = [3, 4, 5] # Possible lengths for each hole\n\n# Decision variables\nholes = intvar(3, 5, shape=num_holes, name=\"holes\") # Lengths of the holes\n\n# Model\nmodel = Model([\n sum(holes) == total_length\n])\n\n# Solve the model\nmodel.solve()\n\n# Print the solution\nsolution = {\"holes\": holes.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__equal_sized_groups", "model": "# Data\n# a: the array of elements to divide into groups\na = [1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4,\n 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7,\n 7, 7, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11,\n 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14,\n 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 18,\n 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20,\n 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22,\n 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,\n 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28, 28,\n 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 30, 30, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31,\n 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 34, 34, 34, 34, 34, 34,\n 34, 34, 34, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 36, 36, 36, 36, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,\n 37, 37, 37, 38, 38, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39, 40, 40, 40, 40, 40, 40, 40, 41, 41,\n 41, 41, 41, 41, 41, 41, 41, 41, 41, 42, 42, 42, 42, 42, 42, 42, 42, 43, 43, 43, 43, 43, 43, 43, 43, 44, 44, 44, 44,\n 44, 44, 44, 44, 44, 44, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,\n 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 47, 47, 47, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 49, 49, 49,\n 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 51, 51, 51, 51, 51, 51,\n 51, 51, 52, 52, 52, 52, 52, 52, 52, 52, 53, 53, 53, 53, 53, 53, 53, 53, 53, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,\n 54, 54, 54, 54, 54, 55, 55, 55, 55, 55, 55, 55, 55, 55, 56, 56, 56, 56, 56, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,\n 57, 57, 57, 57, 58, 58, 58, 58, 58, 58, 59, 59, 59, 59, 59, 59, 59, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,\n 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 62, 62, 62, 62, 62, 62, 62, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,\n 63, 64, 64, 64, 64, 64, 64, 64, 64, 65, 65, 65, 65, 65, 65, 65, 65, 65, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,\n 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 68, 68, 68, 68, 68, 68, 68, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 70,\n 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 72, 72, 72, 72, 72,\n 72, 72, 72, 72, 72, 72, 72, 72, 73, 73, 73, 73, 73, 73, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,\n 74, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 77, 77, 77, 77, 77, 77, 77,\n 78, 78, 78, 78, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 80, 80, 80, 80, 80, 80, 80, 80, 80, 81, 81, 81, 81, 81, 81,\n 81, 81, 81, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,\n 83, 83, 84, 84, 84, 84, 84, 84, 84, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 86, 86, 86, 86, 86, 86, 86, 86, 86, 87,\n 87, 87, 87, 87, 87, 87, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89, 89, 89, 89, 89, 90, 90, 90, 90, 90,\n 90, 90, 90, 90, 90, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,\n 92, 93, 93, 93, 93, 93, 93, 93, 94, 94, 94, 94, 94, 94, 94, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 96, 96,\n 96, 96, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 99,\n 99, 99, 99, 99, 99, 99, 99, 99, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100]\n# k: number of groups to divide the elements into\nk = 10\n# End of data\n\n# Import libraries\nfrom cpmpy import *\nimport json\nimport math\nimport numpy as np\n\n# Assert that we have enough different values to\n# create k groups\nnum_unique_values = len(np.unique(a))\nassert num_unique_values >= k, f\"Number of unique values ({num_unique_values}) is not >= k ({k})\"\n\nn = len(a)\ngsize = math.ceil(n / k) # average (ideal) size of each group\n\n# Decision variables\ns = intvar(1, n, shape=k) # Number of elements in each group\nx = intvar(1, n, shape=k - 1) # The break points\nz = intvar(0, n) # Number of errors (differences to ideal sized groups), to minimize\n\n# Model\nmodel = Model([\n z == sum([abs(s[i] - gsize) for i in range(k)]), # set the error as the sum of the differences to the ideal size\n s[0] == x[0] # the first break point's index is the size of the first group\n])\n\n# the size of each group is the difference between the break points\nfor i in range(1, k - 1):\n model += (s[i] == x[i] - x[i - 1])\nmodel += (s[k - 1] == n - x[k - 2])\n\n# Same values must be in the same group\nfor j in range(1, n):\n model += ((a[j - 1] == a[j]) <= (sum([x[p] == j for p in range(k - 1)]) == 0))\n\n# Minimize the error\nmodel.minimize(z)\n\n# Solve the model\nmodel.solve()\n\n# Print the solution\nsolution = {\"x\": x.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__facility_location", "model": "# Data\nwarehouse_s = [\"New York\", \"Los Angeles\", \"Chicago\", \"Atlanta\"]\nfixed_costs = [400, 500, 300, 150] # Weekly fixed costs per warehouse\nmax_shipping = 100 # Max units per week per warehouse\ndemands = [80, 70, 40] # Weekly demands for regions 1 to 3\nshipping_costs = [\n [20, 40, 50], # New York to regions 1, 2, 3\n [48, 15, 26], # Los Angeles to regions 1, 2, 3\n [26, 35, 18], # Chicago to regions 1, 2, 3\n [24, 50, 35] # Atlanta to regions 1, 2, 3\n]\n# End of data\n\n# Import libraries\nfrom cpmpy import *\nimport json\n\n# Parameters\nnum_companies = len(warehouse_s)\nnum_regions = len(demands)\nnew_york, los_angeles, chicago, atlanta = range(num_companies)\ncosts = cpm_array(shipping_costs)\n\n# Decision Variables\nopen_warehouse = boolvar(shape=num_companies, name=\"open_warehouse\") # 1 if the warehouse is open, 0 otherwise\nships = intvar(0, max_shipping, shape=(num_companies, num_regions), name=\"ships\") # what to ship to each region\ntotal_cost = intvar(0, 10000, name=\"total_cost\") # total cost of shipping\n\n# Model\nmodel = Model()\n\n# each warehouse can only send max 100 units per week\nfor i in range(num_companies):\n model += [sum([open_warehouse[i] * ships[i, j] for j in range(num_regions)]) <= max_shipping]\n\n# the demands of the regions\nfor j in range(num_regions):\n model += [sum([open_warehouse[i] * ships[i, j] for i in range(num_companies)]) >= demands[j]]\n\n# connect open with ships\nfor i in range(num_companies):\n model += [open_warehouse[i].implies(sum([ships[i, j] for j in range(num_regions)]) > 0)]\n\n# total cost\nmodel += [total_cost == sum([open_warehouse[i] *\n (fixed_costs[i] + sum([ships[i, j] * costs[i, j] for j in range(num_regions)]))\n for i in range(num_companies)])]\n\n# 1. If the New York warehouse is opened, then the Los Angeles warehouse must be opened.\nmodel += [open_warehouse[new_york].implies(open_warehouse[los_angeles])]\n\n# 2. At most three warehouses can be opened.\nmodel += [sum(open_warehouse) <= 3]\n\n# 3. Either the Atlanta or the Los Angeles warehouse must be opened.\nmodel += [open_warehouse[atlanta] | open_warehouse[los_angeles]]\n\n# Objective: Minimize total cost\nmodel.minimize(total_cost)\n\n# Solve\nmodel.solve()\n\n# Print\nsolution = {\"total_cost\": total_cost.value(),\n \"open_warehouse\": open_warehouse.value().tolist(),\n \"ships\": ships.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__fancy_dress", "model": "# Import libraries\nfrom cpmpy import *\nimport json\n\n# variables\n# t: tie\n# h: hat\n# r: shirt\n# s: socks\n# n: entrance fee\nt = boolvar(name=\"t\")\nh = boolvar(name=\"h\")\nr = boolvar(name=\"r\")\ns = boolvar(name=\"s\")\nn = boolvar(name=\"n\")\ncost = intvar(0, 100, name=\"cost\")\n\nmodel = Model(minimize=cost)\n\nmodel += [t.implies(r) | n]\n\nmodel += [((s | r).implies(t | h)) | n]\n\nmodel += [(r | h | ~s).implies(t | n)]\n\nmodel += [cost == 10 * t + 2 * h + 12 * s + 11 * n]\n\nmodel.solve()\n\nsolution = {\"t\": t.value(), \"h\": h.value(), \"r\": r.value(), \"s\": s.value(), \"n\": n.value()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__fibonacci_even", "model": "# Import libraries\nfrom cpmpy import *\nimport json\n\nn = 35\nf = intvar(0, 10000000, shape=n + 1)\nx = boolvar(shape=n + 1)\nres = intvar(0, 100000000)\n\nmodel = Model([\n res == sum([x[i] * f[i] for i in range(1, n + 1)]),\n f[0] == 0,\n f[1] == 1,\n f[2] == 1,\n x[0] == 0,\n [f[i] == f[i - 1] + f[i - 2] for i in range(3, n + 1)],\n\n # only even valued < 4000000\n [((f[i] % 2 == 0) & (f[i] < 4000000)) == (x[i] == 1) for i in range(1, n + 1)]\n])\n\nmodel.solve()\n\nsolution = {\"res\": res.value()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__fifty_puzzle", "model": "# Import libraries\nfrom cpmpy import *\nimport json\n\n# Parameters\ntarget_sum = 50 # Target sum to achieve\nvalues = [15, 9, 30, 21, 19, 3, 12, 6, 25, 27] # Numbers on the dummies\nn = len(values)\n\n# Decision variables\ndummies = boolvar(shape=n, name=\"dummies\") # Boolean array to indicate which dummies are knocked over\n\n# Model\nmodel = Model([\n sum([values[i] * dummies[i] for i in range(n)]) == target_sum\n])\n\n# Solve the model\nmodel.solve()\n\n# Print the solution\nsolution = {\"dummies\": dummies.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__finding_celebrities", "model": "# Data\n\n# Adam knows [Dan,Alice,Peter,Eva], [2,3,4,5]\n# Dan knows [Adam,Alice,Peter], [1,4,5]\n# Eva knows [Alice,Peter], [4,5]\n# Alice knows [Peter], [5]\n# Peter knows [Alice] [4]\ngraph = [\n [1, 1, 1, 1, 1], # 1\n [1, 1, 0, 1, 1], # 2\n [0, 0, 1, 1, 1], # 3\n [0, 0, 0, 1, 1], # 4\n [0, 0, 0, 1, 1] # 5\n]\n# End of data\n\n# Import libraries\nfrom cpmpy import *\nimport json\n\nmodel = Model()\n\n# variables\nn = len(graph)\ncelebrities = boolvar(shape=n, name=\"celebrities\") # 1 if a celebrity\nnum_celebrities = intvar(0, n, name=\"num_celebrities\")\n\n# constraints\nmodel += (num_celebrities == sum(celebrities))\n\n# All persons know the celebrities,\n# and the celebrities only know celebrities.\nfor i in range(n):\n model += celebrities[i] == (\n (sum([graph[j][i] for j in range(n)]) == n) & (sum([graph[i][j] for j in range(n)]) == num_celebrities))\n\nmodel.solve()\n\nsolution = {\"celebrities\": celebrities.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__five_brigands", "model": "from cpmpy import *\nimport json\n\nA, B, C, D, E = x = intvar(1, 200, shape=5, name=\"x\")\n\nmodel = Model([\n A + B + C + D + E == 200,\n 6 * (A * 12 + B * 3 + C) + 3 * D + 2 * E == 6 * 200,\n])\n\nmodel.solve()\n\nsolution = {\"A\": A.value(), \"B\": B.value(), \"C\": C.value(), \"D\": D.value(), \"E\": E.value()}\nprint(json.dumps(solution))"} +{"id": "hakan_examples__five_statements", "model": "from cpmpy import *\nimport json\n\nstatements = boolvar(shape=5)\n\nmodel = Model([statements[i] == (sum(statements == 0) == i+1) for i in range(5)])\n\nmodel.solve()\n\nsolution = {\"statements\": statements.value().tolist()}\nprint(json.dumps(solution))"} +{"id": "hakan_examples__fixed_charge", "model": "# Data\nshirtM = 0\nshortM = 1\npantM = 2\nmachines = [shirtM, shortM, pantM]\nnum_machines = len(machines)\nrenting_cost = [200, 150, 100]\n\nshirt = 0\nshorts = 1\npants = 2\nproducts = [shirt, shorts, pants]\nnum_products = len(products)\n\nlabor = 0\ncloth = 1\nresources = [labor, cloth]\n\n# capacity of labor and cloth\ncapacity = [150, 160]\n\nmax_production = max(capacity)\n\n# profit, product type\nproduct = [[6, shirtM],\n [4, shortM],\n [7, pantM]]\n\n# resource: labor, cloth\nuse = [[3, 4],\n [2, 3],\n [6, 4]]\n# End of data\n\nfrom cpmpy import *\nimport json\n\n# variables\n\nrent = boolvar(shape=num_machines)\nproduce = intvar(0, max_production, shape=num_products)\nz = intvar(0, 10000)\n\nmodel = Model([z ==\n sum([product[p][0] * produce[p] for p in products]) -\n sum([renting_cost[m] * rent[m] for m in machines])\n ])\n\nfor r in resources:\n model += (sum([use[p][r] * produce[p] for p in products]) <= capacity[r])\n\nfor p in products:\n model += (produce[p] <= max_production * rent[p])\n\nmodel.maximize(z)\n\nmodel.solve()\n\nsolution = {\"z\": z.value()}\nprint(json.dumps(solution))"} +{"id": "hakan_examples__flip_rows_cols", "model": "# Data\ninput_matrix = [\n [33, 30, 10, -6, 18, -7, -11, 23, -6],\n [16, -19, 9, -26, -8, -19, -8, -21, -14],\n [17, 12, -14, 31, -30, 13, -13, 19, 16],\n [-6, -11, 1, 17, -12, -4, -7, 14, -21],\n [18, -31, 34, -22, 17, -19, 20, 24, 6],\n [33, -18, 17, -15, 31, -5, 3, 27, -3],\n [-18, -20, -18, 31, 6, 4, -2, -12, 24],\n [27, 14, 4, -29, -3, 5, -29, 8, -12],\n [-15, -7, -23, 23, -9, -8, 6, 8, -12],\n [33, -23, -19, -4, -8, -7, 11, -12, 31],\n [-20, 19, -15, -30, 11, 32, 7, 14, -5],\n [-23, 18, -32, -2, -31, -7, 8, 24, 16],\n [32, -4, -10, -14, -6, -1, 0, 23, 23],\n [25, 0, -23, 22, 12, 28, -27, 15, 4],\n [-30, -13, -16, -3, -3, -32, -3, 27, -31],\n [22, 1, 26, 4, -2, -13, 26, 17, 14],\n [-9, -18, 3, -20, -27, -32, -11, 27, 13],\n [-17, 33, -7, 19, -32, 13, -31, -2, -24],\n [-31, 27, -31, -29, 15, 2, 29, -15, 33],\n [-18, -23, 15, 28, 0, 30, -4, 12, -32],\n [-3, 34, 27, -25, -18, 26, 1, 34, 26],\n [-21, -31, -10, -13, -30, -17, -12, -26, 31],\n [23, -31, -19, 21, -17, -10, 2, -23, 23],\n [-3, 6, 0, -3, -32, 0, -10, -25, 14],\n [-19, 9, 14, -27, 20, 15, -5, -27, 18],\n [11, -6, 24, 7, -17, 26, 20, -31, -25],\n [-25, 4, -16, 30, 33, 23, -4, -4, 23]\n]\n# End of data\n\n# Import libraries\nfrom cpmpy import *\nimport json\n\nrows = len(input_matrix)\ncols = len(input_matrix[0])\n\nx = intvar(-100, 100, shape=(rows, cols), name=\"x\")\n\n# The domain is [-1,1], i.e. not including 0\nrow_signs = intvar(-1, 1, shape=rows, name=\"row_signs\")\ncol_signs = intvar(-1, 1, shape=cols, name=\"col_signs\")\n\n# for forcing rows and columns >= 0\nrow_sums = intvar(0, 300, shape=rows, name=\"row_sums\")\ncol_sums = intvar(0, 300, shape=cols, name=\"col_sums\")\n\n# total sum: to be minimized\ntotal_sum = intvar(0, 1000, name=\"total_sum\")\n\nmodel = Model(minimize=total_sum)\n\n# constraints\n\n# connect data + x + row_signs + col_signs\nfor i in range(rows):\n for j in range(cols):\n model += [x[i, j] == input_matrix[i][j] * row_signs[i] * col_signs[j]]\n\nfor i in range(rows):\n model += [row_signs[i] != 0]\n\nfor j in range(cols):\n model += [col_signs[j] != 0]\n\nmodel += [total_sum == x.sum()]\n\n# row sums\nmodel += [[row_sums[i] == sum([x[i, j] for j in range(cols)])] for i in range(rows)]\n\n# column sums\nmodel += [[col_sums[j] == sum([x[i, j] for i in range(rows)])] for j in range(cols)]\n\n# solve\nmodel.solve()\n\n# print\nsolution = {\"row_signs\": row_signs.value().tolist(), \"col_signs\": col_signs.value().tolist()}\nprint(json.dumps(solution, indent=4))\n# End of CPMPy script"} +{"id": "hakan_examples__flow_free_game", "model": "# Data\n# board[i][j] is the color of the cell at row i and column j, or 0 if the cell needs to be filled\nboard = [[1, 0, 0, 2, 3],\n [0, 0, 0, 4, 0],\n [0, 0, 4, 0, 0],\n [0, 2, 3, 0, 5],\n [0, 1, 5, 0, 0]]\n# End of data\n\n# Import libraries\nfrom cpmpy import *\nimport json\n\nM = len(board)\nN = len(board[0])\nB = intvar(1, 10, shape=(M, N), name=\"B\")\n\nmodel = Model()\n\nfor i in range(M):\n for j in range(N):\n same_neighs_ij = sum([B[i][j] == B[k][l]\n for k in range(M) for l in range(N) if abs(k - i) + abs(l - j) == 1])\n if board[i][j] != 0:\n model += [B[i, j] == board[i][j]]\n model += [same_neighs_ij == 1]\n else:\n model += [(same_neighs_ij == 2) | (B[i][j] == 0)]\n\nmodel.solve()\n\nsolution = {\"B\": B.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__football", "model": "# Import libraries\nfrom cpmpy import *\nimport numpy as np\nimport json\n\n# Parameters\n\n# Multiply money values with 1000\nbudget = 30000 # GBP thousands\nnum_players = [3, 8, 10, 5]\nnum_types = len(num_players)\nmax_num_players = max(num_players)\n# min/max of players to buy\nmin_max = [[1, 1],\n [2, max_num_players],\n [3, max_num_players],\n [2, max_num_players]]\n\n# cost matrix (0 means no player)\ncosts = [[ 730, 1280, 3880, 0, 0, 0, 0, 0, 0, 0],\n [ 920, 1310, 1620, 2410, 2790, 3280, 3910, 4570, 0, 0],\n [1800, 2630, 3170, 3769, 4140, 4750, 5380, 5930, 6780, 7130],\n [4460, 6470, 7780, 8390, 9500, 0, 0, 0, 0, 0]]\n\n# the decision variables, i.e. whether we should buy a player or not.\nx = boolvar(shape=(num_types, max_num_players), name=\"x\")\n\n# the total cost of the choosen players\nz = intvar(0, budget, name=\"z\") # total cost in GBP thousands\nnum_player_chosen = intvar(0, sum(num_players), name=\"num_player_chosen\")\n\nmodel = Model(\n [z == sum([x[i, j] * costs[i][j] for i in range(num_types) for j in range(max_num_players) if costs[i][j] > 0]),\n num_player_chosen == x.sum()\n ])\n\n# minimum/maximum of players to buy\nfor i in range(num_types):\n s = intvar(min_max[i][0], min_max[i][1], name=f\"s[{i}]\")\n model += [s == sum([x[i, j] == 1 for j in range(max_num_players) if costs[i][j] > 0])]\n\n# consider only the \"real\" players, i.e. not the \"0\" filled\nfor i in range(num_types):\n for j in range(max_num_players):\n model += [(costs[i][j] == 0) <= (x[i, j] == 0)]\n\nmodel += [z <= budget]\nmodel += [num_player_chosen >= 11]\n\nmodel.maximize(z)\nmodel.solve()\n\nsolution = {\"z\": z.value()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__four_islands", "model": "# Import libraries\nfrom cpmpy import *\nimport numpy as np\nimport json\n\nmodel = Model()\n\nn = 4\n\n[A, B, C, D] = range(n)\n\nisland = intvar(0, n - 1, shape=n, name=\"island\")\nPwana, Quero, Rayou, Skern = island\n\nexport = intvar(0, n - 1, shape=n, name=\"export\")\nalabaster, bananas, coconuts, durian_fruit = export\n\nattraction = intvar(0, n - 1, shape=n, name=\"attraction\")\nresort_hotel, ice_skating_rink, jai_alai_stadium, koala_preserve = attraction\n\nmodel += [AllDifferent(island),\n AllDifferent(export),\n AllDifferent(attraction)]\n\n# 1. The island noted for its koala preserve is due south of Pwana.\nmodel += [\n ((Pwana == A) & (koala_preserve == C))\n |\n ((Pwana == B) & (koala_preserve == D))\n]\n\n# 2. The island with the largest alabaster quarry is due west of Quero.\nmodel += [\n ((alabaster == A) & (Quero == B))\n |\n ((alabaster == C) & (Quero == D))\n]\n\n# 3. The island with the resort hotel is due east of the one that exports\n# durian fruit.\nmodel += [\n ((durian_fruit == A) & (resort_hotel == B))\n |\n ((durian_fruit == C) & (resort_hotel == D))\n]\n\n# 4. Skern and the island with the jai alai stadium are connected by a\n# north-south bridge.\nmodel += [\n ((Skern == A) & (jai_alai_stadium == C))\n |\n ((Skern == C) & (jai_alai_stadium == A))\n |\n ((Skern == B) & (jai_alai_stadium == D))\n |\n ((Skern == D) & (jai_alai_stadium == B))\n]\n\n# 5. Rayou and the island that exports bananas are connected by an\n# east-west bridge.\nmodel += [\n ((Rayou == A) & (bananas == B))\n |\n ((Rayou == B) & (bananas == A))\n |\n ((Rayou == C) & (bananas == D))\n |\n ((Rayou == D) & (bananas == C))\n]\n\n# 6. The islands noted for the South Pacific's largest ice skating rink\n# and for the jai alai stadium are not connected by a bridge.\nmodel += [\n ((ice_skating_rink == A) & (jai_alai_stadium == D))\n |\n ((ice_skating_rink == D) & (jai_alai_stadium == A))\n |\n ((ice_skating_rink == B) & (jai_alai_stadium == C))\n |\n ((ice_skating_rink == C) & (jai_alai_stadium == B))\n]\n\nmodel.solve()\n\nsolution = {\n \"island\": island.value().tolist(),\n \"export\": export.value().tolist(),\n \"attraction\": attraction.value().tolist()\n}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__four_numbers", "model": "# Data\nnumbers = [7, 8, 9, 10]\n# End of data\n\n# Import libraries\nfrom cpmpy import *\nimport numpy as np\nimport json\n\n\ndef increasing(args):\n \"\"\"\n Ensure that the values in args are increasing.\n \"\"\"\n return [args[i - 1] <= args[i] for i in range(1, len(args))]\n\n\nmodel = Model()\n\nm = len(numbers)\nn = 3\n\nx = intvar(1, 10, shape=n, name=\"x\")\n# coefficient matrix\ntmp = boolvar(shape=(m, n), name=\"tmp\")\n\nfor i in range(m):\n model += [sum([tmp[i, j] * x[j] for j in range(n)]) == numbers[i]]\n\nmodel += [increasing(x)]\n\nmodel.solve()\n\nsolution = {\n \"x\": x.value().tolist()\n}\n\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__fractions", "model": "# Import libraries\nfrom cpmpy import *\nimport numpy as np\nimport json\n\n# There is no data for this problem\n\n# Variables\nn = 9\nx = intvar(1, n, shape=9, name=\"x\")\nA, B, C, D, E, F, G, H, I = x\n\nD1 = intvar(1, n * n, name=\"D1\")\nD2 = intvar(1, n * n, name=\"D2\")\nD3 = intvar(1, n * n, name=\"D3\")\n\n# Constraints\nmodel = Model([AllDifferent(x),\n D1 == 10 * B + C,\n D2 == 10 * E + F,\n D3 == 10 * H + I,\n A * D2 * D3 + D * D1 * D3 + G * D1 * D2 == D1 * D2 * D3\n ])\n\n# Solve\nmodel.solve()\n\n# Output\nsolution = {\n \"A\": int(A.value()),\n \"B\": int(B.value()),\n \"C\": int(C.value()),\n \"D\": int(D.value()),\n \"E\": int(E.value()),\n \"F\": int(F.value()),\n \"G\": int(G.value()),\n \"H\": int(H.value()),\n \"I\": int(I.value())\n}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__frog_circle", "model": "# Import libraries\nfrom cpmpy import *\nimport numpy as np\nimport json\n\nn = 12\n\n# declare variables\nx = intvar(1, n, shape=(n,), name=\"x\")\npos = intvar(0, n - 1, shape=(n,), name=\"pos\")\nvisited = intvar(1, n, shape=(n,), name=\"visited\")\n\n# constraints\nmodel = Model([AllDifferent(x),\n AllDifferent(pos),\n AllDifferent(visited),\n # Fix first position\n x[0] == 1,\n pos[0] == 0,\n visited[0] == 1,\n ])\n\n# Loop through all the steps (except the initial)\nfor i in range(1, n):\n # The next position is the previous position + the value of x in that position\n model += [pos[i] == (pos[i - 1] + x[pos[i - 1]]) % n]\n # The number that is visited in this step\n model += [visited[i] == x[pos[i]]]\n\n# The position for n is n at \"6 o'clock\"\nmodel += [pos[n - 1] == n // 2]\nmodel += [x[n // 2] == n]\n\n# Solve\nmodel.solve()\n\n# Output\nsolution = {\n \"x\": x.value().tolist()\n}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__futoshiki", "model": "# Data\n# values[i,j] is the value in row i, column j. 0 means not set.\nvalues = [[0, 0, 3, 2, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0],\n [0, 0, 0, 0, 0]]\n\n# [i1,j1, i2,j2] requires that values[i1,j1] < values[i2,j2]\n# Note: 1-based\nlt = [[1, 2, 1, 1], [1, 4, 1, 5], [2, 3, 1, 3], [3, 3, 2, 3], [3, 4, 2, 4],\n [2, 5, 3, 5], [3, 2, 4, 2], [4, 4, 4, 3], [5, 2, 5, 1], [5, 4, 5, 3],\n [5, 5, 4, 5]]\n# End of data\n\n# Import libraries\nfrom cpmpy import *\nimport numpy as np\nimport json\n\nsize = len(values)\nRANGE = list(range(size))\nNUMQD = list(range(len(lt)))\n\n# variables\ngrid = intvar(1, size, shape=(size, size), name=\"field\")\n\n# constraints\nmodel = Model()\n\n# set initial values\nfor row in RANGE:\n for col in RANGE:\n if values[row][col] > 0:\n model += [grid[row, col] == values[row][col]]\n\n# all rows have to be different\nfor row in RANGE:\n model += [AllDifferent([grid[row, col] for col in RANGE])]\n\n# all columns have to be different\nfor col in RANGE:\n model += [AllDifferent([grid[row, col] for row in RANGE])]\n\n# all < constraints are satisfied\n# Also: make 0-based\nfor i in NUMQD:\n model += [grid[lt[i][0] - 1, lt[i][1] - 1] < grid[lt[i][2] - 1, lt[i][3] - 1]]\n\n# Solve\nmodel.solve()\n\n# Output\nsolution = {\n \"grid\": grid.value().tolist()\n}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__general_store", "model": "# Data\n\n# End of data\n\n# Import libraries\nfrom cpmpy import *\nimport numpy as np\nimport json\n\nn = 10\n\n# variables\nx = intvar(0, 9, shape=n, name=\"x\")\nC, H, E, S, A, B, O, W, P, L = x\n\n# constraints\nmodel = Model([AllDifferent(x),\n 10000 * C + 1000 * H + 100 * E + 10 * S + S\n + 1000 * C + 100 * A + 10 * S + H\n + 100000 * B + 10000 * O + 1000 * W + 100 * W + 10 * O + W\n + 10000 * C + 1000 * H + 100 * O + 10 * P + S\n + 100000 * A + 10000 * L + 1000 * S + 100 * O + 10 * P + S\n + 1000000 * P + 100000 * A + 10000 * L + 1000 * E + 100 * A + 10 * L + E\n + 1000 * C + 100 * O + 10 * O + L\n + 1000 * B + 100 * A + 10 * S + S\n + 1000 * H + 100 * O + 10 * P + S\n + 1000 * A + 100 * L + 10 * E + S\n + 1000 * H + 100 * O + 10 * E + S\n + 100000 * A + 10000 * P + 1000 * P + 100 * L + 10 * E + S\n + 1000 * C + 100 * O + 10 * W + S\n + 100000 * C + 10000 * H + 1000 * E + 100 * E + 10 * S + E\n + 100000 * C + 10000 * H + 1000 * S + 100 * O + 10 * A + P\n + 10000 * S + 1000 * H + 100 * E + 10 * E + P\n == 1000000 * A + 100000 * L + 10000 * L + 1000 * W + 100 * O + 10 * O + L\n ]\n )\n\n# Solve\nmodel.solve()\n\n# Output\nsolution = {\n \"C\": C.value(), \"H\": H.value(), \"E\": E.value(), \"S\": S.value(), \"A\": A.value(), \"B\": B.value(), \"O\": O.value(),\n \"W\": W.value(), \"P\": P.value(), \"L\": L.value()\n}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__giant_cat_army", "model": "# Import libraries\nfrom cpmpy import *\nimport numpy as np\nimport json\n\nmaxval = 60\nn = 24\n\n# variables\nx = intvar(0, maxval, shape=n, name=\"x\")\n\nmodel = Model([AllDifferent(x)])\n\n# Given\nmodel += [x[0] == 0]\n\n# x[1] == 5 || x[1] == 7\nmodel += [(x[1] == 5) | (x[1] == 7)]\nmodel += (x[n - 1] == 14)\n\nfor i in range(n - 1):\n model += [(x[i + 1] == x[i] + 5) |\n (x[i + 1] == x[i] + 7) |\n (x[i] == x[i + 1] * x[i + 1])]\n\n# 0 .. 2 .. 10 .. 14\nix2 = intvar(1, n, name=\"ix2\")\nix10 = intvar(1, n, name=\"ix10\")\nmodel += [2 == x[ix2]]\nmodel += [10 == x[ix10]]\nmodel += [ix2 < ix10]\n\n# Solve\nmodel.solve()\n\n# Output\nsolution = {\n \"x\": x.value().tolist()\n}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__handshaking", "model": "# Import libraries\nfrom cpmpy import *\nimport numpy as np\nimport json\nimport math\n\nn = 10\n\n# variables\n# can shake max n-2 hands\n# coded Pair1a,Pair1b, Pair2a,Pair2b, ...\nx = intvar(0, n - 2, shape=n, name=\"x\") # number of hands shaken by each person\nhil = x[0] # Hilary\n\n# who shake with whom:\n# (not him/herself and not his/her spouse)\ny = boolvar(shape=(n, n), name=\"y\")\ny_flat = [y[i, j] for i in range(n) for j in range(n)]\n\nmodel = Model()\n\n# constraints\n\n# We assumed that Hilary is in position x[0] and Hilary's spouse - Jocelyn - in x[1]\n# All except Hilary's counts are different.\nmodel += [AllDifferent(x[1:])]\n\nfor i in range(math.ceil(n / 2)):\n # don't shake hand with spouse\n model += [y[2 * i, 2 * i + 1] == 0,\n y[2 * i + 1, 2 * i] == 0]\n\nfor i in range(n):\n model += [y[i, i] == 0, # don't shake hand with oneself\n x[i] == y[i].sum() # how many hands has x[i] shaken\n ]\n\nfor i in range(n):\n for j in range(n):\n # symmetry of handshaking:\n # a shake hands with b <-> b shake hands with a\n model += [y[i,j] == y[j,i]]\n\n# Solve\nmodel.solve()\n\n# Output\nsolution = {\n \"hil\": hil.value()\n}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__hanging_weights", "model": "# Import libraries\nfrom cpmpy import *\nimport numpy as np\nimport json\nimport math\n\nN = 13\nx = intvar(1, N, shape=N, name=\"x\")\na, b, c, d, e, f, g, h, i, j, k, l, m = x\n\nmodel = Model([\n AllDifferent(x),\n 4 * a == b,\n 5 * c == d,\n 3 * e == 2 * f,\n 3 * g == 2 * (c + d),\n 3 * (a + b) + 2 * j == k + 2 * (g + c + d),\n 3 * h == 2 * (e + f) + 3 * i,\n (h + i + e + f) == l + 4 * m,\n 4 * (l + m + h + i + e + f) == 3 * (j + k + g + a + b + c + d)\n])\n\n# Solve\nmodel.solve()\n\n# Output\nsolution = {\n \"a\": int(a.value()),\n \"b\": int(b.value()),\n \"c\": int(c.value()),\n \"d\": int(d.value()),\n \"e\": int(e.value()),\n \"f\": int(f.value()),\n \"g\": int(g.value()),\n \"h\": int(h.value()),\n \"i\": int(i.value()),\n \"j\": int(j.value()),\n \"k\": int(k.value()),\n \"l\": int(l.value()),\n \"m\": int(m.value())\n}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__heterosquare", "model": "# Import libraries\nfrom cpmpy import *\nimport numpy as np\nimport json\nimport math\n\nn = 5\n\nmodel = Model()\n\n# variables\nx = intvar(1, n * n, shape=(n, n), name=\"x\")\n\nrow_sums = intvar(1, n ** 3, shape=n, name=\"row_sums\")\ncol_sums = intvar(1, n ** 3, shape=n, name=\"col_sums\")\n\ndiag1 = intvar(1, n ** 3, name=\"diag1\")\ndiag2 = intvar(1, n ** 3, name=\"diag2\")\n\n# constraints\n\n# all the entries in the matrix should be different\nmodel += (AllDifferent(x))\n\n# and all sums should be different\nmodel += (AllDifferent(row_sums + col_sums + [diag1, diag2]))\n\n# calculate rows sums\nfor i in range(n):\n model += (row_sums[i] == sum(x[i, :]))\n\n# calculate column sums\nfor j in range(n):\n model += (col_sums[j] == sum(x[:, j]))\n\n# diag1 sums\nmodel += (sum([x[i, i] for i in range(n)]) == diag1)\n\n# diag2 sums\nmodel += (sum([x[i, n - i - 1] for i in range(n)]) == diag2)\n\n# Solve\nmodel.solve()\n\n# Output\nsolution = {\n \"x\": x.value().tolist(),\n}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__hidato", "model": "# Data\n# 0 is for empty cells that need to be filled. 1-144 are the numbers that are already filled.\npuzzle = [[0, 0, 134, 2, 4, 0, 0, 0, 0, 0, 0, 0],\n [136, 0, 0, 1, 0, 5, 6, 10, 115, 106, 0, 0],\n [139, 0, 0, 124, 0, 122, 117, 0, 0, 107, 0, 0],\n [0, 131, 126, 0, 123, 0, 0, 12, 0, 0, 0, 103],\n [0, 0, 144, 0, 0, 0, 0, 0, 14, 0, 99, 101],\n [0, 0, 129, 0, 23, 21, 0, 16, 65, 97, 96, 0],\n [30, 29, 25, 0, 0, 19, 0, 0, 0, 66, 94, 0],\n [32, 0, 0, 27, 57, 59, 60, 0, 0, 0, 0, 92],\n [0, 40, 42, 0, 56, 58, 0, 0, 72, 0, 0, 0],\n [0, 39, 0, 0, 0, 0, 78, 73, 71, 85, 69, 0],\n [35, 0, 0, 46, 53, 0, 0, 0, 80, 84, 0, 0],\n [36, 0, 45, 0, 0, 52, 51, 0, 0, 0, 0, 88]]\n# End of data\n\n# Import libraries\nfrom cpmpy import *\nimport numpy as np\nimport json\nimport math\n\nmodel = Model()\n\nr, c = len(puzzle), len(puzzle[0])\n\nx = intvar(1, r * c, shape=(c, r), name=\"x\")\n\nmodel += AllDifferent(x)\n\n# Fill in the known values\nfor i in range(r):\n for j in range(c):\n if puzzle[i][j] > 0:\n model += [x[i, j] == puzzle[i][j]]\n\n# From the numbers k = 1 to r*c-1, find this position, and then the position of k+1\nfor k in range(1, r * c):\n i = intvar(0, r)\n j = intvar(0, c)\n a = intvar(-1, 1)\n b = intvar(-1, 1)\n\n # 1) First: fix \"this\" k\n # 2) and then find the position of the next value (k+1)\n model += [\n k == x[i,j],\n k + 1 == x[i+a,j+b]\n ]\n\n # Ensure that the next value is within the matrix, and that it is not the same cell\n model += [\n i + a >= 0,\n j + b >= 0,\n i + a < r,\n j + b < c,\n ((a != 0) | (b != 0))\n ]\n\n# Solve\nmodel.solve()\n\n# Output\nsolution = {\n \"x\": x.value().tolist(),\n}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__huey_dewey_louie", "model": "# Import libraries\nfrom cpmpy import *\nimport json\n\np = boolvar(shape=3)\nhuey, dewey, louie = p\n\nmodel = Model([\n # Huey: Dewey and Louie has equal share in it; if one is quilty, so is the other.\n dewey == louie,\n\n # Dewey: If Huey is guilty, then so am I.\n huey.implies(dewey),\n\n # Louie: Dewey and I are not both guilty.\n ~(dewey & louie)\n])\n\nmodel.solve()\n\nsolution = {\n \"huey\": huey.value(),\n \"dewey\": dewey.value(),\n \"louie\": louie.value()\n}\nprint(json.dumps(solution))"} +{"id": "hakan_examples__initials_queue", "model": "# Import libraries\nfrom cpmpy import *\nimport json\n\nn = 10\n\nA = 0\nB = 1\nC = 2\nD = 3\nE = 4\n\nqueue = intvar(A, E, shape=(n, 2), name=\"queue\")\n\n# constraints\nmodel = Model()\n\n# 1. Alphabetically ordered and distinct initials within each person.\nfor i in range(n):\n model += [queue[i, 0] < queue[i, 1]]\n\n# 2. No two people have the same initials. AllDifferent on combined initials.\nfor i in range(n):\n for j in range(i + 1, n):\n model += [(queue[i, 0] != queue[j, 0]) | (queue[i, 1] != queue[j, 1])]\n\n# 3. No shared letters with the person in front.\nfor i in range(n - 1):\n model += [queue[i, 0] != queue[i + 1, 0]]\n model += [queue[i, 0] != queue[i + 1, 1]]\n model += [queue[i, 1] != queue[i + 1, 0]]\n model += [queue[i, 1] != queue[i + 1, 1]]\n\n# Specific initial assignments based on the problem statement.\nmodel += [queue[0, 0] == 1] # BE in front (B=1, E=4)\nmodel += [queue[0, 1] == 4]\nmodel += [queue[1, 0] == 2] # CD right behind (C=2, D=3)\nmodel += [queue[1, 1] == 3]\nmodel += [queue[n - 1, 0] == 1] # BD at the end (B=1, D=3)\nmodel += [queue[n - 1, 1] == 3]\n\nmodel.solve()\n\nsolution = {\n \"queue\": queue.value().tolist()\n}\nprint(json.dumps(solution))"} +{"id": "hakan_examples__isbn", "model": "# Data\nisbn_init = [9, 7, 8, 3, 3, 1, 9, 2, 5, 8, 8, 1, -1] # Example: Find the missing digit (-1)\n# End of Data\n\nfrom cpmpy import *\nimport json\n\n# Variables\nn = 13\nisbn = intvar(0, 9, shape=n, name=\"isbn\")\n\n# Constraints\nmodel = Model()\n\n# Set known digits (or keep unknowns as -1 is not a valid digit)\nfor i in range(n):\n if isbn_init[i] != -1:\n model += isbn[i] == isbn_init[i]\n\n# ISBN-13 prefixes\nmodel += isbn[0] == 9\nmodel += isbn[1] == 7\nmodel += (isbn[2] == 8) | (isbn[2] == 9)\n\n# Check digit calculation\ncheck_sum = sum(isbn[i] * (1 if i % 2 == 0 else 3) for i in range(n - 1))\nmodel += isbn[n - 1] == (10 - (check_sum % 10)) % 10\n\nmodel.solve()\n\nsolution = {\n 'isbn': isbn.value().tolist()\n}\nprint(json.dumps(solution, indent=4))\n# End of CPMPy script"} +{"id": "hakan_examples__jobs_puzzle", "model": "# Import libraries\nfrom cpmpy import *\nimport json\n\nnum_people = 4\nnum_jobs = 8\n\n# Variables\n# jobs[i] is the person assigned to job i.\njobs = intvar(0, num_people - 1, shape=num_jobs, name=\"jobs\")\nchef, guard, nurse, clerk, police_officer, teacher, actor, boxer = jobs\n\n# Constraints\nmodel = Model()\n\n# Each person holds exactly two jobs.\nfor i in range(num_people):\n model += [sum(jobs == i) == 2]\n\n# 1. The nurse is not a teacher, police officer, or clerk.\nmodel += [nurse != teacher]\nmodel += [nurse != police_officer]\nmodel+= [nurse != clerk]\n\n# 2. The clerk is not the chef\nmodel += [clerk != chef]\n\n# 3. Person 0 is not the boxer.\nmodel += [boxer != 0]\n\n# 4. Person 3 is not the teacher, police officer, or nurse.\nmodel += [teacher != 3]\nmodel += [police_officer != 3]\nmodel += [nurse != 3]\n\n# 5. Person 0, the chef, and the police officer are distinct.\nmodel += [chef != 0]\nmodel += [police_officer != 0]\nmodel += [chef != police_officer]\n\n# Solve\nmodel.solve()\n\n# Output\nsolution = {\n \"chef\": chef.value(), \"guard\": guard.value(), \"nurse\": nurse.value(),\n \"clerk\": clerk.value(), \"police_officer\": police_officer.value(),\n \"teacher\": teacher.value(), \"actor\": actor.value(), \"boxer\": boxer.value()\n}\nprint(json.dumps(solution, indent=4))\n# End of CPMPy script"} +{"id": "hakan_examples__just_forgotten", "model": "# Import libraries\nfrom cpmpy import *\nimport json\n\nx = intvar(0, 9, shape=10, name=\"x\")\n\n# Constraints\nmodel = Model()\n\n# The four sets\nsets = [\n [9, 4, 6, 2, 1, 5, 7, 8, 3, 0],\n [8, 6, 0, 4, 3, 9, 1, 2, 5, 7],\n [1, 6, 4, 0, 2, 9, 7, 8, 5, 3],\n [6, 8, 2, 4, 3, 1, 9, 0, 7, 5]\n]\n\nfor s in sets:\n model += [sum([x[i] == s[i] for i in range(10)]) == 4]\n\n# Solve\nmodel.solve()\n\n# Output\nsolution = {\n 'x': x.value().tolist()\n}\nprint(json.dumps(solution, indent=4))\n# End of CPMPy script"} +{"id": "hakan_examples__kakuro", "model": "# Data\n# size of matrix\nn = 7\n\n# segments\n# [sum, [segments]]\n# Note: 1-based\nproblem = [[16, [1, 1], [1, 2]], [24, [1, 5], [1, 6], [1, 7]],\n [17, [2, 1], [2, 2]], [29, [2, 4], [2, 5], [2, 6], [2, 7]],\n [35, [3, 1], [3, 2], [3, 3], [3, 4], [3, 5]], [7, [4, 2], [4, 3]],\n [8, [4, 5], [4, 6]], [16, [5, 3], [5, 4], [5, 5], [5, 6], [5, 7]],\n [21, [6, 1], [6, 2], [6, 3], [6, 4]], [5, [6, 6], [6, 7]],\n [6, [7, 1], [7, 2], [7, 3]], [3, [7, 6], [7, 7]],\n [23, [1, 1], [2, 1], [3, 1]], [30, [1, 2], [2, 2], [3, 2], [4, 2]],\n [27, [1, 5], [2, 5], [3, 5], [4, 5], [5, 5]], [12, [1, 6], [2, 6]],\n [16, [1, 7], [2, 7]], [17, [2, 4], [3, 4]],\n [15, [3, 3], [4, 3], [5, 3], [6, 3], [7, 3]],\n [12, [4, 6], [5, 6], [6, 6], [7, 6]], [7, [5, 4], [6, 4]],\n [7, [5, 7], [6, 7], [7, 7]], [11, [6, 1], [7, 1]],\n [10, [6, 2], [7, 2]]]\nnum_p = len(problem)\n\n# The blanks\n# Note: 1-based\nblanks = [[1, 3], [1, 4], [2, 3], [3, 6], [3, 7], [4, 1], [4, 4], [4, 7],\n [5, 1], [5, 2], [6, 5], [7, 4], [7, 5]]\nnum_blanks = len(blanks)\n# End of data\n\nfrom cpmpy import *\nimport json\n\nmodel = Model()\n\n# Variables\nx = intvar(0, 9, shape=(n, n), name=\"x\")\n\n# fill the blanks with 0\nfor i in range(num_blanks):\n model += x[blanks[i][0] - 1, blanks[i][1] - 1] == 0\n\nfor i in range(num_p):\n segment = problem[i][1::]\n res = problem[i][0]\n\n for j in segment:\n model += x[j[0] - 1, j[1] - 1] >= 1 # ensure that the values are positive\n # sum the numbers\n model += sum([x[j[0] - 1, j[1] - 1] for j in segment]) == res\n\n # all numbers in this segment must be distinct\n model += AllDifferent([x[p[0] - 1, p[1] - 1] for p in segment])\n\nmodel.solve()\n\n# Output\nsolution = {\n 'x': x.value().tolist()\n}\nprint(json.dumps(solution, indent=4))\n# End of CPMPy script"} +{"id": "hakan_examples__kenken", "model": "# Data\n# size of matrix\nn = 6\n\n# For a better view of the problem, see\n# http://en.wikipedia.org/wiki/File:KenKenProblem.svg\n\n# hints\n# [sum, [segments]]\n# Note: 1-based\nproblem = [[11, [[1, 1], [2, 1]]], [2, [[1, 2], [1, 3]]],\n [20, [[1, 4], [2, 4]]], [6, [[1, 5], [1, 6], [2, 6], [3, 6]]],\n [3, [[2, 2], [2, 3]]], [3, [[2, 5], [3, 5]]],\n [240, [[3, 1], [3, 2], [4, 1], [4, 2]]], [6, [[3, 3], [3, 4]]],\n [6, [[4, 3], [5, 3]]], [7, [[4, 4], [5, 4], [5, 5]]],\n [30, [[4, 5], [4, 6]]], [6, [[5, 1], [5, 2]]],\n [9, [[5, 6], [6, 6]]], [8, [[6, 1], [6, 2], [6, 3]]],\n [2, [[6, 4], [6, 5]]]]\n\nnum_p = len(problem)\n# End of data\n\nfrom cpmpy import *\nimport json\nfrom functools import reduce\n\n\ndef prod1(_x):\n \"\"\"\n prod1(x)\n\n return the product of the values in x.\n \"\"\"\n return reduce(lambda _a, _b: _a * _b, _x)\n\n\nmodel = Model()\n\nx = intvar(1, n, shape=(n, n), name=\"x\")\n\n# all rows and columns must be unique\nmodel += [AllDifferent(row) for row in x]\nmodel += [AllDifferent(col) for col in x.transpose()]\n\n# calculate the segments\nfor (res, segment) in problem:\n if len(segment) == 2:\n\n # for two operands there may be\n # a lot of variants\n c00, c01 = segment[0]\n c10, c11 = segment[1]\n a = x[c00 - 1, c01 - 1]\n b = x[c10 - 1, c11 - 1]\n model += [(a + b == res) |\n (a * b == res) |\n (a * res == b) |\n (b * res == a) |\n (a - b == res) |\n (b - a == res)\n ]\n\n else:\n # res is either sum or product of the segment\n xx = [x[i[0] - 1, i[1] - 1] for i in segment]\n model += [(sum(xx) == res) |\n # (reduce(lambda a, b: a * b, xx) == res)\n # (prod(xx,res)\n (prod1(xx) == res)\n ]\n\nmodel.solve()\n\n# Output\nsolution = {\n 'x': x.value().tolist()\n}\nprint(json.dumps(solution, indent=4))\n# End of CPMPy script"} +{"id": "hakan_examples__killer_sudoku", "model": "# Data\n# size of matrix\nn = 9\n\n# For a better view of the problem, see\n# http://en.wikipedia.org/wiki/File:Killersudoku_color.svg\n\n# hints\n# [sum, [segments]]\n# Note: 1-based\nproblem = [[3, [[1, 1], [1, 2]]], [15, [[1, 3], [1, 4], [1, 5]]],\n [22, [[1, 6], [2, 5], [2, 6], [3, 5]]], [4, [[1, 7], [2, 7]]],\n [16, [[1, 8], [2, 8]]], [15, [[1, 9], [2, 9], [3, 9], [4, 9]]],\n [25, [[2, 1], [2, 2], [3, 1], [3, 2]]], [17, [[2, 3], [2, 4]]],\n [9, [[3, 3], [3, 4], [4, 4]]], [8, [[3, 6], [4, 6], [5, 6]]],\n [20, [[3, 7], [3, 8], [4, 7]]], [6, [[4, 1], [5, 1]]],\n [14, [[4, 2], [4, 3]]], [17, [[4, 5], [5, 5], [6, 5]]],\n [17, [[4, 8], [5, 7], [5, 8]]], [13, [[5, 2], [5, 3], [6, 2]]],\n [20, [[5, 4], [6, 4], [7, 4]]], [12, [[5, 9], [6, 9]]],\n [27, [[6, 1], [7, 1], [8, 1], [9, 1]]],\n [6, [[6, 3], [7, 2], [7, 3]]], [20, [[6, 6], [7, 6], [7, 7]]],\n [6, [[6, 7], [6, 8]]], [10, [[7, 5], [8, 4], [8, 5], [9, 4]]],\n [14, [[7, 8], [7, 9], [8, 8], [8, 9]]], [8, [[8, 2], [9, 2]]],\n [16, [[8, 3], [9, 3]]], [15, [[8, 6], [8, 7]]],\n [13, [[9, 5], [9, 6], [9, 7]]], [17, [[9, 8], [9, 9]]]]\n# End of data\n\nfrom cpmpy import *\nimport json\n\nmodel = Model()\n\nx = intvar(1, n, shape=(n, n), name=\"x\")\n\n# constraints\n\n# all rows and columns must be unique\nmodel += [AllDifferent(row) for row in x]\nmodel += [AllDifferent(col) for col in x.transpose()]\n\n# cells\nfor i in range(2):\n for j in range(2):\n cell = [\n x[r, c]\n for r in range(i * 3, i * 3 + 3)\n for c in range(j * 3, j * 3 + 3)\n ]\n model += [AllDifferent(cell)]\n\n# calculate the segments\nfor (res, segment) in problem:\n # sum the numbers\n cage = [x[i[0] - 1, i[1] - 1] for i in segment]\n model += sum(cage) == res\n model += AllDifferent(cage)\n\nmodel.solve()\n\n# Output\nsolution = {\n 'x': x.value().tolist()\n}\nprint(json.dumps(solution, indent=4))\n# End of CPMPy script"} +{"id": "hakan_examples__knights_tour", "model": "import numpy as np\nfrom cpmpy import *\nimport json\n\n# Data\nn = 8 # Size of the chessboard (must be even)\n\n\n# End of Data\n\n\ndef member_of(_x, val):\n \"\"\"\n member_of(x, val)\n\n Ensures that the value `val` is in the array `x`.\n \"\"\"\n _n = len(_x)\n constraints = [sum([_x[_i] == val for _i in range(_n)]) > 0]\n return constraints\n\n\n# Constraints\n\n# Since we use circuit we have to use 0..n*n-1 instead\nx = intvar(0, n * n - 1, shape=(n, n), name=\"x\")\nx_flat = x.flat\n\nmodel = Model(\n AllDifferent(x),\n Circuit(x_flat),\n)\n\nd = [-2, -1, 1, 2]\nfor i in range(n):\n for j in range(n):\n dom = [(i + a) * n + j + b for a in d for b in d if\n abs(a) + abs(b) == 3 and 0 <= i + a < n and 0 <= j + b < n]\n model += [member_of(dom, x[i, j])]\n\n# Solve the model\nmodel.solve()\n\nsolution = {\n 'x': x.value().tolist()\n}\nprint(json.dumps(solution, indent=4))\n# End of CPMPy Model"} +{"id": "hakan_examples__pythagorean_triplet", "model": "# Import libraries\nfrom cpmpy import *\nimport json\n\na, b, c = intvar(1, 500, shape=3, name=\"x\")\n\nmodel = Model([\n a + b + c == 1000,\n a * a + b * b == c * c\n])\n\nmodel.solve()\n\nsolution = {\"a\": a.value(), \"b\": b.value(), \"c\": c.value()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__three_coins", "model": "# Data\nnum_moves = 3 # Number of moves to make all coins face either all heads or all tails\ninit = [1, 0, 1] # Initial configuration of the coins\n# End of data\n\n# Import libraries\nfrom cpmpy import *\nimport json\n\n# Parameters\nn = len(init)\n\n# decision variables\n# 0: heads, 1: tails\nsteps = boolvar(shape=(num_moves + 1, n), name=\"x\") # The steps to make all coins face either all heads or all tails\n\n# last line, either all heads or all tails\nlast_val = sum(steps[num_moves])\n\nmodel = Model([\n steps[0] == init,\n # Exactly one difference per move\n [sum([steps[m, j] != steps[m - 1, j] for j in range(n)]) == 1 for m in range(1, num_moves + 1)],\n # last line: either all heads of all tails\n ((last_val == 0) | (last_val == n)),\n])\n\n# Solve the model\nmodel.solve()\n\n# Print the solution\nsolution = {\"steps\": steps.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__three_sum", "model": "# Data\nnums = [-1, 6, 8, 9, 10, -100, 78, 0, 1] # Collection of integers\n# End of data\n\n# Import libraries\nfrom cpmpy import *\nimport json\n\n# Parameters\nn = len(nums)\nm = 3 # The number of elements that should sum to 0\n\n# Decision variables\nindices = boolvar(shape=n, name=\"indices\") # Boolean array to indicate which elements are selected\n\n# Model\nmodel = Model([\n sum([nums[i] * indices[i] for i in range(n)]) == 0,\n sum(indices) == m\n])\n\n# Solve the model\nmodel.solve()\n\n# Print the solution\nsolution = {\"indices\": indices.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "hakan_examples__twelve_pack", "model": "# Data\ntarget = 20 # Target number of beers\n# End of data\n\n# Import libraries\nfrom cpmpy import *\nimport json\nimport builtins\n\n# Parameters\nn = 2 # Number of pack sizes\npacks = [7, 13] # Pack sizes\nmax_val = target * 2 # Arbitrary max limit of pack counts\n\n# Decision variables\ncounts = intvar(0, max_val, shape=n, name=\"counts\") # Count of each pack size used\ntotal = intvar(0, max_val * n, name=\"total\") # Total number of beers\n\n# Model\nmodel = Model([\n total == (counts * packs).sum(),\n total >= target,\n])\n\n# Objective\nmodel.minimize(total)\n\n# Solve the model\nmodel.solve()\n\n# Print the solution\nsolution = {\"counts\": counts.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "cpmpy_examples__bus_scheduling", "model": "# Data\ndemands = [4, 8, 10, 7, 12, 4] # Demand for buses in each 4-hour time slot\n# End of data\n\n# Import libraries\nfrom cpmpy import *\nimport json\n\n# Parameters\nslots = len(demands)\n\n# Decision Variables\n# x[i] represents the number of buses scheduled to start working in the i-th 4-hour slot\nx = intvar(0, sum(demands), shape=slots, name=\"x\")\n\n# Model the constraints\n# Each bus operates for 8 hours, so it covers two consecutive 4-hour slots\nconstraints = []\nfor i in range(slots):\n # The number of buses covering the i-th and (i+1)-th slot should meet the demand of the (i+1)-th slot\n constraints.append(x[i] + x[(i + 1) % slots] >= demands[(i + 1) % slots])\n\n# Create the model with constraints\nmodel = Model(constraints)\n\n# Objective: Minimize the total number of buses used\nmodel.minimize(sum(x))\n\n# Solve the model\nmodel.solve()\n\n# Print the solution\nsolution = {\"x\": x.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "cpmpy_examples__jobshop", "model": "# Data\njobs_data = [ # (job_id, task_id) -> (machine_id, duration)\n [(0, 3), (1, 2), (2, 2)], # Job 0\n [(0, 2), (2, 1), (1, 4)], # Job 1\n [(1, 4), (2, 3)] # Job 2\n]\n# End of data\n\n# Import libraries\nfrom cpmpy import *\nimport json\nfrom itertools import combinations\nimport builtins # To access the original built-in functions (because of the import * above)\n\n# Extract job data\nn_jobs = len(jobs_data)\nn_tasks = builtins.sum(len(job) for job in jobs_data)\nmachines = set(task[0] for job in jobs_data for task in job)\nn_machines = len(machines)\n\n# Create variables for start and end times\nmax_duration = builtins.sum(task[1] for job in jobs_data for task in job)\nmax_tasks_per_job = builtins.max(len(job) for job in jobs_data)\nstart_times = intvar(0, max_duration, shape=(n_jobs, max_tasks_per_job), name=\"start_times\")\nend_times = intvar(0, max_duration, shape=(n_jobs, max_tasks_per_job), name=\"end_times\")\nmakespan = intvar(0, max_duration, name=\"makespan\")\n\n# Create the model\nmodel = Model()\n\n# Add constraints for each task\nfor job_id, job in enumerate(jobs_data):\n for task_id, (machine, duration) in enumerate(job):\n model += (end_times[job_id, task_id] == start_times[job_id, task_id] + duration)\n\n # No task can start before the previous one ends\n if task_id > 0:\n model += (start_times[job_id, task_id] >= end_times[job_id, task_id - 1])\n\n# Add machine constraints\nfor machine in machines:\n machine_tasks = [(job_id, task_id) for job_id, job in enumerate(jobs_data) for task_id, (m, duration) in enumerate(job) if m == machine]\n for (job1, task1), (job2, task2) in combinations(machine_tasks, 2):\n model += (start_times[job1, task1] >= end_times[job2, task2]) | (start_times[job2, task2] >= end_times[job1, task1])\n\n# Objective: Minimize makespan\nmodel += (makespan == max(end_times.flatten()))\nmodel.minimize(makespan)\n\n# Solve the model\nmodel.solve()\n\n# Print the solution\nsolution = {\n \"makespan\": makespan.value()\n}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "cpmpy_examples__knapsack", "model": "# Data\nvalues = [4, 2, 3, 7, 1] # Values of the items\nweights = [3, 1, 2, 5, 4] # Weights of the items\ncapacity = 7 # Capacity of the knapsack\n# End of data\n\n# Import libraries\nfrom cpmpy import *\nimport json\n\n# Construct the model\nx = boolvar(shape=len(values), name=\"x\")\n\nmodel = Model(\n sum(x * weights) <= capacity,\n maximize=sum(x * values)\n)\n\n# Solve the model\nmodel.solve()\n\n# Print the solution\nsolution = {\n \"x\": x.value().tolist()\n}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "cpmpy_examples__mario", "model": "# Data\ndata = {\n 'nbHouses': 15,\n 'MarioHouse': 1,\n 'LuigiHouse': 2,\n 'fuelMax': 2000,\n 'goldTotalAmount': 1500,\n 'conso': [ # fuel consumption between houses, conso[i][j] = fuel from i to j\n [0, 221, 274, 808, 13, 677, 670, 921, 943, 969, 13, 18, 217, 86, 322],\n [0, 0, 702, 83, 813, 679, 906, 246, 335, 529, 719, 528, 451, 242, 712],\n [274, 702, 0, 127, 110, 72, 835, 5, 161, 430, 686, 664, 799, 523, 73],\n [808, 83, 127, 0, 717, 80, 31, 71, 683, 668, 248, 826, 916, 467, 753],\n [13, 813, 110, 717, 0, 951, 593, 579, 706, 579, 101, 551, 280, 414, 294],\n [677, 679, 72, 80, 951, 0, 262, 12, 138, 222, 146, 571, 907, 225, 938],\n [670, 906, 835, 31, 593, 262, 0, 189, 558, 27, 287, 977, 226, 454, 501],\n [921, 246, 5, 71, 579, 12, 189, 0, 504, 221, 483, 226, 38, 314, 118],\n [943, 335, 161, 683, 706, 138, 558, 504, 0, 949, 393, 721, 267, 167, 420],\n [969, 529, 430, 668, 579, 222, 27, 221, 949, 0, 757, 747, 980, 589, 528],\n [13, 719, 686, 248, 101, 146, 287, 483, 393, 757, 0, 633, 334, 492, 859],\n [18, 528, 664, 826, 551, 571, 977, 226, 721, 747, 633, 0, 33, 981, 375],\n [217, 451, 799, 916, 280, 907, 226, 38, 267, 980, 334, 33, 0, 824, 491],\n [86, 242, 523, 467, 414, 225, 454, 314, 167, 589, 492, 981, 824, 0, 143],\n [322, 712, 73, 753, 294, 938, 501, 118, 420, 528, 859, 375, 491, 143, 0]\n ],\n 'goldInHouse': [0, 0, 40, 67, 89, 50, 6, 19, 47, 68, 94, 86, 34, 14, 14]\n}\n# End of data\n\n# Import libraries\nfrom cpmpy import *\nimport json\n\nmarioHouse, luigiHouse = data['MarioHouse'] - 1, data['LuigiHouse'] - 1 # 0-based indexing\nfuelLimit = data['fuelMax']\nnHouses = data['nbHouses']\narc_fuel = data['conso'] # arc_fuel[a,b] = fuel from a to b\narc_fuel = cpm_array(arc_fuel) # needed to do arc_fuel[var1] == var2\n\n# s[i] is the house succeeding to the ith house (s[i]=i if not part of the route)\ns = intvar(0, nHouses - 1, shape=nHouses, name=\"s\")\n\nmodel = Model(\n # s should be a path, mimic (sub)circuit by connecting end-point back to start\n s[luigiHouse] == marioHouse,\n Circuit(s), # should be subcircuit?\n)\n\n# consumption, knowing that always conso[i,i]=0\n# node_fuel[i] = arc_fuel[i, successor-of-i]\n# observe how we do NOT create auxiliary CP variables here, just a list of expressions...\nnode_fuel = [arc_fuel[i, s[i]] for i in range(nHouses)]\nmodel += sum(node_fuel) < fuelLimit\n\n# amount of gold earned, only for stops visited, s[i] != i\ngold = sum((s != range(nHouses)) * data['goldInHouse'])\nmodel.maximize(gold)\n\n# Solve\nmodel.solve()\n\n# Print\nsolution = {\"s\": s.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "cpmpy_examples__minesweeper", "model": "# Data\nX = -1\ngame_data = [ # 0-8: number of mines around, -1: not opened\n [2, 3, X, 2, 2, X, 2, 1],\n [X, X, 4, X, X, 4, X, 2],\n [X, X, X, X, X, X, 4, X],\n [X, 5, X, 6, X, X, X, 2],\n [2, X, X, X, 5, 5, X, 2],\n [1, 3, 4, X, X, X, 4, X],\n [0, 1, X, 4, X, X, X, 3],\n [0, 1, 2, X, 2, 3, X, 2]\n]\n# End of data\n\n# Import libraries\nfrom cpmpy import *\nimport numpy as np\nimport json\n\n# Parameters\ngame = np.array(game_data)\nrows, cols = game.shape\nS = [-1, 0, 1] # for the neighbors of a cell\n\n# Decision Variables\nmines = boolvar(shape=game.shape) # True: mine, False: not mine\n\nmodel = Model()\nfor (r, c), val in np.ndenumerate(game):\n if val != X:\n # This cell cannot be a mine\n model += mines[r, c] == 0\n # Count neighbors\n model += (sum(mines[r + a, c + b]\n for a in S for b in S\n if 0 <= r + a < rows and 0 <= c + b < cols and (a, b) != (0, 0))\n == val)\n\n# Solve\nmodel.solve()\n\n# Print\nsolution = {\"mines\": mines.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "cpmpy_examples__n_puzzle", "model": "# Data\nN = 20 # Number of steps to the solution\npuzzle_start = [ # Start state of the puzzle, 0 represents the empty tile\n [0, 3, 6],\n [2, 4, 8],\n [1, 7, 5]\n]\n\npuzzle_end = [ # End state of the puzzle\n [1, 2, 3],\n [4, 5, 6],\n [7, 8, 0]\n]\n# End of data\n\n# Import libraries\nfrom cpmpy import *\nimport json\nimport numpy as np\n\n\ndef n_puzzle(puzzle_start, puzzle_end, N):\n\n m = Model()\n\n (dim,dim2) = puzzle_start.shape\n assert (dim == dim2), \"puzzle needs square shape\"\n n = dim*dim2 - 1 # e.g. an 8-puzzle\n\n # State of puzzle at every step\n x = intvar(0,n, shape=(N,dim,dim), name=\"x\")\n\n # Start state constraint\n m += (x[0] == puzzle_start)\n\n # End state constraint\n m += (x[-1] == puzzle_end)\n\n # define neighbors = allowed moves for the '0'\n def neigh(i,j):\n # same, left,right, down,up, if within bounds\n for (rr, cc) in [(0,0),(-1,0),(1,0),(0,-1),(0,1)]:\n if 0 <= i+rr and i+rr < dim and 0 <= j+cc and j+cc < dim:\n yield (i+rr,j+cc)\n\n # Transition: define next based on prev + invariants\n def transition(m, prev_x, next_x):\n # for each position, determine its reachability\n for i in range(dim):\n for j in range(dim):\n m += (next_x[i,j] == 0).implies(any(prev_x[r,c] == 0 for r,c in neigh(i,j)))\n\n # Invariant: in each step, all cells are different\n m += AllDifferent(next_x)\n\n # Invariant: only the '0' position can move\n m += ((prev_x == 0) | (next_x == 0) | (prev_x == next_x))\n\n # apply transitions (0,1) (1,2) (2,3) ...\n for i in range(1, N):\n transition(m, x[i-1], x[i])\n\n return (m,x)\n\n# Example usage\nmodel, steps = n_puzzle(np.array(puzzle_start), np.array(puzzle_end), N)\nmodel.solve()\n\n# Print\nsolution = {\"steps\": steps.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "cpmpy_examples__packing_rectangles", "model": "# Data\nwidths = [3, 4, 2, 1] # Widths of the items\nheights = [2, 3, 1, 4] # Heights of the items\n# End of data\n\n# Import libraries\nfrom cpmpy import *\nimport json\nfrom cpmpy.expressions.utils import all_pairs\n\n\ndef model_packing_rectangular(widths, heights):\n # Number of different items\n n = len(widths)\n\n # max dimensions of the whole area\n area_min_x, area_max_x = max(widths), sum(widths)\n area_min_y, area_max_y = max(heights), sum(heights)\n\n # Decision variables\n pos_x = intvar(0, area_max_x, shape=n)\n pos_y = intvar(0, area_max_y, shape=n)\n\n total_x = intvar(area_min_x, area_max_x)\n total_y = intvar(area_min_y, area_max_y)\n\n m = Model()\n\n ## Necessary constraints\n # Every item has to be within the overall area\n m += [pos_x + widths <= total_x,\n pos_y + heights <= total_y]\n\n # No-overlap: every item has to be fully above, below or next to every other item\n for i, j in all_pairs(range(n)):\n m += ((pos_x[i] + widths[i] <= pos_x[j]) |\n (pos_x[j] + widths[j] <= pos_x[i]) |\n (pos_y[i] + heights[i] <= pos_y[j]) |\n (pos_y[j] + heights[j] <= pos_y[i]))\n\n # Minimize wrt the overall area\n m.minimize(total_x * total_y)\n\n ## Optional constraints\n # The needed space needs to be wider than taller\n # m += (total_x > total_y),\n\n # The needed space has to have a width larger than 10\n # m += (total_x >= 10),\n\n # The needed space has to have a height larger than 10\n # m += (total_y >= 10)\n\n return m, (pos_x, pos_y, total_x, total_y)\n\n\n# Example usage\nmodel, (pos_x, pos_y, total_x, total_y) = model_packing_rectangular(widths, heights)\nmodel.solve()\n\n# Print\nsolution = {\n \"pos_x\": pos_x.value().tolist(),\n \"pos_y\": pos_y.value().tolist(),\n \"total_x\": total_x.value(),\n \"total_y\": total_y.value()\n}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "cpmpy_examples__resource_constrained_project_scheduling", "model": "# Data\ndurations_data = [0, 3, 2, 5, 4, 2, 3, 4, 2, 4, 6, 0]\nresource_needs_data = [[0, 0], [5, 1], [0, 4], [1, 4], [1, 3], [3, 2], [3, 1], [2, 4], [4, 0], [5, 2], [2, 5], [0, 0]]\nresource_capacities_data = [6, 8]\nsuccessors_link_data = [[0, 1], [0, 2], [0, 3], [1, 4], [1, 5], [2, 9], [2, 10], [3, 8], [4, 6], [4, 7], [5, 9], [5, 10], [6, 8], [6, 9], [7, 8], [8, 11], [9, 11], [10, 11]]\n# End of data\n\n# Import libraries\nfrom cpmpy import *\nimport numpy as np\nimport json\n\n# Parameters\ndurations = np.array(durations_data)\nresource_needs = np.array(resource_needs_data)\nresource_capacities = np.array(resource_capacities_data)\nsuccessors_link = np.array(successors_link_data)\n\nnb_resource = len(resource_capacities)\nnb_jobs = len(durations)\nmax_duration = sum(durations) # dummy upper bound, can be improved of course\n\n# Decision Variables\nstart_time = intvar(0, max_duration, shape=nb_jobs) # start time of each job\n\nmodel = Model()\n\n# Precedence constraints\nfor j in range(successors_link.shape[0]):\n model += start_time[successors_link[j, 1]] >= start_time[successors_link[j, 0]]+durations[successors_link[j, 0]]\n\n# Cumulative resource constraint\nfor r in range(nb_resource):\n model += Cumulative(start=start_time, duration=durations, end=start_time+durations,\n demand=resource_needs[:, r], capacity=resource_capacities[r])\n\nmakespan = max(start_time)\nmodel.minimize(makespan)\n\n# Solve\nmodel.solve()\n\n# Print\nsolution = {\"start_time\": start_time.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "cpmpy_examples__room_assignment", "model": "# Data\nmax_rooms = 5 # Maximum number of rooms available\nstart_data = [\"2024-05-01\", \"2024-05-02\", \"2024-05-03\", \"2024-05-04\"] # Start date of the requests\nend_data = [\"2024-05-05\", \"2024-05-06\", \"2024-05-07\", \"2024-05-08\"] # End date of the requests\npreassigned_room_data = [3, -1, -1, -1] # Room 3 pre-assigned for the first request, -1 for no pre-assignment. So, the second, third, and fourth requests have no pre-assigned rooms.\n# End of data\n\n# Import libraries\nimport pandas as pd\nfrom cpmpy import *\nimport numpy as np\nimport json\n\n# Parameters\ndata = {\n \"start\": pd.to_datetime(start_data),\n \"end\": pd.to_datetime(end_data),\n # convert 0 to NaN\n \"room\": [r if r != -1 else np.nan for r in preassigned_room_data]\n}\ndf = pd.DataFrame(data)\n\n\ndef model_rooms(df, max_rooms):\n n_requests = len(df)\n\n # All requests must be assigned to one out of the rooms (same room during entire period).\n requestvars = intvar(0, max_rooms - 1, shape=(n_requests,))\n\n m = Model()\n\n # Some requests already have a room pre-assigned\n for idx, row in df.iterrows():\n if not pd.isna(row['room']):\n m += (requestvars[idx] == int(row['room']))\n\n # A room can only serve one request at a time.\n # <=> requests on the same day must be in different rooms\n for day in pd.date_range(min(df['start']), max(df['end'])):\n overlapping = df[(df['start'] <= day) & (day < df['end'])]\n if len(overlapping) > 1:\n m += AllDifferent(requestvars[overlapping.index])\n\n return m, requestvars\n\n\n# Example usage\nmodel, room_assignments = model_rooms(df, max_rooms)\nmodel.solve()\n\n# Print\nsolution = {\"room_assignments\": room_assignments.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "cpmpy_examples__send_more_money", "model": "# Import libraries\nfrom cpmpy import *\nimport numpy as np\nimport json\n\n# Decision variables\ns, e, n, d, m, o, r, y = intvar(0, 9, shape=8)\n\nmodel = Model(\n AllDifferent([s, e, n, d, m, o, r, y]),\n (sum([s, e, n, d] * np.array([1000, 100, 10, 1])) \\\n + sum([m, o, r, e] * np.array([1000, 100, 10, 1])) \\\n == sum([m, o, n, e, y] * np.array([10000, 1000, 100, 10, 1]))),\n s > 0,\n m > 0,\n)\n\n# Solve\nmodel.solve()\n\n# Print\nsolution = {\n \"s\": s.value(),\n \"e\": e.value(),\n \"n\": n.value(),\n \"d\": d.value(),\n \"m\": m.value(),\n \"o\": o.value(),\n \"r\": r.value(),\n \"y\": y.value()\n}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "cpmpy_examples__set_game", "model": "# Data\n# Constants\nnumbers = ONE, TWO, THREE = 1, 2, 3\ncolors = RED, PURPLE, GREEN = 1, 2, 3\nshapes = DIAMOND, RECT, ELLIPSE = 1, 2, 3\nfills = FULL, EMPTY, STRIPED = 1, 2, 3\n\n# Make the card deck\ncards_data = [\n [ONE, EMPTY, GREEN, DIAMOND],\n [TWO, STRIPED, RED, RECT],\n [THREE, STRIPED, GREEN, DIAMOND],\n [THREE, FULL, RED, DIAMOND],\n [ONE, STRIPED, GREEN, DIAMOND],\n [ONE, EMPTY, RED, DIAMOND],\n [TWO, FULL, PURPLE, DIAMOND],\n [THREE, FULL, PURPLE, ELLIPSE],\n [THREE, FULL, GREEN, RECT],\n [ONE, FULL, PURPLE, DIAMOND],\n [ONE, STRIPED, PURPLE, DIAMOND],\n [ONE, FULL, GREEN, RECT]\n]\n# End of data\n\n# Import libraries\nfrom cpmpy import *\nimport json\n\n# Parameters\ncards = cpm_array(cards_data)\ngiven_numbers, given_fills, given_colors, given_shapes = cards[:, 0], cards[:, 1], cards[:, 2], cards[:, 3]\n\n# decision variables\nn_cards = len(cards)\nwinning_cards = intvar(0, n_cards - 1, shape=3, name=\"winning\") # indices of the winning cards\nc1, c2, c3 = winning_cards\n\n# constraints\nmodel = Model()\nmodel += AllDifferent(winning_cards)\n\n# numbers must be all equal or all different\nwinning_nbs = [given_numbers[c1], given_numbers[c2], given_numbers[c3]]\nmodel += AllEqual(winning_nbs) | AllDifferent(winning_nbs)\n\n# filling pattern must be all equal or all different\nwinning_fills = [given_fills[c1], given_fills[c2], given_fills[c3]]\nmodel += AllEqual(winning_fills) | AllDifferent(winning_fills)\n\n# colors must be all equal or all different\nwinning_colors = [given_colors[c1], given_colors[c2], given_colors[c3]]\nmodel += AllEqual(winning_colors) | AllDifferent(winning_colors)\n\n# shapes must be all equal or all different\nwinning_shapes = [given_shapes[c1], given_shapes[c2], given_shapes[c3]]\nmodel += AllEqual(winning_shapes) | AllDifferent(winning_shapes)\n\n# Solve\nmodel.solve()\n\n# Print\nsolution = {\"winning_cards\": winning_cards.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "cpmpy_examples__sudoku", "model": "# Data\ninput_grid = [ # 0 represents empty cells\n [0, 0, 0, 2, 0, 5, 0, 0, 0],\n [0, 9, 0, 0, 0, 0, 7, 3, 0],\n [0, 0, 2, 0, 0, 9, 0, 6, 0],\n\n [2, 0, 0, 0, 0, 0, 4, 0, 9],\n [0, 0, 0, 0, 7, 0, 0, 0, 0],\n [6, 0, 9, 0, 0, 0, 0, 0, 1],\n\n [0, 8, 0, 4, 0, 0, 1, 0, 0],\n [0, 6, 3, 0, 0, 0, 0, 8, 0],\n [0, 0, 0, 6, 0, 8, 0, 0, 0]]\n# End of data\n\n# Import libraries\nfrom cpmpy import *\nimport json\nimport numpy as np\n\n# Parameters\ne = 0 # value for empty cells\ngiven = np.array(input_grid) # numpy array for easy indexing\n\n# Decision Variables\ngrid = intvar(1, 9, shape=given.shape, name=\"grid\")\n\n# Model\nmodel = Model(\n # Constraints on given cells (non-empty)\n grid[given != e] == given[given != e], # numpy's indexing, vectorized equality\n # Constraints on rows and columns\n [AllDifferent(row) for row in grid],\n [AllDifferent(col) for col in grid.T], # numpy's transpose\n)\n\n# Constraints on blocks\nfor i in range(0, 9, 3):\n for j in range(0, 9, 3):\n model += AllDifferent(grid[i:i+3, j:j+3]) # python's indexing\n\n# Solve\nmodel.solve()\n\n# Print\nsolution = {\"grid\": grid.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "cpmpy_examples__tsp", "model": "# Data\nlocations = [\n (288, 149), (288, 129), (270, 133), (256, 141), (256, 163), (246, 157),\n (236, 169), (228, 169), (228, 148), (220, 164), (212, 172), (204, 159)\n]\n# End of data\n\n# Import libraries\nimport math\nimport numpy as np\nfrom cpmpy import *\nimport json\n\n\n# Parameters\ndef compute_euclidean_distance_matrix(locations):\n \"\"\"Computes distances between all points (from ortools docs).\"\"\"\n n_city = len(locations)\n distances = np.zeros((n_city, n_city))\n for from_counter, from_node in enumerate(locations):\n for to_counter, to_node in enumerate(locations):\n if from_counter != to_counter:\n distances[from_counter][to_counter] = (int(\n math.hypot((from_node[0] - to_node[0]),\n (from_node[1] - to_node[1]))))\n return distances.astype(int)\n\n\ndistance_matrix = compute_euclidean_distance_matrix(locations)\nn_city = len(locations)\n\n# we use the successor variable formulation and circuit global constraint here\n# alternative is to model like in vrp.py\n\n# x[i]=j means that j is visited immediately after i\nx = intvar(0, n_city - 1, shape=n_city)\n\n# The 'circuit' global constraint ensures that the successor variables from a circuit\nmodel = Model(Circuit(x))\n\n# the objective is to minimize the travelled distance\ndistance_matrix = cpm_array(distance_matrix) # for indexing with variable\ntravel_distance = sum(distance_matrix[i, x[i]] for i in range(n_city))\nmodel.minimize(travel_distance)\n\n# Solve\nmodel.solve()\n\n# Print\nsolution = {\"travel_distance\": travel_distance.value()}\nprint(json.dumps(solution))"} +{"id": "cpmpy_examples__who_killed_agatha", "model": "# Data\nnames = [\"Agatha herself\", \"the butler\", \"Charles\"]\n# End of data\n\n# Import libraries\nfrom cpmpy import *\nimport json\n\n# Agatha, the butler, and Charles live in Dreadsbury Mansion, and\n# are the only ones to live there.\nn = 3\n(agatha, butler, charles) = range(n) # enum constants\n\n# Who killed agatha?\nvictim = agatha\nkiller = intvar(0, n - 1, name=\"killer\") # 0=Agatha, 1=butler, 2=Charles\n\nhates = boolvar(shape=(n, n), name=\"hates\")\nricher = boolvar(shape=(n, n), name=\"richer\")\n\nmodel = Model(\n # A killer always hates, and is no richer than, his victim.\n # note; 'killer' is a variable, so must write ==1/==0 explicitly\n hates[killer, victim] == 1,\n richer[killer, victim] == 0,\n\n # implied richness: no one richer than himself, and anti-reflexive\n [~richer[i, i] for i in range(n)],\n [(richer[i, j]) == (~richer[j, i]) for i in range(n) for j in range(i + 1, n)],\n\n # Charles hates noone that Agatha hates.\n [(hates[agatha, i]).implies(~hates[charles, i]) for i in range(n)],\n\n # Agatha hates everybody except the butler.\n hates[agatha, (agatha, charles, butler)] == [1, 1, 0],\n\n # The butler hates everyone not richer than Aunt Agatha.\n [(~richer[i, agatha]).implies(hates[butler, i]) for i in range(n)],\n\n # The butler hates everyone whom Agatha hates.\n [(hates[agatha, i]).implies(hates[butler, i]) for i in range(n)],\n\n # Noone hates everyone.\n [sum(hates[i, :]) <= 2 for i in range(n)],\n)\n\n# Solve\nmodel.solve()\n\n# Print\nsolution = {\"killer\": killer.value()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "cpmpy_examples__wolf_goat_cabbage", "model": "# Data\nstage = 8 # Number of stages\n# End of data\n\n# Import libraries\nfrom cpmpy import *\nimport json\n\nwolf_pos = boolvar(stage)\ncabbage_pos = boolvar(stage)\ngoat_pos = boolvar(stage)\nboat_pos = boolvar(stage)\n\nmodel = Model(\n # Initial situation\n (boat_pos[0] == 0),\n (wolf_pos[0] == 0),\n (goat_pos[0] == 0),\n (cabbage_pos[0] == 0),\n\n # Boat keeps moving between shores\n [boat_pos[i] != boat_pos[i - 1] for i in range(1, stage)],\n\n # Final situation\n (boat_pos[-1] == 1),\n (wolf_pos[-1] == 1),\n (goat_pos[-1] == 1),\n (cabbage_pos[-1] == 1),\n\n # # Wolf and goat cannot be left alone\n [(goat_pos[i] != wolf_pos[i]) | (boat_pos[i] == wolf_pos[i]) for i in range(stage)],\n\n # # Goat and cabbage cannot be left alone\n [(goat_pos[i] != cabbage_pos[i]) | (boat_pos[i] == goat_pos[i]) for i in range(stage)],\n\n # # Only one animal/cabbage can move per turn\n [abs(wolf_pos[i] - wolf_pos[i + 1]) + abs(goat_pos[i] - goat_pos[i + 1]) + abs(\n cabbage_pos[i] - cabbage_pos[i + 1]) <= 1 for i in range(stage - 1)],\n)\n\n# Solve\nmodel.solve()\n\n# Print\nsolution = {\"wolf_pos\": wolf_pos.value().tolist(), \"goat_pos\": goat_pos.value().tolist(),\n \"cabbage_pos\": cabbage_pos.value().tolist(), \"boat_pos\": boat_pos.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "cpmpy_examples__zebra", "model": "# Import libraries\nfrom cpmpy import *\nimport json\n\nn_houses = 5\n\n# colors[i] is the house of the ith color\nyellow, green, red, white, blue = colors = intvar(0,n_houses-1, shape=n_houses)\n\n# nations[i] is the house of the inhabitant with the ith nationality\nitaly, spain, japan, england, norway = nations = intvar(0,n_houses-1, shape=n_houses)\n\n# jobs[i] is the house of the inhabitant with the ith job\npainter, sculptor, diplomat, pianist, doctor = jobs = intvar(0,n_houses-1, shape=n_houses)\n\n# pets[i] is the house of the inhabitant with the ith pet\ncat, zebra, bear, snails, horse = pets = intvar(0,n_houses-1, shape=n_houses)\n\n# drinks[i] is the house of the inhabitant with the ith preferred drink\nmilk, water, tea, coffee, juice = drinks = intvar(0,n_houses-1, shape=n_houses)\n\nmodel = Model(\n AllDifferent(colors),\n AllDifferent(nations),\n AllDifferent(jobs),\n AllDifferent(pets),\n AllDifferent(drinks),\n\n painter == horse,\n diplomat == coffee,\n white == milk,\n spain == painter,\n england == red,\n snails == sculptor,\n green + 1 == red,\n blue + 1 == norway,\n doctor == milk,\n japan == diplomat,\n norway == zebra,\n abs(green - white) == 1,\n #horse in {diplomat - 1, diplomat + 1},\n (horse == diplomat-1)|(horse == diplomat+1),\n #italy in {red, white, green}\n (italy == red)|(italy == white)|(italy == green),\n)\nmodel.solve()\n\n# Print\nsolution = {\n \"colors\": colors.value().tolist(),\n \"nations\": nations.value().tolist(),\n \"jobs\": jobs.value().tolist(),\n \"pets\": pets.value().tolist(),\n \"drinks\": drinks.value().tolist(),\n}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "aplai_course__bank_card", "model": "# Import libraries\nfrom cpmpy import *\nimport json\n\n# Decision Variables\na, b, c, d = intvar(0, 9, shape=4) # a, b, c, d are the four digits of the PIN\n\n# Constraints\nmodel = Model()\n\nmodel += AllDifferent([a, b, c, d]) # no two digits are the same\nmodel += 10 * c + d == 3 * (10 * a + b) # cd is 3 times ab\nmodel += 10 * d + a == 2 * (10 * b + c) # da is 2 times bc\n\n# Solve\nmodel.solve()\n\n# Print the solution\nsolution = {\"a\": a.value(), \"b\": b.value(), \"c\": c.value(), \"d\": d.value()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "aplai_course__climbing_stairs", "model": "# Import libraries\nfrom cpmpy import *\nimport json\nimport numpy as np\n\n# Parameters\nn = 20 # total number of steps in the stair\nm1, m2 = 3, 5 # number of steps that can be taken at a time\n\n# Decision variables\n# In the worst case, we take all steps one at a time, so we have 'n' decision variables\nsteps = intvar(0, m2, shape=n) # steps taken at each move\n\n# Model setup\nmodel = Model()\n\n# Constraint: the sum of steps should equal the total number of stairs\nmodel += sum(steps) == n\n\n# Constraint: the number of steps taken at each move should be between m1 and m2 or 0\nmodel += [(steps[i] >= m1) | (steps[i] == 0) for i in range(n)]\nmodel += [steps[i] <= m2 for i in range(n)]\n\n# Trailing zeros: If a step is 0, then all the following steps should be 0\nfor i in range(1, n):\n model += (steps[i - 1] == 0).implies(all(steps[j] == 0 for j in range(i, n)))\n\n# Solve\nmodel.solve()\n\n# Print the solution\nsolution = {\"steps\": steps.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "aplai_course__color_simple", "model": "# Data\ngraph = [ # the adjacency of the countries, (i, j) means that country i is adjacent to country j\n [3, 1],\n [3, 6],\n [3, 4],\n [6, 4],\n [6, 1],\n [1, 5],\n [1, 4],\n [4, 5],\n [4, 2]\n]\n# End of data\n\n# Import libraries\nfrom cpmpy import *\nimport json\n\nnum_edges = 9\nnum_nodes = 6\n\n# Decision Variables\ncolors = intvar(1, num_nodes, shape=num_nodes) # the colour assigned to each country\n\n# Constraints\nmodel = Model()\n\n# Two neighbouring countries cannot have the same colour\nfor i, j in graph:\n # Python uses 0-based indexing, but the countries are 1-based, so we need to subtract 1 from the indices\n model += colors[i - 1] != colors[j - 1]\n\n# Objective\n# Find a colouring that minimizes the number of colours used\nmodel.minimize(max(colors))\n\n# Solve\nmodel.solve()\n\n# Print the solution\nsolution = {\"colors\": colors.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "aplai_course__exodus", "model": "# Import libraries\nfrom cpmpy import *\nimport json\n\n# Decision variables\n# We model the ages, children, countries, and stories as integer variables with values from 1 to 5.\nage3, age5, age7, age8, age10 = ages = intvar(1, 5, shape=5)\nbernice, carl, debby, sammy, ted = children = intvar(1, 5, shape=5)\nethiopia, kazakhstan, lithuania, morocco, yemen = countries = intvar(1, 5, shape=5)\nburning_bush, captivity, moses_youth, passover, ten_commandments = stories = intvar(1, 5, shape=5)\n\n# Constraints\nmodel = Model()\n\n# All entities are different per category\nmodel += AllDifferent(ages)\nmodel += AllDifferent(children)\nmodel += AllDifferent(countries)\nmodel += AllDifferent(stories)\n\n# Debby\u00e2\u20ac\u2122s family is from Lithuania.\nmodel += debby == lithuania\n\n# The child who told the story of the Passover is two years older than Bernice.\n# So, we will add constraints for all possible pairs of ages to enforce this relationship.\nage_to_int = {age3: 3, age5: 5, age7: 7, age8: 8, age10: 10}\nmodel += [((a1 == passover) & (a2 == bernice)).implies(age_to_int[a1] == age_to_int[a2] + 2)\n for a1 in ages for a2 in ages]\n\n# The child whose family is from Yemen is younger than the child from the Ethiopian family.\nmodel += [((a1 == yemen) & (a2 == ethiopia)).implies(age_to_int[a1] < age_to_int[a2])\n for a1 in ages for a2 in ages]\n\n# The child from the Moroccan family is three years older than Ted.\nmodel += [((a1 == morocco) & (a2 == ted)).implies(age_to_int[a1] == age_to_int[a2] + 3)\n for a1 in ages for a2 in ages]\n\n# Sammy is three years older than the child who told the story of Moses\u00e2\u20ac\u2122s youth in the house of the Pharaoh.\nmodel += [((a1 == sammy) & (a2 == moses_youth)).implies(age_to_int[a1] == age_to_int[a2] + 3)\n for a1 in ages for a2 in ages]\n\n# Solve\nmodel.solve()\n\n# Print the solution\nsolution = {\n \"ages\": ages.value().tolist(),\n \"children\": children.value().tolist(),\n \"countries\": countries.value().tolist(),\n \"stories\": stories.value().tolist()\n}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "aplai_course__farmer_and_cows", "model": "# Import libraries\nfrom cpmpy import *\nimport json\n\n# Parameters\nnum_cows = 25\nnum_sons = 5\nmilk_per_cow = list(range(1, num_cows + 1))\ncows_per_son = [7, 6, 5, 4, 3]\n\ntotal_milk = sum(milk_per_cow) # Total milk produced by all cows\ntotal_milk_per_son = total_milk // num_sons # Total milk each son should get\n\n# Decision variables\n# Each cow is assigned to a son, represented by 0-4\ncow_assignments = intvar(0, num_sons - 1, shape=num_cows)\n\n# Constraints\nmodel = Model()\n\n# Each son gets a specific number of cows\nfor son in range(num_sons):\n model += sum(cow_assignments == son) == cows_per_son[son]\n\n# The total milk production for each son is equal\nfor son in range(num_sons):\n model += sum(milk_per_cow[i] * (cow_assignments[i] == son) for i in range(num_cows)) == total_milk_per_son\n\n# Solve\nmodel.solve()\n\n# Print the solution\nsolution = {\"cow_assignments\": cow_assignments.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "aplai_course__five_floors", "model": "# Import libraries\nfrom cpmpy import *\nimport json\n\n# Decision Variables\nB = intvar(1, 5) # Baker\nC = intvar(1, 5) # Cooper\nF = intvar(1, 5) # Fletcher\nM = intvar(1, 5) # Miller\nS = intvar(1, 5) # Smith\n\n# Constraints\nmodel = Model()\n\nmodel += B != 5 # Baker does not live on the fifth floor\nmodel += C != 1 # Cooper does not live on the first floor\nmodel += (F != 5) & (F != 1) # Fletcher does not live on either the fifth or the first floor\nmodel += M > C # Miller lives on a higher floor than does Cooper\nmodel += abs(S - F) != 1 # Smith does not live on a floor adjacent to Fletcher\nmodel += abs(F - C) != 1 # Fletcher does not live on a floor adjacent to Cooper\nmodel += AllDifferent([B, C, F, M, S]) # They all live on different floors\n\n# Solve\nmodel.solve()\n\n# Print the solution\nsolution = {\"B\": B.value(), \"C\": C.value(), \"F\": F.value(), \"M\": M.value(), \"S\": S.value()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "aplai_course__grocery", "model": "# Import libraries\nfrom cpmpy import *\nimport json\nimport numpy as np\n\n# Parameters\ntotal_price = 711 # total price in cents\nnum_items = 4\n\n# Decision variables (prices are considered in cents)\nprices = intvar(1, total_price, shape=num_items)\n\n# Constraints\nmodel = Model()\n\n# The sum of the prices in cents is equal to the total price in cents\nmodel += sum(prices) == total_price\n\n# The product of the prices should equal to the scaled total price in cents (to account for the multiplication)\nmodel += np.prod(prices) == total_price * (100 ** (num_items - 1))\n\n# Solve\nmodel.solve()\n\n# Print the solution\nsolution = {\"prices\": prices.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "aplai_course__guards_and_apples", "model": "# Import libraries\nfrom cpmpy import *\nimport json\n\n# Parameters\nnum_gates = 5\n\n# Decision Variables\napples = intvar(0, 100, shape=num_gates + 1) # the number of apples before each gate plus after the last gate\n\n# Constraints\nmodel = Model()\n\n# The boy is left with no apples after giving the apple to the girl, so he has 1 apple after the last gate.\nmodel += apples[-1] == 1\n\n# At each guard, the boy gives half of his apples, plus one.\nfor i in range(1, num_gates + 1):\n has_before = apples[i - 1]\n has_after = apples[i]\n model += has_before == 2 * (has_after + 1)\n\n# Solve\nmodel.solve()\n\n# Print the solution\nsolution = {\"apples\": apples.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "aplai_course__hardy_1729_square", "model": "# Import libraries\nfrom cpmpy import *\nimport json\nimport numpy as np\n\nrange_min = 1\nrange_max = 100\n\n# Decision variables\na, b, c, d = intvar(range_min, range_max, shape=4)\n\n# Constraints\nmodel = Model()\n\n# Sum of squares of any two numbers is equal to the sum of squares of the other two numbers\nmodel += (a**2 + b**2) == (c**2 + d**2)\n\n# Constraints to ensure all variables are distinct\nmodel += AllDifferent([a, b, c, d])\n\n# Solve\nmodel.solve()\n\n# Print the solution\nsolution = {\"a\": a.value(), \"b\": b.value(), \"c\": c.value(), \"d\": d.value()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "aplai_course__kidney_exchange", "model": "# Data\nnum_people = 8 # number of people\ncompatible = [ # 1-based indexing, compatible[i] is the list of people to which i can donate\n [2, 3],\n [1, 6],\n [1, 4, 7],\n [2],\n [2],\n [5],\n [8],\n [3]\n]\n# End of data\n\n# Import libraries\nfrom cpmpy import *\nimport json\n\n# Decision variables\ntransplants = boolvar(shape=(num_people, num_people)) # transplants[i][j] is True if i donates to j\n\n# Model setup\nmodel = Model()\n\n# Constraints for the transplant pairs\nfor i in range(num_people):\n # Anyone who gives a kidney must receive one\n gives_kidney = sum(transplants[i, :]) >= 1\n receives_kidney = sum(transplants[:, i]) >= 1\n model += gives_kidney.implies(receives_kidney)\n\n # Each person can donate to at most one person and receive from at most one person\n can_donate_once = sum(transplants[i, :]) <= 1\n can_receive_once = sum(transplants[:, i]) <= 1\n model += can_donate_once & can_receive_once\n\n # Compatibility constraint: if i can't donate to j, then transplants[i][j] must be 0 (adjust for 0-based indexing)\n model += [transplants[i, j] == 0 for j in range(num_people) if j + 1 not in compatible[i]]\n\n# Objective: maximize the number of transplants\nmodel.maximize(sum(transplants))\n\n# Solve\nmodel.solve()\n\n# Print the solution\nsolution = {\"transplants\": transplants.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "aplai_course__magic_square", "model": "# Import libraries\nfrom cpmpy import *\nimport json\n\n# Parameters\nn = 4 # size of the magic square\nmagic_sum = n * (n**2 + 1) // 2 # sum of each row, column and diagonal\n\n# Decision Variables\nsquare = intvar(1, n ** 2, shape=(n, n)) # the magic square\n\n# Constraints\nmodel = Model()\n\n# All numbers in the magic square must be different\nmodel += AllDifferent(square)\n\n# The sum of the numbers in each row must be equal to the magic sum\nfor i in range(n):\n model += sum(square[i, :]) == magic_sum\n\n# The sum of the numbers in each column must be equal to the magic sum\nfor j in range(n):\n model += sum(square[:, j]) == magic_sum\n\n# The sum of the numbers in the main diagonal must be equal to the magic sum\nmodel += sum(square[i, i] for i in range(n)) == magic_sum\n\n# The sum of the numbers in the other diagonal must be equal to the magic sum\nmodel += sum(square[i, n - 1 - i] for i in range(n)) == magic_sum\n\n# Solve\nmodel.solve()\n\n# Print the solution\nsolution = {\"square\": square.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "aplai_course__maximal_independent_sets", "model": "# Data\nn = 8 # number of nodes in the graph\nadjacency_list = [ # adjacency list for each node in the graph\n [2, 3, 7],\n [1, 4, 8],\n [1, 4, 5],\n [2, 3, 6],\n [3, 6, 7],\n [4, 5, 8],\n [1, 5, 8],\n [2, 6, 7]\n]\n# End of data\n\n# Import libraries\nfrom cpmpy import *\nimport json\n\n\n# Create a binary decision variable for each node to indicate if it's included in the independent set\nnodes = boolvar(shape=n)\n\n# Model setup\nmodel = Model()\n\n# Constraint: No two adjacent nodes can both be in the independent set\nfor i, neighbors in enumerate(adjacency_list):\n for neighbor in neighbors:\n # Subtract 1 to adjust for 1-based indexing in the data\n neighbor_idx = neighbor - 1\n # Ensure that for every edge, at least one of its endpoints is not in the independent set\n model += ~(nodes[i] & nodes[neighbor_idx])\n\n# Objective: Maximize the number of nodes in the independent set\nmodel.maximize(sum(nodes))\n\n# Solve\nmodel.solve()\n\n# Print the solution\nsolution = {\"nodes\": nodes.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "aplai_course__money_change", "model": "# Import libraries\nfrom cpmpy import *\nimport json\n\n# Parameters\namount = 199 # amount of money to give to Bob\nn = 6 # number of types of coins\ntypes_of_coins = [1, 2, 5, 10, 25, 50] # value of each type of coin\navailable_coins = [20, 10, 15, 8, 4, 2] # number of available coins of each type\n\n# Decision Variables\ncoin_counts = intvar(0, 20, shape=n) # number of coins of each type to give to Bob\n\n# Constraints\nmodel = Model()\n\n# The sum of the coins given to Bob must be equal to the amount of money to give him\nmodel += sum(coin_counts[i] * types_of_coins[i] for i in range(n)) == amount\n\n# The number of each type of coin given to Bob must not exceed the available coins\nfor i in range(n):\n model += coin_counts[i] <= available_coins[i]\n\n# Objective: Minimize the total number of coins given to Bob\nmodel.minimize(sum(coin_counts))\n\n# Solve\nmodel.solve()\n\n# Print the solution\nsolution = {\"coin_counts\": coin_counts.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "aplai_course__movie_scheduling", "model": "# Data\nmovies = [ # title, start, end\n [\"Tarjan of the Jungle\", 4, 13],\n [\"The Four Volume Problem\", 17, 27],\n [\"The President's Algorist\", 1, 10],\n [\"Steiner's Tree\", 12, 18],\n [\"Process Terminated\", 23, 30],\n [\"Halting State\", 9, 16],\n [\"Programming Challenges\", 19, 25],\n [\"Discrete Mathematics\", 2, 7],\n [\"Calculated Bets\", 26, 31]\n]\n# End of data\n\n# Import libraries\nfrom cpmpy import *\nimport json\n\n# Parameters\nnum_movies = len(movies)\n\n# Decision Variables\nselected_movies = boolvar(shape=num_movies, name=\"selected_movies\") # 1 if the movie is selected, 0 otherwise\nnum_selected_movies = sum(selected_movies) # Number of selected movies\n\n# Model\nmodel = Model()\n\n# Add constraint for non-overlapping movie schedules\nfor i in range(num_movies):\n for j in range(num_movies):\n # Check if the intervals overlap for each pair of movies\n if (i != j # Different movies\n and movies[i][2] > movies[j][1] # Movie i ends after movie j starts\n and movies[j][2] > movies[i][1] # Movie j ends after movie i starts\n ):\n # Then, the movies cannot be selected together\n model += selected_movies[i] + selected_movies[j] <= 1\n\n# Objective: Maximize the number of selected movies\nmodel.maximize(num_selected_movies)\n\n# Solve\nmodel.solve()\n\n# Print\nsolution = {\"num_selected_movies\": model.objective_value(),\n \"selected_movies\": selected_movies.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "aplai_course__people_in_a_room", "model": "# Import libraries\nfrom cpmpy import *\nimport json\n\ntotal_people = 13\nnum_males = 4\n\n# Decision variable: 0 for male, 1 for female\nsequence = boolvar(shape=total_people)\n\n# Constraints\nmodel = Model()\n\n# Ensure exactly number of males and females\nmodel += [sum(sequence) == total_people - num_males]\n\n# Add constraints for the ratio at each point in the sequence\nfor i in range(1, total_people):\n total_females_so_far = sum(sequence[:i])\n total_males_so_far = i - sum(sequence[:i])\n # Number of females to males is no greater than 7/3, or 3 times the females is less than or equal to 7 times the males\n model += (3 * total_females_so_far) <= (7 * total_males_so_far)\n\n# Solve\nmodel.solve()\n\n# Print the solution\nsolution = {\"sequence\": sequence.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "aplai_course__subsets_100", "model": "# Import libraries\nfrom cpmpy import *\nimport json\n\n# Parameters\nA = [81, 21, 79, 4, 29, 70, 28, 20, 14, 7]\n\n# Decision variables: 1 if an element is in the subset, 0 otherwise\nin_S = boolvar(shape=len(A))\nin_T = boolvar(shape=len(A))\n\n# Model setup\nmodel = Model()\n\n# Constraint: sum of elements in S equals sum of elements in T\nmodel += (sum(in_S * A) == sum(in_T * A))\n\n# S and T are disjoint, so there is no element that is in both S and T\nmodel += (sum(in_S * in_T) == 0)\n\n# S and T are non-empty\nmodel += (sum(in_S) > 0)\nmodel += (sum(in_T) > 0)\n\n# Solve\nmodel.solve()\n\n# Print the solution\nsolution = {\"in_S\": in_S.value().tolist(), \"in_T\": in_T.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "aplai_course__subset_sum", "model": "# Import libraries\nfrom cpmpy import *\nimport json\n\ntotal_coins_lost = 100\ncoin_numbers = [16, 17, 23, 24, 39, 40]\n\n# Decision variables\n# The number of bags stolen for each type of coins\nbags = intvar(0, total_coins_lost, shape=len(coin_numbers))\n\n# Constraints\nmodel = Model()\n\n# The total number of coins lost is equal to the sum of the coins in the stolen bags\nmodel += sum([bags[i] * coin_numbers[i] for i in range(len(coin_numbers))]) == total_coins_lost\n\n# Solve\nmodel.solve()\n\n# Print the solution\nsolution = {\"bags\": bags.value().tolist()}\nprint(json.dumps(solution))\n# End of CPMPy script"} +{"id": "aplai_course__thick_as_thieves", "model": "# Import libraries\nfrom cpmpy import *\nimport json\n\n# Decision Variables for each suspect representing if they are guilty\nartie = boolvar(name=\"Artie\")\nbill = boolvar(name=\"Bill\")\ncrackitt = boolvar(name=\"Crackitt\")\ndodgy = boolvar(name=\"Dodgy\")\nedgy = boolvar(name=\"Edgy\")\nfingers = boolvar(name=\"Fingers\")\nsuspects = [artie, bill, crackitt, dodgy, edgy, fingers]\n\n# Constraints\nmodel = Model()\n\n# At most two are guilty because the getaway car was small\nmodel += sum(suspects) <= 2\n\n# Statement Constraints; if the suspect is guilty, they are lying, so their statement is false\n\n# Artie: \"It wasn't me.\"\nartie_statement = ~artie\nmodel += artie == ~artie_statement\n\n# Bill: \"Crackitt was in it up to his neck.\"\nbill_statement = crackitt\nmodel += bill == ~bill_statement\n\n# Crackitt: \"No I wasn't.\"\ncrackitt_statement = ~crackitt\nmodel += crackitt == ~crackitt_statement\n\n# Dodgy: \"If Crackitt did it, Bill did it with him.\"\ndodgy_statement = crackitt.implies(bill)\nmodel += dodgy == ~dodgy_statement\n\n# Edgy: \"Nobody did it alone.\"\nedgy_statement = sum(suspects) > 1\nmodel += edgy == ~edgy_statement\n\n# Fingers: \"That\u00e2\u20ac\u2122s right: it was Artie and Dodgy together.\"\nfingers_statement = artie & dodgy\nmodel += fingers == ~fingers_statement\n\n# Solve\nmodel.solve()\n\n# Print the solution\nsolution = {\n \"artie\": int(artie.value()),\n \"bill\": int(bill.value()),\n \"crackitt\": int(crackitt.value()),\n \"dodgy\": int(dodgy.value()),\n \"edgy\": int(edgy.value()),\n \"fingers\": int(fingers.value())\n}\nprint(json.dumps(solution))\n# End of CPMPy script"}