def defineObjectives(data: DataInstance, model: Model, boolVars, N, posVars): LAG, RAG, TAG, BAG = boolVars L, R, T, B, H, W = posVars maxX = model.addVar(vtype=GRB.INTEGER, name="maxX") maxY = model.addVar(vtype=GRB.INTEGER, name="maxY") for element in range(data.element_count): model.addConstr(maxX >= R[element]) model.addConstr(maxY >= B[element]) OBJECTIVE_GRIDCOUNT = LinExpr(0.0) for element in range(data.element_count): OBJECTIVE_GRIDCOUNT.addTerms([1.0, 1.0], [LAG[element], TAG[element]]) OBJECTIVE_GRIDCOUNT.addTerms([1.0, 1.0], [BAG[element], RAG[element]]) OBJECTIVE_LT = LinExpr(0) for element in range(data.element_count): OBJECTIVE_LT.addTerms([1, 1, 2, 2, -1, -1], [T[element], L[element], B[element], R[element], W[element], H[element]]) Objective = LinExpr(0) Objective.add(OBJECTIVE_GRIDCOUNT, 1) Objective.add(OBJECTIVE_LT, 0.001) # Objective.add(maxX, 10) # Objective.add(maxY, 10) model.addConstr(OBJECTIVE_GRIDCOUNT >= (calculateLowerBound(N))) model.setObjective(Objective, GRB.MINIMIZE) return OBJECTIVE_GRIDCOUNT, OBJECTIVE_LT
def solve(model, lista_caminhos, variables, lista_cores, path): # Criar array de constraints para limitar as colunas # uma por vertice num_cores = obter_numero_cores(path) num_vertices = obter_numero_vertices(path) constraints = [] nomes_vertices = [] pi = [] # gerar lista de nomes for i in range(0, num_vertices): for j in range(0, num_cores): nomes_vertices.append("vertice" + str(i + 1) + "_cor" + str(j + 1)) for i in range(0, num_vertices * num_cores): expr = LinExpr() # Criando a expressão e já atribuindo o nome para poder recuperar # na geração de coluna constraints.append(model.addRange(expr, 1, 1, nomes_vertices[i])) # Aplicando a heuristica desenvolvida para encontrar solução inicial caminhos_possiveis = encontrar_caminhos_validos(lista_caminhos, lista_cores) caminhos_possiveis = unificar_caminho(model, caminhos_possiveis) # pra cada caminho possivel, achar uma coluna for i in range(0, len(caminhos_possiveis)): coluna = gerar_coluna(caminhos_possiveis[i], constraints) # adicionar ao modelo model.addVar(0, 1, cst_red, GRB.CONTINUOUS, coluna) model.update() solve_lp(pi, path, model)
def criar_funcao_objetivo(model, lista_variaveis, variables, lista_coef): # inicializando a expressão com a primeira variável linear_expression = LinExpr() for i in range(1, len(lista_variaveis)): linear_expression.add(variables.values()[i], lista_coef[i]) model.setObjective(linear_expression, GRB.MINIMIZE) return model
def equationBuilder(index_inequacao, model_vars): index_inequacao.reverse() sinal = '+' expr = LinExpr() for i in range(0, len(index_inequacao)): if sinal == '+': var = model_vars[index_inequacao[i]] # adicionar variavel a expressao expr.add(var, 1) # alterar sinal sinal = '-' elif sinal == '-': var = model_vars[index_inequacao[i]] # adicionar variavel a expressao expr.add(var, -1) # alterar sinal sinal = '+' return expr
def setConstraints(data: DataInstance, model: Model, relVars, boolVars, vVars, elemVars, posVars, N): L, R, T, B, H, W = posVars ABOVE, LEFT = relVars LAG, RAG, TAG, BAG = boolVars vLAG, vRAG, vTAG, vBAG = vVars elemAtLAG, elemAtRAG, elemAtTAG, elemAtBAG = elemVars # Known Position constraints X Y HORIZONTAL_TOLERANCE = data.canvasWidth * FLEXIBILITY_VALUE VERTICAL_TOLERANCE = data.canvasWidth * FLEXIBILITY_VALUE for element in range(data.element_count): print("At element ", element, "with lock = ", data.elements[element].isLocked) if data.elements[element].isLocked: if data.elements[element].X is not None and data.elements[element].X >= 0: model.addConstr(L[element] == data.elements[element].X, "PrespecifiedXOfElement(", element, ")") if data.elements[element].Y is not None and data.elements[element].Y >= 0: model.addConstr(T[element] == data.elements[element].Y, "PrespecifiedYOfElement(", element, ")") else: if data.elements[element].X is not None and data.elements[element].X >= 0: model.addConstr(L[element] >= data.elements[element].X - HORIZONTAL_TOLERANCE, "PrespecifiedXminOfElement(", element, ")") model.addConstr(L[element] <= data.elements[element].X + HORIZONTAL_TOLERANCE, "PrespecifiedXmaxOfElement(", element, ")") if data.elements[element].Y is not None and data.elements[element].Y >= 0: model.addConstr(T[element] >= data.elements[element].Y - VERTICAL_TOLERANCE, "PrespecifiedYminOfElement(", element, ")") model.addConstr(T[element] <= data.elements[element].Y + VERTICAL_TOLERANCE, "PrespecifiedYmaxOfElement(", element, ")") if data.elements[element].aspectRatio is not None and data.elements[element].aspectRatio > 0.001: model.addConstr(W[element] == data.elements[element].aspectRatio * H[element], "PrespecifiedAspectRatioOfElement(", element, ")") # Known Position constraints TOP BOTTOM LEFT RIGHT coeffsForAbsolutePositionExpression = [] varsForAbsolutePositionExpression = [] for element in range(data.element_count): for other in range(data.element_count): if element != other: if data.elements[element].verticalPreference is not None: if data.elements[element].verticalPreference.lower() == "top": varsForAbsolutePositionExpression.append(ABOVE[other, element]) coeffsForAbsolutePositionExpression.append(1.0) if data.elements[element].verticalPreference.lower() == "bottom": varsForAbsolutePositionExpression.append(ABOVE[element, other]) coeffsForAbsolutePositionExpression.append(1.0) if data.elements[element].horizontalPreference is not None: if data.elements[element].horizontalPreference.lower() == "left": varsForAbsolutePositionExpression.append(LEFT[other, element]) coeffsForAbsolutePositionExpression.append(1.0) if data.elements[element].horizontalPreference.lower() == "right": varsForAbsolutePositionExpression.append(LEFT[element, other]) coeffsForAbsolutePositionExpression.append(1.0) expression = LinExpr(coeffsForAbsolutePositionExpression, varsForAbsolutePositionExpression) model.addConstr(expression == 0, "Disable non-permitted based on prespecified") # Height/Width/L/R/T/B Summation Sanity for element in range(N): model.addConstr(W[element] + L[element] == R[element], "R-L=W(" + str(element) + ")") model.addConstr(H[element] + T[element] == B[element], "B-T=H(" + str(element) + ")") # MinMax limits of Left-Above interactions for element in range(N): for otherElement in range(N): if element > otherElement: model.addConstr( ABOVE[element, otherElement] + ABOVE[otherElement, element] + LEFT[element, otherElement] + LEFT[ otherElement, element] >= 1, "NoOverlap(" + str(element) + str(otherElement) + ")") model.addConstr( ABOVE[element, otherElement] + ABOVE[otherElement, element] + LEFT[element, otherElement] + LEFT[ otherElement, element] <= 2, "UpperLimOfQuadrants(" + str(element) + str(otherElement) + ")") model.addConstr(ABOVE[element, otherElement] + ABOVE[otherElement, element] <= 1, "Anti-symmetryABOVE(" + str(element) + str(otherElement) + ")") model.addConstr(LEFT[element, otherElement] + LEFT[otherElement, element] <= 1, "Anti-symmetryLEFT(" + str(element) + str(otherElement) + ")") # Interconnect L-R-LEFT and T-B-ABOVE for element in range(N): for otherElement in range(N): if element != otherElement: model.addConstr( R[element] + data.elementXPadding <= L[otherElement] + (1 - LEFT[element, otherElement]) * ( data.canvasWidth + data.elementXPadding), (str(element) + "(ToLeftOf)" + str(otherElement))) model.addConstr( B[element] + data.elementYPadding <= T[otherElement] + (1 - ABOVE[element, otherElement]) * ( data.canvasHeight + data.elementYPadding), (str(element) + "(Above)" + str(otherElement))) model.addConstr( (L[otherElement] - R[element] - data.elementXPadding) <= data.canvasWidth * LEFT[ element, otherElement] , (str(element) + "(ConverseOfToLeftOf)" + str(otherElement))) model.addConstr( (T[otherElement] - B[element] - data.elementYPadding) <= data.canvasHeight * ABOVE[ element, otherElement] , (str(element) + "(ConverseOfAboveOf)" + str(otherElement))) # One Alignment-group for every edge of every element for element in range(N): coeffsForLAG = [] coeffsForRAG = [] coeffsForTAG = [] coeffsForBAG = [] varsForLAG = [] varsForRAG = [] varsForTAG = [] varsForBAG = [] for alignmentGroupIndex in range(data.element_count): varsForLAG.append(elemAtLAG[element, alignmentGroupIndex]) coeffsForLAG.append(1) varsForRAG.append(elemAtRAG[element, alignmentGroupIndex]) coeffsForRAG.append(1) varsForTAG.append(elemAtTAG[element, alignmentGroupIndex]) coeffsForTAG.append(1) varsForBAG.append(elemAtBAG[element, alignmentGroupIndex]) coeffsForBAG.append(1) model.addConstr(LinExpr(coeffsForLAG, varsForLAG) == 1, "OneLAGForElement[" + str(element) + "]") model.addConstr(LinExpr(coeffsForTAG, varsForTAG) == 1, "OneTAGForElement[" + str(element) + "]") model.addConstr(LinExpr(coeffsForBAG, varsForBAG) == 1, "OneBAGForElement[" + str(element) + "]") model.addConstr(LinExpr(coeffsForRAG, varsForRAG) == 1, "OneRAGForElement[" + str(element) + "]") # Symmetry breaking and sequencing of alignment groups # for alignmentGroupIndex in range(data.N): # if(alignmentGroupIndex >= 1): # print() # gurobi.addConstr(LAG[alignmentGroupIndex] <= LAG[alignmentGroupIndex-1], "SymmBreakLAG["+str(alignmentGroupIndex)+ "]") # gurobi.addConstr(TAG[alignmentGroupIndex] <= TAG[alignmentGroupIndex-1], "SymmBreakTAG["+str(alignmentGroupIndex)+ "]") # gurobi.addConstr(RAG[alignmentGroupIndex] <= RAG[alignmentGroupIndex-1], "SymmBreakRAG["+str(alignmentGroupIndex)+ "]") # gurobi.addConstr(BAG[alignmentGroupIndex] <= BAG[alignmentGroupIndex-1], "SymmBreakBAG["+str(alignmentGroupIndex)+ "]") # gurobi.addConstr(vLAG[alignmentGroupIndex] >= vLAG[alignmentGroupIndex-1]+1, "ProgressiveIndexLAG["+str(alignmentGroupIndex)+"]") # gurobi.addConstr(vTAG[alignmentGroupIndex] >= vTAG[alignmentGroupIndex-1]+1, "ProgressiveIndexTAG["+str(alignmentGroupIndex)+"]") # gurobi.addConstr(vRAG[alignmentGroupIndex] >= vRAG[alignmentGroupIndex-1]+1, "ProgressiveIndexRAG["+str(alignmentGroupIndex)+"]") # gurobi.addConstr(vBAG[alignmentGroupIndex] >= vBAG[alignmentGroupIndex-1]+1, "ProgressiveIndexBAG["+str(alignmentGroupIndex)+"]") # Assign alignment groups to elements only if groups are enabled for alignmentGroupIndex in range(data.element_count): for element in range(N): model.addConstr(elemAtLAG[element, alignmentGroupIndex] <= LAG[alignmentGroupIndex]) model.addConstr(elemAtRAG[element, alignmentGroupIndex] <= RAG[alignmentGroupIndex]) model.addConstr(elemAtTAG[element, alignmentGroupIndex] <= TAG[alignmentGroupIndex]) model.addConstr(elemAtBAG[element, alignmentGroupIndex] <= BAG[alignmentGroupIndex]) # Correlate alignment groups value with element edge if assigned for alignmentGroupIndex in range(data.element_count): for element in range(N): model.addConstr(L[element] <= vLAG[alignmentGroupIndex] + data.canvasWidth * ( 1 - elemAtLAG[element, alignmentGroupIndex]), "MinsideConnectL[" + str(element) + "]ToLAG[" + str(alignmentGroupIndex) + "]") model.addConstr(R[element] <= vRAG[alignmentGroupIndex] + data.canvasWidth * ( 1 - elemAtRAG[element, alignmentGroupIndex]), "MinsideConnectR[" + str(element) + "]ToRAG[" + str(alignmentGroupIndex) + "]") model.addConstr(T[element] <= vTAG[alignmentGroupIndex] + data.canvasHeight * ( 1 - elemAtTAG[element, alignmentGroupIndex]), "MinsideConnectT[" + str(element) + "]ToTAG[" + str(alignmentGroupIndex) + "]") model.addConstr(B[element] <= vBAG[alignmentGroupIndex] + data.canvasHeight * ( 1 - elemAtBAG[element, alignmentGroupIndex]), "MinsideConnectB[" + str(element) + "]ToBAG[" + str(alignmentGroupIndex) + "]") model.addConstr(L[element] >= vLAG[alignmentGroupIndex] - data.canvasWidth * ( 1 - elemAtLAG[element, alignmentGroupIndex]), "MaxsideConnectL[" + str(element) + "]ToLAG[" + str(alignmentGroupIndex) + "]") model.addConstr(R[element] >= vRAG[alignmentGroupIndex] - data.canvasWidth * ( 1 - elemAtRAG[element, alignmentGroupIndex]), "MaxsideConnectR[" + str(element) + "]ToRAG[" + str(alignmentGroupIndex) + "]") model.addConstr(T[element] >= vTAG[alignmentGroupIndex] - data.canvasHeight * ( 1 - elemAtTAG[element, alignmentGroupIndex]), "MaxsideConnectT[" + str(element) + "]ToTAG[" + str(alignmentGroupIndex) + "]") model.addConstr(B[element] >= vBAG[alignmentGroupIndex] - data.canvasHeight * ( 1 - elemAtBAG[element, alignmentGroupIndex]), "MaxsideConnectB[" + str(element) + "]ToBAG[" + str(alignmentGroupIndex) + "]")
# obtendo dados dos arquivos df = obter_variaveis(path) # obtendo a lista de variaveis e respectivos coeficientes para função # obj. lista_variaveis = df['nome_variavel'] lista_coeficientes = df['coeff'] # CRIANDO AS VARIÁVEIS DO MODELO ------------------------------------------ # variables = adicionar_variaveis_modelo(m, lista_variaveis, # "modelo_var") variables = m.addVars(lista_variaveis, vtype=GRB.BINARY, name="variables") # ADICIONANDO EXPRESSÃO LINEAR DA FUNÇÃO OBJETIVO ------------------------- # inicializando a expressão com a primeira variável linear_expression = LinExpr() for i in range(1, len(lista_variaveis)): linear_expression.add(variables.values()[i], lista_coeficientes[i]) m.setObjective(linear_expression, GRB.MINIMIZE) # ADICIONANDO EXPRESSÃO LINEAR DA PRIMEIRA RESTRIÇÃO ------------------ # Garantindo que todos os vértices sejam pintados. for numero_vertice in map(int, obter_lista_vertices(path)): # Abaixo, obtendo indices das variáveis do vertice N, que devem ser # somados em uma restrição linear para garantir que assumam # apenas uma # cor. Nesse caso, itero por cada vertice X de cor 'qualquer', para # posteriomente somar todos quando construo a restrição. lista_temp = [ r[0] for r in [i.lower().split('_') for i in lista_variaveis] ]
import gurobipy as gp from gurobipy import GRB from gurobipy.gurobipy import LinExpr # Create a new model m = gp.Model("mip1") # Create the set of variables lista_variaveis = ['x', 'y', 'z'] vertices = m.addVars(lista_variaveis, vtype=GRB.BINARY, name="lista_variaveis") # FO: Maximize the linear expression # x + y + 2 z expr = LinExpr([1], [vertices['x']]) expr.add(vertices['y'], 1) expr.add(vertices['z'], 2) m.setObjective(expr, GRB.MAXIMIZE) # (outra maneira de passar o mesmo código acima, seria: # expr = LinExpr([1, 1, 2], [vertices['x'], # vertices['y'], # vertices['z']]) # Adding contraints # Add constraint: x + 2 y + 3 z <= 4 expr = LinExpr([1], [vertices['x']]) expr.add(vertices['y'], 2) expr.add(vertices['z'], 3) m.addConstr(expr, "<=", 4) # (outra maneira de passar o mesmo código acima, seria: #expr = LinExpr([1, 2, 3], [vertices['x'], # vertices['y'],