commit 636185c841e9ea238de44401c164e06d7ed7f2e8 Author: Jip J. Dekker Date: Tue Jun 15 16:32:27 2021 +1000 Add original benchmarks diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e660fd9 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +bin/ diff --git a/analyse_chuffed.py b/analyse_chuffed.py new file mode 100755 index 0000000..b5b2b70 --- /dev/null +++ b/analyse_chuffed.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python3 +""" +This script will produce the final value of a variable named 'objective' and its +area for every file ending in '.sol' in the directory provided. The files are +expected to be fzn-gecode output piped through solns2out with the +'--output-time' flag. Furthermore the file is expected to contain the initial +area which can be found by adding +'constraint trace("% init_area = \(ub(objective));\n", true);' +to the model in question. +""" +import csv +import os +import re +import sys + +def compute_area(file, time): + area = -1 + + objectives = [] + times = [0] + timeout = -1 + objectives.append(0) + for line in contents: + # match = re.match(r'%\sinit_area\s=\s(\d+)', line) + # if match: + # objectives.append(int(match[1])) + # continue + match = re.match(r'objective\s=\s(\d+)', line) + if match: + objectives.append(int(match[1])) + continue + match = re.match(r'%\stime elapsed:\s(\d+)\sms', line) + if match: + times.append(int(match[1])) + continue + times.append(time) + + assert(len(objectives) > 0) + assert(len(objectives)+1 == len(times)) + area = 0 + for i in range(len(objectives)): + area += ((times[i+1] - times[i])/1000)*objectives[i] + return int(area) + +folder = sys.argv[1] +stats = {} +for root, dirs, files in os.walk(folder): + for name in files: + if name.endswith('.sol'): + seed = 1 + match = re.search(r"\.(\d+)\.sol", name) + if match: + seed = int(match.group(1)) + with open(os.path.join(root, name)) as f: + contents = f.readlines() + + statistics = {} + for line in contents: + # Nodes + match = re.search(r"nodes:\s+(\d+)", line) + if match: + statistics['nodes'] = int(match.group(1)) + continue + # Solve time + match = re.search(r"search time:\s+(\d+\.\d+)\s*seconds", line) + if match: + statistics['search_time'] = int(float(match.group(1))*1000) + continue + # Restarts + match = re.search(r"restart count:\s+(\d+)", line) + if match: + statistics['restarts'] = int(match.group(1)) + continue + + for line in contents[::-1]: + # Best objective + match = re.match(r'objective\s=\s(\d+)', line) + if match: + statistics['objective'] = int(match[1]) + break + # Area + area = compute_area(contents, statistics['search_time']) + + stats[name[:-(4)].replace(".", ",")] = (area, statistics['objective'], statistics['search_time'], statistics['restarts'], statistics['nodes']) + +sorted_stats = sorted(stats.items()) +a = sorted_stats[0][0][:sorted_stats[0][0].find(",")] +for key, val in sorted_stats: + if key[:key.find(",")] != a: + print("\n\n") + a = key[:key.find(",")] + print("%s,%s" % (key, ",".join([v.__str__() for v in val]))) + +exit(1) diff --git a/analyse_gecode.py b/analyse_gecode.py new file mode 100755 index 0000000..4d95215 --- /dev/null +++ b/analyse_gecode.py @@ -0,0 +1,99 @@ +#!/usr/bin/env python3 +""" +This script will produce the final value of a variable named 'objective' and its +area for every file ending in '.sol' in the directory provided. The files are +expected to be fzn-gecode output piped through solns2out with the +'--output-time' flag. Furthermore the file is expected to contain the initial +area which can be found by adding +'constraint trace("% init_area = \(ub(objective));\n", true);' +to the model in question. +""" +import csv +import os +import re +import sys + +def compute_area(file): + area = -1 + + objectives = [] + times = [0] + timeout = -1 + objectives.append(0) + for line in contents: + # match = re.match(r'%\sinit_area\s=\s(\d+)', line) + # if match: + # objectives.append(int(match[1])) + # continue + match = re.match(r'objective\s=\s(\d+)', line) + if match: + objectives.append(int(match[1])) + continue + match = re.match(r'%\stime elapsed:\s(\d+)\sms', line) + if match: + times.append(int(match[1])) + continue + match = re.search(r"solvetime:.*\((\d+).(\d+)\s+ms\)", line) + if match: + times.append(int(match.group(1))) + continue + + assert(len(objectives) > 0) + assert(len(objectives)+1 == len(times)) + area = 0 + for i in range(len(objectives)): + area += ((times[i+1] - times[i])/1000)*objectives[i] + return int(area) + +folder = sys.argv[1] +statistics = {} +for root, dirs, files in os.walk(folder): + for name in files: + if name.endswith('.sol'): + seed = 1 + match = re.search(r"\.(\d+)\.sol", name) + if match: + seed = int(match.group(1)) + with open(os.path.join(root, name)) as f: + contents = f.readlines() + # Area + area = compute_area(contents) + + objective = 'UNSAT' + for line in contents[::-1]: + # Best objective + match = re.match(r'objective\s=\s(\d+)', line) + if match: + objective = int(match[1]) + break + + nodes = -1 + solvetime = -1 + restarts = -1 + for line in contents: + # Evaluation time + match = re.search(r"copies:\s+(\d+)", line) + if match: + nodes = int(match.group(1)) + continue + # Solve time + match = re.search(r"solvetime:.*\((\d+).(\d+)\s+ms\)", line) + if match: + solvetime = int(match.group(1)) + continue + # Restarts + match = re.search(r"restarts:\s+(\d+)", line) + if match: + restarts = int(match.group(1)) + continue + statistics[name[:-(4)].replace(".", ",")] = (area, objective, solvetime, restarts, nodes) + +sorted_stats = sorted(statistics.items()) +a = sorted_stats[0][0][:sorted_stats[0][0].find(",")] +for key, val in sorted_stats: + if key[:key.find(",")] != a: + print("\n\n") + a = key[:key.find(",")] + print("%s,%s" % (key, ",".join([v.__str__() for v in val]))) + +exit(1) diff --git a/gbac/UD2-gbac.dzn b/gbac/UD2-gbac.dzn new file mode 100644 index 0000000..8ecf908 --- /dev/null +++ b/gbac/UD2-gbac.dzn @@ -0,0 +1,20 @@ +% Real case instance UD2 of http://satt.diegm.uniud.it/projects/gbac/ +% Downloaded from https://bitbucket.org/satt/gbacp-instances/raw/Imported/UD/ +% and translated into a MiniZinc data-file. + +% Ing@UD aa07-08, second level + +n_periods = 6 ; +n_courses = 268 ; +n_curricula = 20 ; +min_courses = 2 ; +max_courses = 6 ; +n_precedences = 174 ; +n_undesirables = 158 ; +w1 = 1; +w2 = 1; +course_load = [6, 6, 6, 6, 6, 5, 5, 6, 6, 6, 6, 16, 5, 6, 6, 6, 5, 5, 5, 6, 5, 5, 6, 5, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 7, 7, 5, 5, 7, 7, 7, 5, 5, 5, 6, 6, 6, 5, 7, 7, 5, 5, 7, 7, 6, 6, 7, 5, 5, 15, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 7, 5, 7, 7, 5, 5, 5, 7, 7, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 5, 6, 5, 5, 5, 6, 6, 5, 15, 17, 5, 5, 7, 7, 5, 6, 5, 6, 5, 5, 6, 6, 16, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 5, 6, 5, 5, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 10, 5, 5, 5, 6, 5, 5, 6, 6, 2, 1, 1, 1, 1, 3, 3, 3, 3, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 6, 16, 6, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 3, 15, 6, 6, 6, 6, 6, 6, 6, 6, 5, 6, 5, 6, 5, 5, 5, 5, 5, 6, 5, 5, 6, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5] ; +courses_of = [{267, 268, 35, 39, 40, 45, 46, 47, 48, 49, 53, 189, 61, 62, 67, 103, 104, 105, 107, 108, 110, 115, 123}, {267, 268, 35, 38, 39, 40, 45, 46, 47, 48, 49, 53, 58, 62, 64, 67, 103, 104, 105, 107, 108, 109, 115}, {268, 16, 35, 36, 37, 38, 39, 40, 41, 42, 45, 46, 47, 48, 190, 191, 79, 98, 99, 103, 106, 115, 117}, {136, 268, 35, 36, 37, 38, 39, 40, 41, 43, 44, 45, 46, 47, 48, 190, 191, 100, 101, 102, 103, 115, 117}, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 147, 19, 22, 23, 24, 25, 31, 160, 186, 213, 215, 238, 111, 112, 239, 240, 241}, {2, 7, 8, 9, 10, 11, 13, 14, 16, 17, 147, 19, 20, 21, 23, 24, 25, 26, 27, 28, 29, 30, 32, 33, 34, 160, 186, 187, 214, 216, 238, 111, 239, 240, 241, 116}, {41, 49, 50, 51, 52, 53, 54, 55, 56, 185, 57, 58, 59, 60, 184, 201, 210, 113, 120, 121, 122, 123, 124}, {49, 50, 52, 53, 54, 55, 56, 185, 57, 184, 60, 61, 62, 63, 64, 201, 202, 209, 210, 211, 108, 113, 121, 122, 123}, {41, 49, 50, 51, 53, 54, 55, 56, 185, 57, 184, 60, 65, 66, 67, 68, 69, 202, 210, 82, 113, 121, 123}, {188, 192, 193, 194, 195, 196, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 96, 97, 114, 118, 119}, {16, 17, 192, 193, 194, 195, 196, 70, 71, 72, 73, 74, 203, 78, 79, 80, 83, 85, 86, 87, 88, 89, 96, 97, 114, 118, 119}, {188, 192, 193, 194, 195, 196, 70, 71, 72, 73, 74, 77, 78, 79, 80, 90, 91, 92, 93, 94, 95, 96, 97, 114, 118, 119}, {128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 267, 139, 140, 141, 142, 155, 156, 158, 159, 197, 198, 199, 200, 85, 89, 243, 244, 249, 250, 251, 252}, {128, 2, 267, 140, 142, 143, 144, 145, 146, 147, 14, 148, 149, 150, 151, 153, 152, 154, 155, 27, 157, 159, 160, 242, 243, 244, 245, 246, 247, 248, 125, 127}, {128, 2, 131, 258, 5, 267, 140, 142, 143, 144, 14, 148, 149, 151, 152, 153, 154, 27, 155, 157, 159, 160, 33, 242, 243, 244, 245, 246, 247, 248, 125, 126}, {259, 260, 261, 262, 263, 264, 265, 266, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 177, 182, 183, 205, 207, 212, 253, 254, 255}, {259, 260, 261, 262, 263, 264, 265, 266, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 175, 176, 182, 183, 205, 207, 212, 253, 254, 255}, {259, 260, 261, 262, 263, 264, 265, 266, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 178, 179, 183, 204, 205, 206, 207, 212, 253, 254, 255}, {259, 260, 261, 262, 263, 264, 265, 266, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 175, 180, 181, 183, 204, 207, 208, 212, 253, 254, 255}, {256, 257, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237}] ; +precedes = array2d(precedences,1..2, [213, 15, 7, 33, 7, 215, 7, 216, 10, 11, 16, 17, 20, 33, 20, 215, 20, 216, 24, 33, 24, 215, 24, 216, 25, 33, 25, 215, 25, 216, 26, 33, 26, 215, 26, 216, 28, 33, 28, 215, 28, 216, 31, 147, 35, 48, 35, 64, 36, 48, 36, 64, 16, 48, 16, 64, 43, 48, 43, 64, 49, 58, 49, 59, 49, 64, 49, 65, 49, 122, 49, 41, 50, 58, 50, 59, 50, 64, 50, 65, 50, 122, 50, 41, 51, 58, 51, 59, 51, 64, 51, 65, 51, 122, 51, 41, 52, 58, 52, 59, 52, 64, 52, 108, 52, 65, 52, 122, 52, 41, 53, 58, 61, 58, 61, 59, 61, 63, 61, 64, 61, 65, 61, 122, 61, 41, 66, 69, 97, 70, 104, 105, 104, 191, 107, 48, 107, 64, 108, 48, 108, 64, 49, 48, 109, 48, 109, 64, 117, 48, 117, 108, 117, 64, 121, 59, 125, 5, 127, 150, 129, 125, 129, 85, 129, 142, 129, 5, 129, 154, 131, 126, 134, 133, 135, 125, 135, 85, 135, 142, 135, 5, 135, 154, 143, 144, 147, 125, 147, 85, 147, 142, 147, 5, 147, 154, 160, 125, 160, 85, 160, 142, 160, 2, 160, 5, 160, 154, 14, 125, 14, 85, 14, 142, 14, 5, 14, 154, 148, 125, 148, 85, 148, 142, 148, 5, 148, 154, 149, 152, 151, 153, 154, 258, 155, 125, 155, 85, 155, 142, 155, 5, 155, 154, 160, 33, 160, 215, 160, 216, 166, 212, 184, 185, 190, 105, 190, 191, 197, 125, 197, 85, 197, 142, 197, 5, 197, 154, 199, 125, 199, 85, 199, 142, 199, 5, 199, 154, 213, 33, 213, 215, 213, 216, 222, 227, 222, 229, 222, 236, 223, 227, 223, 229, 223, 236, 225, 227, 225, 229, 225, 236, 239, 24, 242, 125, 242, 85, 242, 142, 242, 5, 242, 154, 246, 125, 246, 85, 246, 142, 246, 5, 246, 154, 249, 125, 249, 85, 249, 142, 249, 5, 249, 154, 252, 125, 252, 85, 252, 142, 252, 5, 252, 154, 268, 48, 268, 64] ); +undesirable = array2d(undesirables,1..2, [226, 2, 226, 5, 210, 3, 210, 6, 245, 1, 245, 4, 90, 3, 90, 6, 75, 2, 75, 5, 128, 2, 128, 5, 98, 2, 98, 5, 256, 3, 256, 6, 171, 3, 171, 6, 38, 2, 38, 5, 5, 1, 5, 4, 37, 3, 37, 6, 42, 2, 42, 5, 35, 1, 35, 4, 268, 1, 268, 4, 138, 3, 138, 6, 165, 1, 165, 4, 171, 2, 171, 5, 133, 3, 133, 6, 79, 3, 79, 6, 142, 3, 142, 6, 108, 3, 108, 6, 76, 2, 76, 5, 217, 3, 217, 6, 19, 3, 19, 6, 141, 1, 141, 4, 52, 2, 52, 5, 239, 2, 239, 5, 18, 1, 18, 4, 123, 1, 123, 4, 64, 3, 64, 6, 242, 3, 242, 6, 72, 2, 72, 5, 101, 3, 101, 6, 143, 1, 143, 4, 118, 3, 118, 6, 250, 3, 250, 6, 77, 3, 77, 6, 172, 2, 172, 5, 185, 1, 185, 4, 223, 1, 223, 4, 62, 3, 62, 6, 94, 3, 94, 6, 257, 2, 257, 5, 177, 3, 177, 6, 107, 3, 107, 6, 184, 3, 184, 6, 130, 1, 130, 4, 255, 3, 255, 6, 40, 3, 40, 6, 167, 1, 167, 4, 211, 1, 211, 4, 120, 1, 120, 4, 51, 1, 51, 4, 150, 2, 150, 5, 46, 3, 46, 6, 28, 1, 28, 4, 264, 3, 264, 6, 184, 2, 184, 5, 201, 2, 201, 5, 79, 1, 79, 4, 157, 1, 157, 4, 41, 3, 41, 6, 34, 3, 34, 6, 44, 3, 44, 6, 20, 3, 20, 6, 15, 2, 15, 5, 48, 1, 48, 4, 214, 3, 214, 6, 176, 3, 176, 6, 172, 3, 172, 6, 26, 1, 26, 4, 140, 1, 140, 4, 19, 1, 19, 4, 124, 3, 124, 6, 154, 3, 154, 6, 14, 1, 14, 4, 239, 1, 239, 4, 234, 1, 234, 4] ); +% {'c1079': 214, 'c412': 3, 'c1101': 223, 'c816': 147, 'c478': 53, 'c537': 93, 'c1146': 256, 'c676': 113, 'c489': 58, 'c527': 85, 'c420': 8, 'c526': 84, 'c446': 32, 'c431': 18, 'c922': 185, 'c1178': 265, 'c415': 4, 'c856': 173, 'c514': 75, 'c821': 149, 'c495': 61, 'c831': 156, 'c476': 51, 'c498': 64, 'c513': 74, 'c833': 157, 'c839': 161, 'c428': 15, 'c479': 54, 'c504': 68, 'c1072': 212, 'c1003': 194, 'c1105': 227, 'c455': 39, 'c828': 154, 'c865': 178, 'c532': 88, 'c1131': 245, 'c533': 89, 'c1137': 251, 'c1106': 228, 'c803': 136, 'c1065': 207, 'c1123': 238, 'c546': 100, 'c1179': 266, 'c519': 78, 'c474': 49, 'c718': 116, 'c598': 106, 'c1004': 195, 'c606': 109, 'c501': 65, 'c539': 95, 'c647': 111, 'c536': 92, 'c1062': 204, 'c812': 143, 'c848': 168, 'c1135': 249, 'c862': 177, 'c491': 59, 'c835': 159, 'c1096': 218, 'c798': 134, 'c1134': 248, 'c860': 175, 'c814': 145, 'c440': 26, 'c447': 33, 'c1185': 268, 'c871': 182, 'c419': 7, 'c1067': 209, 'c1097': 219, 'c806': 138, 'c1021': 197, 'c435': 21, 'c872': 183, 'c1127': 242, 'c1120': 236, 'c724': 118, 'c737': 121, 'c1063': 205, 'c502': 66, 'c1081': 215, 'c452': 36, 'c841': 163, 'c861': 176, 'c520': 79, 'c425': 12, 'c566': 105, 'c840': 162, 'c460': 43, 'c830': 155, 'c437': 23, 'c1132': 246, 'c1005': 196, 'c815': 146, 'c800': 135, 'c453': 37, 'c523': 81, 'c444': 30, 'c747': 124, 'c515': 76, 'c1122': 237, 'c852': 171, 'c738': 122, 'c510': 71, 'c1053': 201, 'c1099': 221, 'c426': 13, 'c795': 131, 'c721': 117, 'c409': 1, 'c487': 57, 'c1107': 229, 'c788': 125, 'c670': 112, 'c813': 144, 'c1102': 224, 'c599': 107, 'c461': 44, 'c1126': 241, 'c857': 174, 'c1125': 240, 'c869': 181, 'c450': 35, 'c429': 16, 'c1055': 202, 'c1147': 257, 'c506': 69, 'c1110': 231, 'c464': 47, 'c477': 52, 'c462': 45, 'c423': 11, 'c540': 96, 'c496': 62, 'c1142': 255, 'c1095': 217, 'c730': 120, 'c1047': 200, 'c422': 10, 'c1103': 225, 'c427': 14, 'c436': 22, 'c1071': 211, 'c1068': 210, 'c791': 128, 'c507': 70, 'c416': 5, 'c600': 108, 'c561': 103, 'c1001': 192, 'c449': 34, 'c1174': 261, 'c441': 27, 'c866': 179, 'c725': 119, 'c845': 165, 'c538': 94, 'c1184': 267, 'c1111': 232, 'c521': 80, 'c1064': 206, 'c853': 172, 'c432': 19, 'c933': 187, 'c524': 82, 'c454': 38, 'c475': 50, 'c810': 141, 'c849': 169, 'c1119': 235, 'c445': 31, 'c793': 129, 'c745': 123, 'c1066': 208, 'c1002': 193, 'c551': 101, 'c1138': 252, 'c834': 158, 'c804': 137, 'c531': 87, 'c921': 184, 'c534': 90, 'c1166': 259, 'c1140': 253, 'c1124': 239, 'c457': 41, 'c794': 130, 'c456': 40, 'c789': 126, 'c807': 139, 'c417': 6, 'c790': 127, 'c535': 91, 'c820': 148, 'c811': 142, 'c486': 56, 'c433': 20, 'c439': 25, 'c836': 160, 'c1057': 203, 'c868': 180, 'c421': 9, 'c997': 191, 'c1074': 213, 'c1104': 226, 'c544': 99, 'c541': 97, 'c463': 46, 'c1136': 250, 'c824': 152, 'c511': 72, 'c826': 153, 'c1022': 198, 'c458': 42, 'c1118': 234, 'c850': 170, 'c465': 48, 'c932': 186, 'c438': 24, 'c564': 104, 'c1129': 244, 'c494': 60, 'c822': 150, 'c516': 77, 'c1176': 263, 'c530': 86, 'c847': 167, 'c430': 17, 'c525': 83, 'c996': 190, 'c797': 133, 'c1128': 243, 'c1177': 264, 'c1175': 262, 'c1167': 260, 'c846': 166, 'c993': 189, 'c823': 151, 'c796': 132, 'c1133': 247, 'c808': 140, 'c1141': 254, 'c716': 115, 'c1046': 199, 'c607': 110, 'c543': 98, 'c443': 29, 'c1100': 222, 'c936': 188, 'c442': 28, 'c484': 55, 'c512': 73, 'c1109': 230, 'c1112': 233, 'c1148': 258, 'c411': 2, 'c844': 164, 'c678': 114, 'c497': 63, 'c503': 67, 'c1082': 216, 'c1098': 220, 'c554': 102} diff --git a/gbac/UD4-gbac.dzn b/gbac/UD4-gbac.dzn new file mode 100644 index 0000000..317585a --- /dev/null +++ b/gbac/UD4-gbac.dzn @@ -0,0 +1,20 @@ +% Real case instance UD4 of http://satt.diegm.uniud.it/projects/gbac/ +% Downloaded from https://bitbucket.org/satt/gbacp-instances/raw/Imported/UD/ +% and translated into a MiniZinc data-file. + +% Ing@UD aa02-03, VOD + +n_periods = 6 ; +n_courses = 139 ; +n_curricula = 16 ; +min_courses = 2 ; +max_courses = 6 ; +n_precedences = 188 ; +n_undesirables = 80 ; +w1 = 1; +w2 = 1; +course_load = [6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 12, 6, 6, 6, 6, 6, 6, 6, 12, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 12, 6, 6, 12, 6, 6, 6, 6, 12, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 12, 12, 6, 12, 6, 12, 12, 6, 6, 12, 6, 6, 6, 6, 6, 6, 6, 12, 12, 6, 6, 6, 6, 12, 6, 6, 6, 12, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 12, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6] ; +courses_of = [{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 131, 12, 13, 14, 135, 16, 136, 137, 132, 29, 30, 31, 32, 33, 34, 133, 36, 105, 107, 112, 113, 115, 116, 117, 118, 119}, {1, 2, 3, 4, 5, 6, 7, 131, 132, 10, 11, 133, 134, 135, 15, 136, 17, 18, 19, 20, 21, 29, 32, 35, 36, 137, 105, 107, 112, 113, 114, 115, 116, 117, 118, 119}, {1, 2, 3, 4, 5, 6, 7, 131, 132, 133, 135, 136, 13, 137, 16, 22, 23, 24, 25, 29, 34, 36, 105, 106, 107, 112, 113, 115, 116, 117, 118, 119}, {1, 2, 3, 4, 5, 6, 7, 131, 132, 133, 135, 136, 137, 19, 22, 24, 25, 26, 27, 28, 29, 35, 36, 105, 106, 107, 112, 113, 115, 116, 117, 118, 119}, {128, 130, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 111, 53, 54, 55, 58, 60, 61, 62}, {128, 129, 130, 37, 38, 39, 40, 41, 42, 43, 47, 48, 49, 50, 51, 53, 54, 55, 57, 58, 59, 62}, {128, 37, 38, 39, 40, 41, 42, 43, 44, 46, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 61, 62}, {138, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 76, 84, 86, 87, 88, 90, 94, 108, 109, 120, 121, 122, 126, 127}, {138, 63, 64, 65, 66, 67, 68, 69, 70, 73, 77, 78, 79, 82, 84, 86, 87, 88, 90, 94, 108, 109, 111, 120, 121, 122, 126, 127}, {138, 19, 35, 63, 64, 65, 66, 67, 68, 69, 70, 80, 84, 86, 87, 88, 90, 94, 98, 104, 108, 109, 111, 120, 121, 122, 126, 127}, {138, 63, 64, 65, 66, 67, 68, 69, 70, 81, 84, 86, 87, 88, 89, 90, 94, 108, 109, 111, 120, 121, 122, 126, 127}, {138, 47, 63, 64, 65, 66, 67, 68, 69, 70, 74, 75, 83, 84, 85, 86, 87, 88, 94, 108, 109, 111, 120, 121, 122, 126, 127}, {64, 96, 97, 99, 102, 103, 123, 139, 111, 124, 125, 120, 89, 90, 91, 92, 93, 94, 95}, {64, 96, 100, 101, 102, 73, 123, 139, 110, 124, 125, 120, 89, 90, 91, 92, 93, 94, 95}, {64, 96, 98, 35, 102, 104, 123, 139, 124, 81, 19, 125, 120, 89, 90, 91, 92, 93, 94, 95}, {64, 96, 102, 73, 123, 139, 77, 78, 124, 125, 120, 89, 90, 91, 92, 93, 94, 95}] ; +precedes = array2d(precedences,1..2, [1, 5, 1, 18, 1, 20, 1, 27, 1, 28, 1, 36, 1, 114, 1, 117, 1, 118, 1, 134, 2, 5, 2, 18, 2, 20, 2, 27, 2, 28, 2, 36, 2, 114, 2, 117, 2, 118, 2, 134, 8, 5, 8, 18, 8, 20, 8, 27, 8, 28, 8, 36, 8, 114, 8, 117, 8, 118, 8, 134, 9, 5, 9, 18, 9, 20, 9, 27, 9, 28, 9, 36, 9, 114, 9, 117, 9, 118, 9, 134, 11, 5, 11, 18, 11, 20, 11, 27, 11, 28, 11, 36, 11, 114, 11, 117, 11, 118, 11, 134, 37, 111, 37, 49, 37, 60, 37, 61, 37, 62, 38, 111, 38, 49, 38, 60, 38, 61, 38, 62, 39, 111, 39, 49, 39, 60, 39, 61, 39, 62, 63, 66, 63, 69, 63, 70, 63, 76, 63, 77, 63, 78, 63, 81, 63, 87, 63, 127, 63, 138, 65, 66, 65, 69, 65, 70, 65, 76, 65, 77, 65, 78, 65, 81, 65, 87, 65, 127, 65, 138, 90, 66, 90, 69, 90, 70, 90, 76, 90, 77, 90, 78, 90, 81, 90, 87, 90, 127, 90, 138, 71, 66, 71, 69, 71, 70, 71, 76, 71, 77, 71, 78, 71, 81, 71, 87, 71, 127, 71, 138, 74, 66, 74, 69, 74, 70, 74, 76, 74, 77, 74, 78, 74, 81, 74, 87, 74, 127, 74, 138, 90, 111, 90, 99, 90, 100, 90, 101, 90, 110, 90, 139, 91, 111, 91, 99, 91, 100, 91, 101, 91, 81, 91, 77, 91, 78, 91, 110, 91, 139, 92, 111, 92, 99, 92, 100, 92, 101, 92, 81, 92, 77, 92, 78, 92, 110, 92, 139, 105, 5, 105, 18, 105, 20, 105, 27, 105, 28, 105, 36, 105, 114, 105, 117, 105, 118, 105, 134, 108, 66, 108, 69, 108, 70, 108, 76, 108, 77, 108, 78, 108, 81, 108, 87, 108, 127, 108, 138, 124, 111, 124, 99, 124, 100, 124, 101, 124, 81, 124, 77, 124, 78, 124, 110, 124, 139, 126, 66, 126, 69, 126, 70, 126, 76, 126, 77, 126, 78, 126, 81, 126, 87, 126, 127, 126, 138, 131, 5, 131, 18, 131, 20, 131, 27, 131, 28, 131, 36, 131, 114, 131, 117, 131, 118, 131, 134] ); +undesirable = array2d(undesirables,1..2, [117, 2, 117, 5, 109, 3, 109, 6, 127, 1, 127, 4, 47, 3, 47, 6, 39, 2, 39, 5, 67, 2, 67, 5, 51, 2, 51, 5, 133, 3, 133, 6, 89, 3, 89, 6, 20, 2, 20, 5, 3, 1, 3, 4, 20, 3, 20, 6, 22, 2, 22, 5, 19, 1, 19, 4, 139, 1, 139, 4, 72, 3, 72, 6, 86, 1, 86, 4, 89, 2, 89, 5, 69, 3, 69, 6, 41, 3, 41, 6, 74, 3, 74, 6, 56, 3, 56, 6, 40, 2, 40, 5, 113, 3, 113, 6, 10, 3, 10, 6, 74, 1, 74, 4, 27, 2, 27, 5, 124, 2, 124, 5, 9, 1, 9, 4, 64, 1, 64, 4, 34, 3, 34, 6, 126, 3, 126, 6, 38, 2, 38, 5, 53, 3, 53, 6, 61, 3, 61, 6, 130, 3, 130, 6, 40, 3, 40, 6, 96, 1, 96, 4, 62, 3, 62, 6, 116, 1, 116, 4] ); +% {'c365': 78, 'c346': 64, 'c635': 117, 'c652': 128, 'c313': 32, 'c640': 121, 'c664': 139, 'c356': 72, 'c655': 130, 'c401': 103, 'c353': 70, 'c312': 31, 'c651': 127, 'c384': 92, 'c305': 24, 'c309': 28, 'c388': 96, 'c345': 63, 'c393': 99, 'c310': 29, 'c625': 111, 'c289': 8, 'c649': 125, 'c379': 88, 'c292': 11, 'c332': 50, 'c285': 4, 'c333': 51, 'c300': 19, 'c294': 13, 'c339': 57, 'c297': 16, 'c632': 114, 'c661': 136, 'c284': 3, 'c378': 87, 'c319': 38, 'c656': 131, 'c283': 2, 'c286': 5, 'c299': 18, 'c657': 132, 'c347': 65, 'c395': 101, 'c624': 110, 'c322': 41, 'c368': 80, 'c348': 66, 'c307': 26, 'c287': 6, 'c317': 36, 'c373': 84, 'c374': 85, 'c338': 56, 'c370': 82, 'c662': 137, 'c663': 138, 'c296': 15, 'c636': 118, 'c336': 54, 'c351': 68, 'c381': 89, 'c637': 119, 'c337': 55, 'c634': 116, 'c386': 94, 'c316': 35, 'c659': 134, 'c369': 81, 'c350': 67, 'c302': 21, 'c619': 107, 'c617': 105, 'c306': 25, 'c355': 71, 'c642': 123, 'c638': 120, 'c391': 98, 'c376': 86, 'c323': 42, 'c331': 49, 'c330': 48, 'c334': 52, 'c363': 76, 'c311': 30, 'c372': 83, 'c308': 27, 'c290': 9, 'c648': 124, 'c315': 34, 'c318': 37, 'c291': 10, 'c658': 133, 'c653': 129, 'c326': 45, 'c382': 90, 'c618': 106, 'c282': 1, 'c633': 115, 'c361': 74, 'c358': 73, 'c303': 22, 'c402': 104, 'c387': 95, 'c288': 7, 'c400': 102, 'c298': 17, 'c364': 77, 'c325': 44, 'c366': 79, 'c324': 43, 'c620': 108, 'c295': 14, 'c389': 97, 'c328': 47, 'c321': 40, 'c335': 53, 'c630': 112, 'c320': 39, 'c385': 93, 'c623': 109, 'c301': 20, 'c342': 60, 'c344': 62, 'c327': 46, 'c293': 12, 'c352': 69, 'c641': 122, 'c631': 113, 'c383': 91, 'c660': 135, 'c650': 126, 'c394': 100, 'c314': 33, 'c362': 75, 'c341': 59, 'c340': 58, 'c304': 23, 'c343': 61} diff --git a/gbac/UD5-gbac.dzn b/gbac/UD5-gbac.dzn new file mode 100644 index 0000000..3b16b9b --- /dev/null +++ b/gbac/UD5-gbac.dzn @@ -0,0 +1,20 @@ +% Real case instance UD5 of http://satt.diegm.uniud.it/projects/gbac/ +% Downloaded from https://bitbucket.org/satt/gbacp-instances/raw/Imported/UD/ +% and translated into a MiniZinc data-file. + +% Ing@UD aa08-09, first level + +n_periods = 6 ; +n_courses = 282 ; +n_curricula = 31 ; +min_courses = 2 ; +max_courses = 7 ; +n_precedences = 397 ; +n_undesirables = 162 ; +w1 = 1; +w2 = 1; +course_load = [5, 5, 6, 5, 5, 6, 5, 6, 6, 5, 6, 5, 5, 5, 3, 6, 1, 1, 12, 6, 6, 6, 5, 6, 5, 5, 6, 5, 5, 6, 5, 6, 5, 6, 6, 6, 1, 1, 5, 5, 5, 3, 10, 6, 5, 5, 5, 5, 6, 6, 5, 5, 5, 6, 5, 5, 5, 6, 5, 6, 5, 5, 5, 5, 5, 5, 5, 3, 6, 1, 1, 10, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 1, 1, 5, 6, 6, 5, 6, 5, 5, 6, 6, 5, 5, 5, 5, 5, 3, 6, 1, 1, 6, 6, 6, 5, 5, 5, 5, 6, 6, 6, 5, 6, 6, 6, 5, 5, 6, 3, 6, 12, 5, 5, 6, 5, 5, 5, 12, 6, 5, 5, 6, 5, 5, 5, 6, 6, 5, 6, 5, 5, 5, 5, 5, 6, 1, 1, 3, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 31, 5, 5, 5, 5, 5, 5, 5, 5, 11, 4, 1, 5, 5, 5, 5, 5, 6, 5, 3, 5, 20, 2, 6, 1, 1, 1, 5, 1, 10, 5, 1, 4, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 1, 12, 12, 9, 6, 6, 6, 3, 12, 12, 9, 6, 3, 6, 6, 3, 6, 12, 12, 9, 3, 6, 6, 6, 6, 3, 6, 9, 9, 9, 9, 9, 3, 9, 30, 6, 5, 5, 6, 5, 6, 7, 3, 6, 12, 1, 1, 5, 5, 5, 12, 5, 5, 12, 6, 9, 6, 3, 3, 3, 2, 6, 6, 6, 6, 30] ; +courses_of = [{178, 273, 152, 184, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 233, 234, 235, 236, 237, 252}, {178, 273, 152, 184, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 67, 68, 69, 70, 71, 202, 233, 234, 235, 236, 237, 252}, {178, 273, 152, 184, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 67, 68, 69, 70, 71, 202, 233, 234, 235, 236, 237, 252}, {178, 273, 152, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 184, 66, 67, 68, 69, 70, 71, 72, 233, 234, 235, 236, 237, 252}, {178, 273, 152, 153, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 184, 67, 68, 69, 70, 71, 72, 233, 234, 235, 236, 237, 252}, {178, 273, 152, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 184, 67, 68, 69, 70, 71, 72, 202, 233, 234, 235, 236, 237, 252}, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 188, 191, 225, 226, 227, 230, 231, 232, 105, 106, 108, 115, 118}, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 21, 188, 191, 225, 226, 227, 230, 231, 232, 105, 106, 108, 115, 118}, {128, 4, 9, 11, 15, 16, 17, 18, 19, 22, 44, 45, 46, 47, 48, 225, 226, 227, 230, 231, 232, 105, 106, 108, 109, 110, 112, 113, 114, 115, 118, 119}, {128, 4, 6, 9, 11, 15, 16, 17, 18, 22, 44, 45, 46, 47, 48, 49, 225, 226, 227, 230, 231, 232, 105, 106, 108, 109, 110, 112, 113, 114, 115, 118, 119}, {2, 3, 5, 6, 7, 11, 15, 16, 17, 21, 161, 163, 164, 165, 166, 167, 168, 169, 170, 175, 192, 193, 225, 226, 227, 230, 231, 232, 105, 106, 108, 115, 118}, {256, 158, 31, 23, 24, 25, 26, 27, 28, 157, 29, 30, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 159, 176, 186, 187, 196, 197, 199, 216, 217, 218, 219, 220, 221, 222, 223, 224}, {128, 11, 276, 277, 282, 160, 161, 162, 163, 164, 45, 46, 177, 194, 195, 225, 226, 227, 228, 229, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 125, 126, 127}, {128, 11, 275, 276, 160, 161, 162, 163, 164, 45, 46, 177, 194, 195, 225, 226, 227, 228, 229, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127}, {128, 11, 275, 276, 277, 160, 161, 162, 163, 164, 45, 46, 177, 194, 195, 225, 226, 227, 228, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127}, {257, 258, 261, 270, 271, 272, 273, 278, 56, 215, 60, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 253, 255}, {257, 258, 129, 131, 261, 8, 270, 271, 272, 273, 278, 56, 60, 87, 88, 89, 90, 91, 92, 93, 96, 97, 98, 99, 101, 102, 103, 104, 253, 255}, {257, 258, 130, 131, 261, 270, 271, 272, 273, 278, 56, 57, 60, 87, 88, 89, 90, 91, 92, 93, 96, 97, 98, 99, 101, 102, 103, 104, 253, 255}, {171, 172, 173, 174, 189, 190, 200, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 207, 208, 209, 210, 211, 212, 213, 214, 247, 243, 201, 244, 245, 246, 248, 249, 250}, {171, 174, 182, 183, 189, 190, 200, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 207, 208, 209, 210, 211, 212, 213, 214, 247, 243, 201, 244, 245, 246, 248, 249, 250}, {161, 163, 174, 175, 181, 200, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 207, 208, 213, 214, 247, 243, 201, 244, 245, 246, 248, 249, 250, 251}, {171, 174, 181, 189, 190, 200, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 207, 208, 209, 210, 211, 212, 213, 214, 247, 243, 201, 244, 245, 246, 248, 249, 250}, {256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 278, 23, 24, 26, 27, 157, 31, 32, 33, 159, 39, 176, 88, 89, 99, 100, 253, 254, 255}, {256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 278, 23, 24, 26, 27, 157, 31, 32, 33, 159, 39, 176, 88, 89, 99, 100, 253, 254, 255}, {132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 274, 279, 154, 155, 156, 280, 281, 179, 180, 185, 205, 206, 238, 239, 240, 241, 242}, {132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 274, 147, 148, 149, 150, 151, 279, 280, 154, 155, 156, 281, 179, 180, 185, 204, 205, 206, 238, 239, 240, 241, 242}, {132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 274, 147, 148, 149, 150, 151, 279, 280, 154, 155, 156, 281, 179, 180, 185, 203, 205, 206, 238, 239, 240, 241, 242}, {132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 146, 147, 148, 149, 150, 151, 274, 279, 154, 155, 156, 280, 281, 185, 198, 238, 239, 240, 241, 242}, {132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 274, 147, 148, 149, 150, 151, 279, 280, 154, 155, 156, 281, 185, 198, 204, 238, 239, 240, 241, 242}, {132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 274, 147, 148, 149, 150, 151, 279, 280, 154, 155, 156, 281, 185, 198, 203, 238, 239, 240, 241, 242}, {132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 148, 149, 150, 151, 155, 179, 180, 185, 198, 205, 206, 238, 239, 240, 241, 242}] ; +precedes = array2d(precedences,1..2, [105, 3, 105, 6, 105, 7, 105, 8, 105, 9, 105, 10, 105, 12, 105, 13, 105, 14, 105, 20, 105, 21, 105, 22, 105, 44, 105, 119, 105, 46, 105, 47, 105, 128, 105, 48, 105, 49, 105, 112, 105, 113, 105, 188, 29, 199, 30, 25, 30, 34, 30, 35, 30, 36, 30, 39, 30, 40, 30, 41, 30, 157, 30, 158, 30, 176, 30, 256, 30, 187, 30, 196, 30, 197, 32, 25, 32, 34, 32, 35, 32, 36, 32, 39, 32, 40, 32, 41, 32, 157, 32, 158, 32, 176, 32, 256, 32, 196, 58, 52, 58, 56, 58, 57, 58, 63, 58, 64, 58, 65, 58, 66, 58, 178, 58, 184, 257, 88, 257, 89, 257, 255, 257, 56, 257, 90, 257, 94, 257, 95, 257, 99, 257, 100, 257, 8, 257, 129, 257, 130, 257, 57, 257, 215, 105, 116, 105, 117, 105, 120, 105, 121, 105, 125, 105, 126, 105, 127, 105, 160, 105, 45, 105, 177, 139, 133, 139, 137, 139, 138, 139, 143, 139, 144, 139, 145, 139, 146, 139, 185, 139, 203, 140, 133, 140, 137, 140, 138, 140, 143, 140, 144, 140, 145, 140, 146, 140, 185, 140, 203, 159, 199, 187, 199, 230, 3, 230, 6, 230, 7, 230, 8, 230, 9, 230, 10, 230, 12, 230, 13, 230, 14, 230, 20, 230, 21, 230, 22, 230, 44, 230, 119, 230, 46, 230, 47, 230, 128, 230, 48, 230, 49, 230, 112, 230, 113, 230, 188, 233, 52, 233, 56, 233, 57, 233, 63, 233, 64, 233, 65, 233, 66, 233, 178, 233, 184, 238, 133, 238, 137, 238, 138, 238, 143, 238, 144, 238, 145, 238, 146, 238, 185, 238, 203, 252, 52, 252, 56, 252, 57, 252, 63, 252, 64, 252, 65, 252, 66, 252, 178, 252, 184, 257, 256, 257, 39, 257, 157, 257, 176, 257, 264, 257, 265, 257, 266, 257, 268, 257, 269, 261, 88, 261, 89, 261, 255, 261, 99, 261, 256, 261, 39, 261, 157, 261, 176, 261, 100, 261, 264, 261, 265, 261, 266, 261, 268, 261, 269, 261, 56, 261, 90, 261, 94, 261, 95, 261, 8, 261, 129, 261, 130, 261, 57, 261, 215, 271, 273, 271, 253, 271, 87, 271, 88, 271, 89, 271, 255, 271, 56, 271, 90, 271, 91, 271, 92, 271, 60, 271, 93, 271, 258, 271, 94, 271, 95, 271, 96, 271, 97, 271, 98, 271, 99, 271, 100, 271, 8, 271, 129, 271, 130, 271, 57, 271, 215, 16, 2, 16, 4, 16, 5, 16, 6, 16, 9, 16, 118, 16, 12, 16, 19, 16, 20, 16, 21, 16, 114, 16, 109, 16, 110, 16, 45, 16, 46, 16, 47, 16, 128, 16, 49, 16, 164, 16, 175, 16, 167, 16, 169, 16, 192, 24, 33, 26, 27, 36, 41, 114, 119, 109, 110, 46, 47, 56, 63, 69, 51, 69, 54, 69, 55, 69, 57, 69, 61, 69, 63, 69, 64, 69, 65, 69, 66, 69, 152, 69, 153, 69, 202, 70, 57, 70, 63, 70, 64, 70, 65, 70, 66, 70, 153, 70, 202, 84, 75, 84, 78, 84, 79, 84, 80, 84, 81, 84, 82, 84, 173, 84, 175, 84, 181, 84, 182, 84, 190, 84, 200, 84, 211, 84, 212, 84, 213, 84, 214, 84, 251, 85, 75, 85, 78, 85, 79, 85, 80, 85, 81, 85, 82, 85, 173, 85, 175, 85, 181, 85, 182, 85, 190, 85, 200, 85, 211, 85, 212, 85, 213, 85, 214, 85, 251, 86, 75, 86, 78, 86, 79, 86, 80, 86, 81, 86, 82, 86, 173, 86, 175, 86, 181, 86, 182, 86, 190, 86, 200, 86, 211, 86, 212, 86, 213, 86, 214, 86, 251, 94, 95, 102, 253, 102, 90, 102, 92, 102, 93, 102, 94, 102, 95, 102, 96, 102, 97, 102, 98, 102, 100, 102, 129, 102, 57, 112, 113, 123, 109, 123, 110, 123, 111, 123, 114, 123, 117, 123, 118, 123, 120, 123, 121, 123, 46, 123, 124, 123, 126, 123, 127, 123, 128, 123, 45, 123, 164, 123, 282, 137, 143, 148, 135, 148, 136, 148, 138, 148, 143, 148, 144, 148, 145, 148, 146, 148, 154, 148, 156, 148, 179, 148, 180, 148, 203, 148, 204, 149, 138, 149, 143, 149, 144, 149, 145, 149, 146, 149, 203, 149, 204, 165, 166, 186, 24, 186, 25, 186, 26, 186, 27, 186, 29, 186, 33, 186, 35, 186, 39, 186, 40, 186, 41, 186, 43, 186, 157, 186, 159, 186, 176, 186, 256, 186, 199, 193, 9, 193, 12, 193, 19, 193, 20, 193, 21, 193, 46, 193, 47, 193, 128, 193, 49, 193, 175, 193, 167, 193, 169, 193, 118, 193, 6, 205, 206, 218, 220, 225, 227, 234, 236, 250, 74, 157, 176, 270, 272] ); +undesirable = array2d(undesirables,1..2, [5, 1, 5, 3, 5, 5, 19, 1, 19, 3, 19, 5, 20, 2, 20, 4, 20, 6, 37, 1, 37, 3, 37, 5, 39, 2, 39, 4, 39, 6, 40, 2, 40, 4, 40, 6, 42, 2, 42, 4, 42, 6, 45, 1, 45, 3, 45, 5, 48, 2, 48, 4, 48, 6, 53, 1, 53, 3, 53, 5, 55, 2, 55, 4, 55, 6, 65, 2, 65, 4, 65, 6, 68, 2, 68, 4, 68, 6, 76, 2, 76, 4, 76, 6, 79, 2, 79, 4, 79, 6, 80, 1, 80, 3, 80, 5, 81, 2, 81, 4, 81, 6, 83, 2, 83, 4, 83, 6, 95, 2, 95, 4, 95, 6, 99, 2, 99, 4, 99, 6, 103, 2, 103, 4, 103, 6, 106, 2, 106, 4, 106, 6, 113, 2, 113, 4, 113, 6, 124, 2, 124, 4, 124, 6, 125, 2, 125, 4, 125, 6, 127, 1, 127, 3, 127, 5, 130, 1, 130, 3, 130, 5, 135, 2, 135, 4, 135, 6, 137, 1, 137, 3, 137, 5, 140, 2, 140, 4, 140, 6, 145, 2, 145, 4, 145, 6, 149, 2, 149, 4, 149, 6, 150, 1, 150, 3, 150, 5, 157, 1, 157, 3, 157, 5, 173, 1, 173, 3, 173, 5, 175, 1, 175, 3, 175, 5, 180, 2, 180, 4, 180, 6, 181, 1, 181, 3, 181, 5, 186, 2, 186, 4, 186, 6, 193, 2, 193, 4, 193, 6, 194, 1, 194, 3, 194, 5, 221, 2, 221, 4, 221, 6, 222, 1, 222, 3, 222, 5, 228, 2, 228, 4, 228, 6, 234, 1, 234, 3, 234, 5, 237, 1, 237, 3, 237, 5, 252, 1, 252, 3, 252, 5, 255, 2, 255, 4, 255, 6, 258, 1, 258, 3, 258, 5, 263, 2, 263, 4, 263, 6, 268, 2, 268, 4, 268, 6, 269, 2, 269, 4, 269, 6, 270, 2, 270, 4, 270, 6, 282, 1, 282, 3, 282, 5] ); +% {'c685': 133, 'c64': 36, 'c232': 120, 'c473': 131, 'c1239': 233, 'c188': 90, 'c217': 109, 'c58': 31, 'c61': 34, 'c118': 66, 'c73': 40, 'c980': 183, 'c695': 141, 'c253': 128, 'c104': 55, 'c1155': 207, 'c687': 134, 'c1298': 264, 'c770': 162, 'c1309': 273, 'c199': 97, 'c1278': 255, 'c1049': 192, 'c1249': 241, 'c207': 103, 'c162': 82, 'c935': 178, 'c1331': 278, 'c77': 42, 'c24': 12, 'c113': 61, 'c1077': 202, 'c1219': 221, 'c1274': 253, 'c33': 18, 'c1296': 262, 'c9': 2, 'c13': 5, 'c1233': 230, 'c219': 111, 'c88': 46, 'c216': 108, 'c89': 47, 'c150': 80, 'c223': 114, 'c1293': 259, 'c689': 135, 'c53': 28, 'c218': 110, 'c98': 51, 'c690': 136, 'c1059': 197, 'c208': 104, 'c1162': 212, 'c122': 68, 'c698': 143, 'c1328': 277, 'c1156': 208, 'c700': 145, 'c884': 174, 'c200': 98, 'c1264': 250, 'c468': 130, 'c52': 27, 'c198': 96, 'c1051': 194, 'c249': 127, 'c237': 123, 'c875': 170, 'c85': 45, 'c56': 30, 'c117': 65, 'c1291': 258, 'c1076': 201, 'c1226': 227, 'c1326': 275, 'c184': 88, 'c1157': 209, 'c1308': 272, 'c780': 167, 'c105': 56, 'c778': 166, 'c694': 140, 'c693': 139, 'c205': 102, 'c1220': 222, 'c189': 91, 'c51': 26, 'c704': 148, 'c247': 126, 'c1286': 257, 'c26': 13, 'c1307': 271, 'c691': 137, 'c946': 180, 'c125': 71, 'c910': 176, 'c945': 179, 'c1020': 188, 'c1246': 239, 'c1341': 282, 'c772': 163, 'c20': 10, 'c1230': 229, 'c1263': 249, 'c203': 100, 'c133': 75, 'c706': 150, 'c149': 79, 'c101': 53, 'c710': 151, 'c230': 118, 'c37': 22, 'c1266': 252, 'c72': 39, 'c696': 142, 'c1180': 215, 'c969': 182, 'c35': 20, 'c1237': 232, 'c124': 70, 'c59': 32, 'c1050': 193, 'c30': 16, 'c7': 1, 'c1224': 225, 'c143': 77, 'c110': 60, 'c1052': 195, 'c1241': 235, 'c1229': 228, 'c171': 84, 'c1301': 267, 'c123': 69, 'c71': 38, 'c1327': 276, 'c62': 35, 'c204': 101, 'c838': 169, 'c103': 54, 'c211': 105, 'c221': 113, 'c1305': 269, 'c137': 76, 'c14': 6, 'c99': 52, 'c163': 83, 'c734': 156, 'c767': 160, 'c60': 33, 'c742': 158, 'c732': 154, 'c705': 149, 'c49': 25, 'c19': 9, 'c1333': 280, 'c881': 171, 'c236': 122, 'c1043': 190, 'c108': 58, 'c193': 93, 'c1297': 263, 'c174': 86, 'c1257': 245, 'c23': 11, 'c1240': 234, 'c898': 175, 'c15': 7, 'c1306': 270, 'c233': 121, 'c148': 78, 'c29': 15, 'c1255': 243, 'c1078': 203, 'c97': 50, 'c106': 57, 'c1265': 251, 'c931': 177, 'c173': 85, 'c70': 37, 'c1260': 248, 'c115': 63, 'c1294': 260, 'c1325': 274, 'c683': 132, 'c153': 81, 'c1248': 240, 'c191': 92, 'c1299': 265, 'c220': 112, 'c1008': 186, 'c34': 19, 'c1223': 224, 'c201': 99, 'c231': 119, 'c1258': 246, 'c1144': 205, 'c883': 173, 'c225': 116, 'c999': 185, 'c769': 161, 'c197': 95, 'c183': 87, 'c185': 89, 'c55': 29, 'c1161': 211, 'c47': 24, 'c1282': 256, 'c1164': 214, 'c467': 129, 'c1235': 231, 'c27': 14, 'c1334': 281, 'c1250': 242, 'c116': 64, 'c746': 159, 'c701': 146, 'c114': 62, 'c91': 48, 'c722': 152, 'c1145': 206, 'c32': 17, 'c1217': 219, 'c1069': 199, 'c1256': 244, 'c196': 94, 'c1221': 223, 'c1300': 266, 'c126': 72, 'c1042': 189, 'c1225': 226, 'c781': 168, 'c227': 117, 'c80': 44, 'c1192': 217, 'c1295': 261, 'c1084': 204, 'c1061': 198, 'c109': 59, 'c243': 125, 'c773': 164, 'c1191': 216, 'c741': 157, 'c36': 21, 'c1275': 254, 'c1013': 187, 'c1075': 200, 'c777': 165, 'c1058': 196, 'c11': 3, 'c1244': 237, 'c74': 41, 'c1303': 268, 'c723': 153, 'c703': 147, 'c998': 184, 'c1163': 213, 'c733': 155, 'c92': 49, 'c1259': 247, 'c1332': 279, 'c12': 4, 'c1245': 238, 'c963': 181, 'c128': 73, 'c224': 115, 'c699': 144, 'c46': 23, 'c18': 8, 'c1218': 220, 'c212': 106, 'c1045': 191, 'c241': 124, 'c882': 172, 'c78': 43, 'c1216': 218, 'c132': 74, 'c1158': 210, 'c121': 67, 'c215': 107, 'c1242': 236, 'c692': 138} diff --git a/gbac/UD8-gbac.dzn b/gbac/UD8-gbac.dzn new file mode 100644 index 0000000..9775bb1 --- /dev/null +++ b/gbac/UD8-gbac.dzn @@ -0,0 +1,20 @@ +% Real case instance UD8 of http://satt.diegm.uniud.it/projects/gbac/ +% Downloaded from https://bitbucket.org/satt/gbacp-instances/raw/Imported/UD/ +% and translated into a MiniZinc data-file. + +% Ing@UD aa05-06, second level + +n_periods = 6 ; +n_courses = 208 ; +n_curricula = 19 ; +min_courses = 2 ; +max_courses = 6 ; +n_precedences = 149 ; +n_undesirables = 120 ; +w1 = 1; +w2 = 1; +course_load = [6, 6, 6, 6, 6, 5, 5, 6, 6, 6, 6, 16, 5, 6, 6, 6, 5, 5, 5, 6, 5, 5, 6, 5, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 7, 7, 5, 5, 7, 7, 7, 5, 5, 5, 6, 6, 6, 5, 7, 7, 5, 5, 7, 7, 6, 6, 7, 5, 5, 15, 5, 5, 5, 5, 5, 5, 5, 5, 5, 7, 5, 7, 7, 5, 5, 5, 7, 7, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 5, 6, 5, 6, 5, 5, 6, 6, 5, 15, 17, 5, 5, 7, 7, 5, 6, 5, 6, 5, 5, 6, 6, 16, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 5, 6, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 6, 6, 2, 1, 1, 1, 1, 5, 3, 3, 3, 3, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 6, 16, 6, 7, 5] ; +courses_of = [{35, 39, 40, 45, 46, 47, 48, 49, 53, 181, 61, 62, 67, 102, 103, 104, 105, 107, 108, 109, 111, 116, 124}, {35, 38, 39, 40, 45, 46, 47, 48, 49, 53, 58, 62, 64, 67, 102, 103, 104, 105, 107, 108, 109, 110, 116}, {16, 35, 36, 37, 38, 39, 40, 41, 42, 45, 46, 47, 48, 182, 183, 78, 97, 98, 102, 103, 106, 116, 118}, {138, 35, 36, 37, 38, 39, 40, 41, 43, 44, 45, 46, 47, 48, 182, 183, 99, 100, 101, 102, 103, 116, 118}, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 149, 23, 25, 163, 178, 204, 206, 112, 113}, {2, 8, 9, 10, 11, 14, 16, 17, 19, 20, 149, 21, 22, 23, 24, 26, 27, 28, 29, 30, 25, 31, 32, 33, 34, 163, 179, 205, 207, 112, 117}, {41, 176, 177, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 189, 60, 194, 201, 114, 121, 122, 123, 124, 125}, {176, 177, 49, 50, 52, 53, 54, 55, 56, 57, 60, 189, 61, 62, 64, 63, 194, 195, 200, 201, 202, 108, 114, 122, 123, 124}, {41, 176, 177, 49, 50, 51, 53, 54, 55, 56, 57, 60, 189, 65, 66, 67, 68, 195, 201, 208, 81, 114, 122, 124}, {180, 184, 185, 186, 187, 188, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 95, 96, 115, 119, 120}, {16, 17, 184, 185, 186, 187, 188, 196, 69, 70, 71, 72, 73, 77, 78, 79, 82, 84, 85, 86, 87, 88, 95, 96, 115, 119, 120}, {180, 184, 185, 186, 187, 188, 69, 70, 71, 72, 73, 76, 77, 78, 79, 89, 90, 91, 92, 93, 94, 95, 96, 115, 119, 120}, {129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 158, 159, 161, 162, 190, 191, 192, 193, 84, 88, 109}, {128, 129, 2, 142, 14, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 27, 156, 157, 158, 160, 162, 163, 109, 126}, {129, 2, 132, 5, 142, 14, 144, 145, 146, 150, 151, 153, 154, 27, 155, 156, 158, 157, 160, 33, 162, 163, 109, 126, 127}, {164, 165, 166, 167, 168, 169, 170, 171, 172, 198, 203, 175}, {164, 165, 166, 167, 168, 169, 170, 171, 172, 198, 203, 175}, {164, 165, 166, 167, 168, 169, 170, 171, 197, 173, 198, 203}, {164, 165, 166, 167, 168, 169, 170, 171, 197, 199, 174, 203}] ; +precedes = array2d(precedences,1..2, [6, 33, 6, 206, 6, 207, 7, 33, 7, 206, 7, 207, 10, 11, 16, 17, 20, 33, 20, 206, 20, 207, 24, 33, 24, 206, 24, 207, 25, 33, 25, 206, 25, 207, 26, 33, 26, 206, 26, 207, 28, 33, 28, 206, 28, 207, 31, 149, 35, 48, 35, 64, 36, 48, 36, 64, 16, 48, 16, 64, 43, 48, 43, 64, 49, 59, 49, 64, 49, 65, 49, 123, 49, 41, 50, 59, 50, 64, 50, 65, 50, 123, 50, 41, 51, 59, 51, 64, 51, 65, 51, 123, 51, 41, 52, 59, 52, 64, 52, 108, 52, 65, 52, 123, 52, 41, 53, 58, 61, 59, 61, 63, 61, 64, 61, 65, 61, 123, 61, 41, 66, 68, 96, 69, 102, 48, 102, 64, 104, 105, 104, 183, 107, 48, 107, 64, 108, 48, 108, 64, 49, 48, 110, 48, 110, 64, 118, 48, 118, 108, 118, 64, 122, 59, 126, 5, 128, 152, 130, 126, 130, 84, 130, 144, 130, 5, 130, 157, 132, 127, 135, 134, 136, 126, 136, 84, 136, 144, 136, 5, 136, 157, 137, 126, 137, 84, 137, 144, 137, 5, 137, 157, 145, 146, 149, 126, 149, 84, 149, 144, 149, 5, 149, 157, 163, 126, 163, 84, 163, 144, 163, 2, 163, 5, 163, 157, 14, 126, 14, 84, 14, 144, 14, 5, 14, 157, 150, 126, 150, 84, 150, 144, 150, 5, 150, 157, 151, 154, 153, 156, 157, 155, 158, 126, 158, 84, 158, 144, 158, 5, 158, 157, 163, 33, 163, 206, 163, 207, 166, 203, 176, 177, 182, 105, 182, 183, 189, 59, 189, 64, 189, 65, 189, 123, 189, 41, 190, 126, 190, 84, 190, 144, 190, 5, 190, 157, 192, 126, 192, 84, 192, 144, 192, 5, 192, 157, 204, 15] ); +undesirable = array2d(undesirables,1..2, [4, 1, 4, 4, 14, 1, 14, 4, 15, 3, 15, 6, 22, 1, 22, 4, 27, 1, 27, 4, 29, 3, 29, 6, 30, 2, 30, 5, 31, 3, 31, 6, 33, 2, 33, 5, 36, 3, 36, 6, 40, 1, 40, 4, 40, 2, 40, 5, 48, 3, 48, 6, 50, 3, 50, 6, 56, 2, 56, 5, 58, 2, 58, 5, 59, 2, 59, 5, 60, 3, 60, 6, 61, 3, 61, 6, 70, 3, 70, 6, 73, 3, 73, 6, 76, 2, 76, 5, 79, 3, 79, 6, 83, 3, 83, 6, 84, 3, 84, 6, 92, 3, 92, 6, 93, 1, 93, 4, 96, 1, 96, 4, 100, 2, 100, 5, 101, 1, 101, 4, 103, 3, 103, 6, 104, 3, 104, 6, 107, 3, 107, 6, 110, 1, 110, 4, 110, 3, 110, 6, 111, 1, 111, 4, 116, 2, 116, 5, 128, 1, 128, 4, 129, 1, 129, 4, 133, 2, 133, 5, 133, 3, 133, 6, 134, 2, 134, 5, 137, 3, 137, 6, 143, 2, 143, 5, 143, 3, 143, 6, 144, 1, 144, 4, 163, 3, 163, 6, 164, 1, 164, 4, 169, 3, 169, 6, 173, 1, 173, 4, 175, 2, 175, 5, 186, 2, 186, 5, 188, 3, 188, 6, 190, 1, 190, 4, 194, 3, 194, 6, 198, 3, 198, 6, 199, 2, 199, 5, 199, 3, 199, 6, 205, 3, 205, 6, 208, 1, 208, 4] ); +% {'c824': 154, 'c543': 97, 'c825': 155, 'c433': 20, 'c417': 6, 'c527': 84, 'c546': 99, 'c415': 4, 'c993': 181, 'c501': 65, 'c1063': 198, 'c1002': 185, 'c478': 53, 'c833': 160, 'c794': 131, 'c456': 40, 'c1068': 201, 'c427': 14, 'c834': 161, 'c462': 45, 'c1057': 196, 'c454': 38, 'c512': 72, 'c820': 150, 'c1055': 195, 'c422': 10, 'c1046': 192, 'c441': 27, 'c1021': 190, 'c457': 41, 'c429': 16, 'c852': 169, 'c738': 123, 'c516': 76, 'c513': 73, 'c847': 167, 'c502': 66, 'c426': 13, 'c830': 158, 'c534': 89, 'c450': 35, 'c538': 93, 'c745': 124, 'c871': 175, 'c461': 44, 'c442': 28, 'c853': 170, 'c458': 42, 'c474': 49, 'c476': 51, 'c855': 171, 'c525': 82, 'c541': 96, 'c1047': 193, 'c793': 130, 'c411': 2, 'c465': 48, 'c533': 88, 'c599': 107, 'c475': 50, 'c484': 55, 'c437': 23, 'c1079': 205, 'c932': 178, 'c495': 61, 'c816': 149, 'c856': 172, 'c846': 166, 'c561': 103, 'c730': 121, 'c449': 34, 'c607': 111, 'c430': 17, 'c566': 105, 'c438': 24, 'c790': 128, 'c507': 69, 'c455': 39, 'c718': 117, 'c789': 127, 'c536': 91, 'c443': 29, 'c835': 162, 'c845': 165, 'c445': 31, 'c1001': 184, 'c747': 125, 'c724': 119, 'c600': 108, 'c869': 174, 'c598': 106, 'c826': 156, 'c489': 58, 'c812': 145, 'c412': 3, 'c670': 113, 'c796': 133, 'c866': 173, 'c540': 95, 'c463': 46, 'c814': 147, 'c440': 26, 'c409': 1, 'c464': 47, 'c800': 136, 'c423': 11, 'c850': 168, 'c806': 140, 'c804': 139, 'c997': 183, 'c840': 164, 'c996': 182, 'c431': 18, 'c1074': 204, 'c460': 43, 'c1067': 200, 'c531': 86, 'c797': 134, 'c606': 110, 'c788': 126, 'c421': 9, 'c487': 57, 'c498': 64, 'c564': 104, 'c922': 177, 'c444': 30, 'c416': 5, 'c1014': 189, 'c503': 67, 'c1094': 208, 'c801': 137, 'c535': 90, 'c808': 142, 'c676': 114, 'c725': 120, 'c1053': 194, 'c530': 85, 'c491': 59, 'c479': 54, 'c537': 92, 'c1003': 186, 'c1082': 207, 'c836': 163, 'c477': 52, 'c795': 132, 'c496': 62, 'c936': 180, 'c544': 98, 'c737': 122, 'c1071': 202, 'c828': 157, 'c494': 60, 'c716': 116, 'c506': 68, 'c446': 32, 'c511': 71, 'c1066': 199, 'c524': 81, 'c497': 63, 'c1005': 188, 'c532': 87, 'c523': 80, 'c791': 129, 'c831': 159, 'c419': 7, 'c554': 101, 'c425': 12, 'c807': 141, 'c435': 21, 'c436': 22, 'c447': 33, 'c1062': 197, 'c823': 153, 'c1022': 191, 'c602': 109, 'c678': 115, 'c822': 152, 'c798': 135, 'c1072': 203, 'c813': 146, 'c515': 75, 'c428': 15, 'c811': 144, 'c510': 70, 'c721': 118, 'c486': 56, 'c432': 19, 'c1081': 206, 'c539': 94, 'c452': 36, 'c520': 78, 'c439': 25, 'c933': 179, 'c1004': 187, 'c921': 176, 'c526': 83, 'c514': 74, 'c560': 102, 'c519': 77, 'c803': 138, 'c453': 37, 'c647': 112, 'c521': 79, 'c810': 143, 'c551': 100, 'c420': 8, 'c815': 148, 'c821': 151} diff --git a/gbac/gbac.mzn b/gbac/gbac.mzn new file mode 100644 index 0000000..c98642d --- /dev/null +++ b/gbac/gbac.mzn @@ -0,0 +1,122 @@ +%------------------------------------------------------------------------------% +%% Generalised Balanced Academic Curriculum problem +%% +%% Problem 64 in CSPlib: +%% http://www.csplib.org/Problems/prob064/ +%% +%% See http://satt.diegm.uniud.it/projects/gbac/ +%% for a detailed explanation of the problem. +%% Note that the distance from the ideal load, +%% which is a part of the objective, is computed +%% using the squared error. This is following +%% http://dx.doi.org/10.1007/978-3-540-88439-2_11 +%% and allows the found objective value to be +%% compared with found objectives reported on +%% http://satt.diegm.uniud.it/projects/gbac/ +%% +% +%------------------------------------------------------------------------------% +% Model by Jean-Noel Monette +% Modified by Gustav Bjordal +% with help by Fatima Zohra Lebbah, Justin Pearson, and Pierre Flener +% +%------------------------------------------------------------------------------% +% Includes +include "globals.mzn"; + +%------------------------------------------------------------------------------% +% Parameters + +int: n_courses; +set of int: courses = 1..n_courses; +int: n_periods; +set of int: periods = 1..n_periods; +int: n_curricula; +set of int: curricula = 1..n_curricula; +array[curricula] of set of courses: courses_of; +int: n_precedences; +set of int: precedences = 1..n_precedences; +array[precedences,1..2] of int: precedes; + +int: min_courses; +int: max_courses; + +array[courses] of int: course_load; +int: max_load = sum(c in courses)(course_load[c]); + +array [curricula] of int: total_load = [sum(i in courses_of[c])(course_load[i]) | c in curricula]; +array [curricula] of int: ideal_load_floor = [total_load[c] div n_periods | c in curricula]; +array [curricula] of int: ideal_load_ceil = [total_load[c] div n_periods + (if total_load[c] mod n_periods ==0 then 0 else 1 endif) | c in curricula]; + +int: n_undesirables; +set of int: undesirables = 1..n_undesirables; +array [undesirables,1..2] of int: undesirable; + +%weight of the load balancing +int: w1; +%weight of the undesirable assignment violations +int: w2; + + +%------------------------------------------------------------------------------% +% Variables + +%decision variable +array [courses] of var periods: period_of; + + +%------------------------------------------------------------------------------% +% Constraints + +%course load of all periods for each curriculum +constraint forall(c in curricula)( + global_cardinality_low_up_closed( + [period_of[i]|i in courses_of[c]], + [i|i in periods], + [min_courses |i in periods], + [max_courses |i in periods]) +); + +%prerequisites +constraint forall(i in precedences)( + period_of[precedes[i,1]] < period_of[precedes[i,2]] +); + + +%period load +constraint forall(c in curricula)( + bin_packing_load( + [load_of[c,p] |p in periods], + [period_of[i] |i in courses_of[c]], + [course_load[i] |i in courses_of[c]]) +); + +%violation +var 0..n_undesirables: undesirable_violation = sum(i in undesirables)( + bool2int(period_of[undesirable[i,1]]==undesirable[i,2]) +); + +%load of periods +array [curricula,periods] of var 0..max_load: load_of; + +%course balance delta +array [curricula,periods] of var 0..max_load: delta; +var int: norm = sum([delta[c,p]*delta[c,p]|c in curricula, p in periods]); + +%norm +constraint forall(c in curricula, p in periods)( + delta[c,p] = max(load_of[c,p]-ideal_load_ceil[c], + ideal_load_floor[c]-load_of[c,p]) +); + +%objective +var int: objective; +constraint objective = w1 * norm + w2 * undesirable_violation; + +%------------------------------------------------------------------------------% +% Output + +constraint trace("% init_area = \(ub(objective));\n", true); +output + ["objective = ", show(objective)] ++[";\n"] ++ +["period_of = ", show(period_of)] ++ [";\n"]; diff --git a/gbac/on_restart.mzn b/gbac/on_restart.mzn new file mode 100644 index 0000000..841d2c8 --- /dev/null +++ b/gbac/on_restart.mzn @@ -0,0 +1,32 @@ +include "gbac.mzn"; +include "../lib.mzn"; + +predicate int_eq_imp(var int: x, var int: y, var bool: b); +predicate bool_eq_imp(var bool: x, var bool: y, var bool: b); + +predicate random_allocation(var bool: b) = forall(i in courses) ( + int_eq_imp(period_of[i], sol(period_of[i]), b /\ (uniform_internal(1,100) < 80)) +); + +predicate free_period(var bool: b) = let { + var int: period = uniform_internal(periods); + } in forall(i in courses) ( + int_eq_imp(period_of[i], sol(period_of[i]), b /\ (sol(period_of[i]) != period)) + ); + +% Round Robin +array[1..2] of var bool: nbh; +constraint random_allocation(nbh[1]); +constraint free_period(nbh[2]); +var 0..10000000: restart = restart_number(); +var 1..2: select = (restart mod 2) + 1; +constraint bool_eq_imp(nbh[1], false, status() == UNKNOWN); +constraint bool_eq_imp(nbh[2], false, status() == UNKNOWN); +constraint bool_eq_imp(nbh[1], select == 1, status() != UNKNOWN); +constraint bool_eq_imp(nbh[2], select == 2, status() != UNKNOWN); + +annotation main_vars(array[int] of var int: vars); + +solve + :: main_vars(period_of) + :: int_search(period_of,first_fail,indomain_min,complete) minimize objective; diff --git a/gbac/original.mzn b/gbac/original.mzn new file mode 100644 index 0000000..efb3eb2 --- /dev/null +++ b/gbac/original.mzn @@ -0,0 +1,7 @@ +include "gbac.mzn"; + +annotation main_vars(array[int] of var int: vars); + +solve + :: main_vars(period_of) + :: int_search(period_of,first_fail,indomain_min,complete) minimize objective; diff --git a/gbac/reduced_UD4-gbac.dzn b/gbac/reduced_UD4-gbac.dzn new file mode 100644 index 0000000..c42de21 --- /dev/null +++ b/gbac/reduced_UD4-gbac.dzn @@ -0,0 +1,24 @@ +% A reduced (simplified) version of the UD4 instance +% of http://satt.diegm.uniud.it/projects/gbac/ +% +% The instance is reduced by removing all courses +% that do not have an undesired period and lowering +% min_courses to 0, so as not to make the instance UNSAT. +% + +% Ing@UD aa02-03, VOD + +n_periods = 6 ; +n_courses = 36 ; +n_curricula = 16 ; +min_courses = 0 ; +max_courses = 6 ; +n_precedences = 12 ; +n_undesirables = 80 ; +w1 = 1; +w2 = 1; +course_load = [6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 12, 6, 6, 6, 6, 6, 6, 6, 6, 6, 12, 6, 6, 12, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6] ; +courses_of = [{1, 2, 3, 35, 8, 28, 29, 30}, {1, 3, 4, 5, 35, 28, 29, 30}, {1, 35, 6, 8, 28, 29, 30}, {1, 35, 4, 6, 7, 28, 29, 30}, {34, 9, 10, 11, 12, 13, 15, 17, 18}, {34, 9, 10, 11, 12, 13, 14, 15, 18}, {9, 10, 11, 12, 14, 15, 16, 17, 18}, {32, 33, 19, 20, 21, 22, 24, 27}, {32, 33, 19, 20, 21, 24, 27}, {32, 33, 4, 19, 20, 21, 24, 27}, {32, 33, 19, 20, 21, 24, 25, 27}, {32, 33, 13, 19, 20, 21, 23, 24, 27}, {25, 26, 19, 36, 31}, {25, 26, 19, 36, 31}, {4, 36, 19, 25, 26, 31}, {25, 26, 19, 36, 31}] ; +precedes = array2d(precedences,1..2, [2, 5, 2, 7, 2, 30, 9, 17, 9, 18, 10, 17, 10, 18, 23, 21, 23, 33, 31, 36, 32, 21, 32, 33] ); +undesirable = array2d(undesirables,1..2, [1, 1, 1, 4, 2, 1, 2, 4, 3, 3, 3, 6, 4, 1, 4, 4, 5, 2, 5, 5, 5, 3, 5, 6, 6, 2, 6, 5, 7, 2, 7, 5, 8, 3, 8, 6, 9, 2, 9, 5, 10, 2, 10, 5, 11, 2, 11, 5, 11, 3, 11, 6, 12, 3, 12, 6, 13, 3, 13, 6, 14, 2, 14, 5, 15, 3, 15, 6, 16, 3, 16, 6, 17, 3, 17, 6, 18, 3, 18, 6, 19, 1, 19, 4, 20, 2, 20, 5, 21, 3, 21, 6, 22, 3, 22, 6, 23, 3, 23, 6, 23, 1, 23, 4, 24, 1, 24, 4, 25, 3, 25, 6, 25, 2, 25, 5, 26, 1, 26, 4, 27, 3, 27, 6, 28, 3, 28, 6, 29, 1, 29, 4, 30, 2, 30, 5, 31, 2, 31, 5, 32, 3, 32, 6, 33, 1, 33, 4, 34, 3, 34, 6, 35, 3, 35, 6, 36, 1, 36, 4] ); +% {'c308': 7, 'c335': 15, 'c648': 31, 'c655': 34, 'c344': 18, 'c303': 6, 'c320': 10, 'c352': 21, 'c328': 13, 'c284': 1, 'c635': 30, 'c321': 11, 'c650': 32, 'c361': 23, 'c634': 29, 'c338': 16, 'c333': 14, 'c381': 25, 'c319': 9, 'c356': 22, 'c350': 20, 'c376': 24, 'c346': 19, 'c322': 12, 'c664': 36, 'c651': 33, 'c623': 27, 'c301': 5, 'c388': 26, 'c343': 17, 'c658': 35, 'c315': 8, 'c631': 28, 'c291': 3, 'c290': 2, 'c300': 4} diff --git a/lib.mzn b/lib.mzn new file mode 100644 index 0000000..bc14cdf --- /dev/null +++ b/lib.mzn @@ -0,0 +1,100 @@ +/*** + @groupdef internal Internal Builtins + + These annotations and functions provide the basic building blocks to implement + meta-heuristics and governed search with the use of solver internal values and + functionality. +*/ + +/* + A search annotation that supplies a function to be executed on restart +*/ +ann: on_restart(string: pred); + +/* + The 'status' function reports the status of the solver (before restarting). +*/ +enum STATUS = {UNKNOWN, UNSAT, SAT, OPT}; +function var STATUS: status(); + +function var int: restart_number(); + +/* + The 'rnd' function provides random values chosen by the solver. The arguments + to the function limit the values to a certain domain. +*/ +function var int: uniform_internal(int: i, int: j) ::impure = int_uniform(i, j); + +function var int: uniform_internal(set of int: S) ::impure = + if card(S) == max(S) - min(S) + 1 then + int_uniform(min(S),max(S)) + else + [ i | i in S ][int_uniform(1,card(S))] + endif; + +/* + 'int_rnd' is the random intrinsic that needs to be implemented by the solver. +*/ +function var int: int_uniform(int: a, int: b) ::impure; + +/* + The 'sol' functions provides access to solution values of model variables. The + sol functions are only safe to use when the solver status is not UNKNOWN. +*/ +function var bool: sol(var bool: x) = + if is_fixed(x) then + fix(x) + else + bool_sol(x) + endif; + +function var float: sol(var float: x) = + if is_fixed(x) then + fix(x) + else + float_sol(x) + endif; + +function var int: sol(var int: x) = + if is_fixed(x) then + fix(x) + else + int_sol(x) + endif; + +function array[int] of var bool: sol(array[int] of var bool: x) = + [if is_fixed(x[i]) then fix(x[i]) else bool_sol(x[i]) endif | i in index_set(x)]; + +function array[int] of var float: sol(array[int] of var float: x) = + [if is_fixed(x[i]) then fix(x[i]) else float_sol(x[i]) endif | i in index_set(x)]; + +function array[int] of var int: sol(array[int] of var int: x) = + [if is_fixed(x[i]) then fix(x[i]) else int_sol(x[i]) endif | i in index_set(x)]; + +/* + 'bool_rnd', 'float_sol', and 'int_sol' are the solution intrinsics that needs + to be implemented by the solver. +*/ +function var bool: bool_sol(var bool: a); +function var float: float_sol(var float: a); +function var int: int_sol(var int: a); + +/* + 'round_robin' provides a metaheuristic for LNS where each neighbourhood is + chosen sequentially. +*/ +predicate round_robin(array[int] of var bool: nbhs) = + let { + set of int: N = index_set(nbhs); + % Neighbourhood control variables + array[N] of var bool: control; + % Neighbourhood selection + var N: select; + } in forall(i in N) (control[i] -> nbhs[i]) /\ + if status() == UNKNOWN then + control = [false | i in N] + /\ select = max(N) + else + select = (sol(select) + 1) mod card(N) + /\ control = [i == select | i in N] + endif; diff --git a/output/.gitignore b/output/.gitignore new file mode 100644 index 0000000..bf17e1c --- /dev/null +++ b/output/.gitignore @@ -0,0 +1 @@ +*.rec \ No newline at end of file diff --git a/rcpsp-wet/j30_1_3-wet.dzn b/rcpsp-wet/j30_1_3-wet.dzn new file mode 100644 index 0000000..4ce5721 --- /dev/null +++ b/rcpsp-wet/j30_1_3-wet.dzn @@ -0,0 +1,88 @@ +n_tasks = 32; +n_res = 4; +d = [0, 1, 1, 1, 7, 6, 4, 5, 8, 7, 8, 1, 2, 3, 10, 10, 2, 10, 1, 1, 7, 9, 9, 4, 4, 1, 1, 8, 1, 2, 7, 0]; +rr = array2d( + 1..4, + 1..32, + [ + 0, 0, 0, 8, 0, 0, 1, 0, 0, 0, 9, 7, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 7, 0, 0, 0, 0, 0, 2, 0, 0, 4, 3, 0, 0, 0, 0, 8, 4, 0, + 0, 0, 0, 0, 2, 0, 0, 10, 3, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 7, 0, 0, 7, 0, 0, 4, 0, 0, 0, 0, 0, 0, + 0, 5, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 6, 0, 0, 0, 0, 3, 0, 0, 10, 0, 0, 0, 0, 0, 9, 1, 0, 0, 0 + ] +); +rc = [10, 8, 13, 12]; +suc = [ + {2, 3, 4}, + {23, 24}, + {5, 6, 17}, + {7, 20}, + {10, 22, 28}, + {18}, + {8, 9, 12}, + {14, 21, 27}, + {11, 16}, + {16}, + {17}, + {13, 15, 16}, + {30}, + {19}, + {26}, + {25}, + {24}, + {21}, + {25}, + {25, 27}, + {22}, + {29, 30}, + {31}, + {27}, + {26}, + {30}, + {28}, + {31}, + {32}, + {32}, + {32}, + {} +]; +t_max = 56; +deadline = array2d( + 1..32, + 1..3, + [ + 1, 5, 4, + 2, 2, 2, + 6, 4, 0, + 0, 5, 2, + 17, 0, 2, + 8, 1, 5, + 10, 0, 0, + 10, 5, 2, + 7, 2, 0, + 19, 2, 2, + 15, 1, 1, + 9, 1, 0, + 24, 3, 3, + 11, 5, 5, + 7, 1, 4, + 35, 5, 2, + 29, 4, 1, + 15, 5, 5, + 18, 3, 0, + 3, 4, 2, + 21, 3, 4, + 42, 2, 2, + 18, 4, 3, + 26, 2, 0, + 38, 4, 5, + 47, 2, 1, + 32, 5, 4, + 33, 5, 1, + 50, 5, 3, + 49, 1, 3, + 45, 0, 4, + 55, 5, 4 + ] +); +%s = [0, 0, 0, 0, 10, 1, 1, 5, 5, 17, 13, 5, 16, 10, 6, 28, 21, 10, 13, 1, 20, 36, 13, 23, 38, 42, 27, 28, 45, 45, 36, 47]; diff --git a/rcpsp-wet/j30_43_10-wet.dzn b/rcpsp-wet/j30_43_10-wet.dzn new file mode 100644 index 0000000..b5dcf01 --- /dev/null +++ b/rcpsp-wet/j30_43_10-wet.dzn @@ -0,0 +1,88 @@ +n_tasks = 32; +n_res = 4; +d = [0, 6, 9, 1, 9, 1, 5, 7, 1, 10, 6, 8, 5, 9, 5, 9, 1, 1, 3, 6, 8, 6, 4, 5, 4, 3, 2, 9, 7, 3, 2, 0]; +rr = array2d( + 1..4, + 1..32, + [ + 0, 0, 1, 0, 0, 8, 7, 6, 0, 0, 1, 0, 0, 7, 9, 0, 1, 8, 10, 0, 7, 10, 8, 7, 4, 7, 9, 1, 9, 4, 10, 0, + 0, 2, 0, 2, 10, 5, 0, 0, 10, 3, 2, 0, 2, 10, 0, 7, 9, 7, 0, 6, 0, 4, 9, 1, 4, 9, 0, 10, 10, 10, 8, 0, + 0, 0, 5, 10, 7, 0, 9, 6, 3, 7, 7, 7, 4, 8, 1, 2, 2, 0, 9, 4, 6, 9, 0, 6, 0, 7, 4, 0, 3, 10, 0, 0, + 0, 9, 4, 8, 7, 1, 7, 0, 2, 10, 1, 5, 7, 0, 7, 0, 4, 0, 0, 7, 9, 6, 4, 4, 5, 10, 1, 3, 2, 10, 10, 0 + ] +); +rc = [19, 21, 22, 25]; +suc = [ + {2, 3, 4}, + {6, 15, 18}, + {5, 15, 18}, + {6, 7, 16}, + {8, 14, 16}, + {8, 11, 14}, + {9, 12, 23}, + {10, 12, 17}, + {10, 13, 20}, + {22, 30}, + {19, 23, 25}, + {21}, + {15, 18, 19}, + {17, 19, 25}, + {29, 31}, + {23, 27, 30}, + {20, 21}, + {22, 25, 27}, + {21, 26, 28}, + {24, 26, 27}, + {22, 30}, + {24}, + {29}, + {29}, + {26, 28}, + {31}, + {28}, + {31}, + {32}, + {32}, + {32}, + {} +]; +t_max = 72; +deadline = array2d( + 1..32, + 1..3, + [ + 1, 5, 4, + 3, 2, 2, + 8, 4, 0, + 0, 5, 2, + 18, 0, 2, + 15, 1, 5, + 12, 0, 0, + 25, 5, 2, + 8, 2, 0, + 34, 2, 2, + 10, 1, 1, + 30, 1, 0, + 17, 3, 3, + 20, 5, 5, + 13, 1, 4, + 27, 5, 2, + 37, 4, 1, + 19, 5, 5, + 33, 3, 0, + 31, 4, 2, + 36, 3, 4, + 50, 2, 2, + 34, 4, 3, + 53, 2, 0, + 33, 4, 5, + 55, 2, 1, + 43, 5, 4, + 46, 5, 1, + 59, 5, 3, + 61, 1, 3, + 63, 0, 4, + 70, 5, 4 + ] +); +%s = [0, 0, 0, 0, 9, 6, 1, 18, 6, 32, 7, 25, 7, 18, 12, 18, 27, 12, 27, 28, 34, 42, 28, 48, 33, 48, 37, 39, 53, 56, 51, 60]; diff --git a/rcpsp-wet/j60_19_6-wet.dzn b/rcpsp-wet/j60_19_6-wet.dzn new file mode 100644 index 0000000..007519f --- /dev/null +++ b/rcpsp-wet/j60_19_6-wet.dzn @@ -0,0 +1,148 @@ +n_tasks = 62; +n_res = 4; +d = [0, 2, 5, 4, 9, 6, 3, 10, 10, 2, 6, 4, 6, 10, 6, 4, 7, 10, 4, 7, 7, 6, 6, 6, 3, 1, 8, 5, 6, 8, 4, 4, 7, 2, 1, 5, 3, 8, 10, 8, 2, 3, 6, 6, 1, 9, 9, 4, 10, 10, 3, 10, 7, 8, 4, 5, 2, 1, 10, 4, 5, 0]; +rr = array2d( + 1..4, + 1..62, + [ + 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 4, 0, 4, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 4, 7, 0, 0, 0, 8, 5, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 7, 2, 9, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 5, 0, 7, 0, 0, 2, 6, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 2, 7, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 1, 0, 5, 0, 5, 0, 0, 9, 0, 0, 0, 0, 0, 0, 9, 0, 4, 0, 7, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 4, 0, 8, 0, 0, 3, 10, 8, 0, 5, 0, 0, + 0, 0, 1, 10, 0, 0, 0, 0, 8, 6, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 10, 8, 0, 9, 0, 0, 0, 8, 0, 2, 0, 2, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 6, 0, 0, 0, 0, 2, 7, 0, 0, 0, 0, 0, 0, 0 + ] +); +rc = [21, 21, 19, 21]; +suc = [ + {2, 3, 4}, + {8, 36, 46}, + {9}, + {5, 10, 32}, + {6, 7, 9}, + {45, 59}, + {11, 33, 38}, + {17, 31, 59}, + {16, 20}, + {12, 13, 44}, + {14, 15}, + {23, 31}, + {18, 27, 37}, + {17}, + {21}, + {19, 27}, + {26, 29}, + {23, 29}, + {39}, + {24, 30, 61}, + {22, 44, 48}, + {28, 41, 42}, + {35, 38, 58}, + {25, 48}, + {59}, + {30, 37, 55}, + {39}, + {45}, + {52}, + {49}, + {33, 37, 43}, + {34, 50, 54}, + {35}, + {36, 40, 42}, + {52, 54}, + {51}, + {47}, + {41, 43}, + {48, 51}, + {53, 61}, + {51, 52}, + {46, 47, 49}, + {54}, + {45, 47, 56}, + {50}, + {53, 58}, + {57}, + {49}, + {56}, + {58}, + {55}, + {53, 55}, + {60}, + {56}, + {57}, + {60}, + {61}, + {60}, + {62}, + {62}, + {62}, + {} +]; +t_max = 83; +deadline = array2d( + 1..62, + 1..3, + [ + 2, 5, 4, + 3, 2, 2, + 9, 4, 0, + 0, 5, 2, + 15, 0, 2, + 23, 1, 5, + 26, 0, 0, + 10, 5, 2, + 16, 2, 0, + 7, 2, 2, + 19, 1, 1, + 12, 1, 0, + 18, 3, 3, + 24, 5, 5, + 23, 1, 4, + 33, 5, 2, + 44, 4, 1, + 20, 5, 5, + 34, 3, 0, + 26, 4, 2, + 30, 3, 4, + 45, 2, 2, + 29, 4, 3, + 35, 2, 0, + 36, 4, 5, + 49, 2, 1, + 34, 5, 4, + 49, 5, 1, + 46, 5, 3, + 48, 1, 3, + 26, 0, 4, + 16, 5, 4, + 28, 3, 3, + 14, 0, 5, + 36, 1, 3, + 17, 2, 2, + 50, 3, 3, + 34, 0, 1, + 37, 3, 5, + 21, 4, 4, + 44, 5, 4, + 44, 0, 0, + 47, 1, 0, + 48, 2, 0, + 48, 3, 1, + 50, 4, 2, + 53, 2, 0, + 50, 2, 1, + 51, 5, 3, + 50, 3, 4, + 49, 0, 0, + 55, 0, 4, + 65, 3, 1, + 56, 4, 3, + 58, 3, 2, + 68, 1, 3, + 62, 1, 5, + 71, 1, 5, + 43, 5, 4, + 71, 1, 0, + 77, 0, 4, + 83, 3, 1 + ] +); +%s = [0, 0, 0, 0, 4, 13, 13, 2, 13, 4, 16, 6, 6, 22, 22, 23, 32, 12, 27, 23, 28, 35, 22, 30, 36, 41, 27, 41, 39, 42, 12, 4, 16, 8, 28, 10, 42, 28, 35, 10, 41, 43, 36, 39, 46, 46, 49, 45, 50, 47, 49, 45, 55, 42, 55, 60, 62, 58, 39, 65, 64, 69]; diff --git a/rcpsp-wet/j60_28_3-wet.dzn b/rcpsp-wet/j60_28_3-wet.dzn new file mode 100644 index 0000000..e95113c --- /dev/null +++ b/rcpsp-wet/j60_28_3-wet.dzn @@ -0,0 +1,148 @@ +n_tasks = 62; +n_res = 4; +d = [0, 7, 3, 1, 5, 2, 5, 6, 6, 7, 2, 4, 3, 2, 10, 10, 1, 8, 10, 8, 7, 2, 7, 5, 4, 7, 7, 5, 4, 5, 9, 1, 2, 1, 7, 6, 10, 6, 6, 6, 9, 5, 4, 2, 7, 2, 4, 8, 8, 5, 1, 4, 5, 5, 4, 10, 4, 6, 1, 3, 3, 0]; +rr = array2d( + 1..4, + 1..62, + [ + 0, 0, 6, 3, 4, 3, 6, 5, 6, 0, 0, 10, 5, 3, 3, 1, 5, 5, 1, 0, 0, 2, 1, 8, 8, 9, 2, 6, 6, 0, 0, 0, 0, 7, 2, 0, 2, 3, 10, 6, 2, 3, 2, 2, 10, 0, 0, 0, 0, 0, 6, 0, 3, 0, 2, 9, 4, 1, 4, 6, 0, 0, + 0, 5, 9, 8, 10, 1, 10, 0, 0, 4, 7, 1, 3, 10, 2, 4, 10, 0, 9, 7, 10, 3, 0, 7, 2, 7, 1, 5, 1, 10, 6, 10, 1, 0, 0, 3, 10, 10, 7, 5, 7, 7, 0, 5, 9, 6, 5, 10, 1, 2, 1, 7, 3, 0, 3, 9, 1, 1, 4, 8, 1, 0, + 0, 9, 4, 8, 0, 0, 7, 0, 7, 0, 4, 7, 7, 8, 10, 1, 5, 0, 9, 7, 5, 6, 8, 6, 8, 10, 0, 0, 7, 8, 0, 0, 5, 0, 5, 3, 4, 6, 0, 0, 6, 8, 1, 2, 9, 9, 0, 8, 8, 7, 0, 0, 7, 6, 5, 5, 6, 0, 2, 6, 10, 0, + 0, 5, 4, 1, 3, 8, 5, 9, 0, 0, 8, 3, 0, 0, 3, 10, 0, 6, 0, 3, 0, 0, 10, 1, 2, 8, 8, 0, 1, 2, 7, 8, 4, 7, 7, 7, 0, 3, 2, 0, 3, 1, 0, 4, 7, 3, 9, 0, 1, 1, 8, 0, 8, 9, 0, 7, 0, 7, 5, 0, 7, 0 + ] +); +rc = [35, 47, 45, 39]; +suc = [ + {2, 3, 4}, + {16}, + {5, 8, 34}, + {6, 7, 57}, + {39}, + {10, 23, 27}, + {11, 37}, + {9, 14, 15}, + {11, 37}, + {17, 38}, + {12, 22, 25}, + {13, 21, 41}, + {29, 30}, + {32, 51}, + {24, 31, 42}, + {19, 20, 45}, + {18, 37, 40}, + {42}, + {31, 55}, + {22, 41, 48}, + {26, 32}, + {24, 28, 32}, + {35, 61}, + {27, 36}, + {56}, + {42, 44}, + {44}, + {31, 36, 46}, + {39, 46, 50}, + {33, 39, 48}, + {47}, + {47}, + {50}, + {40, 53}, + {58}, + {56}, + {55}, + {46}, + {40, 52, 53}, + {60}, + {54}, + {43, 45, 47}, + {49}, + {51, 61}, + {48, 52}, + {49, 53, 61}, + {50, 59}, + {59}, + {51}, + {54}, + {52, 56}, + {54}, + {55}, + {58}, + {59}, + {58}, + {60}, + {60}, + {62}, + {62}, + {62}, + {} +]; +t_max = 86; +deadline = array2d( + 1..62, + 1..3, + [ + 2, 5, 4, + 3, 2, 2, + 9, 4, 0, + 0, 5, 2, + 14, 0, 2, + 11, 1, 5, + 14, 0, 0, + 11, 5, 2, + 12, 2, 0, + 6, 2, 2, + 18, 1, 1, + 23, 1, 0, + 33, 3, 3, + 11, 5, 5, + 10, 1, 4, + 17, 5, 2, + 22, 4, 1, + 19, 5, 5, + 24, 3, 0, + 20, 4, 2, + 23, 3, 4, + 35, 2, 2, + 10, 4, 3, + 32, 2, 0, + 17, 4, 5, + 36, 2, 1, + 39, 5, 4, + 35, 5, 1, + 31, 5, 3, + 30, 1, 3, + 46, 0, 4, + 40, 5, 4, + 41, 3, 3, + 9, 0, 5, + 18, 1, 3, + 39, 2, 2, + 23, 3, 3, + 16, 0, 1, + 31, 3, 5, + 46, 4, 4, + 28, 5, 4, + 36, 0, 0, + 51, 1, 0, + 48, 2, 0, + 42, 3, 1, + 36, 4, 2, + 45, 2, 0, + 52, 2, 1, + 45, 5, 3, + 48, 3, 4, + 52, 0, 0, + 63, 0, 4, + 45, 3, 1, + 71, 4, 3, + 43, 3, 2, + 61, 1, 3, + 1, 1, 5, + 76, 1, 5, + 59, 5, 4, + 75, 1, 0, + 54, 0, 4, + 86, 3, 1 + ] +); +%s = [0, 0, 0, 0, 3, 1, 1, 3, 9, 3, 15, 17, 21, 9, 9, 7, 10, 11, 17, 17, 21, 25, 3, 27, 17, 28, 32, 27, 24, 24, 32, 28, 29, 3, 10, 32, 15, 10, 29, 35, 25, 35, 40, 39, 40, 32, 41, 47, 44, 45, 52, 53, 35, 57, 40, 53, 1, 63, 55, 69, 41, 72]; diff --git a/rcpsp-wet/j90_48_4-wet.dzn b/rcpsp-wet/j90_48_4-wet.dzn new file mode 100644 index 0000000..cd95338 --- /dev/null +++ b/rcpsp-wet/j90_48_4-wet.dzn @@ -0,0 +1,208 @@ +n_tasks = 92; +n_res = 4; +d = [0, 6, 5, 9, 1, 3, 8, 6, 8, 6, 7, 5, 9, 3, 7, 8, 2, 3, 1, 10, 4, 5, 9, 2, 7, 5, 2, 9, 1, 2, 8, 2, 5, 7, 5, 6, 9, 6, 1, 10, 4, 8, 1, 6, 5, 4, 6, 9, 2, 4, 10, 2, 2, 9, 1, 1, 8, 4, 7, 2, 8, 9, 5, 5, 8, 2, 6, 2, 9, 7, 3, 9, 4, 8, 9, 5, 1, 4, 7, 6, 8, 9, 8, 5, 9, 8, 7, 1, 5, 1, 1, 0]; +rr = array2d( + 1..4, + 1..92, + [ + 0, 1, 3, 9, 2, 6, 7, 6, 6, 10, 8, 6, 9, 4, 7, 7, 4, 8, 6, 3, 3, 1, 1, 2, 8, 2, 6, 10, 7, 8, 1, 10, 6, 9, 10, 7, 4, 4, 7, 7, 2, 6, 9, 4, 10, 10, 4, 7, 5, 7, 1, 9, 6, 3, 10, 3, 1, 1, 9, 5, 9, 8, 7, 8, 4, 7, 3, 4, 6, 6, 6, 7, 3, 7, 2, 1, 5, 7, 2, 1, 8, 3, 9, 7, 5, 2, 4, 6, 6, 7, 5, 0, + 0, 5, 8, 9, 2, 10, 7, 2, 7, 3, 10, 9, 10, 1, 9, 3, 8, 8, 5, 8, 7, 9, 7, 7, 4, 4, 10, 5, 3, 3, 2, 4, 7, 7, 7, 9, 9, 10, 5, 7, 6, 5, 10, 1, 10, 4, 1, 5, 6, 4, 6, 5, 10, 1, 1, 7, 8, 9, 9, 6, 2, 1, 10, 5, 8, 2, 8, 1, 2, 1, 8, 3, 1, 4, 3, 7, 5, 8, 2, 2, 3, 4, 8, 2, 2, 1, 2, 4, 8, 2, 9, 0, + 0, 2, 10, 2, 6, 4, 3, 4, 9, 1, 8, 8, 4, 2, 2, 9, 5, 5, 3, 3, 4, 9, 8, 7, 2, 2, 2, 4, 9, 2, 9, 8, 5, 5, 1, 4, 4, 4, 8, 7, 10, 10, 1, 6, 1, 10, 1, 6, 10, 8, 10, 3, 2, 7, 10, 7, 8, 10, 5, 2, 8, 4, 9, 2, 6, 10, 9, 10, 9, 4, 3, 6, 3, 7, 2, 10, 8, 2, 8, 9, 5, 6, 1, 10, 8, 2, 4, 9, 6, 10, 10, 0, + 0, 4, 8, 2, 5, 2, 8, 7, 4, 10, 5, 3, 1, 2, 2, 6, 6, 5, 9, 5, 9, 9, 3, 4, 5, 5, 6, 3, 5, 6, 5, 10, 5, 5, 5, 6, 5, 3, 7, 9, 10, 4, 7, 6, 9, 7, 8, 3, 2, 6, 5, 9, 1, 9, 9, 1, 10, 6, 9, 6, 6, 10, 4, 3, 2, 2, 7, 2, 9, 8, 9, 8, 5, 6, 8, 6, 1, 1, 8, 5, 4, 10, 3, 1, 6, 1, 9, 9, 2, 1, 6, 0 + ] +); +rc = [57, 69, 73, 65]; +suc = [ + {2, 3, 4}, + {5, 6, 7}, + {13, 25, 80}, + {34, 44, 60}, + {8, 35}, + {9, 15, 25}, + {23, 44, 59}, + {17, 52, 72}, + {10, 11, 22}, + {14, 20, 73}, + {12, 18, 47}, + {13, 27, 57}, + {19, 34, 42}, + {61}, + {16, 24, 28}, + {29, 32, 75}, + {31, 54, 62}, + {33, 44, 55}, + {21, 38, 40}, + {24, 26, 88}, + {23, 41}, + {47, 65, 72}, + {50, 51, 69}, + {36}, + {36, 47, 66}, + {27, 28, 30}, + {64}, + {29, 36, 79}, + {62}, + {63, 65}, + {39, 45, 53}, + {43, 53, 64}, + {46, 57}, + {37, 38, 39}, + {37, 39, 48}, + {62, 81, 86}, + {50, 59, 67}, + {54, 63, 70}, + {51, 58, 59}, + {72}, + {50, 65, 67}, + {52, 56, 82}, + {60, 61}, + {52, 56, 57}, + {55, 61}, + {49}, + {58}, + {49, 51, 68}, + {53, 54}, + {55, 56, 58}, + {70, 74}, + {66, 70}, + {60, 84}, + {64, 91}, + {74}, + {68, 74}, + {66, 67, 80}, + {82, 85}, + {77}, + {63, 79}, + {68, 76, 78}, + {87}, + {90}, + {71, 89}, + {71}, + {69, 73, 75}, + {69, 85}, + {81}, + {71, 84}, + {73, 86}, + {81}, + {77, 78}, + {77}, + {75, 78}, + {83}, + {79, 85}, + {84, 89}, + {87, 88}, + {80, 82}, + {83}, + {90}, + {83, 86}, + {91}, + {91}, + {88}, + {87}, + {89}, + {90}, + {92}, + {92}, + {92}, + {} +]; +t_max = 109; +deadline = array2d( + 1..92, + 1..3, + [ + 2, 5, 4, + 4, 2, 2, + 12, 4, 0, + 0, 5, 2, + 20, 0, 2, + 19, 1, 5, + 23, 0, 0, + 17, 5, 2, + 13, 2, 0, + 21, 2, 2, + 21, 1, 1, + 32, 1, 0, + 44, 3, 3, + 26, 5, 5, + 11, 1, 4, + 29, 5, 2, + 28, 4, 1, + 35, 5, 5, + 47, 3, 0, + 27, 4, 2, + 42, 3, 4, + 29, 2, 2, + 52, 4, 3, + 40, 2, 0, + 9, 4, 5, + 44, 2, 1, + 47, 5, 4, + 48, 5, 1, + 56, 5, 3, + 46, 1, 3, + 33, 0, 4, + 39, 5, 4, + 42, 3, 3, + 46, 0, 5, + 17, 1, 3, + 56, 2, 2, + 55, 3, 3, + 53, 0, 1, + 48, 3, 5, + 54, 4, 4, + 47, 5, 4, + 39, 0, 0, + 40, 1, 0, + 38, 2, 0, + 26, 3, 1, + 37, 4, 2, + 30, 2, 0, + 19, 2, 1, + 38, 5, 3, + 57, 3, 4, + 52, 0, 0, + 59, 0, 4, + 50, 3, 1, + 69, 4, 3, + 62, 3, 2, + 68, 1, 3, + 34, 1, 5, + 74, 1, 5, + 59, 5, 4, + 47, 1, 0, + 44, 0, 4, + 71, 3, 1, + 67, 5, 4, + 69, 2, 2, + 50, 4, 2, + 51, 0, 3, + 59, 2, 1, + 75, 5, 0, + 63, 1, 5, + 76, 2, 1, + 81, 5, 5, + 55, 5, 4, + 78, 5, 1, + 75, 0, 1, + 87, 1, 4, + 47, 5, 2, + 79, 1, 5, + 81, 5, 5, + 49, 3, 0, + 54, 0, 5, + 86, 4, 2, + 73, 4, 2, + 89, 1, 0, + 79, 5, 3, + 79, 2, 1, + 85, 4, 0, + 91, 0, 0, + 90, 0, 1, + 104, 2, 0, + 83, 1, 4, + 88, 5, 2, + 109, 5, 1 + ] +); +%s = [0, 0, 0, 0, 6, 6, 6, 7, 9, 17, 17, 24, 29, 23, 9, 16, 13, 24, 38, 23, 39, 17, 43, 33, 9, 33, 38, 38, 47, 38, 15, 24, 27, 38, 7, 47, 45, 45, 45, 39, 43, 38, 26, 27, 23, 32, 24, 12, 36, 54, 52, 46, 38, 51, 58, 58, 33, 58, 54, 40, 28, 53, 51, 60, 47, 48, 54, 59, 60, 62, 69, 49, 69, 62, 70, 36, 73, 70, 47, 54, 72, 62, 79, 74, 62, 71, 79, 74, 86, 80, 87, 91]; diff --git a/rcpsp-wet/on_restart.mzn b/rcpsp-wet/on_restart.mzn new file mode 100644 index 0000000..38def3e --- /dev/null +++ b/rcpsp-wet/on_restart.mzn @@ -0,0 +1,36 @@ +include "rcpsp-wet.mzn"; +include "../lib.mzn"; + +predicate int_eq_imp(var int: x, var int: y, var bool: b); +predicate bool_eq_imp(var bool: x, var bool: y, var bool: b); + +predicate randomize(var bool: b) = + forall(t in Tasks) ( + int_eq_imp(s[t], sol(s[t]), b /\ uniform_internal(1,100) < 80) + ); + +predicate free_timeslot(var bool: b) = + let { + int: slot = max(Times) div 10; + var int: time = uniform_internal(min(Times), max(Times) - slot); + } in forall(t in Tasks) ( + int_eq_imp(s[t], sol(s[t]), b /\ (sol(s[t]) < time \/ time+slot > sol(s[t]))) + ); + +% Round Robin +array[1..2] of var bool: nbh; +constraint randomize(nbh[1]); +constraint free_timeslot(nbh[2]); +var 0..10000000: restart = restart_number(); +var 1..2: select = (restart mod 2) + 1; +constraint bool_eq_imp(nbh[1], false, status() == UNKNOWN); +constraint bool_eq_imp(nbh[2], false, status() == UNKNOWN); +constraint bool_eq_imp(nbh[1], select == 1, status() != UNKNOWN); +constraint bool_eq_imp(nbh[2], select == 2, status() != UNKNOWN); + +annotation main_vars(array[int] of var int: vars); + +solve + ::main_vars(s) + ::int_search(s, first_fail, indomain_min, complete) + minimize objective; diff --git a/rcpsp-wet/original.mzn b/rcpsp-wet/original.mzn new file mode 100644 index 0000000..3792ecb --- /dev/null +++ b/rcpsp-wet/original.mzn @@ -0,0 +1,8 @@ +include "rcpsp-wet.mzn"; + +annotation main_vars(array[int] of var int: vars); + +solve + ::main_vars(s) + ::int_search(s, first_fail, indomain_min, complete) + minimize objective; diff --git a/rcpsp-wet/rcpsp-wet.mzn b/rcpsp-wet/rcpsp-wet.mzn new file mode 100644 index 0000000..7f881e0 --- /dev/null +++ b/rcpsp-wet/rcpsp-wet.mzn @@ -0,0 +1,139 @@ +%-----------------------------------------------------------------------------% +% vim: ts=4 sw=4 et wm=0 tw=0 +%-----------------------------------------------------------------------------% +% Copyright (C) 2009-2016 The University of Melbourne and NICTA. +% See the file COPYING for license information. +%-----------------------------------------------------------------------------% +% Model example for Resource-Constrained Project Scheduling Problems with +% Weighted Earliness/Tardiness objective (RCPSP/WET) +% +% A RCPSP consists of resources, tasks, and precedences between some tasks +% where resources have of a specific capacity and tasks need some capacity of +% some resource to be executed. +% Here, we consider resources with a constant discrete capacity over time and +% tasks with a constant discrete duration and resource requirements. +% The objective is to find a optimal schedule so that tasks start as close as +% possible to the given start time for each task, penalizing earliness or +% tardiness according to the given weight for earliness and tardiness per task. +% +%-----------------------------------------------------------------------------% + +include "cumulative.mzn"; + +%-----------------------------------------------------------------------------% +% Model parameters. + + + % Resources + % +int: n_res; % The number of resources +set of int: Res = 1..n_res; % The set of all resources +array [Res] of int: rc; % The resource capabilities + + % Tasks + % +int: n_tasks; % The number of tasks +set of int: Tasks = 1..n_tasks; % The set of all tasks +array [Tasks] of int : d ; % The task durations +array [Res, Tasks] of int : rr ; % The resource requirements +array [Tasks] of set of int: suc; % The task successors + + % Deadlines + % + % deadline[i, 1] is the desired start time for task i, + % deadline[i, 2] is the earliness cost per time unit of earliness, + % deadline[i, 3] is the tardiness cost per time unit of tardiness. +array [Tasks, 1..3] of int: deadline; + + % Planning horizon + % + % Note that our RCPSP/WET instance generator requires a solution to the + % equivalent RCPSP problem in order to generate the instances, so it gives + % us a planning horizon = the makespan of the RCPSP problem, plus 20% slop +int: t_max; %= sum(i in Tasks)(d[i]); % End time of the planning horizon +set of int: Times = 0..(t_max - 1); % Possible start times + +%-----------------------------------------------------------------------------% +% Model variables. + +array [Tasks] of var Times: s; % The start times +var 0..sum(i in Tasks) ( + max( + deadline[i, 2] * deadline[i, 1], + deadline[i, 3] * (t_max - deadline[i, 1]) + ) +): objective; + +%-----------------------------------------------------------------------------% +% Constraints. + + % Precedence constraints + % +constraint + forall ( i in Tasks, j in suc[i] ) + ( + s[i] + d[i] <= s[j] + ); + + % Redundant non-overlapping constraints + % +constraint + redundant_constraint( + forall ( i, j in Tasks where i < j ) + ( + if exists(r in Res)(rr[r, i] + rr[r, j] > rc[r]) then + s[i] + d[i] <= s[j] \/ s[j] + d[j] <= s[i] + else + true + endif + ) + ); + + % Cumulative resource constraints + % +constraint + forall ( r in Res ) + ( + let { + set of int: RTasks = + { i | i in Tasks + where rr[r, i] > 0 /\ d[i] > 0 }, + int: sum_rr = sum(i in RTasks)(rr[r, i]) + } in ( + if RTasks != {} /\ sum_rr > rc[r] then + cumulative( + [ s[i] | i in RTasks ], + [ d[i] | i in RTasks ], + [ rr[r, i] | i in RTasks ], + rc[r] + ) + else + true + endif + ) + ); + + % Weighted Earliness/Tardiness objective +constraint + objective = sum (i in Tasks) ( + % earliness + deadline[i, 2] * max(0, deadline[i, 1] - s[i]) + + % tardiness + deadline[i, 3] * max(0, s[i] - deadline[i, 1]) + ); + +%-----------------------------------------------------------------------------% +% Objective. + +constraint trace("% init_area = \(ub(objective));\n", true); + +%-----------------------------------------------------------------------------% + +output [ + "s = \(s);\n", + "objective = \(objective);\n", +]; + +%-----------------------------------------------------------------------------% +%-----------------------------------------------------------------------------% + diff --git a/run_all.sh b/run_all.sh new file mode 100755 index 0000000..d2622c6 --- /dev/null +++ b/run_all.sh @@ -0,0 +1,37 @@ +#!/bin/zsh +trap "exit" INT +set -e + +# Run originals +echo ">> Gecode Original" +./run_original_gecode.sh gbac +./run_original_gecode.sh rcpsp-wet +./run_original_gecode.sh steelmillslab + +echo ">> Chuffed Original" +./run_original_chuffed.sh gbac +./run_original_chuffed.sh rcpsp-wet +./run_original_chuffed.sh steelmillslab + +# Run Half Reified implementations +echo ">> Gecode on_restart" +./run_restart_gecode.sh gbac +./run_restart_gecode.sh rcpsp-wet +./run_restart_gecode.sh steelmillslab + +echo ">> Chuffed on_restarts" +./run_restart_chuffed.sh gbac +./run_restart_chuffed.sh rcpsp-wet +./run_restart_chuffed.sh steelmillslab + +# Record Gecode Neighbourhoods +echo ">> Gecode on_restart_record" +./run_record_gecode.sh gbac +./run_record_gecode.sh rcpsp-wet +./run_record_gecode.sh steelmillslab + +# Replay Gecode Neighbourhoods +echo ">> Gecode on_restart_replay" +./run_replay_gecode.sh gbac +./run_replay_gecode.sh rcpsp-wet +./run_replay_gecode.sh steelmillslab diff --git a/run_original_chuffed.sh b/run_original_chuffed.sh new file mode 100755 index 0000000..4a5da8b --- /dev/null +++ b/run_original_chuffed.sh @@ -0,0 +1,21 @@ +#!/bin/zsh +trap "exit" INT +set -e + +folder=$1 + +source setup.sh + +solver="./bin/fzn-chuffed" +model="./${folder}/original" +output_folder="./output/chuffed/${folder}/original" +mkdir -p ${output_folder} + +for data in ./${folder}/*.dzn; do + echo "Running ${model} with ${data}" + filename=$(basename -- "$data") + filename="${filename%.*}" + ${minizinc}/mzn2fzn -Gchuffed ${model}.mzn ${data} &> ${output_folder}/${filename}.sol + ${solver} -a --time-out ${timeout_sec} -s --verbosity 2 ${model}.fzn &>/dev/null | ${minizinc}/solns2out --output-time ${model}.ozn >> ${output_folder}/${filename}.sol + rm -f ${model}.fzn ${model}.ozn +done diff --git a/run_original_gecode.sh b/run_original_gecode.sh new file mode 100755 index 0000000..d4612db --- /dev/null +++ b/run_original_gecode.sh @@ -0,0 +1,21 @@ +#!/bin/zsh +trap "exit" INT +set -e + +folder=$1 + +source setup.sh + +solver="./bin/fzn-gecode" +model="./${folder}/original" +output_folder="./output/gecode/${folder}/original" +mkdir -p ${output_folder} + +for data in ./${folder}/*.dzn; do + echo "Running ${model} with ${data}" + filename=$(basename -- "$data") + filename="${filename%.*}" + ${minizinc}/mzn2fzn -Ggecode ${model}.mzn ${data} &>${output_folder}/${filename}.sol + ${solver} --c-d 1 --a-d 2 -time ${timeout_sec}000 -a -s ${model}.fzn | ${minizinc}/solns2out --output-time ${model}.ozn >> ${output_folder}/${filename}.sol + rm -f ${model}.fzn ${model}.ozn +done diff --git a/run_record_gecode.sh b/run_record_gecode.sh new file mode 100755 index 0000000..1537f70 --- /dev/null +++ b/run_record_gecode.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env zsh +trap "exit" INT +set -e + +folder=$1 + +source setup.sh + +solver="./bin/fzn-gecode_record" +model="./${folder}/on_restart" +output_folder="./output/gecode/${folder}/record" +mkdir -p ${output_folder} + +for data in ./${folder}/*.dzn; do + echo -n "Recording ${model} with ${data}: " + for i in {1..${runs}}; do + echo -n "${i} " + filename=$(basename -- "$data") + filename="${filename%.*}" + ${minizinc}/mzn2fzn -Ggecode ${model}.mzn ${data} &> ${output_folder}/${filename}.${i}.sol + ${solver} --c-d 1 --a-d 2 -time ${record_timeout_sec}000 -r $i -a -restart constant -s ${model}.fzn | ${minizinc}/solns2out --output-time ${model}.ozn >> ${output_folder}/${filename}.${i}.sol + mv record.txt ${output_folder}/${filename}.${i}.rec + done + rm -f ${model}.fzn ${model}.ozn + echo "" +done diff --git a/run_replay_gecode.sh b/run_replay_gecode.sh new file mode 100755 index 0000000..08c5bd8 --- /dev/null +++ b/run_replay_gecode.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env zsh +trap "exit" INT +set -e + +folder=$1 + +source setup.sh + +solver="./bin/fzn-gecode_replay" +model="./${folder}/original" +output_folder="./output/gecode/${folder}/replay" +records_folder="./output/gecode/${folder}/record" +mkdir -p ${output_folder} + +for data in ./${folder}/*.dzn; do + echo -n "Replaying ${model} with ${data}: " + for i in {1..${runs}}; do + echo -n "${i} " + filename=$(basename -- "$data") + filename="${filename%.*}" + cp ${records_folder}/${filename}.${i}.rec record.txt + ${minizinc}/mzn2fzn -Ggecode ${model}.mzn ${data} &> ${output_folder}/${filename}.${i}.sol + ${solver} --c-d 1 --a-d 2 -time ${timeout_sec}000 -r $i -a -restart constant -s ${model}.fzn | ${minizinc}/solns2out --output-time ${model}.ozn >> ${output_folder}/${filename}.${i}.sol + done + rm -f ${model}.fzn ${model}.ozn + echo "" +done diff --git a/run_restart_chuffed.sh b/run_restart_chuffed.sh new file mode 100755 index 0000000..b9b3f8d --- /dev/null +++ b/run_restart_chuffed.sh @@ -0,0 +1,25 @@ +#!/bin/zsh +trap "exit" INT +set -e + +folder=$1 + +source setup.sh + +solver="./bin/fzn-chuffed" +model="./${folder}/on_restart" +output_folder="./output/chuffed/${folder}/restart" +mkdir -p ${output_folder} + +for data in ./${folder}/*.dzn; do + echo -n "Running ${model} with ${data}: " + for i in {1..${runs}}; do + echo -n "${i} " + filename=$(basename -- "$data") + filename="${filename%.*}" + ${minizinc}/mzn2fzn -Gchuffed ${model}.mzn ${data} &> ${output_folder}/${filename}.${i}.sol + ${solver} -a --time-out ${timeout_sec} --restart constant --restart-scale 250 -s --verbosity 2 --rnd-seed $i --restart-base 250 ${model}.fzn &>/dev/null | ${minizinc}/solns2out --output-time ${model}.ozn >> ${output_folder}/${filename}.${i}.sol + done + rm -f ${model}.fzn ${model}.ozn + echo "" +done diff --git a/run_restart_gecode.sh b/run_restart_gecode.sh new file mode 100755 index 0000000..cfab90b --- /dev/null +++ b/run_restart_gecode.sh @@ -0,0 +1,25 @@ +#!/bin/zsh +trap "exit" INT +set -e + +folder=$1 + +source setup.sh + +solver="./bin/fzn-gecode" +model="./${folder}/on_restart" +output_folder="./output/gecode/${folder}/restart" +mkdir -p ${output_folder} + +for data in ./${folder}/*.dzn; do + echo -n "Running ${model} with ${data}: " + for i in {1..${runs}}; do + echo -n "${i} " + filename=$(basename -- "$data") + filename="${filename%.*}" + ${minizinc}/mzn2fzn -Ggecode ${model}.mzn ${data} &> ${output_folder}/${filename}.${i}.sol + ${solver} --c-d 1 --a-d 2 -time ${timeout_sec}000 -r $i -a -restart constant -s ${model}.fzn | ${minizinc}/solns2out --output-time ${model}.ozn >> ${output_folder}/${filename}.${i}.sol + done + rm -f ${model}.fzn ${model}.ozn + echo "" +done diff --git a/setup.sh b/setup.sh new file mode 100644 index 0000000..39e421e --- /dev/null +++ b/setup.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env zsh + +timeout_sec=120 +record_timeout_sec=240 +runs=10 + +minizinc="/Users/jdek0001/Repositories/minizinc/libmzn/build/release" diff --git a/steelmillslab/bench_13_0.dzn b/steelmillslab/bench_13_0.dzn new file mode 100644 index 0000000..de41b16 --- /dev/null +++ b/steelmillslab/bench_13_0.dzn @@ -0,0 +1,5 @@ +nbOrders = 111; +nbColours = 88; +sizes = {0, 11, 14, 20, 23, 25, 31, 34, 35, 39, 40, 43, 46, 49}; +ordSize = [4, 22, 9, 5, 8, 3, 3, 4, 7, 7, 3, 2, 2, 8, 5, 7, 4, 7, 5, 7, 8, 3, 25, 14, 3, 22, 19, 19, 22, 22, 22, 20, 22, 5, 4, 10, 26, 17, 20, 16, 10, 19, 10, 10, 23, 22, 26, 27, 22, 27, 22, 22, 13, 14, 16, 26, 26, 27, 22, 20, 26, 22, 13, 19, 20, 16, 15, 17, 10, 20, 5, 26, 19, 15, 10, 10, 13, 13, 13, 12, 12, 18, 10, 18, 16, 20, 12, 6, 6, 15, 15, 15, 21, 30, 30, 30, 30, 23, 15, 15, 27, 27, 27, 27, 27, 27, 27, 27, 27, 10, 3]; +ordCol = [1, 2, 3, 4, 5, 6, 4, 7, 4, 8, 6, 6, 4, 9, 10, 11, 7, 11, 10, 11, 9, 1, 12, 13, 6, 14, 15, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 27, 34, 42, 35, 36, 43, 24, 44, 45, 46, 47, 48, 49, 50, 28, 51, 52, 24, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 68, 69, 70, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 79, 85, 86, 87, 88]; diff --git a/steelmillslab/bench_14_1.dzn b/steelmillslab/bench_14_1.dzn new file mode 100644 index 0000000..46da3a3 --- /dev/null +++ b/steelmillslab/bench_14_1.dzn @@ -0,0 +1,5 @@ +nbOrders = 111; +nbColours = 88; +sizes = {0, 11, 16, 18, 19, 20, 24, 26, 30, 31, 34, 37, 39, 40, 47}; +ordSize = [4, 22, 9, 5, 8, 3, 3, 4, 7, 7, 3, 2, 2, 8, 5, 7, 4, 7, 5, 7, 8, 3, 25, 14, 3, 22, 19, 19, 22, 22, 22, 20, 22, 5, 4, 10, 26, 17, 20, 16, 10, 19, 10, 10, 23, 22, 26, 27, 22, 27, 22, 22, 13, 14, 16, 26, 26, 27, 22, 20, 26, 22, 13, 19, 20, 16, 15, 17, 10, 20, 5, 26, 19, 15, 10, 10, 13, 13, 13, 12, 12, 18, 10, 18, 16, 20, 12, 6, 6, 15, 15, 15, 21, 30, 30, 30, 30, 23, 15, 15, 27, 27, 27, 27, 27, 27, 27, 27, 27, 10, 3]; +ordCol = [1, 2, 3, 4, 5, 6, 4, 7, 4, 8, 6, 6, 4, 9, 10, 11, 7, 11, 10, 11, 9, 1, 12, 13, 6, 14, 15, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 27, 34, 42, 35, 36, 43, 24, 44, 45, 46, 47, 48, 49, 50, 28, 51, 52, 24, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 68, 69, 70, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 79, 85, 86, 87, 88]; diff --git a/steelmillslab/bench_15_11.dzn b/steelmillslab/bench_15_11.dzn new file mode 100644 index 0000000..51b501a --- /dev/null +++ b/steelmillslab/bench_15_11.dzn @@ -0,0 +1,5 @@ +nbOrders = 111; +nbColours = 88; +sizes = {0, 15, 18, 19, 21, 25, 26, 32, 33, 34, 37, 41, 42, 45, 46, 50}; +ordSize = [4, 22, 9, 5, 8, 3, 3, 4, 7, 7, 3, 2, 2, 8, 5, 7, 4, 7, 5, 7, 8, 3, 25, 14, 3, 22, 19, 19, 22, 22, 22, 20, 22, 5, 4, 10, 26, 17, 20, 16, 10, 19, 10, 10, 23, 22, 26, 27, 22, 27, 22, 22, 13, 14, 16, 26, 26, 27, 22, 20, 26, 22, 13, 19, 20, 16, 15, 17, 10, 20, 5, 26, 19, 15, 10, 10, 13, 13, 13, 12, 12, 18, 10, 18, 16, 20, 12, 6, 6, 15, 15, 15, 21, 30, 30, 30, 30, 23, 15, 15, 27, 27, 27, 27, 27, 27, 27, 27, 27, 10, 3]; +ordCol = [1, 2, 3, 4, 5, 6, 4, 7, 4, 8, 6, 6, 4, 9, 10, 11, 7, 11, 10, 11, 9, 1, 12, 13, 6, 14, 15, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 27, 34, 42, 35, 36, 43, 24, 44, 45, 46, 47, 48, 49, 50, 28, 51, 52, 24, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 68, 69, 70, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 79, 85, 86, 87, 88]; diff --git a/steelmillslab/bench_16_10.dzn b/steelmillslab/bench_16_10.dzn new file mode 100644 index 0000000..d5284db --- /dev/null +++ b/steelmillslab/bench_16_10.dzn @@ -0,0 +1,5 @@ +nbOrders = 111; +nbColours = 88; +sizes = {0, 13, 15, 16, 17, 18, 21, 26, 28, 30, 33, 36, 37, 38, 42, 44, 50}; +ordSize = [4, 22, 9, 5, 8, 3, 3, 4, 7, 7, 3, 2, 2, 8, 5, 7, 4, 7, 5, 7, 8, 3, 25, 14, 3, 22, 19, 19, 22, 22, 22, 20, 22, 5, 4, 10, 26, 17, 20, 16, 10, 19, 10, 10, 23, 22, 26, 27, 22, 27, 22, 22, 13, 14, 16, 26, 26, 27, 22, 20, 26, 22, 13, 19, 20, 16, 15, 17, 10, 20, 5, 26, 19, 15, 10, 10, 13, 13, 13, 12, 12, 18, 10, 18, 16, 20, 12, 6, 6, 15, 15, 15, 21, 30, 30, 30, 30, 23, 15, 15, 27, 27, 27, 27, 27, 27, 27, 27, 27, 10, 3]; +ordCol = [1, 2, 3, 4, 5, 6, 4, 7, 4, 8, 6, 6, 4, 9, 10, 11, 7, 11, 10, 11, 9, 1, 12, 13, 6, 14, 15, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 27, 34, 42, 35, 36, 43, 24, 44, 45, 46, 47, 48, 49, 50, 28, 51, 52, 24, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 68, 69, 70, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 79, 85, 86, 87, 88]; diff --git a/steelmillslab/bench_19_5.dzn b/steelmillslab/bench_19_5.dzn new file mode 100644 index 0000000..8db9b0b --- /dev/null +++ b/steelmillslab/bench_19_5.dzn @@ -0,0 +1,5 @@ +nbOrders = 111; +nbColours = 88; +sizes = {0, 14, 18, 20, 24, 25, 27, 28, 29, 33, 34, 35, 37, 40, 42, 43, 46, 47, 48, 50}; +ordSize = [4, 22, 9, 5, 8, 3, 3, 4, 7, 7, 3, 2, 2, 8, 5, 7, 4, 7, 5, 7, 8, 3, 25, 14, 3, 22, 19, 19, 22, 22, 22, 20, 22, 5, 4, 10, 26, 17, 20, 16, 10, 19, 10, 10, 23, 22, 26, 27, 22, 27, 22, 22, 13, 14, 16, 26, 26, 27, 22, 20, 26, 22, 13, 19, 20, 16, 15, 17, 10, 20, 5, 26, 19, 15, 10, 10, 13, 13, 13, 12, 12, 18, 10, 18, 16, 20, 12, 6, 6, 15, 15, 15, 21, 30, 30, 30, 30, 23, 15, 15, 27, 27, 27, 27, 27, 27, 27, 27, 27, 10, 3]; +ordCol = [1, 2, 3, 4, 5, 6, 4, 7, 4, 8, 6, 6, 4, 9, 10, 11, 7, 11, 10, 11, 9, 1, 12, 13, 6, 14, 15, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 27, 34, 42, 35, 36, 43, 24, 44, 45, 46, 47, 48, 49, 50, 28, 51, 52, 24, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 68, 69, 70, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 79, 85, 86, 87, 88]; diff --git a/steelmillslab/on_restart.mzn b/steelmillslab/on_restart.mzn new file mode 100644 index 0000000..2009a7d --- /dev/null +++ b/steelmillslab/on_restart.mzn @@ -0,0 +1,33 @@ +include "steelmillslab.mzn"; +include "../lib.mzn"; + +predicate int_eq_imp(var int: x, var int: y, var bool: b); +predicate bool_eq_imp(var bool: x, var bool: y, var bool: b); + +predicate random_assignment(var bool: b) = forall(i in 1..nbSlabs) ( + int_eq_imp(assign[i], sol(assign[i]), b /\ (uniform_internal(1,100) < 80)) +); + +predicate random_bin(var bool: b) = let { + var int: bin = uniform_internal(1, nbSlabs); + } in forall(i in 1..nbSlabs) ( + int_eq_imp(assign[i], sol(assign[i]), b /\ (bin != sol(assign[i]))) + ); + +% Round Robin +array[1..2] of var bool: nbh; +constraint random_assignment(nbh[1]); +constraint random_bin(nbh[2]); +var 0..10000000: restart = restart_number(); +var 1..2: select = (restart mod 2) + 1; +constraint bool_eq_imp(nbh[1], false, status() == UNKNOWN); +constraint bool_eq_imp(nbh[2], false, status() == UNKNOWN); +constraint bool_eq_imp(nbh[1], select == 1, status() != UNKNOWN); +constraint bool_eq_imp(nbh[2], select == 2, status() != UNKNOWN); + +annotation main_vars(array[int] of var int: vars); + +solve + :: main_vars(assign) + :: int_search(ordered, first_fail, indomain_min, complete) + minimize objective; diff --git a/steelmillslab/original.mzn b/steelmillslab/original.mzn new file mode 100644 index 0000000..7ff3d38 --- /dev/null +++ b/steelmillslab/original.mzn @@ -0,0 +1,8 @@ +include "steelmillslab.mzn"; + +annotation main_vars(array[int] of var int: vars); + +solve + :: main_vars(assign) + :: int_search(ordered, first_fail, indomain_min, complete) + minimize objective; diff --git a/steelmillslab/steelmillslab.mzn b/steelmillslab/steelmillslab.mzn new file mode 100644 index 0000000..e100423 --- /dev/null +++ b/steelmillslab/steelmillslab.mzn @@ -0,0 +1,51 @@ +include "globals.mzn"; + +%------------------------------------------------------------------------------% +% Parameters + +par int: nbOrders; +par int: nbColours; + +par set of int: sizes; + +array[int] of par int: ordSize; +array[int] of par int: ordCol; + +par int: nbSlabs = nbOrders; + +%------------------------------------------------------------------------------% +% Variables + +array[1..nbOrders] of var 1..nbSlabs: assign; + +array[int] of par int: order = arg_sort(ordSize); + +array[int] of var 1..nbSlabs: ordered = [ assign[order[nbOrders-p+1]] | p in 1..nbOrders ]; + +constraint forall(i in 1..nbSlabs) ( + sum([ bool2int(exists(o in 1..nbOrders where ordCol[o]=c)(assign[o] = i)) | c in 1..nbColours ]) <= 2 + ); + +array[1..nbSlabs] of var 0..max(sizes): loads = bin_packing_load(assign, [ordSize[i] | i in 1..nbOrders]); + +array[0..max(sizes)] of par int: frees = + array1d(0..max(sizes), [min([c - l | c in sizes where c >= l]) | l in 0..max(sizes)]); + + +constraint symmetry_breaking_constraint( + forall(i in 1..nbSlabs-1) (loads[i] = 0 -> loads[i+1] = 0)); + +constraint symmetry_breaking_constraint( + forall(i in 1..nbOrders, j in 1..nbOrders where j > i)( + (ordSize[i] = ordSize[j] /\ ordCol[i] = ordCol[j]) -> assign[i] <= assign[j])); + +int: objub = max(frees)*nbSlabs; +var 0..objub: objective; + +constraint objective = sum(j in 1..nbSlabs)(frees[loads[j]]); +constraint trace("% init_area = \(ub(objective));\n", true); + +output [ + "assign = \(assign);\n", + "objective = \(objective);\n", +];