예제 #1
0
n_sweeps = 10000
n_replicas = 10
n_iterations = 10

# replicas are initialized with random samples
state = hybrid.State.from_problem(bqm)
replicas = hybrid.States(*[state.updated() for _ in range(n_replicas)])

# get a reasonable beta range
beta_hot, beta_cold = neal.default_beta_range(bqm)

# generate betas for all branches/replicas
betas = np.geomspace(beta_hot, beta_cold, n_replicas)

# run replicas update/swap for n_iterations
# (after each update/sampling step, do n_replicas-1 swap operations)
update = hybrid.Branches(
    *[FixedTemperatureSampler(beta, num_sweeps=n_sweeps) for beta in betas])
swap = SwapReplicasSweepDown(betas)
workflow = hybrid.Loop(update | swap, max_iter=n_iterations) \
         | hybrid.MergeSamples(aggregate=True)

solution = workflow.run(replicas).result()

# show execution profile
hybrid.profiling.print_counters(workflow)

# show results
print("Solution: sample={0.samples.first}, energy={0.samples.first.energy}".
      format(solution))
replicas = hybrid.States(*[state.updated() for _ in range(n_replicas)])

# get a reasonable beta range
beta_hot, beta_cold = neal.default_beta_range(bqm)

# generate betas for all branches/replicas
betas = np.geomspace(beta_hot, beta_cold, n_replicas)

# QPU branch: limits the PT workflow to QPU-sized problems
qpu = hybrid.IdentityDecomposer() | hybrid.QPUSubproblemAutoEmbeddingSampler(
) | hybrid.IdentityComposer()

# use QPU as the hottest temperature sampler and `n_replicas-1` fixed-temperature-samplers
update = hybrid.Branches(
    qpu, *[
        FixedTemperatureSampler(beta=beta, num_sweeps=n_sweeps)
        for beta in betas[1:]
    ])

# swap step is `n_replicas-1` pairwise potential swaps
swap = SwapReplicasDownsweep(betas=betas)

# we'll run update/swap sequence for `n_iterations`
workflow = hybrid.Loop(update | swap, max_iter=n_iterations) \
         | hybrid.MergeSamples(aggregate=True)

# execute the workflow
solution = workflow.run(replicas).result()

# show execution profile
hybrid.profiling.print_counters(workflow)
예제 #3
0
def HybridizedParallelTempering(num_sweeps=10000,
                                num_replicas=10,
                                max_iter=None,
                                max_time=None,
                                convergence=3):
    """Parallel tempering workflow generator.

    Args:
        num_sweeps (int, optional):
            Number of sweeps in the fixed temperature sampling.

        num_replicas (int, optional):
            Number of replicas (parallel states / workflow branches).

        max_iter (int/None, optional):
            Maximum number of iterations of the update/swaps loop.

        max_time (int/None, optional):
            Maximum wall clock runtime (in seconds) allowed in the update/swaps
            loop.

        convergence (int/None, optional):
            Number of times best energy of the coldest replica has to repeat
            before we terminate.

    Returns:
        Workflow (:class:`~hybrid.core.Runnable` instance).

    """

    # expand single input state into `num_replicas` replica states
    preprocess = SpawnParallelTemperingReplicas(num_replicas=num_replicas)

    # QPU branch: limits the PT workflow to QPU-sized problems
    qpu = (hybrid.IdentityDecomposer()
           | hybrid.QPUSubproblemAutoEmbeddingSampler()
           | hybrid.IdentityComposer())

    # use QPU as the hottest temperature sampler and `num_replicas-1` fixed-temperature-samplers
    update = hybrid.Branches(
        qpu, *[
            FixedTemperatureSampler(num_sweeps=num_sweeps)
            for _ in range(num_replicas - 1)
        ])

    # replica exchange step: do the top-down sweep over adjacent pairs
    # (good hot samples sink to bottom)
    swap = SwapReplicasDownsweep()

    # loop termination key function
    def key(states):
        if states is not None:
            return states[-1].samples.first.energy

    # replicas update/swap until Loop termination criteria reached
    loop = hybrid.Loop(update | swap,
                       max_iter=max_iter,
                       max_time=max_time,
                       convergence=convergence,
                       key=key)

    # collapse all replicas (although the bottom one should be the best)
    postprocess = hybrid.MergeSamples(aggregate=True)

    workflow = preprocess | loop | postprocess

    return workflow