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]
Exemple #2
0
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)
Exemple #3
0
    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]
Exemple #5
0
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()
Exemple #6
0
    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()
Exemple #7
0
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()
Exemple #9
0
    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 = {}
Exemple #11
0
    def create(self):
        """
        Returns a new empty optimisation problem.

        Returns
        -------
        problem : xpress.problem
        """
        return xp.problem()
Exemple #12
0
 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]
Exemple #14
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
Exemple #15
0
    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
Exemple #19
0
    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
Exemple #20
0
    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]
Exemple #22
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"
Exemple #23
0
    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 = []
Exemple #24
0
# 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(
Exemple #25
0
    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()
Exemple #27
0
    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)
Exemple #28
0
    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
Exemple #29
0
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()
Exemple #30
0
 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])