コード例 #1
0
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
コード例 #2
0
    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)
コード例 #3
0
    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)
コード例 #4
0
    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
コード例 #5
0
    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
コード例 #6
0
x_2_b = m.variable('x_2_b', *binary)
x_2_c = m.variable('x_2_c', *binary)
x_2_d = m.variable('x_2_d', *binary)

x_3_b = m.variable('x_3_b', *binary)
x_3_c = m.variable('x_3_c', *binary)
x_3_d = m.variable('x_3_d', *binary)

# Provide a variable for each maximal clique and maximal sub-clique.
x_23_bcd = m.variable('x_23_bcd', *binary)

x_123_b = m.variable('x_123_b', *binary)
x_123_b_23_cd = m.variable('x_123_b_23_cd', *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, x_123_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, 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))
コード例 #7
0
    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[i,s,c] = 1 if image i runs command c during stage s, 0 otherwise.
        self.x = x = {}
        for i, cmds in problem.images.items():
            for s, c in product(problem.stages[i], cmds):
                x[i,s,c] = model.variable(
                    'x[%s,%s,%s]' % (i,s,c), 1,
                    Domain.inRange(0.0, 1.0),
                    Domain.isInteger()
                )

        # y[ip,iq,s,c] = 1 if images ip & iq have a shared path through stage
        #                s by running command c during s, 0 otherwise.
        y = {}
        for (ip, iq), cmds in problem.shared_cmds.items():
            for s, c in product(problem.shared_stages[ip, iq], cmds):
                y[ip,iq,s,c] = model.variable(
                    'y[%s,%s,%s,%s]' % (ip,iq,s,c), 1,
                    Domain.inRange(0.0, 1.0),
                    Domain.isInteger()
                    # Domain.inRange(0.0, 1.0)
                )

        # TODO: need to remove presolved commands so the heuristic doesn't try them.
        # TODO: Add a heuristic initial solution.
        # TODO: Presolving

        # Each image one command per stage, and each command once.
        for i in problem.images:
            for s in problem.stages[i]:
                model.constraint('c1[%s,%s]' % (i,s),
                    Expr.add([x[i,s,c] for c in problem.images[i]]),
                    Domain.equalsTo(1.0)
                )
            for c in problem.images[i]:
                model.constraint('c2[%s,%s]' % (i,c),
                    Expr.add([x[i,s,c] for s in problem.stages[i]]),
                    Domain.equalsTo(1.0)
                )

        # Find shared paths among image pairs.
        for (ip, iq), cmds in problem.shared_cmds.items():
            for s in problem.shared_stages[ip,iq]:
                for c in cmds:
                    model.constraint('c3[%s,%s,%s,%s]' % (ip,iq,s,c),
                        Expr.sub(y[ip,iq,s,c], x[ip,s,c]),
                        Domain.lessThan(0.0)
                    )
                    model.constraint('c4[%s,%s,%s,%s]' % (ip,iq,s,c),
                        Expr.sub(y[ip,iq,s,c], x[iq,s,c]),
                        Domain.lessThan(0.0)
                    )
                if s > 1:
                    lhs = Expr.add([y[ip,iq,s,c] for c in cmds])
                    rhs = Expr.add([y[ip,iq,s-1,c] for c in cmds])
                    model.constraint('c5[%s,%s,%s,%s]' % (ip,iq,s,c),
                        Expr.sub(lhs, rhs), Domain.lessThan(0.0)
                    )

        if y:
            obj = Expr.add(y.values())
        else:
            obj = 0.0
        model.objective('z', ObjectiveSense.Maximize, obj)
        model.setLogHandler(sys.stdout)
        model.acceptedSolutionStatus(AccSolutionStatus.Feasible)
        model.solve()

        # Create optimal schedule.
        schedule = defaultdict(list)
        for i, stages in problem.stages.items():
            for s in stages:
                for c in problem.images[i]:
                    if x[i,s,c].level()[0] > 0.5:
                        schedule[i].append(c)
                        break

        saver(schedule)
コード例 #8
0
    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)
コード例 #9
0
z_2_c = m.variable('z_2_c', *binary)
z_2_d = m.variable('z_2_d', *binary)

z_3_b = m.variable('z_3_b', *binary)
z_3_c = m.variable('z_3_c', *binary)
z_3_d = m.variable('z_3_d', *binary)

# Inclusion of an image and a command means that image must
# use all command invocation from the clique.
# For instance:
#     (1) z_1_a <= w_1
#     (2) z_1_a <= y_a
#     (3) z_1_a >= w_1 + y_a - 1
m.constraint('c_1_a_1', Expr.sub(z_1_a, w_1), Domain.lessThan(0.0))
m.constraint('c_1_a_2', Expr.sub(z_1_a, y_a), Domain.lessThan(0.0))
m.constraint('c_1_a_3', Expr.sub(z_1_a, Expr.add([w_1, y_a])), Domain.greaterThan(-1.0))

m.constraint('c_1_b_1', Expr.sub(z_1_b, w_1), Domain.lessThan(0.0))
m.constraint('c_1_b_2', Expr.sub(z_1_b, y_b), Domain.lessThan(0.0))
m.constraint('c_1_b_3', Expr.sub(z_1_b, Expr.add([w_1, y_b])), Domain.greaterThan(-1.0))

m.constraint('c_1_c', Expr.sub(0.0, Expr.add([w_1, y_c])), Domain.greaterThan(-1.0))
m.constraint('c_1_d', Expr.sub(0.0, Expr.add([w_1, y_d])), Domain.greaterThan(-1.0))

m.constraint('c_2_a_1', Expr.sub(z_2_a, w_2), Domain.lessThan(0.0))
m.constraint('c_2_a_2', Expr.sub(z_2_a, y_a), Domain.lessThan(0.0))
m.constraint('c_2_a_3', Expr.sub(z_2_a, Expr.add([w_2, y_a])), Domain.greaterThan(-1.0))

m.constraint('c_2_b_1', Expr.sub(z_2_b, w_2), Domain.lessThan(0.0))
m.constraint('c_2_b_2', Expr.sub(z_2_b, y_b), Domain.lessThan(0.0))
m.constraint('c_2_b_3', Expr.sub(z_2_b, Expr.add([w_2, y_b])), Domain.greaterThan(-1.0))
コード例 #10
0
q_2_c = m.variable('q_2_c', *binary)
q_2_d = m.variable('q_2_d', *binary)

q_3_b = m.variable('q_3_b', *binary)
q_3_c = m.variable('q_3_c', *binary)
q_3_d = m.variable('q_3_d', *binary)

# Inclusion of an image and a command means that image must
# use all command invocation from the clique.
# For instance:
#     (1) z_1_a <= w_1
#     (2) z_1_a <= y_a
#     (3) z_1_a >= w_1 + y_a - 1
m.constraint('c_1_a_1', Expr.sub(z_1_a, w_1), Domain.lessThan(0.0))
m.constraint('c_1_a_2', Expr.sub(z_1_a, y_a), Domain.lessThan(0.0))
m.constraint('c_1_a_3', Expr.sub(z_1_a, Expr.add([w_1, y_a])),
             Domain.greaterThan(-1.0))

m.constraint('c_1_b_1', Expr.sub(z_1_b, w_1), Domain.lessThan(0.0))
m.constraint('c_1_b_2', Expr.sub(z_1_b, y_b), Domain.lessThan(0.0))
m.constraint('c_1_b_3', Expr.sub(z_1_b, Expr.add([w_1, y_b])),
             Domain.greaterThan(-1.0))

m.constraint('c_1_c', Expr.sub(0.0, Expr.add([w_1, y_c])),
             Domain.greaterThan(-1.0))
m.constraint('c_1_d', Expr.sub(0.0, Expr.add([w_1, y_d])),
             Domain.greaterThan(-1.0))

m.constraint('c_2_a_1', Expr.sub(z_2_a, w_2), Domain.lessThan(0.0))
m.constraint('c_2_a_2', Expr.sub(z_2_a, y_a), Domain.lessThan(0.0))
m.constraint('c_2_a_3', Expr.sub(z_2_a, Expr.add([w_2, y_a])),
コード例 #11
0
x_2_d = m.variable('x_2_d', *binary)

x_3_b = m.variable('x_3_b', *binary)
x_3_c = m.variable('x_3_c', *binary)
x_3_d = m.variable('x_3_d', *binary)

# Provide a variable for each maximal clique and maximal sub-clique.
x_23_bcd = m.variable('x_23_bcd', *binary)

x_123_b = m.variable('x_123_b', *binary)
x_123_b_23_cd = m.variable('x_123_b_23_cd', *binary)

x_12_a  = m.variable('x_12_a', *binary)

# Each command must be run once for each image.
m.constraint('c_1_a', Expr.add([x_1_a, x_12_a]), Domain.equalsTo(1.0))
m.constraint('c_1_b', Expr.add([x_1_b, x_123_b]), Domain.equalsTo(1.0))
m.constraint('c_2_a', Expr.add([x_2_a, x_12_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))
m.constraint('e2', Expr.add([x_12_a, x_123_b]), Domain.lessThan(1.0))
コード例 #12
0
    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)
コード例 #13
0
# Provide a variable for each image and command. This is 1 if the command
# is not run as part of a clique for the image.
x_1_a = m.variable('x_1_a', *binary)
x_1_b = m.variable('x_1_b', *binary)

x_2_a = m.variable('x_2_a', *binary)
x_2_b = m.variable('x_2_b', *binary)
x_2_c = m.variable('x_2_c', *binary)
x_2_d = m.variable('x_2_d', *binary)

x_3_b = m.variable('x_3_b', *binary)
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),
コード例 #14
0
q_2_c = m.variable('q_2_c', *binary)
q_2_d = m.variable('q_2_d', *binary)

q_3_b = m.variable('q_3_b', *binary)
q_3_c = m.variable('q_3_c', *binary)
q_3_d = m.variable('q_3_d', *binary)

# Inclusion of an image and a command means that image must
# use all command invocation from the clique.
# For instance:
#     (1) z_1_a <= w_1
#     (2) z_1_a <= y_a
#     (3) z_1_a >= w_1 + y_a - 1
m.constraint('c_1_a_1', Expr.sub(z_1_a, w_1), Domain.lessThan(0.0))
m.constraint('c_1_a_2', Expr.sub(z_1_a, y_a), Domain.lessThan(0.0))
m.constraint('c_1_a_3', Expr.sub(z_1_a, Expr.add([w_1, y_a])), Domain.greaterThan(-1.0))

m.constraint('c_1_b_1', Expr.sub(z_1_b, w_1), Domain.lessThan(0.0))
m.constraint('c_1_b_2', Expr.sub(z_1_b, y_b), Domain.lessThan(0.0))
m.constraint('c_1_b_3', Expr.sub(z_1_b, Expr.add([w_1, y_b])), Domain.greaterThan(-1.0))

m.constraint('c_1_c', Expr.sub(0.0, Expr.add([w_1, y_c])), Domain.greaterThan(-1.0))
m.constraint('c_1_d', Expr.sub(0.0, Expr.add([w_1, y_d])), Domain.greaterThan(-1.0))

m.constraint('c_2_a_1', Expr.sub(z_2_a, w_2), Domain.lessThan(0.0))
m.constraint('c_2_a_2', Expr.sub(z_2_a, y_a), Domain.lessThan(0.0))
m.constraint('c_2_a_3', Expr.sub(z_2_a, Expr.add([w_2, y_a])), Domain.greaterThan(-1.0))

m.constraint('c_2_b_1', Expr.sub(z_2_b, w_2), Domain.lessThan(0.0))
m.constraint('c_2_b_2', Expr.sub(z_2_b, y_b), Domain.lessThan(0.0))
m.constraint('c_2_b_3', Expr.sub(z_2_b, Expr.add([w_2, y_b])), Domain.greaterThan(-1.0))
コード例 #15
0
z_2_c = m.variable('z_2_c', *binary)
z_2_d = m.variable('z_2_d', *binary)

z_3_b = m.variable('z_3_b', *binary)
z_3_c = m.variable('z_3_c', *binary)
z_3_d = m.variable('z_3_d', *binary)

# Inclusion of an image and a command means that image must
# use all command invocation from the clique.
# For instance:
#     (1) z_1_a <= w_1
#     (2) z_1_a <= y_a
#     (3) z_1_a >= w_1 + y_a - 1
m.constraint('c_1_a_1', Expr.sub(z_1_a, w_1), Domain.lessThan(0.0))
m.constraint('c_1_a_2', Expr.sub(z_1_a, y_a), Domain.lessThan(0.0))
m.constraint('c_1_a_3', Expr.sub(z_1_a, Expr.add([w_1, y_a])),
             Domain.greaterThan(-1.0))

m.constraint('c_1_b_1', Expr.sub(z_1_b, w_1), Domain.lessThan(0.0))
m.constraint('c_1_b_2', Expr.sub(z_1_b, y_b), Domain.lessThan(0.0))
m.constraint('c_1_b_3', Expr.sub(z_1_b, Expr.add([w_1, y_b])),
             Domain.greaterThan(-1.0))

m.constraint('c_1_c', Expr.sub(0.0, Expr.add([w_1, y_c])),
             Domain.greaterThan(-1.0))
m.constraint('c_1_d', Expr.sub(0.0, Expr.add([w_1, y_d])),
             Domain.greaterThan(-1.0))

m.constraint('c_2_a_1', Expr.sub(z_2_a, w_2), Domain.lessThan(0.0))
m.constraint('c_2_a_2', Expr.sub(z_2_a, y_a), Domain.lessThan(0.0))
m.constraint('c_2_a_3', Expr.sub(z_2_a, Expr.add([w_2, y_a])),
コード例 #16
0
def __sum_weighted(c1, expr1, c2, expr2):
    return Expr.add(Expr.mul(c1, expr1), Expr.mul(c2, expr2))
コード例 #17
0
def __sum_weighted(c1, expr1, c2, expr2):
    return Expr.add(Expr.mul(c1, expr1), Expr.mul(c2, expr2))
コード例 #18
0
q_2_c = m.variable('q_2_c', *binary)
q_2_d = m.variable('q_2_d', *binary)

q_3_b = m.variable('q_3_b', *binary)
q_3_c = m.variable('q_3_c', *binary)
q_3_d = m.variable('q_3_d', *binary)

# Inclusion of an image and a command means that image must
# use all command invocation from the clique.
# For instance:
#     (1) z_1_a <= w_1
#     (2) z_1_a <= y_a
#     (3) z_1_a >= w_1 + y_a - 1
m.constraint('c_1_a_1', Expr.sub(z_1_a, w_1), Domain.lessThan(0.0))
m.constraint('c_1_a_2', Expr.sub(z_1_a, y_a), Domain.lessThan(0.0))
m.constraint('c_1_a_3', Expr.sub(z_1_a, Expr.add([w_1, y_a])), Domain.greaterThan(-1.0))

m.constraint('c_1_b_1', Expr.sub(z_1_b, w_1), Domain.lessThan(0.0))
m.constraint('c_1_b_2', Expr.sub(z_1_b, y_b), Domain.lessThan(0.0))
m.constraint('c_1_b_3', Expr.sub(z_1_b, Expr.add([w_1, y_b])), Domain.greaterThan(-1.0))

m.constraint('c_1_c', Expr.sub(0.0, Expr.add([w_1, y_c])), Domain.greaterThan(-1.0))
m.constraint('c_1_d', Expr.sub(0.0, Expr.add([w_1, y_d])), Domain.greaterThan(-1.0))

m.constraint('c_2_a_1', Expr.sub(z_2_a, w_2), Domain.lessThan(0.0))
m.constraint('c_2_a_2', Expr.sub(z_2_a, y_a), Domain.lessThan(0.0))
m.constraint('c_2_a_3', Expr.sub(z_2_a, Expr.add([w_2, y_a])), Domain.greaterThan(-1.0))

m.constraint('c_2_b_1', Expr.sub(z_2_b, w_2), Domain.lessThan(0.0))
m.constraint('c_2_b_2', Expr.sub(z_2_b, y_b), Domain.lessThan(0.0))
m.constraint('c_2_b_3', Expr.sub(z_2_b, Expr.add([w_2, y_b])), Domain.greaterThan(-1.0))
コード例 #19
0
# Provide a variable for each image and command. This is 1 if the command
# is not run as part of a clique for the image.
x_1_a = m.variable('x_1_a', *binary)
x_1_b = m.variable('x_1_b', *binary)

x_2_a = m.variable('x_2_a', *binary)
x_2_b = m.variable('x_2_b', *binary)
x_2_c = m.variable('x_2_c', *binary)
x_2_d = m.variable('x_2_d', *binary)

x_3_b = m.variable('x_3_b', *binary)
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),
コード例 #20
0
    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