def disposizione_kCavalli(n: int, k: int): m = nj.Matrix(n, n) # Matrice di variabili booleane nxn kCavalli = nj.Model() # Vincoli di interdizione delle celle rispetto alla cella corrente for i in range(n): for j in range(n): if j - 2 >= 0 and i + 1 <= n - 1: kCavalli.add((m[i][j] + m[i + 1][j - 2]) != 2) if j - 1 >= 0 and i + 2 <= n - 1: kCavalli.add((m[i][j] + m[i + 2][j - 1]) != 2) if j + 1 <= n - 1 and i + 2 <= n - 1: kCavalli.add((m[i][j] + m[i + 2][j + 1]) != 2) if j + 2 <= n - 1 and i + 1 <= n - 1: kCavalli.add((m[i][j] + m[i + 1][j + 2]) != 2) kCavalli.add(sum([m[i][j] for i in range(n) for j in range(n)]) == k) # Vincolo per il numero di cavalli totali solver: nj.NBJ_STD_Solver = kCavalli.load('MiniSat') if solver.solve(): print("In una scacchiera %dx%d una soluzione che dispone %d cavalli senza attacchi è :" % (n, n, k)) print(m) else: print("In una scacchiera %dx%d è impossibile disporre %d cavalli senza attacchi!" % (n, n, k))
def __init__(self, grid_categories, extra_categories=None): if nj is None: raise ValueError("Numberjack not installed, cannot use Solver.") super().__init__(grid_categories) self.xcats = extra_categories or dict() # Create grids of variables for each pair of categories self.vgrids = {n: {} for n in self.categories} self.all_grids = [] for f1, f2 in self.pairs: vname = '{}_{}.'.format(f1, f2) mat = nj.Matrix(self.num_items, self.num_items, vname) # Like the normal grid, these are two views of the same object self.vgrids[f1][f2] = mat self.vgrids[f2][f1] = mat.col self.all_grids.append(mat) # Create variables for each extra category self.vcats = {} for (name, domain) in self.xcats.items(): v = self.vcats[name] = {} for cat in self.categories: vname = '{}_{}'.format(cat, name) v[cat] = nj.VarArray(self.num_items, domain, vname) self.vars = VarLookup(self) # Precompute sanity constraints self.constraints = (self.cons_rowcol() + self.cons_sanity()) self.model = self.solver = None self.soln = self._soln_df = self._soln_grid = None
def disposizione_kCavalli(n: int, k: int): m = nj.Matrix(n, n) # Matrice di variabili booleane nxn kCavalli = nj.Model() # Vincoli di interdizione delle celle rispetto alla cella corrente for i in range(n): for j in range(n): if j - 2 >= 0 and i + 1 <= n - 1: kCavalli.add((m[i][j] + m[i + 1][j - 2]) != 2) if j - 1 >= 0 and i + 2 <= n - 1: kCavalli.add((m[i][j] + m[i + 2][j - 1]) != 2) if j + 1 <= n - 1 and i + 2 <= n - 1: kCavalli.add((m[i][j] + m[i + 2][j + 1]) != 2) if j + 2 <= n - 1 and i + 1 <= n - 1: kCavalli.add((m[i][j] + m[i + 1][j + 2]) != 2) kCavalli.add(sum([m[i][j] for i in range(n) for j in range(n) ]) == k) # Vincolo per il numero di cavalli totali solver: nj.NBJ_STD_Solver = kCavalli.load('MiniSat') start = timer() esito = solver.solve() end = timer() return [end - start, esito]
def cons_rowcol(self): '''Return basic structural nj constraints. The returned list of constraints will require every row and column of every grid to have exactly one 1. ''' for grid in self.all_grids: for i in range(self.num_items): yield nj.Gcc(grid.row[i], {1: (1, 1)}) yield nj.Gcc(grid.col[i], {1: (1, 1)})
def solve(): N = int(stdin.readline().strip()) data = collections.defaultdict(list) for i in range(N): sentence = stdin.readline().strip() for word in sentence.split(" "): data[word].append(i) model = Numberjack.Model() is_english = Numberjack.VarArray(N, 0, 1) model.add(is_english[0] == 1) model.add(is_english[1] == 0) common = Numberjack.Variable(0, 1000000) zero = Numberjack.Variable(0,0) total = [] for word, sentences in data.items(): have_french = Numberjack.Variable(0, 1) for i in sentences: model.add(have_french <= is_english[i]) # have_french is 0 if there is french, otherwise 0 or 1 have_english = Numberjack.Variable(0, 1) for i in sentences: model.add(have_english >= is_english[i]) # have_english is 1 if there is english, otherwise 0 or 1 have_both = Numberjack.Variable(0, 1) model.add(have_both >= have_english - have_french) total.append(have_both) model.add(Numberjack.Sum(total) <= common) model.add(Numberjack.Minimize(common)) solver = model.load("SCIP") #solver.setVerbosity(1) solver.solve() assert solver.is_opt() return common.get_value()
def solve(self, fmt='dict', solvername='MiniSat'): if self.model is None: self.constraints.extend(self.cons_grid()) self.model = nj.Model(*self.constraints) self.solver = self.model.load(solvername) assert self.solver.solve() return self._make_soln()
def solve(self, verbose=0): model = nj.Model(self.constraints) solver = model.load('Toulbar2') solver.setVerbosity(verbose) solver.setOption('updateUb', str(1000000)) solver.setOption('btdMode', 1) solver.solve() return [self.Variables[m].get_value() for m in xrange(self.L)]
def set_constraints(self, constraints): words = self._scheme.horizontal_words() words.update(self._scheme.vertical_words()) for key, value in constraints.items(): self._model.add( NJ.Sum([ self._vars[row - 1][col - 1] for (row, col) in words[key] ]) == value)
def __init__(self, mk_list, mk_pairs, recmap_f): self.mk = list(mk_list) self.pairs = mk_pairs self.recf = recmap_f self.L = len(self.mk) ## Initialize Optim. model ### Creates an array of phase indicators self.Variables = nj.VarArray(self.L) ### Init model with simple constraint Var[0]==False self.constraints = [self.Variables[0] == 0]
def testSmallBibd(self): v, b, r, k, l = [7, 7, 3, 3, 1] # This test uses the modelling layer for ease of use import Numberjack model = Numberjack.Model() # Create the model matrix = Numberjack.Matrix(v, b) # every row adds up to k model.add([Numberjack.Sum(row) == k for row in matrix.row]) # every column adds up to r model.add([Numberjack.Sum(col) == r for col in matrix.col]) # the scalar product of every pair of columns adds up to l model.add([ Numberjack.Sum([(row[col_i] & row[col_j]) for row in matrix.row]) == l for col_i in range(v) for col_j in range(col_i) ]) solver = Solver(model, [var for col in matrix.col for var in col]) assert (solver.solve())
def add_constraints(self): ''' Build constraints from marker pairs ''' for p, Nkl in self.pairs.items(): ## gt mk indices k = self.mk.index(p[0]) l = self.mk.index(p[1]) ## ger recomb rate rkl = self.recf(p[0], p[1]) assert rkl > 0 ## get cost Wkl = (Nkl[0] - Nkl[1]) * np.log((1 - rkl) / rkl) ## create constraints hk = self.Variables[k] hl = self.Variables[l] if Wkl < 0: cost = [-Wkl, 0, 0, -Wkl] else: cost = [0, Wkl, Wkl, 0] cost = [int(x) for x in cost] self.constraints.append(nj.PostBinary(hk, hl, cost)) print("Constraints:", *self.constraints, sep='\n')
def solve(vol, temp, sources): model = Numberjack.Model() times = Numberjack.VarArray( len(sources), 0.0, 1e100 ) worst = Numberjack.Variable(0.0, 1e100) # add constraints # times * sources.rate == volume rates = [x[0] for x in sources] model.add(Numberjack.Sum(times, rates) == vol) # times * sources.rate * sources.temp == temp * vol tmp = [x[0] * x[1] for x in sources] model.add(Numberjack.Sum(times, tmp) == vol * temp) for i in range(len(sources)): model.add(worst >= times[i]) model.add(Numberjack.Minimize(worst)) solver = model.load("SCIP") solver.solve() if not solver.is_opt(): return "IMPOSSIBLE" return "%.14f" % worst.get_value()
def knapsack(costs, nutrients, n): z = nj.Variable(0, 10000) x = nj.VarArray(len(costs), 0, 20) model = nj.Model( z >= 0, z == nj.Sum(x, costs), nj.Sum(x, nutrients[0]) >= n[0], #nutrient #1 nj.Sum(x, nutrients[1]) >= n[1], #nutrient #2 nj.Sum(x, nutrients[2]) >= n[2], #nutrient #3 nj.Sum(x, nutrients[3]) >= n[3], #nutrient #4 nj.Sum(x, nutrients[4]) >= n[4], #nutrient #5 nj.Sum(x, nutrients[5]) >= n[5], #nutrient #6 nj.Minimise(z)) return [model, x, z]
def knapsack(costs, nutrients, n, patient): z = nj.Variable(patient, 10000) x = nj.VarArray(len(costs), 0, 1) model = nj.Model( # (z >= patient) & (z <= 950), #z >= patient, z == nj.Sum(x, costs), (nj.Sum(x, nutrients[0]) >= n[0]) & (nj.Sum(x, nutrients[0]) <= 250000), #nutrient #1 (nj.Sum(x, nutrients[1]) >= n[1]) & (nj.Sum(x, nutrients[1]) <= 20000), #nutrient #2 (nj.Sum(x, nutrients[2]) >= n[2]) & (nj.Sum(x, nutrients[2]) <= 10000), #nutrient #3 (nj.Sum(x, nutrients[3]) >= n[3]) & (nj.Sum(x, nutrients[3]) <= 1100), #nutrient #4 (nj.Sum(x, nutrients[4]) >= n[4]) & (nj.Sum(x, nutrients[4]) <= 200000), #nutrient #5 (nj.Sum(x, nutrients[5]) >= n[5]) & (nj.Sum(x, nutrients[5]) <= 10000), #nutrient #6 #nj.Sum(x)<=20, nj.Minimise(z)) return [model, x, z]
), "\tfrom sentence:", sentence_index[i], "\t", ph.tree().tag(), " ".join( ph.leaves()) # features and information about each of the phrases # token length is number of tokens in each phrase # you might want to change this to number of characters, to match Twitter limit phrase_token_length = [len(ph.leaves()) for ph in phrases] # phrase scores should come from your ML model phrase_scores = [0.0 for ph in phrases] # for now, we can hard-code some scores phrase_scores[1] = 1.0 #phrase_scores[7] = 1.0 # make the ILP model model = nj.Model() phrase_variable = [nj.Variable("phr_%d" % i) for i in range(n)] sentence_variable = [ nj.Variable("sentence_%d" % i) for i in range(doc.sentenceCount()) ] # connect sentence and phrase variables for internal logic for i in range(n): s = sentence_index[i] model.add(sentence_variable[s] >= phrase_variable[i]) # set a maximum length for the output MAX_TOKENS = 10 model.add( nj.Sum([phrase_variable[i] * phrase_token_length[i] for i in range(n)]) <= MAX_TOKENS)
def __init__(self, scheme, domain): self._scheme = scheme self._vars = NJ.Matrix(scheme.rows, scheme.cols, domain[0], domain[1]) self._model = NJ.Model() self._solver = None
def numberjack_scheduler(tasks, upper_bound=500, lower_bound=None, optimize=True, time_limit=5, solver_method="Mistral", randomization=False, verbose_solver=False): """Makes an optimized schedule for the processes. Examples -------- >>> >>> >>> >>> Parameters ----------- tasks A list of tasks to be sceduled upper_bound Upper bound for the time. The unit depends on the unit chosen for the duration of the work unit's tasks. optimize If false, any solution satisfying the constraints (including deadlines) will be returned. But sometimes it is not possible to respect all deadlines. If True, the function will try to return a schedule which minimizes the days over the deadlines. The function minimized is the sum of (wu.priority*wu.delay) for all work units with a due time. time_limit Time in seconds after which the optimizer stops. If the optimizer stops because of this time limit the solution may not be optimal. solver_method The solver used by NumberJack (see NumberJack docs). """ ZERO = nj.Variable([0]) C_LOWER_BOUND = 0 # Create Numberjack variables to represent the tasks # ( starting times and resource instance that they use). tasks = [ task for task in tasks if ((task.scheduled_start is None) or ((task.scheduled_start is not None) and (task.scheduled_start < upper_bound)) or ((task.scheduled_end is not None) and (lower_bound is not None) and (task.scheduled_end > lower_bound))) ] nj_tasks = {} for task in tasks: if task.scheduled_start is None: if lower_bound is not None: new_nj_task = nj.Task(lower_bound, upper_bound, task.duration) else: new_nj_task = nj.Task(upper_bound, task.duration) else: new_nj_task = nj.Task( task.scheduled_start, task.scheduled_end, task.duration ) new_nj_task.name = task.name nj_tasks[task] = new_nj_task nj_taskresources = { task: { resource: ( # If a task is already scheduled to some slot, its slot is # one-choice variable. Otherwise it is a 1..nSlots variable nj.Variable(1, resource.capacity) if task.scheduled_resources is None else nj.Variable([task.scheduled_resources[resource]]) ) for resource in task.resources } for task in tasks } all_resources = list(set([ resource for task in tasks for resource in task.resources ])) model = nj.Model() for resource in all_resources: if resource.capacity == 'inf': continue elif resource.capacity == 1: # The resource has one slot: Only one job at the same time model.add(nj.UnaryResource([ nj_tasks[task] for task in tasks if (resource in task.resources) ])) else: # The resource has several slots tasks_pairs_sharing_resource = [ (task, other_task) for (task, other_task) in itt.combinations(tasks, 2) if ((resource in task.resources) and (resource in other_task.resources)) ] for (task, other_task) in tasks_pairs_sharing_resource: different_times = nj.Or([ nj_tasks[task] + task.duration <= nj_tasks[other_task], nj_tasks[other_task] + other_task.duration < nj_tasks[task] ]) different_resources = nj.AllDiff([ nj_taskresources[task][resource], nj_taskresources[other_task][resource] ]) different_resources.lb = 0 different_resources.ub = 1 model.add(nj.Or([different_times, different_resources])) model.add([ (nj_tasks[task] + task.duration <= nj_tasks[next_task]) for next_task in tasks for task in next_task.follows ]) model.add([ (nj_tasks[next_task] <= nj_tasks[task] + task.duration + next_task.max_wait) for next_task in tasks for task in next_task.follows if next_task.max_wait is not None ]) if optimize: C_max = nj.Variable(C_LOWER_BOUND, 150000000, 'C_max') model.add( C_max > sum([ nj.Max([ZERO, nj_tasks[task] + task.duration - task.due_time]) * (1000 * task.priority) for task in tasks if task.due_time is not None ]) + sum([ nj_tasks[task] for task in tasks ]) ) # Specify that the goal is to minimize C_max (compress the schedule). model.add(nj.Minimize(C_max)) else: model.add([ nj_tasks[task] + task.duration < task.due_time for task in tasks if task.due_time is not None ]) solver = model.load(solver_method) solver.setVerbosity(verbose_solver) solver.setTimeLimit(time_limit) solver.setRandomized(randomization) result = solver.solve() if result is False: raise ValueError("No solution found by the schedule optimizer !") for task in tasks: nj_task = nj_tasks[task] start = nj_task.get_value() resources = {resource: nj_taskresources[task][resource].get_value() for resource in task.resources} task.scheduled_start = start task.scheduled_resources = resources return tasks
def add_it(fn): for choices in product(*opts): if not fn(*[c.val for c in choices]): vs = [self.vars[v, c] for (v, c) in zip(vars, choices)] self.add(nj.Sum(vs) < len(vs)) return fn