Exemple #1
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()
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 optimize(self, goal='cost'):
        '''
        Optimizes the micro grid with the given objective goal
        Raise a TimoutError, if the time limit is reached
        '''
        self.__addVariablesToModel()
        self.__createContraints() 
        if goal == 'cost':
            self.model.setObjective( 
                (xp.Sum(self.buy[t]*(self.total_demand[t]- self.total_supply[t])  for t in self.time_steps)),
                #(xp.Sum(
                #((self.total_supply[t] - self.total_demand[t])*self.sell[t]*self.sell_prices[t])
                # + ((self.total_supply[t]- self.total_demand[t])*self.buy[t]*self.buy_prices[t])
                 #for t in self.time_steps))/10**6 , 

                 sense=xp.maximize)
        elif goal == 'independent':
            obj_independent = (xp.Sum(self.buy[t]*(1- self.total_demand[t]- self.total_supply[t]) + self.sell[t]*(self.total_supply[t] - self.total_demand[t])  for t in self.time_steps))
            self.model.setObjective(obj_independent, sense=xp.minimize)
        elif goal == 'xp.minbuy':
            obj_independent = (xp.Sum(self.buy[t]*(self.total_demand[t]- self.total_supply[t])  for t in self.time_steps))
            self.model.setObjective(obj_independent, sense=xp.minimize)
        else:
            raise ValueError('Unkown objective goal')
        self.model.solve()
        print("Status: ", self.model.getProbStatusString())
        print("Solution: ", self.model.getSolution())
        if self.model.getProbStatus() == GRB.TIME_LIMIT:
            raise TimeoutError()
Exemple #4
0
 def set_objective(self):
     self.p.setObjective(xp.Sum(
         xp.Sum(self.e[a, t] for t in self._periods.keys())
         for a in range(len(self._areasList))) + 0.001 * xp.Sum(
             xp.Sum(
                 xp.Sum(self.y[a, b, t] for t in self._periods.keys())
                 for a in range(len(self._areasList)))
             for b in range(len(self._areasList))),
                         sense=xp.minimize)
Exemple #5
0
    def set_constraints(self):
        for i in self.emptySlots:
            for j in self.slots:
                self.m.addConstraint(self.x[i, j] == 0)

        for flight in self.flights:
            if not self.f_in_matched(flight):
                self.m.addConstraint(self.x[flight.slot.index,
                                            flight.slot.index] == 1)
            else:
                self.m.addConstraint(
                    xp.Sum(self.x[flight.slot.index, j.index]
                           for j in flight.compatibleSlots) == 1)

        for j in self.slots:
            self.m.addConstraint(
                xp.Sum(self.x[i.index, j.index] for i in self.slots) <= 1)

        for flight in self.flights:
            for j in flight.notCompatibleSlots:
                self.m.addConstraint(self.x[flight.slot.index, j.index] == 0)

        for flight in self.flights_in_matches:
            self.m.addConstraint(xp.Sum(self.x[flight.slot.index, slot_to_swap.index] for slot_to_swap in
                                        [s for s in self.slots if s != flight.slot]) \
                                 == xp.Sum([self.c[j] for j in self.get_match_for_flight(flight)]))

        for flight in self.flights:
            for other_flight in flight.airline.flights:
                if flight != other_flight:
                    self.m.addConstraint(self.x[flight.slot.index,
                                                other_flight.slot.index] == 0)

        k = 0
        for match in self.matches:
            pairA = match[0]
            pairB = match[1]

            self.m.addConstraint(xp.Sum(self.x[i.slot.index, j.slot.index] for i in pairA for j in pairB) + \
                                 xp.Sum(self.x[i.slot.index, j.slot.index] for i in pairB for j in pairA) >= \
                                 (self.c[k]) * 4)

            self.m.addConstraint(
                xp.Sum(self.x[i.slot.index, j.slot.index] * i.costFun(i, j.slot) for i in pairA for j in pairB) - \
                (1 - self.c[k]) * 100000 \
                <= xp.Sum(self.x[i.slot.index, j.slot.index] * i.costFun(i, i.slot) for i in pairA for j in pairB) - \
                self.epsilon)

            self.m.addConstraint(
                xp.Sum(self.x[i.slot.index, j.slot.index] * i.costFun(i, j.slot) for i in pairB for j in pairA) - \
                (1 - self.c[k]) * 100000 \
                <= xp.Sum(self.x[i.slot.index, j.slot.index] * i.costFun(i, i.slot) for i in pairB for j in pairA) - \
                self.epsilon)

            k += 1
    def _set_objective_function(self):
        # Similar to constraints, saving the costs expressions as attributes
        # can give you the chance to retrieve their values at the end of the optimization
        self.total_holding_cost = self.input_params['holding_cost'] * xp.Sum(
            self.inventory_variables)
        self.total_production_cost = xp.Sum(
            row['production_cost'] * self.production_variables[index]
            for index, row in self.input_data.iterrows())

        objective = self.total_holding_cost + self.total_production_cost
        self.model.setObjective(objective, sense=xp.minimize)
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 #8
0
    def set_constraints(self):
        flight: modFl.Flight
        airline: air.Airline
        for flight in self.flights:
            self.m.addConstraint(
                xp.Sum(self.x[flight.slot.index, slot.index]
                       for slot in flight.compatibleSlots) == 1)

        for slot in self.slots:
            self.m.addConstraint(
                xp.Sum(self.x[flight.slot.index, slot.index]
                       for flight in self.flights) <= 1)
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]
Exemple #10
0
 def force_auxiliary_variables_1(self, doctor, total_work_time):
     aux_definition1 = xp.constraint(
         xp.Sum(p.shift.duration_in_hours * self.x[p]
                for p in self.x if p.doctor == doctor) -
         doctor.allocation * total_work_time <= self.t[doctor],
         name=f'Auxiliary 1 for {doctor}')
     self.model.addConstraint(aux_definition1)
Exemple #11
0
    def _get_expr_from_pyomo_repn(self, repn, max_degree=2):
        referenced_vars = ComponentSet()

        degree = repn.polynomial_degree()
        if (degree is None) or (degree > max_degree):
            raise DegreeError(
                'XpressDirect does not support expressions of degree {0}.'.
                format(degree))

        # NOTE: xpress's python interface only allows for expresions
        #       with native numeric types. Others, like numpy.float64,
        #       will cause an exception when constructing expressions
        if len(repn.linear_vars) > 0:
            referenced_vars.update(repn.linear_vars)
            new_expr = xpress.Sum(
                float(coef) * self._pyomo_var_to_solver_var_map[var]
                for coef, var in zip(repn.linear_coefs, repn.linear_vars))
        else:
            new_expr = 0.0

        for coef, (x, y) in zip(repn.quadratic_coefs, repn.quadratic_vars):
            new_expr += float(coef) * self._pyomo_var_to_solver_var_map[
                x] * self._pyomo_var_to_solver_var_map[y]
            referenced_vars.add(x)
            referenced_vars.add(y)

        new_expr += repn.constant

        return new_expr, referenced_vars
Exemple #12
0
 def force_shift_fulfillment(self, shift, hospital):
     shift_fulfillment = xp.constraint(
         xp.Sum(self.x[p] for p in self.x
                if p.shift == shift and p.hospital == hospital) == 1,
         name=
         f'Force shift fulfillment for shift {shift} and hospital {hospital}'
     )
     self.model.addConstraint(shift_fulfillment)
	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 #14
0
    def set_objective(self):

        # self.m.setObjective(
        #     xp.Sum(self.x[flight.slot.index, j.index] * self.score(flight, j)
        #            for flight in self.flights for j in self.slots), sense=xp.minimize)
        self.m.setObjective(
            xp.Sum(self.x[flight.slot.index, j.index] * flight.costFun(flight, j)
                   for flight in self.flights for j in self.slots), sense=xp.minimize)
Exemple #15
0
 def max_time_working(self, doctor, shift_day, day_limit):
     time_working = xp.constraint(
         xp.Sum(self.x[p] for p in self.x for j in range(day_limit + 1)
                if p.doctor == doctor and p.shift.start_time.date() ==
                (shift_day + timedelta(days=j)).date()) <= day_limit,
         name=
         f'Max working time for day {shift_day} and doctor {doctor.name}')
     self.model.addConstraint(time_working)
Exemple #16
0
 def force_nightshift_work(self, nightshift, n_days_working):
     nightshift_work = xp.constraint(
         xp.Sum(self.x[p] for p in self.x for k in range(n_days_working)
                if p.doctor == nightshift.doctor and p.shift.start_time.
                date() == (nightshift.day.date() + timedelta(days=k))) >=
         3 * self.y[nightshift],
         name=
         f'Force nightshift for doctor {nightshift.doctor} at day {nightshift.day}'
     )
     self.model.addConstraint(nightshift_work)
Exemple #17
0
    def set_constraints(self):
        flight: modFl.Flight
        airline: air.Airline
        for flight in self.flights:
            self.m.addConstraint(
                xp.Sum(self.x[flight.slot.index, slot.index]
                       for slot in flight.compatibleSlots) == 1)

        for slot in self.slots:
            self.m.addConstraint(
                xp.Sum(self.x[flight.slot.index, slot.index]
                       for flight in self.flights) <= 1)

        for airline in self.airlines:
            self.m.addConstraint(
                xp.Sum(flight.costFun(flight, flight.slot) for flight in airline.flights) >= \
                xp.Sum(self.x[flight.slot.index, slot.index] * flight.costFun(flight, slot)
                       for flight in airline.flights for slot in self.slots)
            )
Exemple #18
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 #19
0
    def solve(self, X):
        """
            Implementation of the dual of SVDD problem
            
            Params:
                - X, the dataset without labels
            Returns:
                None
        """

        m = X.shape[0]

        # Define Variables of the problem
        alphas = [xp.var(lb=0, ub=self.C) for i in range(m)]
        self.p.addVariable(alphas)

        # Define Constraints
        # constr1 = [alpha <= C for alpha in alphas]
        # p.addConstraint(constr1)
        # already defined in the definition of the variable as a upper bound

        # Define objective function
        obj1 = xp.Sum(alphas[i] * np.sum(
            self.kernel(X[i].reshape(1, -1), X[i].reshape(1, -1))[0][0])
                      for i in range(m))
        obj2 = xp.Sum(alphas[i] * alphas[j] * np.sum(
            self.kernel(X[i].reshape(1, -1), X[j].reshape(1, -1))[0][0])
                      for i in range(m) for j in range(m))

        obj = obj1 - obj2
        self.p.setObjective(obj, sense=xp.maximize)  #set maximization problem
        # solve the problem
        self.p.solve()

        self.opt = np.array(
            self.p.getSolution(alphas))  #save the values of alphas
        self.c0 = np.sum(self.opt.reshape(-1, 1) * X, axis=0)

        indices_support_vectors = self.select_support_vectors(
        )  #choose a point as support vector
        self.support_vectors = X[indices_support_vectors]
Exemple #20
0
 def force_rest(self, nightshift, n_days_working, n_days_rest):
     force_rest = xp.constraint(
         xp.Sum(
             self.x[p] for p in self.x
             for k in range(n_days_working, n_days_working + n_days_rest)
             if p.doctor == nightshift.doctor and p.shift.start_time.date()
             == (nightshift.day.date() + timedelta(days=k))) <= 3 *
         (1 - self.y[nightshift]),
         name=
         f'Force rest for doctor {nightshift.doctor} at day {nightshift.day}'
     )
     self.model.addConstraint(force_rest)
Exemple #21
0
    def set_constraints(self):
        for i in self.emptySlots:
            for j in self.slots:
                self.m.addConstraint(self.x[i, j] == 0)

        for flight in self.flights:
            if not self.f_in_matched(flight):
                self.m.addConstraint(self.x[flight.slot.index, flight.slot.index] == 1)
            else:
                self.m.addConstraint(xp.Sum(self.x[flight.slot.index, j.index] for j in flight.compatibleSlots) == 1)

        for j in self.slots:
            self.m.addConstraint(xp.Sum(self.x[i.index, j.index] for i in self.slots) <= 1)

        # for flight in self.flights:
        #     for j in flight.notCompatibleSlots:
        #         self.m.addConstraint(self.x[flight.slot.index, j.index] == 0)


        for flight in self.flights_in_matches:
            self.m.addConstraint(
                                 xp.Sum(self.x[flight.slot.index, slot.index]
                                        for slot in self.slots if slot != flight.slot) \
                                 <= xp.Sum([self.c[j] for j in self.get_match_for_flight(flight)]))

            self.m.addConstraint(xp.Sum([self.c[j] for j in self.get_match_for_flight(flight)]) <= 1)



        k = 0
        for match in self.matches:
            flights = [flight for pair in match for flight in pair]
            self.m.addConstraint(xp.Sum(xp.Sum(self.x[i.slot.index, j.slot.index] for i in pair for j in flights)
                                        for pair in match) >= (self.c[k]) * len(flights))


            for pair in match:
                self.m.addConstraint(
                    xp.Sum(self.x[i.slot.index, j.slot.index] * i.costFun(i, j.slot) for i in pair for j in flights) -
                    (1 - self.c[k]) * 10000000 \
                    <= xp.Sum(self.x[i.slot.index, j.slot.index] * i.costFun(i, i.slot) for i in pair for j in flights) - \
                    self.epsilon)


            k += 1
Exemple #22
0
    def set_constraints(self):
        # t is the index of the time period

        for acc in self.accs:
            # no self colab
            for t in range(self.intNum):
                self.p.addConstraint(self.x[acc.index, acc.index, t] == 0)

            self.p.addConstraint(xp.Sum(self.m[k] for k in self.get_acc_matches(acc)) <= 1)

        # colab with only one for each interval
        for acc_A in self.accs:
            for t in range(self.intNum):
                self.p.addConstraint(
                    xp.Sum(self.x[acc_A.index, acc_B.index, t] for acc_B in self.accs) <= 1
                )

        k = 0
        for match in self.matches:
            acc_A, acc_B = match[0], match[1]
            self.p.addConstraint(
                xp.Sum(self.x[acc_A.index, acc_B.index, t] for t in range(self.intNum)) <= self.m[k]
            )
            k += 1
Exemple #23
0
    def set_constraints(self):
        for a in range(len(self._areasList)):
            for t in self._periods.keys():
                self.p.addConstraint(
                    self._areasList[a].demand[self._periods[t]] -
                    self._areasList[a].capacity[self._periods[t]] -
                    xp.Sum(self.y[a, other_area, t]
                           for other_area in range(len(self._areasList))) +
                    xp.Sum(self.y[other_area, a, t]
                           for other_area in range(len(self._areasList))) <=
                    self.e[a, t])

                available = 1 if (
                    self._areasList[a].demand[self._periods[t]] -
                    self._areasList[a].capacity[self._periods[t]]) < 0 else 0

                self.p.addConstraint(
                    xp.Sum(self.y[j, a, t]
                           for j in range(len(self._areasList))) <= 10000 *
                    available)

                self.p.addConstraint(
                    xp.Sum(self.y[a, j, t]
                           for j in range(len(self._areasList))) <= 10000 *
                    (1 - available))

            idxs = [
                i for i in range(len(self._matches))
                if self._matches[i][0].name == self._areasList[a].name
                or self._matches[i][1].name == self._areasList[a].name
            ]

            self.p.addConstraint(xp.Sum(self.m[i] for i in idxs) <= 1)

        for i in range(len(self._matches)):
            a = self._matches[i][0].index
            b = self._matches[i][1].index

            self.p.addConstraint(
                xp.Sum(self.y[a, b, t] + self.y[b, a, t]
                       for t in self._periods.keys()) <= 10000 * self.m[i])
Exemple #24
0
# 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(
    0.5 * (
        xp.Sum(rho[i] * rho[i - 1] * xp.sin(theta[i] - theta[i - 1])
               for i in Vertices
               if i != 0)  # sum of the first N-1 triangle areas
        + rho[0] * rho[N - 1] * xp.sin(theta[0] - theta[N - 1])),
    sense=xp.maximize)  # plus area between segments N and 1

# Angles are in increasing order, and should be different (the solver
# finds a bad local optimum otherwise

p.addConstraint(theta[i] >= theta[i - 1] + 1e-4 for i in Vertices if i != 0)

# solve the problem

p.solve()

# The following command saves the final problem onto a file
#
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 xpress_sum(terms):
    """ Sum the given terms """

    return xp.Sum(terms)
Exemple #27
0
# the Xpress API routines to amend the problem with rows and quadratic
# terms.
#

p = xp.problem ()

N = 5
S = range (N)

x = [xp.var (vartype = xp.binary) for i in S]

p.addVariable (x)

# vectors can be used whole or addressed with their index

c0 = xp.Sum (x) <= 10
cc = [x[i]/1.1 <= x[i+1]*2 for i in range (N-1)]

p.addConstraint (c0, cc)

p.setObjective (3 - x[0])

mysol = [0, 0, 1, 1, 1, 1.4]

# add a variable with its coefficients

p.addcols ([4], [0,3], [c0,4,2], [-3, 2.4, 1.4], [0], [2], ['YY'], ['B'])
p.write ("problem1", "lp")

# load a MIP solution
p.loadmipsol ([0,0,1,1,1,1.4])
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 enforce_hospital_limit(self, doctor):
     hospital_limit = xp.constraint(
         xp.Sum(self.x[p] for p in self.x if p.doctor == doctor
                and p.hospital not in doctor.work_locations) == 0,
         name=f'Enforce hospital limits for doctor {doctor.name}')
     self.model.addConstraint(hospital_limit)