Ejemplo n.º 1
0
 def _update_variables_type(self):
     vartype = self._modeltype_to_vartype(self._mtype)
     for name, variable in self._variables.items():
         self._variables[name] = pyqubo.Array.create(name,
                                                     shape=variable.shape,
                                                     vartype=vartype)
     df = self.select_interaction(query="removed == False")
     for index, interaction in df.iterrows():
         interacts = interaction["interacts"]
         if self._mtype == constants.MODEL_ISING:
             if isinstance(interacts, tuple):
                 self._interactions_array["interacts"][index] = (
                     pyqubo.Spin(interaction["interacts"][0].label),
                     pyqubo.Spin(interaction["interacts"][1].label),
                 )
             else:
                 self._interactions_array["interacts"][index] = pyqubo.Spin(
                     interaction["interacts"].label)
         elif self._mtype == constants.MODEL_QUBO:
             if isinstance(interacts, tuple):
                 self._interactions_array["interacts"][index] = (
                     pyqubo.Binary(interaction["interacts"][0].label),
                     pyqubo.Binary(interaction["interacts"][1].label),
                 )
             else:
                 self._interactions_array["interacts"][
                     index] = pyqubo.Binary(interaction["interacts"].label)
Ejemplo n.º 2
0
def test_zero_or_one_hot_constraint():
    c = ZeroOrOneHotConstraint()
    assert c.get_constraint_class() == "ZeroOrOneHotConstraint"
    assert c.get_variables() == set()
    assert c.get_label() == "Default Zero-or-One-hot Constraint"
    assert c.get_strength() == 1.0

    x0 = pyqubo.Spin("x0")
    x1 = pyqubo.Spin("x1")
    x2 = pyqubo.Binary("x2")

    c.add_variable(x0)
    assert c.get_variables() == set([x0])
    assert len(c.get_variables()) == 1

    c.add_variable([x1, x2])
    assert c.get_variables() == set([x0, x1, x2])
    assert len(c.get_variables()) == 3

    c.add_variable(set([x0]))
    assert c.get_variables() == set([x0, x1, x2])
    assert len(c.get_variables()) == 3

    c.add_variable(variables=[x0, x1])
    assert c.get_variables() == set([x0, x1, x2])
    assert len(c.get_variables()) == 3

    c.remove_variable(variables=[x0])
    assert c.get_variables() == set([x1, x2])
    assert len(c.get_variables()) == 2

    with pytest.raises(ValueError):
        c.remove_variable(variables=[x0])
Ejemplo n.º 3
0
def test_n_hot_constraint():
    c = NHotConstraint()
    assert c.get_constraint_class() == "NHotConstraint"
    assert c.get_variables() == set()
    assert c.get_n() == 1
    assert c.get_label() == "Default N-hot Constraint"
    assert c.get_strength() == 1.0

    x0 = pyqubo.Spin("x0")
    x1 = pyqubo.Spin("x1")
    x2 = pyqubo.Binary("x2")

    c.add_variable(x0)
    assert c.get_variables() == {x0}
    assert len(c.get_variables()) == 1

    c.add_variable([x1, x2])
    assert c.get_variables() == {x0, x1, x2}
    assert len(c.get_variables()) == 3

    c.add_variable({x0})
    assert c.get_variables() == {x0, x1, x2}
    assert len(c.get_variables()) == 3

    c.add_variable(variables=[x0, x1])
    assert c.get_variables() == {x0, x1, x2}
    assert len(c.get_variables()) == 3

    c.remove_variable(variables=[x0])
    assert c.get_variables() == {x1, x2}
    assert len(c.get_variables()) == 2

    with pytest.raises(ValueError):
        c.remove_variable(variables=[x0])
Ejemplo n.º 4
0
def Constrain_NumberOfFermions(n_so, n_ferm):
    # see https://buildmedia.readthedocs.org/media/pdf/pyqubo/stable/pyqubo.pdf
    qubits = [pyqubo.Binary(str(i)) for i in range(n_so)]
    H = sum(qubits) - n_ferm
    H = H * H
    model = H.compile()
    qubo, offset = model.to_qubo()
    return qubo
Ejemplo n.º 5
0
 def create_bin_vars(self):
     bin_vars = {}
     for job, ops in self.time_vars.items():
         bin_vars[job] = {}
         for op_num, op_times in enumerate(ops, start=1):
             bin_vars[job][op_num] = {}
             for op_time in op_times:
                 bin_vars[job][op_num][op_time] = pyqubo.Binary(
                     "x_{}_o{}_t{}".format(job, op_num, op_time))
     return bin_vars
def test_equality_constraint():
    c = EqualityConstraint()
    assert c.get_constraint_class() == "EqualityConstraint"
    assert c.get_variables_1() == set()
    assert c.get_variables_2() == set()
    assert c.get_label() == "Default Equality Constraint"
    assert c.get_strength() == 1.0

    x0 = pyqubo.Spin("x0")
    x1 = pyqubo.Spin("x1")
    y0 = pyqubo.Binary("y0")
    y1 = pyqubo.Binary("y1")

    c.add_variable_to_1(x0)
    assert c.get_variables_1() == {x0}
    assert c.get_variables_2() == set()

    c.add_variable_to_1([x1])
    assert c.get_variables_1() == {x0, x1}
    assert c.get_variables_2() == set()

    c.add_variable_to_2({y0})
    assert c.get_variables_1() == {x0, x1}
    assert c.get_variables_2() == {y0}

    c.add_variable_to_2(variables=[y0, y1])
    assert c.get_variables_1() == {x0, x1}
    assert c.get_variables_2() == {y0, y1}

    c.remove_variable_from_1(variables=x0)
    assert c.get_variables_1() == {x1}
    assert c.get_variables_2() == {y0, y1}

    c.remove_variable_from_2(variables=y1)
    assert c.get_variables_1() == {x1}
    assert c.get_variables_2() == {y0}

    with pytest.raises(ValueError):
        c.remove_variable_from_1(variables=[x0])

    with pytest.raises(ValueError):
        c.remove_variable_from_2(variables=[y1])
Ejemplo n.º 7
0
def test_n_hot_constraint_eq():
    assert NHotConstraint() == NHotConstraint()

    a = pyqubo.Spin("a")
    b = pyqubo.Binary("b")
    c1 = NHotConstraint(variables={a, b}, n=2, label="my label", strength=20)
    c2 = NHotConstraint(variables=[a, b],
                        n=2,
                        label="my label",
                        strength=2 * 10)
    assert c1 == c2
Ejemplo n.º 8
0
def test_zero_or_one_hot_constraint_eq():
    assert ZeroOrOneHotConstraint() == ZeroOrOneHotConstraint()

    a = pyqubo.Spin("a")
    b = pyqubo.Binary("b")
    c1 = ZeroOrOneHotConstraint(variables=set([a, b]),
                                label="my label",
                                strength=20)
    c2 = ZeroOrOneHotConstraint(variables=[a, b],
                                label="my label",
                                strength=2 * 10)
    assert c1 == c2
def test_equality_constraint_eq():
    assert EqualityConstraint() == EqualityConstraint()

    a = pyqubo.Spin("a")
    b = pyqubo.Binary("b")
    c1 = EqualityConstraint(variables_1={a},
                            variables_2=b,
                            label="my label",
                            strength=20)
    c2 = EqualityConstraint(variables_1=[a],
                            variables_2=b,
                            label="my label",
                            strength=2 * 10)
    assert c1 == c2
Ejemplo n.º 10
0
def test_zero_or_one_hot_constraint_ne():
    a = pyqubo.Spin("a")
    b = pyqubo.Binary("b")
    c = []
    c.append(ZeroOrOneHotConstraint())
    c.append(
        ZeroOrOneHotConstraint(variables=[a, b], label="my label",
                               strength=20))
    c.append(ZeroOrOneHotConstraint(variables=set([a, b])))
    c.append(ZeroOrOneHotConstraint(variables=a))
    c.append(ZeroOrOneHotConstraint(label="my label"))
    c.append(ZeroOrOneHotConstraint(strength=20))
    c.append("another type")

    for i in range(len(c) - 1):
        for j in range(i + 1, len(c)):
            assert c[i] != c[j]
Ejemplo n.º 11
0
def test_n_hot_constraint_ne():
    a = pyqubo.Spin("a")
    b = pyqubo.Binary("b")
    c = []
    c.append(NHotConstraint())
    c.append(
        NHotConstraint(variables=[a, b], n=2, label="my label", strength=20))
    c.append(NHotConstraint(variables={a, b}))
    c.append(NHotConstraint(variables=a))
    c.append(NHotConstraint(n=2))
    c.append(NHotConstraint(label="my label"))
    c.append(NHotConstraint(strength=20))
    c.append("another type")

    for i in range(len(c) - 1):
        for j in range(i + 1, len(c)):
            assert c[i] != c[j]
def test_equality_constraint_ne():
    a = pyqubo.Spin("a")
    b = pyqubo.Binary("b")
    c = []
    c.append(EqualityConstraint())
    c.append(
        EqualityConstraint(variables_1=[a],
                           variables_2=[b],
                           label="my label",
                           strength=20))
    c.append(EqualityConstraint(variables_1=[a], variables_2=[b]))
    c.append(EqualityConstraint(variables_1={a, b}))
    c.append(EqualityConstraint(variables_2={a, b}))
    c.append(EqualityConstraint(variables_1=a))
    c.append(EqualityConstraint(variables_2=a))
    c.append(EqualityConstraint(variables_1=b))
    c.append(EqualityConstraint(variables_2=b))
    c.append(EqualityConstraint(label="my label"))
    c.append(EqualityConstraint(strength=20))
    c.append("another type")

    for i in range(len(c) - 1):
        for j in range(i + 1, len(c)):
            assert c[i] != c[j]
Ejemplo n.º 13
0
    def to_physical(self, placeholder={}):
        physical = PhysicalModel(mtype=self._mtype)

        linear, quadratic = {}, {}
        will_remove = []

        # Save the model before merging constraints to restore it later
        # original_variables = copy.deepcopy(self._variables)  # Variables will not be changed
        original_offset = self._offset
        original_deleted = copy.deepcopy(self._deleted)
        original_fixed = copy.deepcopy(self._fixed)
        # original_constraints = copy.deepcopy(self._constraints)  # Constraints will not be changed
        original_interactions_array = copy.deepcopy(self._interactions_array)
        original_interactions_attrs = copy.deepcopy(self._interactions_attrs)
        original_interactions_length = self._interactions_length

        # Resolve constraints, and convert them to the interactions
        for label, constraint in self._constraints.items():
            constraint_model = constraint.to_model()
            self.merge(constraint_model)

        # group by key
        for i in range(self._interactions_length):
            if self._interactions_array["removed"][i]:
                will_remove.append(self._interactions_array["name"][i])
                continue

            # Resolve placeholders for coefficients and scales, using PyQUBO.
            # Firstly resolve placeholders if the coefficient is already Coefficient type
            coeff_i = self._interactions_array["coefficient"][i]
            scale_i = self._interactions_array["scale"][i]
            if isinstance(coeff_i, pyqubo.core.Coefficient):
                coeff_i = coeff_i.evaluate(feed_dict=placeholder)

            # Calculate coefficient with the placeholder
            coeff_with_ph = coeff_i * scale_i
            coeff_model = (
                coeff_with_ph + pyqubo.Binary("sawatabi-fake-variable")
            ).compile()  # We need a variable for a valid model for pyqubo
            coeff_ph_resolved = coeff_model.to_qubo(feed_dict=placeholder)
            coeff = coeff_ph_resolved[
                1]  # We don't need the variable just prepared, extracting only offset

            if self._interactions_array["body"][
                    i] == constants.INTERACTION_LINEAR:
                if self._interactions_array["key"][i] in linear:
                    linear[self._interactions_array["key"][i]] += coeff
                else:
                    linear[self._interactions_array["key"][i]] = coeff

            elif self._interactions_array["body"][
                    i] == constants.INTERACTION_QUADRATIC:
                if self._interactions_array["key"][i] in quadratic:
                    quadratic[self._interactions_array["key"][i]] += coeff
                else:
                    quadratic[self._interactions_array["key"][i]] = coeff

        # For offset as well
        offset = self._offset
        if isinstance(self._offset, pyqubo.core.Coefficient):
            offset = self._offset.evaluate(feed_dict=placeholder)
        # Calculate coefficient with the placeholder
        offset_model = (
            offset + pyqubo.Binary("sawatabi-fake-variable")
        ).compile()  # We need a variable for a valid model for pyqubo
        offset_ph_resolved = offset_model.to_qubo(feed_dict=placeholder)
        offset = offset_ph_resolved[
            1]  # We don't need the variable just prepared, extracting only offset

        # set to physical
        for k, v in linear.items():
            if v != 0.0:
                physical.add_interaction(k,
                                         body=constants.INTERACTION_LINEAR,
                                         coefficient=v)
                physical._variables_set.add(k)
        for k, v in quadratic.items():
            if v != 0.0:
                physical.add_interaction(k,
                                         body=constants.INTERACTION_QUADRATIC,
                                         coefficient=v)
                physical._variables_set.add(k[0])
                physical._variables_set.add(k[1])
        physical._offset = offset

        # label_to_index / index_to_label
        current_index = 0
        for val in self._variables.values():
            flattened = list(Functions._flatten(val.bit_list))
            for v in flattened:
                if (v.label
                        not in self._deleted) and (v.label
                                                   in physical._variables_set):
                    physical._label_to_index[v.label] = current_index
                    physical._index_to_label[current_index] = v.label
                    current_index += 1

        # save the last physical model
        self._previous_physical_model = physical

        # Restore the model before adding constraints
        # self._variables = original_variables  # Variables were not changed
        self._offset = original_offset
        self._deleted = original_deleted
        self._fixed = original_fixed
        # self._constraints = original_constraints  # Constraints were not changed
        self._interactions_array = original_interactions_array
        self._interactions_attrs = original_interactions_attrs
        self._interactions_length = original_interactions_length

        # Remove interactions
        # TODO: Physically remove the logically removed interactions
        for rm in will_remove:
            idx = self._interactions_array["name"].index(rm)
            for k in self._interactions_array.keys():
                self._interactions_array[k].pop(idx)
            self._interactions_length -= 1

        # Set dirty flag
        for i in range(self._interactions_length):
            # TODO: Calc difference from previous physical model by referencing dirty flags.
            if self._interactions_array["dirty"][i]:
                self._interactions_array["dirty"][i] = False

        return physical
Ejemplo n.º 14
0
    def _create_model(self, job_num, machine_num, job_ids, r_times, d_times,
                      p_intervals, assign, prev_start_time):
        """ Set I' is set of jobs assigned to machines, their assign variable equal to 1"""
        print("assignment:", assign)
        print("previous start time:", prev_start_time)
        # set_I_apos = set S' = {i,j | x_im = x_jm = 1}
        set_I_apos = [
            i_id for i_id in range(job_num) for m_id in range(machine_num)
            if assign[(i_id, m_id)].x == 1
        ]
        # print("set I apos:", set_I_apos)
        z_apos = {
            i_id: m_id
            for i_id in range(job_num) for m_id in range(machine_num)
            if assign[(i_id, m_id)].x == 1
        }
        print(z_apos)
        """ Prepare the index for decision variables """
        # start time of process
        jobs = tuple(job_ids)
        # print("inside:", jobs)
        # sequence of processing jobs: tuple list
        job_pairs_apos = [(i, j) for i in set_I_apos for j in set_I_apos
                          if i != j and z_apos[i] == z_apos[j]]
        # print(job_pairs_apos)
        # # assignment of jobs on machines
        # job_machine_pairs = [(i, m) for i in jobs for m in machines]
        # print(job_machine_pairs)
        """ Parameters model (dictionary) """
        # 1. release time
        release_time = dict(zip(jobs, tuple(r_times)))
        # print("release time:", release_time)
        # 2. due time
        due_time = dict(zip(jobs, tuple(d_times)))
        # print("due time:", due_time)
        # 3. processing time
        process_time = dict(zip(jobs, tuple(p_intervals)))
        print("process time:", process_time)
        U = sum([max(p_intervals[i]) for i in range(job_num)])
        print("test U:", U)

        # for (i,j) in job_pairs_apos:
        #     print("job apos:", i,j)
        #     print(process_time[i][z_apos[i]] - max(due_time.values()))
        """ Create decision variables """
        # # 1. Sequence (Order) of executing jobs
        # y = model.addVars(job_pairs_apos, vtype=grb.GRB.BINARY, name="sequence")
        # # 2. Start time of executing each job (ts = time_start)
        # ts = model.addVars(set_I_apos, lb=0, name="start_time")

        y = {
            item: pyqubo.Binary("y_(%d,%d)" % item)
            for item in job_pairs_apos
        }
        print("y is: {}".format(y))
        """ Create the objective function """
        # model.setObjective(0, sense=grb.GRB.MINIMIZE)
        H = 0
        for (i, j) in job_pairs_apos:
            H += (1 - y[(i, j)] - y[(j, i)] + 2 * y[(i, j)] * y[(j, i)] +
                  y[(i, j)] *
                  (U * (prev_start_time[i].x - prev_start_time[j].x) +
                   sum(process_time[i][m] * assign[(i, m)].x
                       for m in range(machine_num) if assign[(i, m)].x == 1)))
        print("H is {}".format(H))

        # """ Create constraints """
        # # 1. job release time constraint
        # model.addConstrs((ts[i] >= release_time[i] for i in set_I_apos), name="assigned job release constraint")
        # # 2. job due time constraint
        # model.addConstrs((ts[i] <= due_time[i] - process_time[i][z_apos[i]] for i in set_I_apos),
        #                  name="assigned job due constraint")
        # # 3. when assigned, either job 'i' is processed before job 'j' or vice versa
        # model.addConstrs((y[(i,j)] + y[(j,i)] == 1 for (i,j) in job_pairs_apos if i > j and
        #                   assign[(i,z_apos[i])].x == assign[(j,z_apos[j])].x), name="sequence of assigned jobs")
        # # 4. valid cut, starting times, using latest due date as big-M parameter
        # model.addConstrs((ts[j] >= ts[i] + process_time[i][z_apos[i]] - max(due_time.values())*(1 - y[(i,j)])
        #                   for (i,j) in job_pairs_apos if z_apos[j] == z_apos[i]), name="valid cut by big-M")

        # return model, y, ts
        """ Create model """
        model = H.compile()

        ts = prev_start_time

        return model, y, ts, job_pairs_apos, z_apos, U