Ejemplo n.º 1
0
# Each cell (blank or not) must be adjacent to at least another
for l in range(SIZE):
    for c in range(SIZE):
        lvars = [color[l2][c2] for l2, c2 in get_neighbors(l, c)]
        mdl.add(mdl.sum(lvars) < len(lvars))

# At least cell 0,0 or cell 0,1 is blank.
# Build table of distance to one of these cells
# Black cells are associated to a max distance SIZE*SIZE
MAX_DIST = SIZE * SIZE
distance = [[
    mdl.integer_var(min=0, max=MAX_DIST, name="D" + str(l) + "_" + str(c))
    for c in range(SIZE)
] for l in range(SIZE)]
mdl.add(distance[0][0] == mdl.conditional(color[0][0], MAX_DIST, 0))
mdl.add(distance[0][1] == mdl.conditional(color[0][1], MAX_DIST, 0))
for c in range(2, SIZE):
    mdl.add(distance[0][c] == mdl.conditional(
        color[0][c], MAX_DIST, 1 + mdl.min(distance[l2][c2]
                                           for l2, c2 in get_neighbors(0, c))))
for l in range(1, SIZE):
    for c in range(SIZE):
        mdl.add(distance[l][c] == mdl.conditional(
            color[l][c], MAX_DIST, 1 +
            mdl.min(distance[l2][c2] for l2, c2 in get_neighbors(l, c))))

# Force distance of blank cells to be less than max
for l in range(SIZE):
    for c in range(SIZE):
        mdl.add((color[l][c] > 0) | (distance[l][c] < MAX_DIST))
for k in range(2):
    #each bin's load can range(0..bin size)
    loads = [mdl.integer_var(0,bins[int(bin.id)].size[k], name="sizeBin"+str(bin.id)+",d"+str(k)) for bin in bins]
    mdl.add(mdl.pack(loads, wheres, [item.size[k] for item in items]))
    
#===============SETUP OBJECTIVE=============== 
#maximize number of items allocated to all bins EXCEPT the big bin
#nb_allocated_items = mdl.sum([(wheres[int(item.id)] != nb_bins) for item in items])

#maximize x_1 * x_2 * ... *x_n, where x_1, x_2,..., x_n is the number of items in bin 1, 2, ..., n
product_x = 1
for bin in bins[0:len(bins)-1]:
    #get the number of items in the bin
    nb_items_in_bin = mdl.sum([(wheres[int(item.id)] == int(bin.id)) for item in items])
    #if the bin is empty, assume it has 1 item so that the product won't be zero (ignore empty bins)
    x = mdl.conditional(nb_items_in_bin != 0, nb_items_in_bin, 1)
    #divided by 10 so that CPO won't have to handle big integer, just in case many x are large
    product_x = mdl.times(product_x, x/10)
        
#add lecicographic objs
#mdl.add(mdl.maximize_static_lex([nb_allocated_items, product_x]))
mdl.add(mdl.maximize(product_x))

#solve the problem and print the solution
print("...solving...")
msol = mdl.solve(url = None, key = None, TimeLimit = None, SearchType = 'Auto')
msol.print_solution()
print("Obj vals: " + str(msol.get_objective_values()))
print("x_1 * x_2 * ... * x_n = ",msol.get_objective_values()[0]*(10**nb_bins))
mdl.export_as_cpo(out='cpo.txt')
with open('log.txt', "w") as text_file: