def solve(x0, risk_alphas, loadings, srisk, cost_per_trade=DEFAULT_COST, max_risk=0.01): N = len(x0) # don't hold no risk data (likely dead) lim = np.where(srisk.isnull(), 0.0, 1.0) loadings = loadings.fillna(0) srisk = srisk.fillna(0) risk_alphas = risk_alphas.fillna(0) with Model() as m: w = m.variable(N, Domain.inRange(-lim, lim)) longs = m.variable(N, Domain.greaterThan(0)) shorts = m.variable(N, Domain.greaterThan(0)) gross = m.variable(N, Domain.greaterThan(0)) m.constraint( "leverage_consistent", Expr.sub(gross, Expr.add(longs, shorts)), Domain.equalsTo(0), ) m.constraint("net_consistent", Expr.sub(w, Expr.sub(longs, shorts)), Domain.equalsTo(0.0)) m.constraint("leverage_long", Expr.sum(longs), Domain.lessThan(1.0)) m.constraint("leverage_short", Expr.sum(shorts), Domain.lessThan(1.0)) buys = m.variable(N, Domain.greaterThan(0)) sells = m.variable(N, Domain.greaterThan(0)) gross_trade = Expr.add(buys, sells) net_trade = Expr.sub(buys, sells) total_gross_trade = Expr.sum(gross_trade) m.constraint( "net_trade", Expr.sub(w, net_trade), Domain.equalsTo(np.asarray(x0)), # cannot handle series ) # add risk constraint vol = m.variable(1, Domain.lessThan(max_risk)) stacked = Expr.vstack(vol.asExpr(), Expr.mulElm(w, srisk.values)) stacked = Expr.vstack(stacked, Expr.mul(loadings.values.T, w)) m.constraint("vol-cons", stacked, Domain.inQCone()) alphas = risk_alphas.dot(np.vstack([loadings.T, np.diag(srisk)])) gain = Expr.dot(alphas, net_trade) loss = Expr.mul(cost_per_trade, total_gross_trade) m.objective(ObjectiveSense.Maximize, Expr.sub(gain, loss)) m.solve() result = pd.Series(w.level(), srisk.index) return result
def _update(self, clique_data, parent=None): for c in clique_data['cliques']: self.cliques[c['name']] = v = self.model.variable( c['name'], Domain.inRange(0.0, 1.0), Domain.isInteger() ) for img, cmd in product(c['images'], c['commands']): self.by_img_cmd[img,cmd].append(v) self._obj.append(Expr.mul(float(c['time']), v)) if parent is not None: self.model.constraint( 'c-%s-%s' % (c['name'], parent['name']), Expr.sub(v, self.cliques[parent['name']]), Domain.lessThan(0.0) ) for child in c['children']: self._update(child, c) for inter in clique_data['intersections']: self.model.constraint( 'iter-%d' % self._inter, Expr.add([self.cliques[i] for i in inter]), Domain.lessThan(1.0) ) self._inter += 1
def minimum_variance(matrix): # Given the matrix of returns a (each column is a series of returns) this method # computes the weights for a minimum variance portfolio, e.g. # min 2-Norm[a*w]^2 # s.t. # w >= 0 # sum[w] = 1 # This is the left-most point on the efficiency frontier in the classic Markowitz theory # build the model with Model("Minimum Variance") as model: # introduce the weight variable weights = model.variable("weights", matrix.shape[1], Domain.inRange(0.0, 1.0)) # sum of weights has to be 1 model.constraint(Expr.sum(weights), Domain.equalsTo(1.0)) # returns r = Expr.mul(Matrix.dense(matrix), weights) # compute l2_norm squared of those returns # minimize this l2_norm model.objective(ObjectiveSense.Minimize, __l2_norm_squared(model, "2-norm^2(r)", expr=r)) # solve the problem model.solve() # return the series of weights return np.array(weights.level())
def solve(self, problem, saver): # Construct model. self.problem = problem # Do recursive maximal clique detection. self.clique_data = clique_data = problem.cliques() self.model = model = Model() if self.time is not None: model.setSolverParam('mioMaxTime', 60.0 * int(self.time)) # Each image needs to run all its commands. This keep track of # what variables run each command for each image. self.by_img_cmd = by_img_cmd = defaultdict(list) # Objective is the total cost of all the commands we run. self._obj = [] # x[i,c] = 1 if image i incurs the cost of command c directly self.x = x = {} for img, cmds in problem.images.items(): for cmd in cmds: name = 'x[%s,%s]' % (img, cmd) x[name] = v = self.model.variable( name, Domain.inRange(0.0, 1.0), Domain.isInteger() ) self._obj.append(Expr.mul(float(problem.commands[cmd]), v)) by_img_cmd[img,cmd].append(v) # cliques[i] = 1 if clique i is used, 0 otherwise self.cliques = {} self._inter = 1 self._update(clique_data) # Each image has to run each of its commands. for img_cmd, vlist in by_img_cmd.items(): name = 'img-cmd-%s-%s' % img_cmd self.model.constraint( name, Expr.add(vlist), Domain.equalsTo(1.0) ) model.objective('z', ObjectiveSense.Minimize, Expr.add(self._obj)) model.setLogHandler(sys.stdout) model.acceptedSolutionStatus(AccSolutionStatus.Feasible) model.solve() # Translate the output of this to a schedule. schedule = defaultdict(list) self._translate(schedule, clique_data) for name, v in x.items(): img, cmd = name.replace('x[','').replace(']','').split(',') if v.level()[0] > 0.5: schedule[img].append(cmd) saver(schedule)
def solve(self, problem, saver): # Construct model. self.problem = problem # Do recursive maximal clique detection. self.clique_data = clique_data = problem.cliques() self.model = model = Model() if self.time is not None: model.setSolverParam('mioMaxTime', 60.0 * int(self.time)) # Each image needs to run all its commands. This keep track of # what variables run each command for each image. self.by_img_cmd = by_img_cmd = defaultdict(list) # Objective is the total cost of all the commands we run. self._obj = [] # x[i,c] = 1 if image i incurs the cost of command c directly self.x = x = {} for img, cmds in problem.images.items(): for cmd in cmds: name = 'x[%s,%s]' % (img, cmd) x[name] = v = self.model.variable(name, Domain.inRange(0.0, 1.0), Domain.isInteger()) self._obj.append(Expr.mul(float(problem.commands[cmd]), v)) by_img_cmd[img, cmd].append(v) # cliques[i] = 1 if clique i is used, 0 otherwise self.cliques = {} self._inter = 1 self._update(clique_data) # Each image has to run each of its commands. for img_cmd, vlist in by_img_cmd.items(): name = 'img-cmd-%s-%s' % img_cmd self.model.constraint(name, Expr.add(vlist), Domain.equalsTo(1.0)) model.objective('z', ObjectiveSense.Minimize, Expr.add(self._obj)) model.setLogHandler(sys.stdout) model.acceptedSolutionStatus(AccSolutionStatus.Feasible) model.solve() # Translate the output of this to a schedule. schedule = defaultdict(list) self._translate(schedule, clique_data) for name, v in x.items(): img, cmd = name.replace('x[', '').replace(']', '').split(',') if v.level()[0] > 0.5: schedule[img].append(cmd) saver(schedule)
def markowitz(exp_ret, covariance_mat, aversion): # define model model = mModel.build_model("mean_var") # set of n weights (unconstrained) weights = mModel.weights(model, "weights", n=len(exp_ret)) mBound.equal(model, Expr.sum(weights), 1.0) # standard deviation induced by covariance matrix var = mMath.variance(model, "var", weights, covariance_mat) mModel.maximise(model=model, expr=Expr.sub(Expr.dot(exp_ret, weights), Expr.mul(aversion, var))) return np.array(weights.level())
def markowitz(exp_ret, covariance_mat, aversion): # define model with Model("mean var") as model: # set of n weights (unconstrained) weights = model.variable("weights", len(exp_ret), Domain.inRange(-np.infty, +np.infty)) model.constraint(Expr.sum(weights), Domain.equalsTo(1.0)) # standard deviation induced by covariance matrix var = __variance(model, "var", weights, covariance_mat) model.objective( ObjectiveSense.Maximize, Expr.sub(Expr.dot(exp_ret, weights), Expr.mul(aversion, var))) model.solve() #mModel.maximise(model=model, expr=Expr.sub(Expr.dot(exp_ret, weights), Expr.mul(aversion, var))) return np.array(weights.level())
def __init__(self,name, foods, nutrients, daily_allowance, nutritive_value): Model.__init__(self,name) finished = False try: self.foods = [ str(f) for f in foods ] self.nutrients = [ str(n) for n in nutrients ] self.dailyAllowance = array.array(daily_allowance, float) self.nutrientValue = DenseMatrix(nutritive_value).transpose() M = len(self.foods) N = len(self.nutrients) if len(self.dailyAllowance) != N: raise ValueError("Length of daily_allowance does not match " "the number of nutrients") if self.nutrientValue.numColumns() != M: raise ValueError("Number of rows in nutrient_value does not " "match the number of foods") if self.nutrientValue.numRows() != N: raise ValueError("Number of columns in nutrient_value does " "not match the number of nutrients") self.__dailyPurchase = self.variable('Daily Purchase', StringSet(self.foods), Domain.greaterThan(0.0)) self.__dailyNutrients = \ self.constraint('Nutrient Balance', StringSet(nutrients), Expr.mul(self.nutrientValue,self.__dailyPurchase), Domain.greaterThan(self.dailyAllowance)) self.objective(ObjectiveSense.Minimize, Expr.sum(self.__dailyPurchase)) finished = True finally: if not finished: self.__del__()
def __init__(self,name, foods, nutrients, daily_allowance, nutritive_value): Model.__init__(self,name) finished = False try: self.foods = [ str(f) for f in foods ] self.nutrients = [ str(n) for n in nutrients ] self.dailyAllowance = numpy.array(daily_allowance, float) self.nutrientValue = Matrix.dense(nutritive_value).transpose() M = len(self.foods) N = len(self.nutrients) if len(self.dailyAllowance) != N: raise ValueError("Length of daily_allowance does not match " "the number of nutrients") if self.nutrientValue.numColumns() != M: raise ValueError("Number of rows in nutrient_value does not " "match the number of foods") if self.nutrientValue.numRows() != N: raise ValueError("Number of columns in nutrient_value does " "not match the number of nutrients") self.__dailyPurchase = self.variable('Daily Purchase', StringSet(self.foods), Domain.greaterThan(0.0)) self.__dailyNutrients = \ self.constraint('Nutrient Balance', StringSet(nutrients), Expr.mul(self.nutrientValue,self.__dailyPurchase), Domain.greaterThan(self.dailyAllowance)) self.objective(ObjectiveSense.Minimize, Expr.sum(self.__dailyPurchase)) finished = True finally: if not finished: self.__del__()
def _update(self, clique_data, parent=None): for c in clique_data['cliques']: self.cliques[c['name']] = v = self.model.variable( c['name'], Domain.inRange(0.0, 1.0), Domain.isInteger()) for img, cmd in product(c['images'], c['commands']): self.by_img_cmd[img, cmd].append(v) self._obj.append(Expr.mul(float(c['time']), v)) if parent is not None: self.model.constraint( 'c-%s-%s' % (c['name'], parent['name']), Expr.sub(v, self.cliques[parent['name']]), Domain.lessThan(0.0)) for child in c['children']: self._update(child, c) for inter in clique_data['intersections']: self.model.constraint('iter-%d' % self._inter, Expr.add([self.cliques[i] for i in inter]), Domain.lessThan(1.0)) self._inter += 1
def __sum_weighted(c1, expr1, c2, expr2): return Expr.add(Expr.mul(c1, expr1), Expr.mul(c2, expr2))
m.constraint('c_3_b_3', Expr.sub(z_3_b, Expr.add([w_3, y_b])), Domain.greaterThan(-1.0)) m.constraint('c_3_c_1', Expr.sub(z_3_c, w_3), Domain.lessThan(0.0)) m.constraint('c_3_c_2', Expr.sub(z_3_c, y_c), Domain.lessThan(0.0)) m.constraint('c_3_c_3', Expr.sub(z_3_c, Expr.add([w_3, y_c])), Domain.greaterThan(-1.0)) m.constraint('c_3_d_1', Expr.sub(z_3_d, w_3), Domain.lessThan(0.0)) m.constraint('c_3_d_2', Expr.sub(z_3_d, y_d), Domain.lessThan(0.0)) m.constraint('c_3_d_3', Expr.sub(z_3_d, Expr.add([w_3, y_d])), Domain.greaterThan(-1.0)) # Maximize the amount we can improve our objective by adding a new clique. obj1 = [ Expr.mul(c, y) for c, y in [(r['A'], y_a), (r['B'], y_b), (r['C'], y_c), (r['D'], y_d)] ] obj2 = [ Expr.mul(c, z) for c, z in [ # Individual image/command pairs (r['A'], z_1_a), (r['B'], z_1_b), (r['A'], z_2_a), (r['B'], z_2_b), (r['C'], z_2_c), (r['D'], z_2_d), (r['B'], z_3_b), (r['C'], z_3_c), (r['D'], z_3_d), ]
def __mat_vec_prod(matrix, expr): return Expr.mul(Matrix.dense(matrix), expr)
m.constraint('d_2_d', Expr.sub(z_2_d, Expr.add([m_2, n_d])), Domain.lessThan(0.0)) m.constraint('d_2_b_q_2_b', Expr.sub(Expr.add([z_2_b, q_2_b]), Expr.add([m_2, n_b])), Domain.greaterThan(0.0)) m.constraint('d_2_c_q_2_c', Expr.sub(Expr.add([z_2_c, q_2_c]), Expr.add([m_2, n_c])), Domain.greaterThan(0.0)) m.constraint('d_2_d_q_2_d', Expr.sub(Expr.add([z_2_d, q_2_d]), Expr.add([m_2, n_d])), Domain.greaterThan(0.0)) m.constraint('d_3_b', Expr.sub(z_3_b, Expr.add([m_3, n_b])), Domain.lessThan(0.0)) m.constraint('d_3_c', Expr.sub(z_3_c, Expr.add([m_3, n_c])), Domain.lessThan(0.0)) m.constraint('d_3_d', Expr.sub(z_3_d, Expr.add([m_3, n_d])), Domain.lessThan(0.0)) m.constraint('d_3_b_q_3_b', Expr.sub(Expr.add([z_3_b, q_3_b]), Expr.add([m_3, n_b])), Domain.greaterThan(0.0)) m.constraint('d_3_c_q_3_c', Expr.sub(Expr.add([z_3_c, q_3_c]), Expr.add([m_3, n_c])), Domain.greaterThan(0.0)) m.constraint('d_3_d_q_3_d', Expr.sub(Expr.add([z_3_d, q_3_d]), Expr.add([m_3, n_d])), Domain.greaterThan(0.0)) # Maximize the amount we can improve our objective by adding a new clique. obj1 = [Expr.mul(c, y) for c, y in [ (r['A'], y_a), (r['B'], y_b), (r['C'], y_c), (r['D'], y_d) ]] obj2 = [Expr.mul(c, z) for c, z in [ # Individual image/command pairs (r['A'], z_1_a), (r['A'], z_2_a), ]] obj3 = [Expr.mul(c, z) for c, z in [ # Individual image/command pairs for commands that are now run alone (r['B'], q_1_b), (r['B'], q_2_b), (r['C'], q_2_c), (r['D'], q_2_d), (r['B'], q_3_b), (r['C'], q_3_c), (r['D'], q_3_d), ]] obj4 = [Expr.mul(c, y) for c, y in [ # Commands taken out of the existing cliques
m.constraint('c_2_a', Expr.add([x_2_a]), Domain.equalsTo(1.0)) m.constraint('c_2_b', Expr.add([x_2_b, x_23_bcd, x_123_b]), Domain.equalsTo(1.0)) m.constraint('c_2_c', Expr.add([x_2_c, x_23_bcd, x_123_b_23_cd]), Domain.equalsTo(1.0)) m.constraint('c_2_d', Expr.add([x_2_d, x_23_bcd, x_123_b_23_cd]), Domain.equalsTo(1.0)) m.constraint('c_3_b', Expr.add([x_3_b, x_23_bcd, x_123_b]), Domain.equalsTo(1.0)) m.constraint('c_3_c', Expr.add([x_3_c, x_23_bcd, x_123_b_23_cd]), Domain.equalsTo(1.0)) m.constraint('c_3_d', Expr.add([x_3_d, x_23_bcd, x_123_b_23_cd]), Domain.equalsTo(1.0)) # Add dependency constraints for sub-cliques. m.constraint('d_123_b_23_cd', Expr.sub(x_123_b, x_123_b_23_cd), Domain.greaterThan(0.0)) # Eliminated intersections between cliques. m.constraint('e1', Expr.add([x_23_bcd, x_123_b]), Domain.lessThan(1.0)) # Minimize resources required to construct all images. obj = [Expr.mul(c, x) for c, x in [ # Individual image/command pairs (r['A'], x_1_a), (r['B'], x_1_b), (r['A'], x_2_a), (r['B'], x_2_b), (r['C'], x_2_c), (r['D'], x_2_d), (r['B'], x_3_b), (r['C'], x_3_c), (r['D'], x_3_d), # Cliques (r['B'] + r['C'] + r['D'], x_23_bcd), (r['B'], x_123_b), (r['C'] + r['D'], x_123_b_23_cd), ]] m.objective('w', ObjectiveSense.Minimize, Expr.add(obj)) m.setLogHandler(sys.stdout) m.solve() print
def markowitz(exp_ret, covariance_mat, aversion): # define model with Model("mean var") as model: # set of n weights (unconstrained) weights = model.variable("weights", len(exp_ret), Domain.inRange(-np.infty, +np.infty)) model.constraint(Expr.sum(weights), Domain.equalsTo(1.0)) # standard deviation induced by covariance matrix var = __variance(model, "var", weights, covariance_mat) model.objective(ObjectiveSense.Maximize, Expr.sub(Expr.dot(exp_ret, weights), Expr.mul(aversion, var))) model.solve() #mModel.maximise(model=model, expr=Expr.sub(Expr.dot(exp_ret, weights), Expr.mul(aversion, var))) return np.array(weights.level())
def solve(self, problem, saver): # Construct model. self.problem = problem self.model = model = Model() if self.time is not None: model.setSolverParam('mioMaxTime', 60.0 * int(self.time)) # x[1,c] = 1 if the master schedule has (null, c) in its first stage # x[s,c1,c2] = 1 if the master schedule has (c1, c2) in stage s > 1 x = {} for s in problem.all_stages: if s == 1: # First arc in the individual image path. for c in problem.commands: x[1,c] = model.variable( 'x[1,%s]' % c, 1, Domain.inRange(0.0, 1.0), Domain.isInteger() ) else: # Other arcs. for c1, c2 in product(problem.commands, problem.commands): if c1 == c2: continue x[s,c1,c2] = model.variable( 'x[%s,%s,%s]' % (s,c1,c2), 1, Domain.inRange(0.0, 1.0), Domain.isInteger() ) smax = max(problem.all_stages) obj = [0.0] # TODO: deal with images that do not have the same number of commands. # t[s,c] is the total time incurred at command c in stage s t = {} for s in problem.all_stages: for c in problem.commands: t[s,c] = model.variable( 't[%s,%s]' % (c,s), 1, Domain.greaterThan(0.0) ) if s == 1: model.constraint('t[1,%s]' % c, Expr.sub(t[1,c], Expr.mul(float(problem.commands[c]), x[1,c])), Domain.greaterThan(0.0) ) else: rhs = [0.0] for c1, coeff in problem.commands.items(): if c1 == c: continue else: rhs = Expr.add(rhs, Expr.mulElm(t[s-1,c1], x[s,c1,c])) model.constraint('t[%s,%s]' % (s,c), Expr.sub(t[1,c], rhs), Domain.greaterThan(0.0) ) # Objective function = sum of aggregate comand times if s == smax: obj = Expr.add(obj, t[s,c]) # y[i,1,c] = 1 if image i starts by going to c # y[i,s,c1,c2] = 1 if image i goes from command c1 to c2 in stage s > 1 y = {} for i, cmds in problem.images.items(): for s in problem.stages[i]: if s == 1: # First arc in the individual image path. for c in cmds: y[i,1,c] = model.variable( 'y[%s,1,%s]' % (i,c), 1, Domain.inRange(0.0, 1.0), Domain.isInteger() ) model.constraint('x_y[i%s,1,c%s]' % (i,c), Expr.sub(x[1,c], y[i,1,c]), Domain.greaterThan(0.0) ) else: # Other arcs. for c1, c2 in product(cmds, cmds): if c1 == c2: continue y[i,s,c1,c2] = model.variable( 'y[%s,%s,%s,%s]' % (i,s,c1,c2), 1, Domain.inRange(0.0, 1.0), Domain.isInteger() ) model.constraint('x_y[i%s,s%s,c%s,c%s]' % (i,s,c1,c2), Expr.sub(x[s,c1,c2], y[i,s,c1,c2]), Domain.greaterThan(0.0) ) for c in cmds: # Each command is an arc destination exactly once. arcs = [y[i,1,c]] for c1 in cmds: if c1 == c: continue arcs.extend([y[i,s,c1,c] for s in problem.stages[i][1:]]) model.constraint('y[i%s,c%s]' % (i,c), Expr.add(arcs), Domain.equalsTo(1.0) ) # Network balance equations (stages 2 to |stages|-1). # Sum of arcs in = sum of arcs out. for s in problem.stages[i][:len(problem.stages[i])-1]: if s == 1: arcs_in = [y[i,1,c]] else: arcs_in = [y[i,s,c1,c] for c1 in cmds if c1 != c] arcs_out = [y[i,s+1,c,c2] for c2 in cmds if c2 != c] model.constraint('y[i%s,s%s,c%s]' % (i,s,c), Expr.sub(Expr.add(arcs_in), Expr.add(arcs_out)), Domain.equalsTo(0.0) ) model.objective('z', ObjectiveSense.Minimize, Expr.add(x.values())) # model.objective('z', ObjectiveSense.Minimize, obj) model.setLogHandler(sys.stdout) model.acceptedSolutionStatus(AccSolutionStatus.Feasible) model.solve() # Create optimal schedule. schedule = defaultdict(list) for i, cmds in problem.images.items(): for s in problem.stages[i]: if s == 1: # First stage starts our walk. for c in cmds: if y[i,s,c].level()[0] > 0.5: schedule[i].append(c) break else: # After that we know what our starting point is. for c2 in cmds: if c2 == c: continue if y[i,s,c,c2].level()[0] > 0.5: schedule[i].append(c2) c = c2 break saver(schedule)
def solve(self, problem, saver): # Construct model. self.problem = problem self.model = model = Model() if self.time is not None: model.setSolverParam('mioMaxTime', 60.0 * int(self.time)) # x[1,c] = 1 if the master schedule has (null, c) in its first stage # x[s,c1,c2] = 1 if the master schedule has (c1, c2) in stage s > 1 x = {} for s in problem.all_stages: if s == 1: # First arc in the individual image path. for c in problem.commands: x[1, c] = model.variable('x[1,%s]' % c, 1, Domain.inRange(0.0, 1.0), Domain.isInteger()) else: # Other arcs. for c1, c2 in product(problem.commands, problem.commands): if c1 == c2: continue x[s, c1, c2] = model.variable('x[%s,%s,%s]' % (s, c1, c2), 1, Domain.inRange(0.0, 1.0), Domain.isInteger()) smax = max(problem.all_stages) obj = [0.0] # TODO: deal with images that do not have the same number of commands. # t[s,c] is the total time incurred at command c in stage s t = {} for s in problem.all_stages: for c in problem.commands: t[s, c] = model.variable('t[%s,%s]' % (c, s), 1, Domain.greaterThan(0.0)) if s == 1: model.constraint( 't[1,%s]' % c, Expr.sub(t[1, c], Expr.mul(float(problem.commands[c]), x[1, c])), Domain.greaterThan(0.0)) else: rhs = [0.0] for c1, coeff in problem.commands.items(): if c1 == c: continue else: rhs = Expr.add( rhs, Expr.mulElm(t[s - 1, c1], x[s, c1, c])) model.constraint('t[%s,%s]' % (s, c), Expr.sub(t[1, c], rhs), Domain.greaterThan(0.0)) # Objective function = sum of aggregate comand times if s == smax: obj = Expr.add(obj, t[s, c]) # y[i,1,c] = 1 if image i starts by going to c # y[i,s,c1,c2] = 1 if image i goes from command c1 to c2 in stage s > 1 y = {} for i, cmds in problem.images.items(): for s in problem.stages[i]: if s == 1: # First arc in the individual image path. for c in cmds: y[i, 1, c] = model.variable('y[%s,1,%s]' % (i, c), 1, Domain.inRange(0.0, 1.0), Domain.isInteger()) model.constraint('x_y[i%s,1,c%s]' % (i, c), Expr.sub(x[1, c], y[i, 1, c]), Domain.greaterThan(0.0)) else: # Other arcs. for c1, c2 in product(cmds, cmds): if c1 == c2: continue y[i, s, c1, c2] = model.variable( 'y[%s,%s,%s,%s]' % (i, s, c1, c2), 1, Domain.inRange(0.0, 1.0), Domain.isInteger()) model.constraint( 'x_y[i%s,s%s,c%s,c%s]' % (i, s, c1, c2), Expr.sub(x[s, c1, c2], y[i, s, c1, c2]), Domain.greaterThan(0.0)) for c in cmds: # Each command is an arc destination exactly once. arcs = [y[i, 1, c]] for c1 in cmds: if c1 == c: continue arcs.extend( [y[i, s, c1, c] for s in problem.stages[i][1:]]) model.constraint('y[i%s,c%s]' % (i, c), Expr.add(arcs), Domain.equalsTo(1.0)) # Network balance equations (stages 2 to |stages|-1). # Sum of arcs in = sum of arcs out. for s in problem.stages[i][:len(problem.stages[i]) - 1]: if s == 1: arcs_in = [y[i, 1, c]] else: arcs_in = [y[i, s, c1, c] for c1 in cmds if c1 != c] arcs_out = [y[i, s + 1, c, c2] for c2 in cmds if c2 != c] model.constraint( 'y[i%s,s%s,c%s]' % (i, s, c), Expr.sub(Expr.add(arcs_in), Expr.add(arcs_out)), Domain.equalsTo(0.0)) model.objective('z', ObjectiveSense.Minimize, Expr.add(x.values())) # model.objective('z', ObjectiveSense.Minimize, obj) model.setLogHandler(sys.stdout) model.acceptedSolutionStatus(AccSolutionStatus.Feasible) model.solve() # Create optimal schedule. schedule = defaultdict(list) for i, cmds in problem.images.items(): for s in problem.stages[i]: if s == 1: # First stage starts our walk. for c in cmds: if y[i, s, c].level()[0] > 0.5: schedule[i].append(c) break else: # After that we know what our starting point is. for c2 in cmds: if c2 == c: continue if y[i, s, c, c2].level()[0] > 0.5: schedule[i].append(c2) c = c2 break saver(schedule)
x_23_bcd = m.variable('x_23_bcd', *binary) # Each command must be run once for each image. m.constraint('c_1_a', Expr.add([x_1_a]), Domain.equalsTo(1.0)) m.constraint('c_1_b', Expr.add([x_1_b]), Domain.equalsTo(1.0)) m.constraint('c_2_a', Expr.add([x_2_a]), Domain.equalsTo(1.0)) m.constraint('c_2_b', Expr.add([x_2_b, x_23_bcd]), Domain.equalsTo(1.0)) m.constraint('c_2_c', Expr.add([x_2_c, x_23_bcd]), Domain.equalsTo(1.0)) m.constraint('c_2_d', Expr.add([x_2_d, x_23_bcd]), Domain.equalsTo(1.0)) m.constraint('c_3_b', Expr.add([x_3_b, x_23_bcd]), Domain.equalsTo(1.0)) m.constraint('c_3_c', Expr.add([x_3_c, x_23_bcd]), Domain.equalsTo(1.0)) m.constraint('c_3_d', Expr.add([x_3_d, x_23_bcd]), Domain.equalsTo(1.0)) # Minimize resources required to construct all images. obj = [ Expr.mul(c, x) for c, x in [ # Individual image/command pairs (r['A'], x_1_a), (r['B'], x_1_b), (r['A'], x_2_a), (r['B'], x_2_b), (r['C'], x_2_c), (r['D'], x_2_d), (r['B'], x_3_b), (r['C'], x_3_c), (r['D'], x_3_d), # Cliques (r['B'] + r['C'] + r['D'], x_23_bcd), ] ]
m.constraint('d_2_d', Expr.sub(z_2_d, Expr.add([m_2, n_d])), Domain.lessThan(0.0)) m.constraint('d_2_b_q_2_b', Expr.sub(Expr.add([z_2_b, q_2_b]), Expr.add([m_2, n_b])), Domain.greaterThan(0.0)) m.constraint('d_2_c_q_2_c', Expr.sub(Expr.add([z_2_c, q_2_c]), Expr.add([m_2, n_c])), Domain.greaterThan(0.0)) m.constraint('d_2_d_q_2_d', Expr.sub(Expr.add([z_2_d, q_2_d]), Expr.add([m_2, n_d])), Domain.greaterThan(0.0)) m.constraint('d_3_b', Expr.sub(z_3_b, Expr.add([m_3, n_b])), Domain.lessThan(0.0)) m.constraint('d_3_c', Expr.sub(z_3_c, Expr.add([m_3, n_c])), Domain.lessThan(0.0)) m.constraint('d_3_d', Expr.sub(z_3_d, Expr.add([m_3, n_d])), Domain.lessThan(0.0)) m.constraint('d_3_b_q_3_b', Expr.sub(Expr.add([z_3_b, q_3_b]), Expr.add([m_3, n_b])), Domain.greaterThan(0.0)) m.constraint('d_3_c_q_3_c', Expr.sub(Expr.add([z_3_c, q_3_c]), Expr.add([m_3, n_c])), Domain.greaterThan(0.0)) m.constraint('d_3_d_q_3_d', Expr.sub(Expr.add([z_3_d, q_3_d]), Expr.add([m_3, n_d])), Domain.greaterThan(0.0)) # Maximize the amount we can improve our objective by adding a new clique. obj1 = [Expr.mul(c, y) for c, y in [ (r['A'], y_a), (r['B'], y_b), (r['C'], y_c), (r['D'], y_d) ]] obj2 = [Expr.mul(c, z) for c, z in [ # Individual image/command pairs (r['A'], z_1_a), (r['B'], z_1_b), (r['A'], z_2_a), ]] obj3 = [Expr.mul(c, z) for c, z in [ # Individual image/command pairs for commands that are now run alone (r['B'], q_2_b), (r['C'], q_2_c), (r['D'], q_2_d), (r['B'], q_3_b), (r['C'], q_3_c), (r['D'], q_3_d), ]] obj4 = [Expr.mul(c, y) for c, y in [ # Commands taken out of the existing cliques (r['B'], n_b), (r['C'], n_c), (r['D'], n_d)
x_3_c = m.variable('x_3_c', *binary) x_3_d = m.variable('x_3_d', *binary) # Each command must be run once for each image. m.constraint('c_1_a', Expr.add([x_1_a]), Domain.equalsTo(1.0)) m.constraint('c_1_b', Expr.add([x_1_b]), Domain.equalsTo(1.0)) m.constraint('c_2_a', Expr.add([x_2_a]), Domain.equalsTo(1.0)) m.constraint('c_2_b', Expr.add([x_2_b]), Domain.equalsTo(1.0)) m.constraint('c_2_c', Expr.add([x_2_c]), Domain.equalsTo(1.0)) m.constraint('c_2_d', Expr.add([x_2_d]), Domain.equalsTo(1.0)) m.constraint('c_3_b', Expr.add([x_3_b]), Domain.equalsTo(1.0)) m.constraint('c_3_c', Expr.add([x_3_c]), Domain.equalsTo(1.0)) m.constraint('c_3_d', Expr.add([x_3_d]), Domain.equalsTo(1.0)) # Minimize resources required to construct all images. obj = [Expr.mul(c, x) for c, x in [ # Individual image/command pairs (r['A'], x_1_a), (r['B'], x_1_b), (r['A'], x_2_a), (r['B'], x_2_b), (r['C'], x_2_c), (r['D'], x_2_d), (r['B'], x_3_b), (r['C'], x_3_c), (r['D'], x_3_d), ]] m.objective('w', ObjectiveSense.Minimize, Expr.add(obj)) m.setLogHandler(sys.stdout) m.solve() print print 'Image 1:' print '\tx_1_a = %.0f' % x_1_a.level()[0] print '\tx_1_b = %.0f' % x_1_b.level()[0] print
def Build_Co_Model(self): r = len(self.roads) mu, sigma = self.mu, self.sigma m, n, r = self.m, self.n, len(self.roads) f, h = self.f, self.h M, N = m + n + r, 2 * m + 2 * n + r A = self.__Construct_A_Matrix() A_Mat = Matrix.dense(A) b = self.__Construct_b_vector() # ---- build Mosek Model COModel = Model() # -- Decision Variable Z = COModel.variable('Z', m, Domain.inRange(0.0, 1.0)) I = COModel.variable('I', m, Domain.greaterThan(0.0)) Alpha = COModel.variable('Alpha', M, Domain.unbounded()) # M by 1 vector Beta = COModel.variable('Beta', M, Domain.unbounded()) # M by 1 vector Theta = COModel.variable('Theta', N, Domain.unbounded()) # N by 1 vector # M1_matrix related decision variables ''' [tau, xi^T, phi^T M1 = xi, eta, psi^t phi, psi, w ] ''' # no-need speedup variables Psi = COModel.variable('Psi', [N, n], Domain.unbounded()) Xi = COModel.variable('Xi', n, Domain.unbounded()) # n by 1 vector Phi = COModel.variable('Phi', N, Domain.unbounded()) # N by 1 vector # has the potential to speedup Tau, Eta, W = self.__Declare_SpeedUp_Vars(COModel) # M2 matrix decision variables ''' [a, b^T, c^T M2 = b, e, d^t c, d, f ] ''' a_M2 = COModel.variable('a_M2', 1, Domain.greaterThan(0.0)) b_M2 = COModel.variable('b_M2', n, Domain.greaterThan(0.0)) c_M2 = COModel.variable('c_M2', N, Domain.greaterThan(0.0)) e_M2 = COModel.variable('e_M2', [n, n], Domain.greaterThan(0.0)) d_M2 = COModel.variable('d_M2', [N, n], Domain.greaterThan(0.0)) f_M2 = COModel.variable('f_M2', [N, N], Domain.greaterThan(0.0)) # -- Objective Function obj_1 = Expr.dot(f, Z) obj_2 = Expr.dot(h, I) obj_3 = Expr.dot(b, Alpha) obj_4 = Expr.dot(b, Beta) obj_5 = Expr.dot([1], Expr.add(Tau, a_M2)) obj_6 = Expr.dot([2 * mean for mean in mu], Expr.add(Xi, b_M2)) obj_7 = Expr.dot(sigma, Expr.add(Eta, e_M2)) COModel.objective( ObjectiveSense.Minimize, Expr.add([obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7])) # Constraint 1 _expr = Expr.sub(Expr.mul(A_Mat.transpose(), Alpha), Theta) _expr = Expr.sub(_expr, Expr.mul(2, Expr.add(Phi, c_M2))) _expr_rhs = Expr.vstack(Expr.constTerm([0.0] * n), Expr.mul(-1, I), Expr.constTerm([0.0] * M)) COModel.constraint('constr1', Expr.sub(_expr, _expr_rhs), Domain.equalsTo(0.0)) del _expr, _expr_rhs # Constraint 2 _first_term = Expr.add([ Expr.mul(Beta.index(row), np.outer(A[row], A[row]).tolist()) for row in range(M) ]) _second_term = Expr.add([ Expr.mul(Theta.index(k), Matrix.sparse(N, N, [k], [k], [1])) for k in range(N) ]) _third_term = Expr.add(W, f_M2) _expr = Expr.sub(Expr.add(_first_term, _second_term), _third_term) COModel.constraint('constr2', _expr, Domain.equalsTo(0.0)) del _expr, _first_term, _second_term, _third_term # Constraint 3 _expr = Expr.mul(-2, Expr.add(Psi, d_M2)) _expr_rhs = Matrix.sparse([[Matrix.eye(n)], [Matrix.sparse(N - n, n)]]) COModel.constraint('constr3', Expr.sub(_expr, _expr_rhs), Domain.equalsTo(0)) del _expr, _expr_rhs # Constraint 4: I <= M*Z COModel.constraint('constr4', Expr.sub(Expr.mul(20000.0, Z), I), Domain.greaterThan(0.0)) # Constraint 5: M1 is SDP COModel.constraint( 'constr5', Expr.vstack(Expr.hstack(Tau, Xi.transpose(), Phi.transpose()), Expr.hstack(Xi, Eta, Psi.transpose()), Expr.hstack(Phi, Psi, W)), Domain.inPSDCone(1 + n + N)) return COModel