def classical_exactcover_solver(A, w=None, num_threads=4):
    nrows, ncolumns = np.shape(A)
    if w is None:
        w = np.ones(ncolumns)
    assert(len(w) == ncolumns)
    assert(sum(w >= 0))
    model = CyLPModel()
    # Decision variables, one for each cover
    x = model.addVariable('x', ncolumns, isInt=True)
    # Adding the box contraints
    model += 0 <= x <= 1
    # Adding the cover constraints
    # Sum_j x_ij ==  1
    for i in range(nrows):
        model += CyLPArray(A[i,:]) * x == 1
    # Adding the objective function
    model.objective = CyLPArray(w) * x
    lp = CyClpSimplex(model)
    lp.logLevel = 0
    lp.optimizationDirection = 'min'
    mip = lp.getCbcModel()
    mip.logLevel = 0
    # Setting number of threads
    mip.numberThreads = num_threads
    mip.solve()

    return mip.objectiveValue, [int(i) for i in mip.primalVariableSolution['x']]
def branch_and_bound(G, num_threads=4):
    N = len(G)
    model = CyLPModel()
    # Decision variables, one for each node
    x = model.addVariable('x', N, isInt=True)
    # Adjacency matrix (possibly weighted)
    W = nx.to_numpy_matrix(G)
    z_ind = dict()
    ind = 0
    w = []
    for i in range(N):
        j_range = range(N)
        if (not nx.is_directed(G)):
            # Reduced range for undirected graphs
            j_range = range(i, N)
        for j in j_range:
            if (W[i,j] == 0):
                continue
            if (i not in z_ind):
                z_ind[i] = dict()  
            z_ind[i][j] = ind
            w.append(W[i,j])
            ind += 1
    # Aux variables, one for each edge
    z = model.addVariable('z', len(w), isInt=True)
    # Adding the box contraints
    model += 0 <= x <= 1
    model += 0 <= z <= 1
    # Adding the cutting constraints
    # If x_i == x_j then z_ij = 0
    # If x_i != x_j then z_ij = 1
    for i in z_ind:
        for j in z_ind[i]:
            model += z[z_ind[i][j]] - x[i] - x[j] <= 0
            model += z[z_ind[i][j]] + x[i] + x[j] <= 2
    # Adding the objective function
    model.objective = CyLPArray(w) * z
    lp = CyClpSimplex(model)
    lp.logLevel = 0
    lp.optimizationDirection = 'max'
    mip = lp.getCbcModel()
    mip.logLevel = 0
    # Setting number of threads
    mip.numberThreads = num_threads
    mip.solve()

    return mip.objectiveValue, [int(i) for i in mip.primalVariableSolution['x']]
def plpd2d(xs, zs, ys, x_0, z_0):
    x, z, y = xs, zs, ys
    dim_p = len(x)
    rhs_p = np.array([x_0, z_0, 1], dtype=np.double)
    dim_d = len(rhs_p)

    s = CyClpSimplex()
    u = s.addVariable('u', dim_p)
    l = s.addVariable('l', dim_d)

    A_p = np.vstack([y, x, z, np.ones(dim_p)])

    A_p = np.matrix(A_p)
    b_p = CyLPArray([0, x_0, z_0, 1])

    A_d = np.hstack(
        [x.reshape(-1, 1),
         z.reshape(-1, 1),
         np.ones(len(x)).reshape(-1, 1)])
    A_d = np.matrix(A_d)
    b_d = CyLPArray(y)

    A_d1 = np.matrix(np.vstack([-rhs_p, np.zeros((3, 3))]))

    s += A_p * u + A_d1 * l == b_p

    s += A_d * l <= b_d

    for i in range(dim_p):
        s += u[i] >= 0

    s.optimizationDirection = 'max'
    s.objective = u[0]
    s.primal()
    cond = s.primalVariableSolution['u']
    y_res = np.dot(cond, y)

    return y_res
Beispiel #4
0
x0, z0 = 0.5, 0.5

rhs_p = np.array([x0, z0, 1], dtype=np.double)

dim_d = len(rhs_p)

A_d = np.hstack(
    [x.reshape(-1, 1),
     z.reshape(-1, 1),
     np.ones(len(x)).reshape(-1, 1)])
A_d = np.matrix(A_d)

s = CyClpSimplex()

l = s.addVariable('l', dim_d)

b_d = CyLPArray(y)

s += A_d * l >= b_d

s.optimizationDirection = 'max'
s.objectiveCoefficients = rhs_p

s.primal()

print(s.primalVariableSolution)
print(s.dualVariableSolution)

print(s.dualConstraintSolution)
print(s.primalConstraintSolution)
# s_pos += A_p_pos*u_pos + A_d1*l_pos == b_p
# s_neg += A_p_neg*u_neg + A_d1*l_neg == b_p

for i in range(dim_p):
    s += u[i] >= 0
    # s_pos += u_pos[i] >= 0
    # s_neg += u_neg[i] >= 0

# s_pos += A_d*l_pos <= b_d_pos
# s_neg += A_d*l_neg >= b_d_neg

# s_pos.objective = u_pos[0]
# s_neg.objective = u_neg[0]

s.optimizationDirection = 'min'
s.objectiveCoefficients = y

# s_pos.primal()
# s_neg.primal()

s.primal()

# print(s_pos.primalVariableSolution)
# print(s_pos.dualVariableSolution)

# cond_pos = s_pos.primalVariableSolution['u']
# x1_pos = np.dot(cond_pos, x)
# y1_pos = np.dot(cond_pos, y_pos)

# cond_neg = s_neg.primalVariableSolution['u']
def classical_maxkcut_solver(G, num_partitions, num_threads=4):
    # G: NetworkX graph
    # num_partitions: the number partitions or groups in which we should
    #                 subdivide the nodes (i.e., the value of K)

    N = len(G)
    model = CyLPModel()
    # Decision variables, one for each node
    x = model.addVariable('x', num_partitions * N, isInt=True)
    # Adjacency matrix (possibly weighted)
    W = nx.to_numpy_matrix(G)
    z_ind = dict()
    ind = 0
    w = []
    for i in range(N):
        j_range = range(N)
        if (not nx.is_directed(G)):
            # Reduced range for undirected graphs
            j_range = range(i, N)
        for j in j_range:
            if (W[i, j] == 0):
                continue
            if (i not in z_ind):
                z_ind[i] = dict()
            z_ind[i][j] = ind
            w.append(W[i, j])
            ind += 1
    # Aux variables, one for each edge
    z = model.addVariable('z', len(w), isInt=True)
    # Adding the box contraints
    model += 0 <= x <= 1
    model += 0 <= z <= 1
    # Adding the selection constraints
    for i in range(N):
        indices = [i + k * N for k in range(num_partitions)]
        model += x[indices].sum() == 1
    # Adding the cutting constraints
    for i in z_ind:
        for j in z_ind[i]:
            for k in range(num_partitions):
                shift = k * N
                model += z[z_ind[i][j]] + x[i + shift] + x[j + shift] <= 2
                model += z[z_ind[i][j]] + x[i + shift] - x[j + shift] >= 0
                model += z[z_ind[i][j]] - x[i + shift] + x[j + shift] >= 0
    # Adding the objective function
    model.objective = CyLPArray(w) * z
    lp = CyClpSimplex(model)
    lp.logLevel = 0
    lp.optimizationDirection = 'max'
    mip = lp.getCbcModel()
    mip.logLevel = 0
    # Setting number of threads
    mip.numberThreads = num_threads
    mip.solve()
    sol = [int(i) for i in mip.primalVariableSolution['x']]
    sol_formatted = []
    for i in range(N):
        indices = [i + k * N for k in range(num_partitions)]
        for j in range(num_partitions):
            if (sol[indices[j]] == 1):
                sol_formatted.append(j)
                break

    assert (len(sol_formatted) == N)

    return mip.objectiveValue, sol_formatted