def qsap_ss(qsap, **kwargs): """ Sherali-Smith Linear Formulation for the quadratic semi-assignment problem """ n = qsap.n m = qsap.m e = qsap.e c = qsap.c #create model and add variables mdl = xp.problem(name='qsap_ss') x = np.array([[xp.var(vartype=xp.binary) for i in range(n)]for j in range(m)]) s = np.array([[xp.var(vartype=xp.continuous) for i in range(n)]for j in range(m)]) y = np.array([[xp.var(vartype=xp.continuous) for i in range(n)]for j in range(m)]) mdl.addVariable(x,s,y) mdl.addConstraint((sum(x[i,k] for k in range(n)) == 1) for i in range(m)) start = timer() U = np.zeros((m,n)) L = np.zeros((m,n)) bound_mdl = xp.problem(name='upper_bound_model') bound_mdl.setlogfile("xpress.log") bound_x = np.array([xp.var(vartype=xp.continuous, lb=0, ub=1) for i in range(m) for j in range(n)]).reshape(m,n) bound_mdl.addVariable(bound_x) bound_mdl.addConstraint((sum(bound_x[i,k] for k in range(n)) == 1) for i in range(m)) for i in range(m-1): for k in range(n): bound_mdl.setObjective(sum(sum(c[i,k,j,l]*bound_x[j,l] for l in range(n)) for j in range(i+1,m)), sense=xp.maximize) bound_mdl.solve() U[i,k] = bound_mdl.getObjVal() bound_mdl.setObjective(sum(sum(c[i,k,j,l]*bound_x[j,l] for l in range(n)) for j in range(i+1,m)), sense=xp.minimize) bound_mdl.solve() L[i,k] = bound_mdl.getObjVal() end = timer() setup_time = end-start #add auxiliary constraints for i in range(m-1): for k in range(n): mdl.addConstraint(sum(sum(c[i,k,j,l]*x[j,l] for j in range(i+1,m)) for l in range(n))-s[i,k]-L[i,k]==y[i,k]) mdl.addConstraint(y[i,k] <= (U[i,k]-L[i,k])*(1-x[i,k])) mdl.addConstraint(s[i,k] <= (U[i,k]-L[i,k])*x[i,k]) mdl.addConstraint(y[i,k] >= 0) mdl.addConstraint(s[i,k] >= 0) #set objective function linear_values = sum(sum(e[i,k]*x[i,k] for i in range(m)) for k in range(n)) mdl.setObjective(linear_values + sum(sum(s[i,k]+x[i,k]*(L[i,k]) for i in range(m-1)) for k in range(n)), sense=xp.maximize) #return model + setup time return [mdl, setup_time]
def bb(A, b): pb = xp.problem() x_lp = np.array([xp.var(vartype=xp.continuous) for _ in range(A.shape[1])]) pb.addVariable(x_lp) pb.addConstraint(xp.Dot(A, x_lp) <= b) pb.setObjective(xp.Dot(c, x_lp), sense=xp.maximize) lb_node = Node(xp.problem(), -1) root_node = Node(pb) is_integer, is_infeasible = root_node.solve() show_tree(root_node) if is_integer: return root_node.pb.getObjVal(), root_node.pb.getSolution() elif is_infeasible: return False, False l_node, r_node = root_node.make_sub_problems() active_nodes = [l_node, r_node] while True: show_tree(root_node) not_pruned_nodes = [] for node in active_nodes: is_integer, is_infeasible = node.solve() if is_integer: if node.objVal > lb_node.objVal: lb_node = node elif not is_infeasible and node.objVal > lb_node.objVal: not_pruned_nodes.append(node) else: node.is_pruned = True # # inp = input() if is_optimal(lb_node, not_pruned_nodes): lb_node.is_optimal = True show_tree(root_node) return lb_node.pb.getObjVal(), lb_node.pb.getSolution() active_nodes = [] for node in not_pruned_nodes: l_node, r_node = node.make_sub_problems() active_nodes.append(l_node) active_nodes.append(r_node)
def __init__(self, df_init, costFun: Union[Callable, List[Callable]], alpha=1, model_name="istop"): self.preference_function = lambda x, y: x * (y**alpha) self.offers = None super().__init__(df_init=df_init, costFun=costFun, airline_ctor=air.IstopAirline) airline: air.IstopAirline for airline in self.airlines: airline.set_preferences(self.preference_function) self.airlines_pairs = np.array(list(combinations(self.airlines, 2))) self.epsilon = sys.float_info.min self.m = xp.problem() self.x = None self.c = None # self.m.threads = -1 # self.m.verbose = 0 self.matches = [] self.couples = [] self.flights_in_matches = []
def no_linearization(quad, **kwargs): """ Solve a problem using the solver's default approach to quadratics (for cplex, this is the std linearization) """ start = timer() n = quad.n c = quad.c m = xp.problem(name='no_linearization') x = np.array([xp.var(vartype=xp.binary) for i in range(n)]) m.addVariable(x) if type(quad) is Knapsack: #HSP and UQP don't have cap constraint #add capacity constraint(s) for k in range(quad.m): m.addConstraint(xp.Sum(x[i]*quad.a[k][i] for i in range(n)) <= quad.b[k]) #k_item constraint if necessary (if KQKP or HSP) if quad.num_items > 0: m.addConstraint(xp.Sum(x[i] for i in range(n)) == quad.num_items) #compute quadratic values contirbution to obj quadratic_values = 0 for i in range(n): for j in range(i+1,n): quadratic_values = quadratic_values + (x[i]*x[j]*quad.C[i,j]) #set objective function linear_values = xp.Sum(x[i]*c[i] for i in range(n)) m.setObjective(linear_values + quadratic_values, sense=xp.maximize) end = timer() setup_time = end-start return [m, setup_time]
def subproblem(xhat): '''子问题求解 ''' # 初始化问题 r = xp.problem() # 定义变量 y = [xp.var() for i in range(n2)] z = [xp.var(lb=-xp.infinity) for i in range(n1)] epsilon = xp.var(lb=-xp.infinity) r.addVariable(y, z, epsilon) # 定义约束 dummy1 = [z[i] == xhat[i] for i in range(n1)] dummy2 = epsilon == 1 constr=[xp.Sum(A1[ii][jj]*z[jj] for jj in range(n1)) + \ xp.Sum(A2[ii][jj]*y[jj] for jj in range(n2)) \ - epsilon*b[ii]<=0 for ii in range(m)] r.addConstraint(constr, dummy1, dummy2) # 定义目标函数 r.setObjective(xp.Sum(c2[jj] * y[jj] for jj in range(n2)), sense=xp.minimize) r.setControl({"presolve": 0}) # 解该问题 r.setControl('outputlog', 0) r.solve() # 寻找切片 xind1 = [r.getIndex(dummy1[ii]) for ii in range(n1)] # 根据自问题的解的情况判断下一步 if r.getProbStatus() == xp.lp_optimal: # 获得了最优解 print("Optimal Subproblem") dualmult = r.getDual() lamb = [dualmult[ii] for ii in xind1] beta = r.getObjVal() return (lamb, beta, 'Optimal') elif r.getProbStatus() == xp.lp_infeas: # 子问题不可行 print("Infeasible Subproblem") if not r.hasdualray(): print("Could not retrieve a dual ray, return no good cut instead:") xhatones = set(ii for ii in range(n1) if xhat[ii] >= 0.5) lamb = [2 * xhat[ii] - 1 for ii in range(n1)] beta = -sum(xhat) + 1 else: # 求解对偶 dray = [] r.getdualray(dray) print("Dual Ray:", dray) lamb = [dray[ii] for ii in xind1] beta = dray[r.getIndex(dummy2)] return (lamb, beta, 'Infeasible') else: print("ERROR: Subproblem not optimal or infeasible. Terminating.") sys.exit()
def run(self, num_iterations, df=None, training_start_iteration=100, train_t=200): xp_problem = xp.problem() for i in range(training_start_iteration): print(i) instance = instanceMaker.Instance(triples=False, df=df, xp_problem=xp_problem) schedule = instance.get_schedule_tensor() self.episode(schedule, instance, eps=1) print('Finished initial exploration') s = 10_000 for i in range(training_start_iteration, num_iterations): instance = instanceMaker.Instance(triples=False, df=df, xp_problem=xp_problem) schedule = instance.get_schedule_tensor() self.eps = self.epsFun(i, num_iterations) self.episode(schedule, instance, self.eps) print("{0} {1:2f} {2:2f}".format(i, self.hyperAgent.network.loss, self.eps)) if i % train_t == 0: print("\n TEST") self.test_episode(schedule, instance, self.eps) print(instance.matches) instance.print_performance()
def bb(A, b): lb_node = Node(xp.problem()) root_node = Node(pb) is_integer, is_infeasible = root_node.solve() if is_integer: return root_node.pb.getObjVal(), root_node.pb.getSolution() elif is_infeasible: return False, False l_node, r_node = root_node.make_sub_problems() active_nodes = [l_node, r_node] while True: not_pruned_nodes = [] for node in active_nodes: is_integer, is_infeasible = node.solve() if is_integer: if node.objVal > lb_node.objVal: lb_node = node elif not is_infeasible: not_pruned_nodes.append(node) if is_optimal(lb_node, not_pruned_nodes): return lb_node.pb.getObjVal(), lb_node.pb.getSolution() active_nodes = [] for node in not_pruned_nodes: l_node, r_node = node.make_sub_problems() active_nodes.append(l_node) active_nodes.append(r_node)
def __init__(self, input_data, input_params): self.input_data = input_data self.input_params = input_params self.model = xp.problem('prod_planning') self._create_decision_variables() self._create_main_constraints() self._set_objective_function()
def __init__(self, num_flights=50, num_airlines=5, triples=True, reduction_factor=100, discretisation_size=50, custom_schedule=None, df=None, xp_problem=None): scheduleTypes = scheduleMaker.schedule_types(show=False) # init variables, schedule and cost function if custom_schedule is None and df is None: schedule_df = scheduleMaker.df_maker(num_flights, num_airlines, distribution=scheduleTypes[0]) else: if df is None: schedule_df = scheduleMaker.df_maker(custom=custom_schedule) else: schedule_df = df self.reductionFactor = reduction_factor self.costFun = CostFuns().costFun["realistic"] self.flightTypeDict = CostFuns().flightTypeDict self.discretisationSize = discretisation_size if xp_problem is None: self.xp_problem = xp.problem() else: self.xp_problem = xp_problem with HiddenPrints(): self.xp_problem.reset() # internal optimisation step udpp_model_xp = udppModel.UDPPmodel(schedule_df, self.costFun, self.xp_problem) udpp_model_xp.run() with HiddenPrints(): self.xp_problem.reset() super().__init__(udpp_model_xp.get_new_df(), self.costFun, triples=triples, xp_problem=self.xp_problem) flights = [flight for flight in self.flights] for flight in self.flights: flights[flight.slot.index] = flight self.flights = flights self.set_flights_input_net(self.discretisationSize) self.offerChecker = checkOffer.OfferChecker(self.scheduleMatrix) _, self.matches_vect = self.offerChecker.all_couples_check( self.airlines_pairs) self.reverseAirDict = dict( zip(list(self.airDict.keys()), list(self.airDict.values())))
def __init__(self, number_of_time_steps=24): # Create a new model self.model = xp.problem() # optimization horizon: self.time_steps = range(0, number_of_time_steps) self.time_steps_with_tomorrow = range(0, number_of_time_steps+1) self.buildings = {} self.batteries = {} self.generators = {}
def create(self): """ Returns a new empty optimisation problem. Returns ------- problem : xpress.problem """ return xp.problem()
def _set_instance(self, model, kwds={}): self._range_constraints = set() DirectOrPersistentSolver._set_instance(self, model, kwds) self._pyomo_con_to_solver_con_map = dict() self._solver_con_to_pyomo_con_map = ComponentMap() self._pyomo_var_to_solver_var_map = ComponentMap() self._solver_var_to_pyomo_var_map = ComponentMap() try: if model.name is not None: self._solver_model = xpress.problem(name=model.name) else: self._solver_model = xpress.problem() except Exception: e = sys.exc_info()[1] msg = ("Unable to create Xpress model. " "Have you installed the Python " "bindings for Xpress?\n\n\t" + "Error message: {0}".format(e)) raise Exception(msg) self._add_block(model)
def standard_linearization(quad, lhs_constraints=True, **kwargs): """ Apply the standard linearization to a QP and return resulting model param lhs_constraints: can choose to include optional lower bound constraints (or upper bound if mixed_sign) """ n = quad.n c = quad.c C = quad.C a = quad.a b = quad.b # create model and add variables m = xp.problem(name='standard_linearization') x = np.array([xp.var(vartype=xp.binary) for i in range(n)]) w = np.array([[xp.var(vartype=xp.continuous) for i in range(n)] for i in range(n)]) m.addVariable(x,w) if type(quad) is Knapsack: # HSP and UQP don't have cap constraint # add capacity constraint(s) for k in range(quad.m): m.addConstraint(xp.Sum(x[i]*a[k][i] for i in range(n)) <= b[k]) #k_item constraint if necessary (if KQKP or HSP) if quad.num_items > 0: m.addConstraint(xp.Sum(x[i] for i in range(n)) == quad.num_items) # add auxiliary constraints for i in range(n): for j in range(i+1, n): if lhs_constraints: if C[i,j]+C[j,i] > 0: m.addConstraint(w[i,j] <= x[i]) m.addConstraint(w[i,j] <= x[j]) else: m.addConstraint(x[i]+x[j]-1 <= w[i,j]) m.addConstraint(w[i,j] >= 0) else: m.addConstraint(w[i,j] <= x[i]) m.addConstraint(w[i,j] <= x[j]) m.addConstraint(x[i]+x[j]-1 <= w[i,j]) m.addConstraint(w[i,j] >= 0) #compute quadratic values contirbution to obj quadratic_values = 0 for i in range(n): for j in range(i+1, n): quadratic_values = quadratic_values + (w[i, j]*(C[i, j]+C[j, i])) # set objective function linear_values = sum(x[i]*c[i] for i in range(n)) m.setObjective(linear_values + quadratic_values, sense=xp.maximize) # return model + setup time return [m, 0]
def __init__(self, df_init: pd.DataFrame, costFun: Union[Callable, List[Callable]], model_name="Max Benefit"): self.airlineConstructor = air.Airline self.flightConstructor = modFl.Flight super().__init__(df_init=df_init, costFun=costFun) self.m = xp.problem() self.x = None
def __init__(self, accs, intervals): self.accs = accs self.accsNum = len(accs) self.intervals = intervals self.intNum = len(intervals) self.matches = np.array(list(combinations(self.accs, 2))) self.p = xp.problem() self.x = np.array([[[xp.var(vartype=xp.binary) for _ in intervals] for _ in accs] for _ in self.accs]) self.m = np.array([xp.var(vartype=xp.binary) for _ in self.matches]) self.p.addVariable(self.x, self.m)
def extended_linear_formulation(quad, **kwargs): """ Apply the extended linear formulation to a QP and return resulting model """ start = timer() n = quad.n c = quad.c C = quad.C a = quad.a b = quad.b #create model and add variables m = xp.problem(name='extended_linear_formulation') x = np.array([xp.var(vartype=xp.binary) for i in range(n)]) z = np.array([[[xp.var(vartype=xp.continuous, lb=-xp.infinity) for i in range(n)] for j in range(n)] for k in range(n)]) m.addVariable(x,z) if type(quad) is Knapsack: #HSP and UQP don't have cap constraint #add capacity constraint(s) for k in range(quad.m): m.addConstraint(xp.Sum(x[i]*a[k][i] for i in range(n)) <= b[k]) #k_item constraint if necessary (if KQKP or HSP) if quad.num_items > 0: m.addConstraint(xp.Sum(x[i] for i in range(n)) == quad.num_items) #add auxiliary constraints for i in range(n): for j in range(i+1,n): m.addConstraint(z[i,i,j]+z[j,i,j] <= 1) if C[i,j] < 0: m.addConstraint(x[i] + z[i,i,j] <= 1) m.addConstraint(x[j] + z[j,i,j] <= 1) elif C[i,j] > 0: m.addConstraint(x[i] + z[i,i,j] + z[j,i,j] >= 1) m.addConstraint(x[j] + z[i,i,j] + z[j,i,j] >= 1) #compute quadratic values contirbution to obj constant = 0 quadratic_values = 0 for i in range(n): for j in range(i+1,n): constant = constant + C[i,j] quadratic_values = quadratic_values + (C[i,j]*(z[i,i,j]+z[j,i,j])) #set objective function linear_values = xp.Sum(x[i]*c[i] for i in range(n)) m.setObjective(linear_values + constant - quadratic_values, sense=xp.maximize) end = timer() setup_time = end-start #return model + setup time return [m, setup_time]
def qsap_standard(qsap, **kwargs): """ standard linearization for the quadratic semi-assignment problem """ n = qsap.n m = qsap.m e = qsap.e c = qsap.c #create model and add variables mdl = xp.problem(name='qsap_standard_linearization') x = np.array([[xp.var(vartype=xp.binary) for i in range(n)]for j in range(m)]) w = np.array([[[[xp.var(vartype=xp.continuous) for i in range(n)]for j in range(m)] for k in range(n)]for l in range(m)]) mdl.addVariable(x,w) mdl.addConstraint((sum(x[i,k] for k in range(n)) == 1) for i in range(m)) #add auxiliary constraints for i in range(m-1): for k in range(n): for j in range(i+1,m): for l in range(n): if lhs_constraints: if c[i,k,j,l]+c[j,l,i,k] > 0: mdl.add_constraint(w[i,k,j,l] <= x[i,k]) mdl.add_constraint(w[i,k,j,l] <= x[j,l]) else: mdl.add_constraint(x[i,k] + x[j,l] - 1 <= w[i,k,j,l]) mdl.add_constraint(w[i,k,j,l] >= 0) else: mdl.add_constraint(w[i,k,j,l] <= x[i,k]) mdl.add_constraint(w[i,k,j,l] <= x[j,l]) mdl.add_constraint(x[i,k] + x[j,l] - 1 <= w[i,k,j,l]) mdl.add_constraint(w[i,k,j,l] >= 0) #compute quadratic values contirbution to obj quadratic_values = 0 for i in range(m-1): for j in range(i+1,m): for k in range(n): for l in range(n): quadratic_values = quadratic_values + (c[i,k,j,l]*(w[i,k,j,l])) linear_values = sum(x[i,k]*e[i,k] for k in range(n) for i in range(m)) mdl.setObjective(linear_values + quadratic_values, sense=xp.maximize) #return model. no setup time for std return [mdl, 0]
def prlt1_linearization(quad): # only called from within reformulate_glover (make inner func?) n = quad.n c = quad.c C = quad.C a = quad.a b = quad.b # create model and add variables m = xp.problem(name='PRLT-1_linearization') x = m.addVars(n, lb=0, ub=1, vtype=GRB.CONTINUOUS) w = m.addVars(n, n, vtype=GRB.CONTINUOUS) if type(quad) is Knapsack: # HSP and UQP don't have cap constraint # add capacity constraint(s) for k in range(quad.m): m.addConstraint(xp.Sum(x[i]*a[k][i] for i in range(n)) <= b[k]) #k_item constraint if necessary (if KQKP or HSP) if quad.num_items > 0: m.addConstraint(xp.Sum(x[i] for i in range(n)) == quad.num_items) # add auxiliary constraints for i in range(n): for j in range(i+1, n): m.addConstraint(w[i, j] == w[j, i], name='con16'+str(i)+str(j)) for k in range(quad.m): for j in range(n): m.addConstraint(xp.Sum(a[k][i]*w[i, j] for i in range(n) if i != j) <= (b[k]-a[k][j])*x[j]) for i in range(n): m.addConstraint(w[i, j] <= x[j]) # add objective function quadratic_values = 0 for j in range(n): for i in range(n): if(i == j): continue quadratic_values = quadratic_values + (C[i, j]*w[i, j]) m.setObjective(linear_values + quadratic_values, sense=xp.maximize) linear_values = xp.Sum(x[j]*c[j] for j in range(n)) # return model return m
def __init__(self, areas_list, periods): self._areasList = areas_list self._periods = periods self._matches = np.array(list(combinations(self._areasList, 2))) self.p = xp.problem() self.e = np.array([[xp.var(vartype=xp.integer) for _ in self._periods] for _ in areas_list]) self.y = np.array( [[[xp.var(vartype=xp.integer) for _ in self._periods] for _ in areas_list] for _ in areas_list]) self.m = np.array([xp.var(vartype=xp.binary) for _ in self._matches]) self.p.addVariable(self.e, self.y, self.m) self.flow = None self.solutionMatches = None
def __init__(self, df_init, costFun: Union[Callable, List[Callable]], alpha=1, triples=False, xp_problem=None): self.preference_function = lambda x, y: x * (y ** alpha) self.offers = None self.triples = triples self.xp_problem = xp_problem super().__init__(df_init=df_init, costFun=costFun, airline_ctor=air.IstopAirline) airline: air.IstopAirline for airline in self.airlines: airline.set_preferences(self.preference_function) self.airlines_pairs = np.array(list(combinations(self.airlines, 2))) self.airlines_triples = np.array(list(combinations(self.airlines, 3))) self.epsilon = sys.float_info.min self.offerChecker = OfferChecker(self.scheduleMatrix) if self.xp_problem is None: self.m = xp.problem() else: self.m = xp_problem # self.m.controls.presolve = 0 # self.m.controls.maxnode = 1 # self.m.mipoptimize('p') # # self.m.setControl('maxnode', 1) # self.m.setControl('cutstrategy', 0) # self.m.setControl('mippresolve', 0) # print(self.m.getControl('defaultalg')) # print(self.m.getControl('cutdepth')) # print("controllo ", self.m.controls.presolve) # # self.m.addcbnewnode(self.p, self.m, 1) self.x = None self.c = None self.matches = [] self.couples = [] self.flights_in_matches = [] self.offers_selected = [] self.preprocessed = False
def qsap_elf(qsap, **kwargs): """ extended linear formulation for the quadratic semi-assignment problem """ n = qsap.n m = qsap.m e = qsap.e c = qsap.c mdl = xp.problem(name='qsap_elf') x = np.array([[xp.var(vartype=xp.binary) for i in range(n)]for j in range(m)]) z = np.array([[[[[[xp.var(vartype=xp.continuous, lb=-xp.infinity) for i in range(n)] for j in range(m)] for k in range(n)] for l in range(m)] for r in range(n)] for s in range(m)]) mdl.addVariable(x, z) cons = [xp.constraint(sum(x[i,k] for k in range(n)) == 1) for i in range(m)] mdl.addConstraint(cons) #add auxiliary constraints for i in range(m-1): for j in range(i+1,m): for k in range(n): for l in range(n): mdl.addConstraint(z[i,k,i,k,j,l] + z[j,l,i,k,j,l] <= 1) mdl.addConstraint(x[i,k] + z[i,k,i,k,j,l] <= 1) mdl.addConstraint(x[j,l] + z[j,l,i,k,j,l] <= 1) mdl.addConstraint(x[i,k] + z[i,k,i,k,j,l] + z[j,l,i,k,j,l] >= 1) mdl.addConstraint(x[j,l] + z[i,k,i,k,j,l] + z[j,l,i,k,j,l] >= 1) #compute quadratic values contirbution to obj constant = 0 quadratic_values = 0 for i in range(m-1): for j in range(i+1,m): for k in range(n): for l in range(n): constant = constant + c[i,k,j,l] quadratic_values = quadratic_values + (c[i,k,j,l]*(z[i,k,i,k,j,l]+z[j,l,i,k,j,l])) linear_values = sum(x[i,k]*e[i,k] for k in range(n) for i in range(m)) mdl.setObjective(linear_values + constant - quadratic_values, sense=xp.maximize) #return model + setup time return [mdl, 0]
def UDPPlocalOpt(airline: air.UDPPairline, slots: List[sl.Slot], xp_problem=None): if xp_problem is None: m = xp.problem() else: m = xp_problem x = np.array([[xp.var(vartype=xp.binary) for j in slots] for i in airline.flights]) m.addVariable(x) flight: fl.UDPPflight for k in range(airline.numFlights): #one x max for slot m.addConstraint( xp.Sum(x[flight.localNum, k] for flight in airline.flights) == 1) for flight in airline.flights: # flight assignment m.addConstraint( xp.Sum(x[flight.localNum, k] for k in range(eta_limit_slot(flight, airline.AUslots), airline.numFlights)) == 1) m.setObjective( xp.Sum( x[flight.localNum][k] * flight.costFun(flight, airline.AUslots[k]) for flight in airline.flights for k in range(airline.numFlights))) m.solve() # print("airline ",airline) for flight in airline.flights: for k in range(airline.numFlights): if m.getSolution(x[flight.localNum, k]) > 0.5: flight.newSlot = airline.flights[k].slot flight.priorityNumber = k flight.priorityValue = "N"
def __init__(self, **params): """ The class implement the Support Vector Data Description method for novelty detection as in paper https://www.researchgate.net/publication/226109293_Support_Vector_Data_Description. The class make use of the solver FICO Express and it is composed by the following method: - solve: to model the svdd problem - select_support_vectors: method that randomply pick a point that can be considered as a good support vector candidate - outliers: returns the outliers of the dataset X - count_outliers: returns the number of outiers in X - kernel: define the kernel in the dual problem """ # DUAL PROBLEM self.p = xp.problem() self.C = params['C'] self.params = params #self.l = params['l'] self.opt = [] self.c0 = [] self.support_vectors = []
# every vertex i is at distance rho[i] from the center and at angle # theta[i]. We would certainly expect that the local optimum found has # all rho's are equal to 1. N = 9 Vertices = range(N) # Declare variables rho = [xp.var(name='rho_{}'.format(i), lb=1e-5, ub=1.0) for i in Vertices] theta = [ xp.var(name='theta_{}'.format(i), lb=-math.pi, ub=math.pi) for i in Vertices ] p = xp.problem() p.addVariable(rho, theta) # The objective function is the total area of the polygon. Considering # the segment S[i] joining the center to the i-th vertex and A(i,j) # the area of the triangle defined by the two segments S[i] and S[j], # the objective function is # # A[0,1] + A[1,2] + ... + A[N-1,0] # # Where A[i,i+1] is given by # # 1/2 * rho[i] * rho[i+1] * sin (theta[i+1] - theta[i]) p.setObjective(
def solve(self): ### Params ### self.n_plyrs_per_game = [ self.game_list[i][1] for i in range(len(self.game_list)) ] req_plyrs_per_round = sum([ct * 2 for ct in self.n_plyrs_per_game]) if self.trim_gms & (req_plyrs_per_round > self.n_plyrs): if self.debug: st.text("Removing games to fit the number of passed players") while req_plyrs_per_round > self.n_plyrs: self.game_list = self.game_list[:-1] self.n_plyrs_per_game = [ self.game_list[i][1] for i in range(len(self.game_list)) ] req_plyrs_per_round = sum( [ct * 2 for ct in self.n_plyrs_per_game]) print(req_plyrs_per_round, self.n_plyrs) # max number of times a player can play a given game self.max_gm_plays = max( 2, math.ceil(req_plyrs_per_round * self.n_rounds / self.n_plyrs)) st.text(f'Final game list: {self.game_list}') if not self.max_gm_plays_soft: st.text( f'Max times a player is allowed to play same game: {self.max_gm_plays}' ) self.n_games = len(self.game_list) ## Instantiate problem ## self.model = xp.problem() ################# ### Variables ### ################# # Player-game-round-team plyrs = {} for p in range(self.n_plyrs): plyrs[p] = {} for g in range(self.n_games): plyrs[p][g] = {} for r in range(self.n_rounds): plyr_var_list = [ xp.var(name=f"p{p}_g{g}_r{r}_t{t}", vartype=xp.binary) for t in range(self.n_tms) ] plyrs[p][g][r] = plyr_var_list self.model.addVariable(plyr_var_list) # Team assignments tms = {} for t in range(self.n_tms): tm_var_list = [ xp.var(name=f"p{p}_tm{t}", vartype=xp.binary) for p in range(self.n_plyrs) ] tms[t] = tm_var_list self.model.addVariable(tm_var_list) # Variable set greater_than/equal_to game_played count for all players for all games - this quantity is minimized max_gm_plays_global = xp.var(name='max_gm_plays_global', lb=0) self.model.addVariable(max_gm_plays_global) ################### ### Constraints ### ################### # Correct number of plyrs per game per team ## Why need both less/greater than and not equal to? for g in range(self.n_games): for r in range(self.n_rounds): for t in range(self.n_tms): suff_plyrs_tm_1 = xp.Sum(plyrs[p][g][r][t] for p in range( self.n_plyrs)) >= self.n_plyrs_per_game[g] suff_plyrs_tm_2 = xp.Sum(plyrs[p][g][r][t] for p in range( self.n_plyrs)) <= self.n_plyrs_per_game[g] self.model.addConstraint( xp.constraint(suff_plyrs_tm_1, name=f'gteq_plyrs_tm{t}_rnd{r}_gm{g}')) self.model.addConstraint( xp.constraint(suff_plyrs_tm_2, name=f'lteq_plyrs_tm{t}_rnd{r}_gm{g}')) # One game per time per player for p in range(self.n_plyrs): for r in range(self.n_rounds): for t in range(self.n_tms): one_game_per_round_per_plyr = xp.Sum( plyrs[p][g][r][t] for g in range(self.n_games)) <= 1 self.model.addConstraint( xp.constraint( one_game_per_round_per_plyr, name=f"one_gm_in_rnd{r}_for_plyr{p}_tm{t}")) # Team assignment constraints for p in range(self.n_plyrs): # One team per player tm_lb = xp.Sum(tms[t][p] for t in range(self.n_tms)) <= 1 tm_ub = xp.Sum(tms[t][p] for t in range(self.n_tms)) >= 1 self.model.addConstraint( xp.constraint(tm_lb, name=f'plyr{p}_lteq_1_tm')) self.model.addConstraint( xp.constraint(tm_ub, name=f'plyr{p}_gteq_1_tm')) for t in range(self.n_tms): # Forcing tm variables to be flipped when player selected tm_enforce = xp.Sum( plyrs[p][g][r][t] for g in range(self.n_games) for r in range(self.n_rounds)) <= tms[t][p] * self.n_rounds self.model.addConstraint( xp.constraint(tm_enforce, name=f'plyr{p}_tm{t}_enforce')) # Teams evenly split tms_even_1 = xp.Sum(tms[0][p] for p in range(self.n_plyrs)) - xp.Sum( tms[1][p] for p in range(self.n_plyrs)) <= 1 tms_even_2 = xp.Sum(tms[1][p] for p in range(self.n_plyrs)) - xp.Sum( tms[0][p] for p in range(self.n_plyrs)) <= 1 self.model.addConstraint(tms_even_1) self.model.addConstraint(tms_even_2) # Each player plays each game at most 'self.max_gm_plays' for p in range(self.n_plyrs): for g in range(self.n_games): for t in range(self.n_tms): max_rds_per_game_per_plyr = xp.Sum( plyrs[p][g][r][t] for r in range(self.n_rounds)) if not self.max_gm_plays_soft: self.model.addConstraint( xp.constraint( max_rds_per_game_per_plyr <= self.max_gm_plays, name= f"plyr{p}_plays_gm{g}_max_{self.max_gm_plays}_times_tm{t}" )) self.model.addConstraint( xp.constraint( max_gm_plays_global >= max_rds_per_game_per_plyr, name=f'max_gm_plays_global_gteq_p{p}_g{g}_t{t}')) # Each player plays at most once more than every other player for p1 in range(self.n_plyrs): n_plays = xp.Sum(plyrs[p1][g][r][t] for g in range(self.n_games) for r in range(self.n_rounds) for t in range(self.n_tms)) for p2 in range(p1 + 1, self.n_plyrs): n_plays_ = xp.Sum(plyrs[p2][g][r][t] for g in range(self.n_games) for r in range(self.n_rounds) for t in range(self.n_tms)) self.model.addConstraint( (n_plays - n_plays_) <= self.max_gm_gap) self.model.addConstraint( (n_plays_ - n_plays) <= self.max_gm_gap) # Objective self.model.setObjective(max_gm_plays_global, sense=xp.minimize) self.model.solve() self.check_model_feasibility() return plyrs, tms
def build_problem(): """ Build an xpress problem instance """ return xp.problem()
def solve(self, objective, constraints, cached_data, warm_start, verbose, solver_opts): """Returns the result of the call to the solver. Parameters ---------- objective : LinOp The canonicalized objective. constraints : list The list of canonicalized cosntraints. cached_data : dict A map of solver name to cached problem data. warm_start : bool Should the previous solver result be used to warm_start? verbose : bool Should the solver print output? solver_opts : dict Additional arguments for the solver. Returns ------- tuple (status, optimal value, primal, equality dual, inequality dual) """ import xpress verbose = True # Get problem data data = super(XPRESS, self).get_problem_data(objective, constraints, cached_data) origprob = None if 'original_problem' in solver_opts.keys(): origprob = solver_opts['original_problem'] if 'no_qp_reduction' in solver_opts.keys() and solver_opts['no_qp_reduction'] is True: self.translate_back_QP_ = True c = data[s.C] # objective coefficients dims = data[s.DIMS] # contains number of columns, rows, etc. nrowsEQ = dims[s.EQ_DIM] nrowsLEQ = dims[s.LEQ_DIM] nrows = nrowsEQ + nrowsLEQ # linear constraints b = data[s.B][:nrows] # right-hand side A = data[s.A][:nrows] # coefficient matrix n = c.shape[0] # number of variables solver_cache = cached_data[self.name()] ########################################################################################### # Allow warm start if all dimensions match, i.e., if the # modified problem has the same number of rows/column and the # same list of cone sizes. Failing that, we can just take the # standard route and build the problem from scratch. if warm_start and \ solver_cache.prev_result is not None and \ n == len(solver_cache.prev_result['obj']) and \ nrows == len(solver_cache.prev_result['rhs']) and \ data[s.DIMS][s.SOC_DIM] == solver_cache.prev_result['cone_ind']: # We are re-solving a problem that was previously solved # Initialize the problem as the same as the previous solve self.prob_ = solver_cache.prev_result['problem'] c0 = solver_cache.prev_result['obj'] A0 = solver_cache.prev_result['mat'] b0 = solver_cache.prev_result['rhs'] vartype0 = solver_cache.prev_result['vartype'] # If there is a parameter in the objective, it may have changed. if len(linutils.get_expr_params(objective)) > 0: dci = numpy.where(c != c0)[0] self.prob_.chgobj(dci, c[dci]) # Get equality and inequality constraints. sym_data = self.get_sym_data(objective, constraints, cached_data) all_constrs, _, _ = self.split_constr(sym_data.constr_map) # If there is a parameter in the constraints, # A or b may have changed. if any(len(linutils.get_expr_params(con.expr)) > 0 for con in constraints): dAi = (A != A0).tocoo() # retrieves row/col nonzeros as a tuple of two arrays dbi = numpy.where(b != b0)[0] if dAi.getnnz() > 0: self.prob_.chgmcoef(dAi.row, dAi.col, [A[i, j] for (i, j) in list(zip(dAi.row, dAi.col))]) if len(dbi) > 0: self.prob_.chgrhs(dbi, b[dbi]) vartype = [] self.prob_.getcoltype(vartype, 0, len(data[s.C]) - 1) vti = (numpy.array(vartype) != numpy.array(vartype0)) if any(vti): self.prob_.chgcoltype(numpy.arange(len(c))[vti], vartype[vti]) ############################################################################################ else: # No warm start, create problem from scratch # Problem self.prob_ = xpress.problem() mstart = makeMstart(A, len(c), 1) varGroups = {} # If origprob is passed, used to tie IIS to original constraints transf2Orig = {} # Ties transformation constraints to originals via varGroups nOrigVar = len(c) # From a summary knowledge of origprob.constraints() and # the constraints list, the following seems to hold: # # 1) origprob.constraints is the list as generated by the # user. origprob.constraints[i].size returns the number # of actual rows in each constraint, while .constr_id # returns its id (not necessarily numbered from 0). # # 2) constraints is also a list whose every element # contains fields size and constr_id. These correspond # to the items in origprob.constraints, though the list # is in not in order of constr_id. Also, given that it # refers to the transformed problem, it contains extra # constraints deriving from the cone transformations, # all with a constr_id and a size. # # Given this information, attempt to set names in varnames # and linRownames so that they can be easily identified # Load linear part of the problem. if origprob is not None: # The original problem was passed, we can take a # better guess at the constraints and variable names. nOrigVar = 0 orig_id = [i.id for i in origprob.constraints] varnames = [] for v in origprob.variables(): nOrigVar += v.size[0] if v.size[0] == 1: varnames.append('{0}'. format(v.var_id)) else: varnames.extend(['{0}_{1:d}'. format(v.var_id, j) for j in range(v.size[0])]) varnames.extend(['aux_{0:d}'.format(i) for i in range(len(varnames), len(c))]) # Construct constraint name list by checking constr_id for each linRownames = [] for con in constraints: if con.constr_id in orig_id: prefix = '' if type(con.constr_id) == int: prefix = 'row_' if con.size[0] == 1: name = '{0}{1}'.format(prefix, con.constr_id) linRownames.append(name) transf2Orig[name] = con.constr_id else: names = ['{0}{1}_{2:d}'.format(prefix, con.constr_id, j) for j in range(con.size[0])] linRownames.extend(names) for i in names: transf2Orig[i] = con.constr_id # Tie auxiliary variables to constraints. Scan all # auxiliary variables in the objective function and in # the corresponding columns of A.indices iObjQuad = 0 # keeps track of quadratic quantities in the objective for i in range(nOrigVar, len(c)): if c[i] != 0: varGroups[varnames[i]] = 'objF_{0}'.format(iObjQuad) iObjQuad += 1 if len(A.indices[mstart[i]:mstart[i+1]]) > 0: varGroups[varnames[i]] = linRownames[min(A.indices[mstart[i]:mstart[i+1]])] else: # fall back to flat naming. Warning: this mixes # original with auxiliary variables. varnames = ['x_{0:05d}'. format(i) for i in range(len(c))] linRownames = ['lc_{0:05d}'.format(i) for i in range(len(b))] self.prob_.loadproblem("CVXproblem", ['E'] * nrowsEQ + ['L'] * nrowsLEQ, # qrtypes b, # rhs None, # range c, # obj coeff mstart, # mstart None, # mnel A.indices, # row indices A.data, # coefficients [-xpress.infinity] * len(c), # lower bound [xpress.infinity] * len(c), # upper bound colnames=varnames, # column names rownames=linRownames) # row names x = numpy.array(self.prob_.getVariable()) # get whole variable vector # Set variable types for discrete variables self.prob_.chgcoltype(data[s.BOOL_IDX] + data[s.INT_IDX], 'B' * len(data[s.BOOL_IDX]) + 'I' * len(data[s.INT_IDX])) currow = nrows iCone = 0 auxVars = set(range(nOrigVar, len(c))) # Conic constraints # # Quadratic objective and constraints fall in this category, # as all quadratic stuff is converted into a cone via a linear transformation for k in dims[s.SOC_DIM]: # k is the size of the i-th cone, where i is the index # within dims [s.SOC_DIM]. The cone variables in # CVXOPT, apparently, are separate variables that are # marked as conic but not shown in a cone explicitly. A = data[s.A][currow: currow + k].tocsr() b = data[s.B][currow: currow + k] currow += k if self.translate_back_QP_: # Conic problem passed by CVXPY is translated back # into a QP problem. The problem is passed to us # as follows: # # min c'x # s.t. Ax <>= b # y[i] = P[i]' * x + b[i] # ||y[i][1:]||_2 <= y[i][0] # # where P[i] is a matrix, b[i] is a vector. Get # rid of the y variables by explicitly rewriting # the conic constraint as quadratic: # # y[i][1:]' * y[i][1:] <= y[i][0]^2 # # and hence # # (P[i][1:]' * x + b[i][1:])^2 <= (P[i][0]' * x + b[i][0])^2 Plhs = A[1:] Prhs = A[0] indRowL, indColL = Plhs.nonzero() indRowR, indColR = Prhs.nonzero() coeL = Plhs.data coeR = Prhs.data lhs = list(b[1:]) rhs = b[0] for i in range(len(coeL)): lhs[indRowL[i]] -= coeL[i] * x[indColL[i]] for i in range(len(coeR)): rhs -= coeR[i] * x[indColR[i]] self.prob_.addConstraint(xpress.Sum([lhs[i]**2 for i in range(len(lhs))]) <= rhs**2) else: # Create new (cone) variables and add them to the problem conevar = numpy.array([xpress.var(name='cX{0:d}_{1:d}'.format(iCone, i), lb=-xpress.infinity if i > 0 else 0) for i in range(k)]) self.prob_.addVariable(conevar) initrow = self.prob_.attributes.rows mstart = makeMstart(A, k, 0) trNames = ['linT_qc{0:d}_{1:d}'.format(iCone, i) for i in range(k)] # Linear transformation for cone variables <--> original variables self.prob_.addrows(['E'] * k, # qrtypes b, # rhs mstart, # mstart A.indices, # ind A.data, # dmatval names=trNames) # row names self.prob_.chgmcoef([initrow + i for i in range(k)], conevar, [1] * k) conename = 'cone_qc{0:d}'.format(iCone) # Real cone on the cone variables (if k == 1 there's no # need for this constraint as y**2 >= 0 is redundant) if k > 1: self.prob_.addConstraint( xpress.constraint(constraint=xpress.Sum (conevar[i]**2 for i in range(1, k)) <= conevar[0] ** 2, name=conename)) auxInd = list(set(A.indices) & auxVars) if len(auxInd) > 0: group = varGroups[varnames[auxInd[0]]] for i in trNames: transf2Orig[i] = group transf2Orig[conename] = group iCone += 1 # Objective. Minimize is by default both here and in CVXOPT self.prob_.setObjective(xpress.Sum(c[i] * x[i] for i in range(len(c)))) # End of the conditional (warm-start vs. no warm-start) code, # set options, solve, and report. # Set options # # The parameter solver_opts is a dictionary that contains only # one key, 'solver_opt', and its value is a dictionary # {'control': value}, matching perfectly the format used by # the Xpress Python interface. if verbose: self.prob_.controls.miplog = 2 self.prob_.controls.lplog = 1 self.prob_.controls.outputlog = 1 else: self.prob_.controls.miplog = 0 self.prob_.controls.lplog = 0 self.prob_.controls.outputlog = 0 if 'solver_opts' in solver_opts.keys(): self.prob_.setControl(solver_opts['solver_opts']) self.prob_.setControl({i: solver_opts[i] for i in solver_opts.keys() if i in xpress.controls.__dict__.keys()}) # Solve self.prob_.solve() results_dict = { 'problem': self.prob_, 'status': self.prob_.getProbStatus(), 'obj_value': self.prob_.getObjVal(), } status_map_lp, status_map_mip = self.get_status_maps() if self.is_mip(data): status = status_map_mip[results_dict['status']] else: status = status_map_lp[results_dict['status']] results_dict[s.XPRESS_TROW] = transf2Orig results_dict[s.XPRESS_IIS] = None # Return no IIS if problem is feasible if status in s.SOLUTION_PRESENT: results_dict['x'] = self.prob_.getSolution() if not self.is_mip(data): results_dict['y'] = self.prob_.getDual() elif status == s.INFEASIBLE: # Retrieve all IIS. For LPs there can be more than one, # but for QCQPs there is only support for one IIS. iisIndex = 0 self.prob_.iisfirst(0) # compute all IIS row, col, rtype, btype, duals, rdcs, isrows, icols = [], [], [], [], [], [], [], [] self.prob_.getiisdata(0, row, col, rtype, btype, duals, rdcs, isrows, icols) origrow = [] for iRow in row: if iRow.name in transf2Orig.keys(): name = transf2Orig[iRow.name] else: name = iRow.name if name not in origrow: origrow.append(name) results_dict[s.XPRESS_IIS] = [{'orig_row': origrow, 'row': row, 'col': col, 'rtype': rtype, 'btype': btype, 'duals': duals, 'redcost': rdcs, 'isolrow': isrows, 'isolcol': icols}] while self.prob_.iisnext() == 0: iisIndex += 1 self.prob_.getiisdata(iisIndex, row, col, rtype, btype, duals, rdcs, isrows, icols) results_dict[s.XPRESS_IIS].append(( row, col, rtype, btype, duals, rdcs, isrows, icols)) return self.format_results(results_dict, data, cached_data)
def solve_via_data(self, data, warm_start, verbose, solver_opts, solver_cache=None): import xpress if 'no_qp_reduction' in solver_opts.keys( ) and solver_opts['no_qp_reduction'] is True: self.translate_back_QP_ = True c = data[s.C] # objective coefficients dims = dims_to_solver_dict( data[s.DIMS]) # contains number of columns, rows, etc. nrowsEQ = dims[s.EQ_DIM] nrowsLEQ = dims[s.LEQ_DIM] nrows = nrowsEQ + nrowsLEQ # linear constraints b = data[s.B][:nrows] # right-hand side A = data[s.A][:nrows] # coefficient matrix # Problem self.prob_ = xpress.problem() mstart = makeMstart(A, len(c), 1) varGroups = { } # If origprob is passed, used to tie IIS to original constraints transf2Orig = { } # Ties transformation constraints to originals via varGroups nOrigVar = len(c) # Uses flat naming. Warning: this mixes # original with auxiliary variables. varnames = ['x_{0:05d}'.format(i) for i in range(len(c))] linRownames = ['lc_{0:05d}'.format(i) for i in range(len(b))] self.prob_.loadproblem( "CVXproblem", ['E'] * nrowsEQ + ['L'] * nrowsLEQ, # qrtypes None, # range c, # obj coeff mstart, # mstart None, # mnel A.indices, # row indices A.data, # coefficients [-xpress.infinity] * len(c), # lower bound [xpress.infinity] * len(c), # upper bound colnames=varnames, # column names rownames=linRownames) # row names x = np.array(self.prob_.getVariable()) # get whole variable vector # Set variable types for discrete variables self.prob_.chgcoltype( data[s.BOOL_IDX] + data[s.INT_IDX], 'B' * len(data[s.BOOL_IDX]) + 'I' * len(data[s.INT_IDX])) currow = nrows iCone = 0 auxVars = set(range(nOrigVar, len(c))) # Conic constraints # # Quadratic objective and constraints fall in this category, # as all quadratic stuff is converted into a cone via a linear transformation for k in dims[s.SOC_DIM]: # k is the size of the i-th cone, where i is the index # within dims [s.SOC_DIM]. The cone variables in # CVXOPT, apparently, are separate variables that are # marked as conic but not shown in a cone explicitly. A = data[s.A][currow:currow + k].tocsr() b = data[s.B][currow:currow + k] currow += k if self.translate_back_QP_: # Conic problem passed by CVXPY is translated back # into a QP problem. The problem is passed to us # as follows: # # min c'x # s.t. Ax <>= b # y[i] = P[i]' * x + b[i] # ||y[i][1:]||_2 <= y[i][0] # # where P[i] is a matrix, b[i] is a vector. Get # rid of the y variables by explicitly rewriting # the conic constraint as quadratic: # # y[i][1:]' * y[i][1:] <= y[i][0]^2 # # and hence # # (P[i][1:]' * x + b[i][1:])^2 <= (P[i][0]' * x + b[i][0])^2 Plhs = A[1:] Prhs = A[0] indRowL, indColL = Plhs.nonzero() indRowR, indColR = Prhs.nonzero() coeL = Plhs.data coeR = Prhs.data lhs = list(b[1:]) rhs = b[0] for i in range(len(coeL)): lhs[indRowL[i]] -= coeL[i] * x[indColL[i]] for i in range(len(coeR)): rhs -= coeR[i] * x[indColR[i]] self.prob_.addConstraint( xpress.Sum([lhs[i]**2 for i in range(len(lhs))]) <= rhs**2) else: # Create new (cone) variables and add them to the problem conevar = np.array([ xpress.var(name='cX{0:d}_{1:d}'.format(iCone, i), lb=-xpress.infinity if i > 0 else 0) for i in range(k) ]) self.prob_.addVariable(conevar) initrow = self.prob_.attributes.rows mstart = makeMstart(A, k, 0) trNames = [ 'linT_qc{0:d}_{1:d}'.format(iCone, i) for i in range(k) ] # Linear transformation for cone variables <--> original variables self.prob_.addrows( ['E'] * k, # qrtypes b, # rhs mstart, # mstart A.indices, # ind A.data, # dmatval names=trNames) # row names self.prob_.chgmcoef([initrow + i for i in range(k)], conevar, [1] * k) conename = 'cone_qc{0:d}'.format(iCone) # Real cone on the cone variables (if k == 1 there's no # need for this constraint as y**2 >= 0 is redundant) if k > 1: self.prob_.addConstraint( xpress.constraint(constraint=xpress.Sum( conevar[i]**2 for i in range(1, k)) <= conevar[0]**2, name=conename)) auxInd = list(set(A.indices) & auxVars) if len(auxInd) > 0: group = varGroups[varnames[auxInd[0]]] for i in trNames: transf2Orig[i] = group transf2Orig[conename] = group iCone += 1 # Objective. Minimize is by default both here and in CVXOPT self.prob_.setObjective(xpress.Sum(c[i] * x[i] for i in range(len(c)))) # End of the conditional (warm-start vs. no warm-start) code, # set options, solve, and report. # Set options # # The parameter solver_opts is a dictionary that contains only # one key, 'solver_opt', and its value is a dictionary # {'control': value}, matching perfectly the format used by # the Xpress Python interface. if verbose: self.prob_.controls.miplog = 2 self.prob_.controls.lplog = 1 self.prob_.controls.outputlog = 1 else: self.prob_.controls.miplog = 0 self.prob_.controls.lplog = 0 self.prob_.controls.outputlog = 0 if 'solver_opts' in solver_opts.keys(): self.prob_.setControl(solver_opts['solver_opts']) self.prob_.setControl({ i: solver_opts[i] for i in solver_opts.keys() if i in xpress.controls.__dict__.keys() }) # Solve self.prob_.solve() results_dict = { 'problem': self.prob_, 'status': self.prob_.getProbStatus(), 'obj_value': self.prob_.getObjVal(), } status_map_lp, status_map_mip = self.get_status_maps() if self.is_mip(data): status = status_map_mip[results_dict['status']] else: status = status_map_lp[results_dict['status']] results_dict[s.XPRESS_TROW] = transf2Orig results_dict[ s.XPRESS_IIS] = None # Return no IIS if problem is feasible if status in s.SOLUTION_PRESENT: results_dict['x'] = self.prob_.getSolution() if not (data[s.BOOL_IDX] or data[s.INT_IDX]): results_dict['y'] = self.prob_.getDual() elif status == s.INFEASIBLE: # Retrieve all IIS. For LPs there can be more than one, # but for QCQPs there is only support for one IIS. iisIndex = 0 self.prob_.iisfirst(0) # compute all IIS row, col, rtype, btype, duals, rdcs, isrows, icols = [], [], [], [], [], [], [], [] self.prob_.getiisdata(0, row, col, rtype, btype, duals, rdcs, isrows, icols) origrow = [] for iRow in row: if iRow.name in transf2Orig.keys(): name = transf2Orig[iRow.name] else: name = iRow.name if name not in origrow: origrow.append(name) results_dict[s.XPRESS_IIS] = [{ 'orig_row': origrow, 'row': row, 'col': col, 'rtype': rtype, 'btype': btype, 'duals': duals, 'redcost': rdcs, 'isolrow': isrows, 'isolcol': icols }] while self.prob_.iisnext() == 0: iisIndex += 1 self.prob_.getiisdata(iisIndex, row, col, rtype, btype, duals, rdcs, isrows, icols) results_dict[s.XPRESS_IIS].append( (row, col, rtype, btype, duals, rdcs, isrows, icols)) # Generate solution. solution = {} if results_dict["status"] != s.SOLVER_ERROR: self.prob_ = results_dict['problem'] vartypes = [] self.prob_.getcoltype(vartypes, 0, len(data[s.C]) - 1) status_map_lp, status_map_mip = self.get_status_maps() if data[s.BOOL_IDX] or data[s.INT_IDX]: solution[s.STATUS] = status_map_mip[results_dict['status']] else: solution[s.STATUS] = status_map_lp[results_dict['status']] if solution[s.STATUS] in s.SOLUTION_PRESENT: solution[s.PRIMAL] = results_dict['x'] solution[s.VALUE] = results_dict['obj_value'] if not (data[s.BOOL_IDX] or data[s.INT_IDX]): solution[s.EQ_DUAL] = [-v for v in results_dict['y']] solution[s.XPRESS_IIS] = results_dict[s.XPRESS_IIS] solution[s.XPRESS_TROW] = results_dict[s.XPRESS_TROW] return solution
def max_flow(): global graph global vertices_no global vertices global weight thres = 0.4 # density of network thresdem = 0.8 # density of demand mesh dem = [] for i in range(vertices_no): for j in range(vertices_no): if i != j and np.random.random() < thresdem: dem.append((vertices[i], vertices[j], math.ceil(200 * np.random.random()))) print("This is a random demand for each node", dem) for i in range(vertices_no): for j in range(vertices_no): if graph[i][j] != 0: pair = vertices[i], vertices[j] print(pair) #*********************************************************************************************************************** #flow variables f = {(i, j, d): xp.var(name='f_{0}_{1}_{2}_{3}'.format(i, j, dem[d][0], dem[d][1])) for (i, j) in pair for d in range(len(dem))} # capacity variables x = {(i, j): xp.var(vartype=xp.integer, name='cap_{0}_{1}'.format(i, j)) for (i, j) in pair} print("this is x", x) p = xp.problem('network flow') p.addVariable(f, x) def demand(i, d): if dem[d][0] == i: # source return 1 elif dem[d][1] == i: # destination return -1 else: return 0 # Flow conservation constraints: total flow balance at node i for each demand d # must be 0 if i is an intermediate node, 1 if i is the source of demand d, and # -1 if i is the destination. flow = {(i, d): xp.constraint( constraint=xp.Sum(f[vertices[i], vertices[j], d] for j in range(vertices_no) if (vertices[i], vertices[j]) in weight) - xp.Sum(f[vertices[j], vertices[i], d] for j in range(vertices_no) if (vertices[j], vertices[i]) in weight) == demand( vertices[i], d), name='cons_{0}_{1}_{2}'.format(i, dem[d][0], dem[d][1])) for d in range(len(dem)) for i in range(vertices_no)} # Capacity constraints: weighted sum of flow variables must be contained in the # total capacity installed on the arc (i, j) capacity = { (i, j): xp.constraint(constraint=xp.Sum( dem[d][2] * f[vertices[i], vertices[j], d] for d in range(len(dem))) <= x[vertices[i], vertices[j]], name='capacity_{0}_{1}'.format(vertices[i], vertices[j])) for (i, j) in weight } p.addConstraint(flow, capacity) p.setObjective(xp.Sum(x[i, j] for (i, j) in weight)) p.solve() p.getSolution()
def __init__(self): self.model = xp.problem("Doctor scheduling")
CV = np.array([5, 30, 120]) CR = np.array([10, 10, 10]) D = np.array([30, 60, 120]) RAMPMAX = np.array([100, 100, 100]) A = np.ones((NGen, NSce)) B = np.ones((NLin, NSce)) for i in numGen: A[i, i + 1] = 0 for i in range(NLin): B[i, NGen + i + 1] = 0 #Define problem model = xp.problem() #Variables p = np.array([[xp.var(lb=0, vartype=xp.continuous) for s in numSce] for g in numGen]) x = np.array([xp.var(vartype=xp.binary) for g in numGen]) f = np.array([[xp.var(lb=-xp.infinity, vartype=xp.continuous) for s in numSce] for l in numLin]) theta = np.array( [[xp.var(lb=-xp.infinity, vartype=xp.continuous) for s in numSce] for n in numBar]) rup = np.array([xp.var(lb=0, vartype=xp.continuous) for g in numGen]) rdown = np.array([xp.var(lb=0, vartype=xp.continuous) for g in numGen]) #Objective totalcost = xp.Sum(p[g, 0] * CV[g] + CR[g] * (rup[g] + rdown[g])