Beispiel #1
0
def from_pandas_dataframe(bqm_df, offset=0.0, interactions=[]):
    """Build a binary quadratic model from a pandas dataframe.

    Args:
        bqm_df (:class:`pandas.DataFrame`):
            A pandas dataframe. The row and column indices should be that variables of the binary
            quadratic program. The values should be the coefficients of a qubo.

        offset (optional, default=0.0):
            The constant offset for the binary quadratic program.

        interactions (iterable, optional, default=[]):
            Any additional 0.0-bias interactions to be added to the binary quadratic model.

    Returns:
        :class:`.BinaryQuadraticModel`

    """
    bqm = BinaryQuadraticModel({}, {}, offset, Vartype.BINARY)

    for u, row in bqm_df.iterrows():
        for v, bias in row.iteritems():
            if u == v:
                bqm.add_variable(u, bias)
            elif bias:
                bqm.add_interaction(u, v, bias)

    for u, v in interactions:
        bqm.add_interaction(u, v, 0.0)

    return bqm
Beispiel #2
0
def bin_packing(
        num_items: int,
        seed: int = 32,
        weight_range: Tuple[int, int] = (10, 30),
) -> ConstrainedQuadraticModel:
    """Returns a constrained quadratic model encoding a bin packing problem

    Given the number of items, the code generates a random bin packing problem
    formulated as a Constrained Quadratic model. The weights for each item are
    integers uniformly drawn from in the weight_range. The bin capacity is set
    to num_items * mean(weights) / 5.

    Args:
        num_items: Number of items to choose from.

        seed: Seed for numpy random number  generator.

        weight_range: The range of the randomly generated weights for each item.

    Returns:
        The constrained quadratic model encoding the bin packing problem.
        Variables are labeled as y_{j} where y_{j} = 1 means that bin j has
        been used and x_{i}_{j} where x_{i}_{j} = 1 means that item i has been
        placed in bin j.

    """
    max_num_bins = num_items
    np.random.seed(seed)
    weights = list(np.random.randint(*weight_range, num_items))
    bin_capacity = int(num_items * np.mean(weights) / 5)
    model = ConstrainedQuadraticModel()

    obj = BinaryQuadraticModel(vartype='BINARY')
    y = {j: obj.add_variable(f'y_{j}') for j in range(max_num_bins)}

    for j in range(max_num_bins):
        obj.set_linear(y[j], 1)

    model.set_objective(obj)

    x = {(i, j): model.add_variable(f'x_{i}_{j}', vartype='BINARY')
         for i in range(num_items) for j in range(max_num_bins)}

    # Each item goes to one bin
    for i in range(num_items):
        model.add_constraint([(x[(i, j)], 1)
                              for j in range(max_num_bins)] + [(-1, )],
                             sense="==",
                             label='item_placing_{}'.format(i))

    # Bin capacity constraint
    for j in range(max_num_bins):
        model.add_constraint([(x[(i, j)], weights[i])
                              for i in range(num_items)] +
                             [(y[j], -bin_capacity)],
                             sense="<=",
                             label='capacity_bin_{}'.format(j))

    return model
Beispiel #3
0
def from_numpy_matrix(mat, variable_order=None, offset=0.0, interactions=[]):
    """Build a binary quadratic model from a numpy matrix.

    Args:
        mat (:class:`numpy.matrix`):
            A square numpy matrix. The coefficients of a qubo.

        variable_order (list, optional):
            If variable_order is provided, provides the labels for the variables in the binary
            quadratic program, otherwise the row/column indices will be used. If variable_order
            is longer than the matrix, the extra values are ignored.

        offset (optional, default=0.0):
            The constant offset for the binary quadratic program.

        interactions (iterable, optional, default=[]):
            Any additional 0.0-bias interactions to be added to the binary quadratic model.

    Returns:
        :class:`.BinaryQuadraticModel`

    """
    import numpy as np

    if mat.ndim != 2:
        raise ValueError("expected input mat to be a square matrix")  # pragma: no cover

    num_row, num_col = mat.shape
    if num_col != num_row:
        raise ValueError("expected input mat to be a square matrix")  # pragma: no cover

    if variable_order is None:
        variable_order = list(range(num_row))

    bqm = BinaryQuadraticModel({}, {}, offset, Vartype.BINARY)

    for (row, col), bias in np.ndenumerate(mat):
        if row == col:
            bqm.add_variable(variable_order[row], bias)
        elif bias:
            bqm.add_interaction(variable_order[row], variable_order[col], bias)

    for u, v in interactions:
        bqm.add_interaction(u, v, 0.0)

    return bqm
Beispiel #4
0
def random_knapsack(
    num_items: int,
    seed: int = 32,
    value_range: Tuple[int, int] = (10, 30),
    weight_range: Tuple[int, int] = (10, 30),
    tightness_ratio: float = 0.5,
) -> ConstrainedQuadraticModel:
    """Returns a Constrained Quadratic Model encoding a knapsack problem.

    Given the number of items, the code generates a random knapsack problem,
    formulated as a Constrained Quadratic model. The capacity of the bin is set
    to be ``tightness_ratio`` times the sum of the weights.

    Args:
        num_items: Number of items to choose from.

        seed: Seed for numpy random number generator.

        value_range: The range of the randomly generated values for each item.

        weight_range: The range of the randomly generated weights for each item.

        tightness_ratio: ratio of capacity over sum of weights.

    Returns:
        The quadratic model encoding the knapsack problem. Variables are
        denoted as ``x_{i}`` where ``x_{i} == 1`` means that the item ``i`` has
        been placed in the knapsack.

    """

    rng = np.random.RandomState(seed)

    value = {i: rng.randint(*value_range) for i in range(num_items)}
    weight = {i: rng.randint(*weight_range) for i in range(num_items)}
    capacity = int(sum(weight.values()) * tightness_ratio)

    model = ConstrainedQuadraticModel()
    obj = BinaryQuadraticModel(vartype='BINARY')
    x = {i: obj.add_variable(f'x_{i}') for i in range(num_items)}

    for i in range(num_items):
        obj.set_linear(x[i], -value[i])

    model.set_objective(obj)
    constraint = [(x[i], weight[i])
                  for i in range(num_items)] + [(-capacity, )]
    model.add_constraint(constraint, sense="<=", label='capacity')

    return model
Beispiel #5
0
def random_multi_knapsack(
        num_items: int,
        num_bins: int,
        seed: int = 32,
        value_range: Tuple[int, int] = (10, 50),
        weight_range: Tuple[int, int] = (10, 50),
) -> ConstrainedQuadraticModel:
    """Return a constrained quadratic model encoding a multiple knapsack
    problem.

    Given the number of items and the number of bins, the code generates a
    multiple-knapsack problem, formulated as a Constrained Quadratic Model.
    Values and weights  for each item are uniformly sampled within the provided
    ranges. Capacities of bins are randomly assigned.

    Args:
        num_items: Number of items.

        num_bins: Number of bins.

        seed: seed for RNG.

        value_range: The range of the randomly generated values for each item.

        weight_range: The range of the randomly generated weights for each item.

    Returns:

        A constrained quadratic model encoding the multiple knapsack problem.
        Variables are labelled as ``x_{i}_{j}``, where ``x_{i}_{j} == 1`` means
        that item ``i`` is placed in bin ``j``.

    """

    rng = np.random.RandomState(seed)

    weights = rng.randint(*weight_range, num_items)
    values = rng.randint(*value_range, num_items)

    cap_low = int(weight_range[0] * num_items / num_bins)
    cap_high = int(weight_range[1] * num_items / num_bins)
    capacities = rng.randint(cap_low, cap_high, num_bins)

    model = ConstrainedQuadraticModel()

    obj = BinaryQuadraticModel(vartype='BINARY')
    x = {(i, j): obj.add_variable(f'x_{i}_{j}')
         for i in range(num_items) for j in range(num_bins)}

    for i in range(num_items):
        for j in range(num_bins):
            obj.set_linear(x[(i, j)], -values[i])

    model.set_objective(obj)

    # Each item at most goes to one bin.
    for i in range(num_items):
        model.add_constraint([(x[(i, j)], 1)
                              for j in range(num_bins)] + [(-1, )],
                             sense="<=",
                             label='item_placing_{}'.format(i))

    # Build knapsack capacity constraints
    for j in range(num_bins):
        model.add_constraint([(x[(i, j)], weights[i])
                              for i in range(num_items)] +
                             [(-capacities[j], )],
                             sense="<=",
                             label='capacity_bin_{}'.format(j))

    return model