Exemplo n.º 1
0
def solve(Ws, Cs, Qs, ws, b, transitive_reduction=True,
          svg_file="", lp_file="", mps_file="",
          script=None, script_options=None, stats=None, verbose=None):
    """
    Solve multiple-choice vector bin packing instances
    using the method proposed in:
    Brandao, F. and Pedroso, J. P. (2013). Multiple-choice Vector
    Bin Packing: Arc-flow Formulation with Graph Compression. Technical Report
    DCC-2013-13, Faculdade de Ciencias da Universidade do Porto, Universidade
    do Porto, Portugal.
    """
    assert script is not None
    assert svg_file == "" or svg_file.endswith(".svg")
    if stats is None and verbose is not None:
        stats = verbose
    nbtypes = len(Ws)
    ndims = len(Ws[0])

    ww = []
    bb = []
    itlabel = []
    for i in range(len(ws)):
        for j in range(len(ws[i])):
            itlabel.append((i, j))
            ww.append(ws[i][j])
            bb.append(b[i])

    LOSS = "L"
    instances = [None] * nbtypes
    graphs = [None] * nbtypes
    Ss, Ts = [None] * nbtypes, [None] * nbtypes
    for i in range(nbtypes):
        bbi = bb[:]
        for j in range(len(ww)):
            if any(a > b for a, b in zip(ww[j], Ws[i])):
                bbi[j] = 0
                continue
        symb = "G{0}:".format(i)
        instances[i] = VBP(Ws[i], ww, bbi, verbose=False)
        graphs[i] = AFG(instances[i], verbose=verbose).graph()
        loss = graphs[i].LOSS
        graphs[i].relabel(
            lambda u: "{0}{1}".format(symb, u),
            lambda lbl: lbl if lbl != loss else LOSS
        )
        Ss[i] = graphs[i].S
        Ts[i] = graphs[i].Ts[0]
        graphs[i].A.remove((Ts[i], Ss[i], LOSS))
        if svg_file.endswith(".svg"):
            try:
                graphs[i].draw(
                    svg_file.replace(".svg", "{0}.svg".format(i+1)),
                    verbose=verbose
                )
            except Exception as e:
                VPSolver.log(e, verbose)

    S, T = "S", "T"
    V = sum([g.V for g in graphs], [])
    A = sum([g.A for g in graphs], [])
    V += [S, T]
    A += [(S, s, LOSS) for s in Ss]
    A += [(t, T, LOSS) for t in Ts]
    A += [(T, S, LOSS)]

    graph = AFGraph(V, A, S, [T], LOSS)
    if svg_file.endswith(".svg"):
        try:
            graph.draw(svg_file, verbose=verbose)
        except Exception as e:
            VPSolver.log(e, verbose)

    adj = {u: [] for u in V}
    for (u, v, i) in A:
        adj[v].append((u, i))

    VPSolver.log("Final compression steps:", verbose)

    nv1, na1 = len(V), len(A)
    VPSolver.log("  #V1: {0} #A1: {1}".format(nv1, na1), verbose=stats)
    zero = tuple([0]*ndims)

    def compress(u):
        if u == S:
            return zero
        if u in newlbl:
            return newlbl[u]
        lbl = zero
        for v, i in adj[u]:
            wi = ww[i] if i != LOSS else zero
            vlbl = compress(v)
            lbl = tuple(max(lbl[d], vlbl[d]+wi[d]) for d in range(ndims))
        newlbl[u] = lbl
        return lbl

    # Relabel the graph using the longest path from the source:
    newlbl = {}
    compress(T)
    newlbl[S] = S
    newlbl[T] = T
    for t in Ts:
        newlbl[t] = t
    for u in newlbl:
        if newlbl[u] == zero:
            newlbl[u] = S
    graph.relabel(lambda u: newlbl.get(u, u))

    if transitive_reduction:
        # Reduce graph size by connecting nodes to non-dominated targets only:
        tadj = {}
        for (u, v, i) in graph.A:
            if isinstance(u, tuple):
                if v in Ts:
                    if u not in tadj:
                        tadj[u] = []
                    tadj[u].append(Ts.index(v))

        graph.A = [
            (u, v, i) for (u, v, i) in graph.A if v not in Ts
        ]
        V, A = set(graph.V), set(graph.A)

        def fits(w1, w2):
            return all(x <= y for x, y in zip(w1, w2))

        dominatedby = {i: [] for i in range(nbtypes)}
        for i in range(nbtypes):
            for j in range(nbtypes):
                if i < j and Ws[i] == Ws[j]:
                    dominatedby[i].append(j)
                elif i != j and fits(Ws[i], Ws[j]):
                    dominatedby[i].append(j)

        for v in tadj:
            tgts = set(tadj[v])
            for i in range(nbtypes):
                if i not in tgts:
                    continue
                for j in dominatedby[i]:
                    try:
                        tgts.remove(j)
                    except:
                        pass
            for t in tgts:
                A.add((v, Ts[t], LOSS))

        for i in range(nbtypes):
            tgts = set(dominatedby[i])
            for j in dominatedby[i]:
                for t in dominatedby[j]:
                    try:
                        tgts.remove(t)
                    except:
                        pass
            for t in tgts:
                A.add((Ts[i], Ts[t], LOSS))

        graph.V, graph.A = V, A

    # Relabel the graph with indices:
    newlbl = {}
    for u in graph.get_vertices_sorted():
        if isinstance(u, tuple):
            newlbl[u] = len(newlbl)+1
    graph.relabel(lambda u: newlbl.get(u, u))
    V, A = graph.V, graph.A

    nv2, na2 = len(V), len(A)
    VPSolver.log("  #V2: {0} #A2: {1}".format(nv2, na2), verbose=stats)
    VPSolver.log("  #V2/#V1 = {0:.2f}".format(nv2/nv1), verbose=stats)
    VPSolver.log("  #A2/#A1 = {0:.2f}".format(na2/na1), verbose=stats)

    if svg_file.endswith(".svg"):
        try:
            graph.draw(svg_file.replace(".svg", ".final.svg"), verbose=verbose)
        except Exception as e:
            VPSolver.log(e, verbose)

    # Remove redudant parallel arcs:
    At = []
    used = set()
    for (u, v, i) in A:
        k = itlabel[i][0] if i != LOSS else LOSS
        if (u, v, k) not in used:
            At.append((u, v, i))
            used.add((u, v, k))
    A = At
    graph = AFGraph(V, A, S, [T], LOSS)

    nv3, na3 = len(V), len(A)
    VPSolver.log("  #V3: {0} #A3: {1}".format(nv3, na3), verbose=stats)
    VPSolver.log("  #V3/#V1 = {0:.2f}".format(nv3/nv1), verbose=stats)
    VPSolver.log("  #A3/#A1 = {0:.2f}".format(na3/na1), verbose=stats)

    # Generate the model:
    varl, cons = graph.get_flow_cons()
    assocs = graph.get_assocs()
    for i in range(len(b)):
        lincomb = [
            (var, 1)
            for it, (j, t) in enumerate(itlabel) if j == i
            for var in assocs[it]
        ]
        if b[i] > 1:
            cons.append((lincomb, ">=", b[i]))
        else:
            cons.append((lincomb, "=", b[i]))

    model = Model()

    ub = {}
    for i in range(len(b)):
        for var in assocs[i]:
            ub[var] = b[i]

    n = sum(b)
    for i in range(nbtypes):
        var = graph.vname(Ts[i], T, LOSS)
        if Qs[i] == -1:
            ub[var] = n
        else:
            ub[var] = min(Qs[i], n)

    for var in varl:
        # model.add_var(name=var, lb=0, vtype="I")
        model.add_var(name=var, lb=0, ub=ub.get(var, None), vtype="I")

    for lincomb, sign, rhs in cons:
        model.add_con(lincomb, sign, rhs)

    lincomb = [(graph.vname(Ts[i], T, LOSS), Cs[i]) for i in range(nbtypes)]
    model.set_obj("min", lincomb)

    model_file = VPSolver.new_tmp_file(".lp")
    model.write(model_file)
    if lp_file.endswith(".lp"):
        model.write(lp_file)
        VPSolver.log(".LP model successfully generated!", verbose)
    if mps_file.endswith(".mps"):
        model.write(mps_file)
        VPSolver.log(".MPS model successfully generated!", verbose)
    out, varvalues = VPSolver.script_wsol(script, model_file, verbose=verbose)
    os.remove(model_file)

    VPSolver.log("#V1: {0} #A1: {1}".format(nv1, na1), verbose)
    VPSolver.log("#V2: {0} #A2: {1}".format(nv2, na2), verbose)
    VPSolver.log("#V3: {0} #A3: {1}".format(nv3, na3), verbose)
    VPSolver.log(
        "#V3/#V1: {0:.2f} #A3/#A1: {1:.2f}".format(
            nv3/nv1, na3/na1
        ),
        verbose
    )

    labels = {}
    for (u, v, i) in A:
        if i != LOSS:
            labels[u, v, i] = [itlabel[i]]

    lst_sol = []
    graph.set_flow(varvalues)
    graph.set_labels(labels)
    for i in range(nbtypes):
        lst_sol.append(graph.extract_solution(S, "<-", Ts[i]))

    validate_solution(lst_sol, nbtypes, ndims, Ws, ws, b)

    c1 = sum(sum(r for r, patt in lst_sol[i])*Cs[i] for i in range(nbtypes))
    c2 = sum(
        varvalues.get(graph.vname(Ts[i], T, LOSS), 0) * Cs[i]
        for i in range(nbtypes)
    )
    assert c1 == c2

    return c1, lst_sol
Exemplo n.º 2
0
def solve(
        Ws, Cs, Qs, ws, b, svg_file="", lp_file="", mps_file="",
        script="vpsolver_glpk.sh", verbose=False):
    """
    Solves multiple-choice vector bin packing instances
    using the method proposed in:
    Brandao, F. and Pedroso, J. P. (2013). Multiple-choice Vector
    Bin Packing: Arc-flow Formulation with Graph Compression. Technical Report
    DCC-2013-13, Faculdade de Ciencias da Universidade do Porto, Universidade
    do Porto, Portugal.
    """
    assert svg_file == "" or svg_file.endswith(".svg")
    nbtypes = len(Ws)
    ndims = len(Ws[0])

    ww = []
    bb = []
    itlabel = []
    for i in range(len(ws)):
        for j in range(len(ws[i])):
            itlabel.append((i, j))
            ww.append(ws[i][j])
            bb.append(b[i])

    instances = [None] * nbtypes
    graphs = [None] * nbtypes
    Ss, Ts = [None] * nbtypes, [None] * nbtypes
    for i in range(nbtypes):
        bbi = bb[:]
        for j in range(len(ww)):
            if any(a > b for a, b in zip(ww[j], Ws[i])):
                bbi[j] = 0
                continue
        symb = "G{0}".format(i)
        instances[i] = VBP(Ws[i], ww, bbi, verbose=False)
        graphs[i] = AFG(instances[i], verbose=verbose).graph()
        graphs[i].relabel(lambda u: "{0}{1}".format(symb, u))
        Ss[i] = symb+"S"
        Ts[i] = symb+"T"
        if svg_file.endswith(".svg"):
            try:
                graphs[i].draw(svg_file.replace(".svg", "{0}.svg".format(i)))
            except Exception as e:
                VPSolver.log(e, verbose)

    V = sum([g.V for g in graphs], [])
    A = sum([g.A for g in graphs], [])
    V += ["S", "T"]
    A += [("S", s, "L") for s in Ss]
    A += [(t, "T", "L") for t in Ts]
    A += [("T", "S", "L")]

    graph = AFGraph(V, A, "S", "T")
    if svg_file.endswith(".svg"):
        try:
            graph.draw(svg_file, ignore=[("T", "S")])
        except Exception as e:
                VPSolver.log(e, verbose)

    adj = {u: [] for u in V}
    for (u, v, i) in A:
        adj[v].append((u, i))
    S, T = "S", "T"

    newlbl = {}

    def compress(u):
        if u == S:
            return [0]*ndims
        if u in newlbl:
            return newlbl[u]

        def itemw(lbl):
            if isinstance(lbl, int) and lbl < len(ww):
                return ww[lbl]
            else:
                return [0]*ndims

        lbl = [0]*ndims
        for v, i in adj[u]:
            wi = itemw(i)
            vlbl = compress(v)
            for d in range(ndims):
                lbl[d] = max(lbl[d], vlbl[d]+wi[d])
        newlbl[u] = lbl
        return lbl

    compress(T)
    revlbl = {tuple(x): [] for x in newlbl.values()}
    for u in newlbl:
        if u not in Ts+[T]:
            revlbl[tuple(newlbl[u])].append(u)

    revlbl2 = {}
    for i, x in enumerate(sorted(revlbl)):
        if sum(x) != 0:
            revlbl2["V{0}".format(i)] = revlbl[x]
        else:
            revlbl2[S] = revlbl[x]

    vlbl = {}
    for lbl in revlbl2:
        for v in revlbl2[lbl]:
            vlbl[v] = lbl

    assert set([v for v in V if v not in vlbl]) == set([S, T]+Ts)

    VPSolver.log("Final compression steps:", verbose)

    nv1, na1 = len(V), len(A)
    VPSolver.log("  #V1: {0} #A1: {1}".format(nv1, na1), verbose)

    graph.relabel(lambda u: vlbl.get(u, u))
    V, A = graph.V, graph.A

    nv2, na2 = len(V), len(A)
    VPSolver.log("  #V2: {0} #A2: {1}".format(nv2, na2), verbose)
    VPSolver.log("  #V2/#V1 = {0:.2f}".format(nv2/nv1), verbose)
    VPSolver.log("  #A2/#A1 = {0:.2f}".format(na2/na1), verbose)

    if svg_file.endswith(".svg"):
        try:
            graph.draw(
                svg_file.replace(".svg", ".final.svg"), ignore=[("T", "S")]
            )
        except Exception as e:
                VPSolver.log(e, verbose)

    # remove redudant parallel arcs
    At = []
    used = set()
    for (u, v, i) in A:
        k = itlabel[i][0] if (isinstance(i, int) and i < len(itlabel)) else "L"
        if (u, v, k) not in used:
            At.append((u, v, i))
            used.add((u, v, k))

    A = At
    graph = AFGraph(V, A, "S", "T")

    nv3, na3 = len(V), len(A)
    VPSolver.log("  #V3: {0} #A3: {1}".format(nv3, na3), verbose)
    VPSolver.log("  #V3/#V1 = {0:.2f}".format(nv3/nv1), verbose)
    VPSolver.log("  #A3/#A1 = {0:.2f}".format(na3/na1), verbose)

    varl, cons = graph.get_flow_cons()

    assocs = graph.get_assocs()
    for i in range(len(b)):
        lincomb = [
            (var, 1)
            for it, (j, t) in enumerate(itlabel) if j == i
            for var in assocs[it]
        ]
        # cons.append((lincomb, ">=", b[i]))
        if b[i] > 1:
            cons.append((lincomb, ">=", b[i]))
        else:
            cons.append((lincomb, "=", b[i]))

    model = Model()

    ub = {}
    for i in range(len(b)):
        for var in assocs[i]:
            ub[var] = b[i]

    n = sum(b)
    for i in range(nbtypes):
        var = graph.vname(Ts[i], "T", "L")
        ub[var] = min(Qs[i], n)

    for var in varl:
        # model.add_var(name=var, lb=0, vtype="I")
        model.add_var(name=var, lb=0, ub=ub.get(var, None), vtype="I")

    for lincomb, sign, rhs in cons:
        model.add_con(lincomb, sign, rhs)

    lincomb = [(graph.vname(Ts[i], "T", "L"), Cs[i]) for i in range(nbtypes)]
    model.set_obj("min", lincomb)

    model_file = VPSolver.new_tmp_file(".lp")
    model.write(model_file)
    if lp_file.endswith(".lp"):
        model.write(lp_file)
        VPSolver.log(".LP model successfully generated!", verbose)
    if mps_file.endswith(".mps"):
        model.write(mps_file)
        VPSolver.log(".MPS model successfully generated!", verbose)
    out, varvalues = VPSolver.script_wsol(script, model_file, verbose=verbose)
    os.remove(model_file)

    VPSolver.log("#V1: {0} #A1: {1}".format(nv1, na1), verbose)
    VPSolver.log("#V2: {0} #A2: {1}".format(nv2, na2), verbose)
    VPSolver.log("#V3: {0} #A3: {1}".format(nv3, na3), verbose)
    VPSolver.log(
        "#V3/#V1: {0:.2f} #A3/#A1: {1:.2f}".format(
            nv3/nv1, na3/na1
        ),
        verbose
    )

    labels = {}
    for (u, v, i) in A:
        if isinstance(i, int) and i < len(itlabel):
            labels[u, v, i] = [itlabel[i]]

    lst_sol = []
    graph.set_flow(varvalues)
    graph.set_labels(labels)
    for i in range(nbtypes):
        lst_sol.append(graph.extract_solution("S", "<-", Ts[i]))

    assert graph.validate_solution(lst_sol, nbtypes, ndims, Ws, ws, b)

    c1 = sum(sum(r for r, patt in lst_sol[i])*Cs[i] for i in range(nbtypes))
    c2 = sum(
        varvalues.get(graph.vname(Ts[i], "T", "L"), 0) * Cs[i]
        for i in range(nbtypes)
    )
    assert c1 == c2

    return c1, lst_sol
Exemplo n.º 3
0
def solve(Ws,
          Cs,
          Qs,
          ws,
          b,
          transitive_reduction=True,
          svg_file="",
          lp_file="",
          mps_file="",
          script=None,
          script_options=None,
          stats=None,
          verbose=None):
    """
    Solve multiple-choice vector bin packing instances
    using the method proposed in:
    Brandao, F. and Pedroso, J. P. (2013). Multiple-choice Vector
    Bin Packing: Arc-flow Formulation with Graph Compression. Technical Report
    DCC-2013-13, Faculdade de Ciencias da Universidade do Porto, Universidade
    do Porto, Portugal.
    """
    assert script is not None
    assert svg_file == "" or svg_file.endswith(".svg")
    if stats is None and verbose is not None:
        stats = verbose
    nbtypes = len(Ws)
    ndims = len(Ws[0])

    ww = []
    bb = []
    itlabel = []
    for i in range(len(ws)):
        for j in range(len(ws[i])):
            itlabel.append((i, j))
            ww.append(ws[i][j])
            bb.append(b[i])

    LOSS = "L"
    instances = [None] * nbtypes
    graphs = [None] * nbtypes
    Ss, Ts = [None] * nbtypes, [None] * nbtypes
    for i in range(nbtypes):
        bbi = bb[:]
        for j in range(len(ww)):
            if any(a > b for a, b in zip(ww[j], Ws[i])):
                bbi[j] = 0
                continue
        symb = "G{0}:".format(i)
        instances[i] = VBP(Ws[i], ww, bbi, verbose=False)
        graphs[i] = AFG(instances[i], verbose=verbose).graph()
        loss = graphs[i].LOSS
        graphs[i].relabel(lambda u: "{0}{1}".format(symb, u), lambda lbl: lbl
                          if lbl != loss else LOSS)
        Ss[i] = graphs[i].S
        Ts[i] = graphs[i].Ts[0]
        graphs[i].A.remove((Ts[i], Ss[i], LOSS))
        if svg_file.endswith(".svg"):
            try:
                graphs[i].draw(svg_file.replace(".svg",
                                                "{0}.svg".format(i + 1)),
                               verbose=verbose)
            except Exception as e:
                VPSolver.log(e, verbose)

    S, T = "S", "T"
    V = sum([g.V for g in graphs], [])
    A = sum([g.A for g in graphs], [])
    V += [S, T]
    A += [(S, s, LOSS) for s in Ss]
    A += [(t, T, LOSS) for t in Ts]
    A += [(T, S, LOSS)]

    graph = AFGraph(V, A, S, [T], LOSS)
    if svg_file.endswith(".svg"):
        try:
            graph.draw(svg_file, verbose=verbose)
        except Exception as e:
            VPSolver.log(e, verbose)

    adj = {u: [] for u in V}
    for (u, v, i) in A:
        adj[v].append((u, i))

    VPSolver.log("Final compression steps:", verbose)

    nv1, na1 = len(V), len(A)
    VPSolver.log("  #V1: {0} #A1: {1}".format(nv1, na1), verbose=stats)
    zero = tuple([0] * ndims)

    def compress(u):
        if u == S:
            return zero
        if u in newlbl:
            return newlbl[u]
        lbl = zero
        for v, i in adj[u]:
            wi = ww[i] if i != LOSS else zero
            vlbl = compress(v)
            lbl = tuple(max(lbl[d], vlbl[d] + wi[d]) for d in range(ndims))
        newlbl[u] = lbl
        return lbl

    # Relabel the graph using the longest path from the source:
    newlbl = {}
    compress(T)
    newlbl[S] = S
    newlbl[T] = T
    for t in Ts:
        newlbl[t] = t
    for u in newlbl:
        if newlbl[u] == zero:
            newlbl[u] = S
    graph.relabel(lambda u: newlbl.get(u, u))

    if transitive_reduction:
        # Reduce graph size by connecting nodes to non-dominated targets only:
        tadj = {}
        for (u, v, i) in graph.A:
            if isinstance(u, tuple):
                if v in Ts:
                    if u not in tadj:
                        tadj[u] = []
                    tadj[u].append(Ts.index(v))

        graph.A = [(u, v, i) for (u, v, i) in graph.A if v not in Ts]
        V, A = set(graph.V), set(graph.A)

        def fits(w1, w2):
            return all(x <= y for x, y in zip(w1, w2))

        dominatedby = {i: [] for i in range(nbtypes)}
        for i in range(nbtypes):
            for j in range(nbtypes):
                if i < j and Ws[i] == Ws[j]:
                    dominatedby[i].append(j)
                elif i != j and fits(Ws[i], Ws[j]):
                    dominatedby[i].append(j)

        for v in tadj:
            tgts = set(tadj[v])
            for i in range(nbtypes):
                if i not in tgts:
                    continue
                for j in dominatedby[i]:
                    try:
                        tgts.remove(j)
                    except:
                        pass
            for t in tgts:
                A.add((v, Ts[t], LOSS))

        for i in range(nbtypes):
            tgts = set(dominatedby[i])
            for j in dominatedby[i]:
                for t in dominatedby[j]:
                    try:
                        tgts.remove(t)
                    except:
                        pass
            for t in tgts:
                A.add((Ts[i], Ts[t], LOSS))

        graph.V, graph.A = V, A

    # Relabel the graph with indices:
    newlbl = {}
    for u in graph.get_vertices_sorted():
        if isinstance(u, tuple):
            newlbl[u] = len(newlbl) + 1
    graph.relabel(lambda u: newlbl.get(u, u))
    V, A = graph.V, graph.A

    nv2, na2 = len(V), len(A)
    VPSolver.log("  #V2: {0} #A2: {1}".format(nv2, na2), verbose=stats)
    VPSolver.log("  #V2/#V1 = {0:.2f}".format(nv2 / nv1), verbose=stats)
    VPSolver.log("  #A2/#A1 = {0:.2f}".format(na2 / na1), verbose=stats)

    if svg_file.endswith(".svg"):
        try:
            graph.draw(svg_file.replace(".svg", ".final.svg"), verbose=verbose)
        except Exception as e:
            VPSolver.log(e, verbose)

    # Remove redudant parallel arcs:
    At = []
    used = set()
    for (u, v, i) in A:
        k = itlabel[i][0] if i != LOSS else LOSS
        if (u, v, k) not in used:
            At.append((u, v, i))
            used.add((u, v, k))
    A = At
    graph = AFGraph(V, A, S, [T], LOSS)

    nv3, na3 = len(V), len(A)
    VPSolver.log("  #V3: {0} #A3: {1}".format(nv3, na3), verbose=stats)
    VPSolver.log("  #V3/#V1 = {0:.2f}".format(nv3 / nv1), verbose=stats)
    VPSolver.log("  #A3/#A1 = {0:.2f}".format(na3 / na1), verbose=stats)

    # Generate the model:
    varl, cons = graph.get_flow_cons()
    assocs = graph.get_assocs()
    for i in range(len(b)):
        lincomb = [(var, 1) for it, (j, t) in enumerate(itlabel) if j == i
                   for var in assocs[it]]
        if b[i] > 1:
            cons.append((lincomb, ">=", b[i]))
        else:
            cons.append((lincomb, "=", b[i]))

    model = Model()

    ub = {}
    for i in range(len(b)):
        for var in assocs[i]:
            ub[var] = b[i]

    n = sum(b)
    for i in range(nbtypes):
        var = graph.vname(Ts[i], T, LOSS)
        if Qs[i] == -1:
            ub[var] = n
        else:
            ub[var] = min(Qs[i], n)

    for var in varl:
        # model.add_var(name=var, lb=0, vtype="I")
        model.add_var(name=var, lb=0, ub=ub.get(var, None), vtype="I")

    for lincomb, sign, rhs in cons:
        model.add_con(lincomb, sign, rhs)

    lincomb = [(graph.vname(Ts[i], T, LOSS), Cs[i]) for i in range(nbtypes)]
    model.set_obj("min", lincomb)

    model_file = VPSolver.new_tmp_file(".lp")
    model.write(model_file)
    if lp_file.endswith(".lp"):
        model.write(lp_file)
        VPSolver.log(".LP model successfully generated!", verbose)
    if mps_file.endswith(".mps"):
        model.write(mps_file)
        VPSolver.log(".MPS model successfully generated!", verbose)
    out, varvalues = VPSolver.script_wsol(script, model_file, verbose=verbose)
    os.remove(model_file)

    VPSolver.log("#V1: {0} #A1: {1}".format(nv1, na1), verbose)
    VPSolver.log("#V2: {0} #A2: {1}".format(nv2, na2), verbose)
    VPSolver.log("#V3: {0} #A3: {1}".format(nv3, na3), verbose)
    VPSolver.log(
        "#V3/#V1: {0:.2f} #A3/#A1: {1:.2f}".format(nv3 / nv1, na3 / na1),
        verbose)

    labels = {}
    for (u, v, i) in A:
        if i != LOSS:
            labels[u, v, i] = [itlabel[i]]

    lst_sol = []
    graph.set_flow(varvalues)
    graph.set_labels(labels)
    for i in range(nbtypes):
        lst_sol.append(graph.extract_solution(S, "<-", Ts[i]))

    validate_solution(lst_sol, nbtypes, ndims, Ws, ws, b)

    c1 = sum(sum(r for r, patt in lst_sol[i]) * Cs[i] for i in range(nbtypes))
    c2 = sum(
        varvalues.get(graph.vname(Ts[i], T, LOSS), 0) * Cs[i]
        for i in range(nbtypes))
    assert c1 == c2

    return c1, lst_sol
Exemplo n.º 4
0
def test_model():
    """Test model."""
    from pympl import Model, Tools, glpkutils
    os.chdir(os.path.dirname(__file__) or os.curdir)
    model = Model()
    values = [15, 10, 9, 5]
    weights = [1, 5, 3, 4]
    xvars = []
    for i in range(len(values)):
        var = model.add_var(lb=0, ub=1, vtype="I")
        xvars.append(var)
    profit = model.add_var(lb=0, vtype="C")
    model.add_con([(x, w) for x, w in zip(xvars, weights)], "<=", 8)
    model.add_con(profit, "=", [(x, v) for x, v in zip(xvars, values)])
    model.set_obj("max", profit)
    lp_out = "tmp/model.lp"
    mps_out = "tmp/model.mps"
    mod_out = "tmp/model.mod"
    model.write(lp_out)
    model.write(mps_out)
    model.write(mod_out)
    out, varvalues = Tools.script("glpk_wrapper.sh", lp_out, verbose=True)
    assert varvalues[profit] == 29
    out, varvalues = Tools.script("glpk_wrapper.sh",
                                  mps_out,
                                  options="--max",
                                  verbose=True)
    assert varvalues[profit] == 29
    glpkutils.mod2lp(mod_out, lp_out, verbose=True)
    out, varvalues = Tools.script("glpk_wrapper.sh", lp_out, verbose=True)
    assert varvalues[profit] == 29
Exemplo n.º 5
0
def test_model():
    """Test model."""
    from pympl import Model, Tools, glpkutils
    os.chdir(os.path.dirname(__file__) or os.curdir)
    model = Model()
    values = [15, 10, 9, 5]
    weights = [1, 5, 3, 4]
    xvars = []
    for i in range(len(values)):
        var = model.add_var(lb=0, ub=1, vtype="I")
        xvars.append(var)
    profit = model.add_var(lb=0, vtype="C")
    model.add_con([(x, w) for x, w in zip(xvars, weights)], "<=", 8)
    model.add_con(profit, "=", [(x, v) for x, v in zip(xvars, values)])
    model.set_obj("max", profit)
    lp_out = "tmp/model.lp"
    mps_out = "tmp/model.mps"
    mod_out = "tmp/model.mod"
    model.write(lp_out)
    model.write(mps_out)
    model.write(mod_out)
    out, varvalues = Tools.script("glpk_wrapper.sh", lp_out, verbose=True)
    assert varvalues[profit] == 29
    out, varvalues = Tools.script(
        "glpk_wrapper.sh", mps_out, options="--max", verbose=True
    )
    assert varvalues[profit] == 29
    glpkutils.mod2lp(mod_out, lp_out, verbose=True)
    out, varvalues = Tools.script("glpk_wrapper.sh", lp_out, verbose=True)
    assert varvalues[profit] == 29