示例#1
0
def ParallelTempering(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)

    # fixed temperature sampling on all replicas in parallel
    update = hybrid.Map(FixedTemperatureSampler(num_sweeps=num_sweeps))

    # 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
示例#2
0
subproblem_size = 100

print("BQM size: {}, subproblem size: {}".format(len(bqm), subproblem_size))
# Classical solvers
#subproblem = hybrid.EnergyImpactDecomposer(size=50, rolling_history=0.15)
#subproblem = hybrid.EnergyImpactDecomposer(size=1024, rolling_history=0.15, traversal="bfs")
# Parallel subproblem
subproblem = hybrid.Unwind(
    #hybrid.EnergyImpactDecomposer(size=subproblem_size, rolling_history=0.15, traversal="bfs")
    hybrid.EnergyImpactDecomposer(size=subproblem_size, rolling_history=0.1))

# QPU
#subsampler = hybrid.QPUSubproblemAutoEmbeddingSampler() | hybrid.SplatComposer()

subsampler = hybrid.Map(
    hybrid.QPUSubproblemAutoEmbeddingSampler()) | hybrid.Reduce(
        hybrid.Lambda(merge_substates)) | hybrid.SplatComposer()

# Define the workflow
# iteration = hybrid.RacingBranches(
#     hybrid.InterruptableTabuSampler(),
#     hybrid.EnergyImpactDecomposer(size=2)
#     | hybrid.QPUSubproblemAutoEmbeddingSampler()
#     | hybrid.SplatComposer()
# ) | hybrid.ArgMin()

#iteration = hybrid.RacingBranches(
iteration = hybrid.Race(
    hybrid.InterruptableTabuSampler(),
    #hybrid.SimulatedAnnealingProblemSampler(),
    subproblem | subsampler) | hybrid.ArgMin()
示例#3
0
n_replicas = 10
n_iterations = 10

# states are randomly initialized
state = hybrid.State.from_problem(bqm)

# 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)

# create n_replicas with geometric distribution of betas (inverse temperature)
replicas = hybrid.States(*[state.updated(beta=b) for b in betas])

# run replicas update/swap for n_iterations
# (after each update/sampling step, do n_replicas-1 swap operations)
update = hybrid.Map(FixedTemperatureSampler(num_sweeps=n_sweeps))
swap = SwapReplicasDownsweep()
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))
示例#4
0
problem = sys.argv[1]
with open(problem) as fp:
    bqm = dimod.BinaryQuadraticModel.from_coo(fp)


# define a qbsolv-like workflow
def merge_substates(_, substates):
    a, b = substates
    return a.updated(
        subsamples=hybrid.hstack_samplesets(a.subsamples, b.subsamples))


subproblems = hybrid.Unwind(
    hybrid.EnergyImpactDecomposer(size=50, rolling_history=0.15))

qpu = hybrid.Map(hybrid.QPUSubproblemAutoEmbeddingSampler()) | hybrid.Reduce(
    hybrid.Lambda(merge_substates)) | hybrid.SplatComposer()

random = hybrid.Map(hybrid.RandomSubproblemSampler()) | hybrid.Reduce(
    hybrid.Lambda(merge_substates)) | hybrid.SplatComposer()

subsampler = hybrid.Parallel(qpu, random, endomorphic=False) | hybrid.ArgMin()

iteration = hybrid.Race(hybrid.InterruptableTabuSampler(),
                        subproblems | subsampler) | hybrid.ArgMin()

main = hybrid.Loop(iteration, max_iter=10, convergence=3)

# run the workflow
init_state = hybrid.State.from_sample(hybrid.min_sample(bqm), bqm)
solution = main.run(init_state).result()