Odpowiednikiem „Hello World” w świecie D-Wave jest przykład szachownicy 2D. W tym przykładzie przedstawiono następujący kwadratowy wykres z 4 węzłami:
Zdefiniujmy, że kolorujemy wierzchołek czarny, jeśli σ i = - 1, i biały, jeśli σ i = + 1 . Celem jest utworzenie wzoru szachownicy z czterema wierzchołkami na wykresie. Istnieją różne sposoby definiowania
h i J w celu osiągnięcia tego wyniku. Przede wszystkim istnieją dwa możliwe rozwiązania tego problemu:σjaσja= - 1σja= + 1hjot
Kwantowy annealer D-Wave minimalizuje zdefiniowany przez nas Hamiltonian Isinga i ważne jest, aby zrozumieć wpływ różnych ustawień sprzęgacza. Rozważmy na przykład łącznik :jot0 , 1
Jeśli ustawimy , hamiltonian zostanie zminimalizowany, jeśli oba kubity przyjmą tę samą wartość. Mówimy, że sprzęgi ujemne korelują . Natomiast jeśli ustawimy ją na J 0 , 1 = + 1 , hamiltonian zostanie zminimalizowany, jeśli dwa kubity przyjmą przeciwne wartości. Zatem sprzęgi dodatnie są anty-skorelowane .jot0 , 1= - 1jot0 , 1= + 1
W przykładzie szachownicy chcemy skorelować każdą parę sąsiadujących kubitów, co daje początek następującemu Hamiltonianowi:
H.= σ0σ1+ σ0σ2)+ σ1σ3)+ σ2)σ3)
Dla celów demonstracyjnych dodajemy również warunek polaryzacji na kubicie, tak że otrzymujemy tylko rozwiązanie nr 1. To rozwiązanie wymaga σ 0 = - 1 i dlatego ustawiamy jego odchylenie h0σ0= - 1. Ostateczny Hamiltonian to teraz:h0= 1
H.= σ0+ σ0σ1+ σ0σ2)+ σ1σ3)+ σ2)σ3)
Więc napiszmy to!
UWAGA: POTRZEBUJESZ dostępu do usługi chmurowej D-Wave, aby wszystko działało.
Przede wszystkim upewnij się, że masz zainstalowany dwave_sapi2
( https://cloud.dwavesys.com/qubist/downloads/ ) pakiet Python. Wszystko będzie w języku Python 2.7, ponieważ D-Wave obecnie nie obsługuje żadnej wyższej wersji języka Python. To powiedziawszy, zaimportuj niezbędne rzeczy:
from dwave_sapi2.core import solve_ising
from dwave_sapi2.embedding import find_embedding, embed_problem, unembed_answer
from dwave_sapi2.util import get_hardware_adjacency
from dwave_sapi2.remote import RemoteConnection
Aby połączyć się z interfejsem API D-Wave Solver, potrzebujesz prawidłowego tokena API dla ich solvera SAPI, adresu URL SAPI i musisz zdecydować, którego procesora kwantowego chcesz użyć:
DWAVE_SAPI_URL = 'https://cloud.dwavesys.com/sapi'
DWAVE_TOKEN = [your D-Wave API token]
DWAVE_SOLVER = 'DW_2000Q_VFYC_1'
Polecam korzystanie z wirtualnej chimery VFYC (D-Wave 2000Q), która jest w pełni funkcjonalnym układem bez martwych kubitów! Oto układ czipów Chimera:
W tym momencie dzielę samouczek na dwie odrębne części. W pierwszej części ręcznie osadzamy problem na wykresie sprzętowym Chimera, aw drugiej sekcji używamy heurystyki osadzania D-Wave, aby znaleźć osadzenie sprzętowe.
Osadzanie ręczne
Komórka jednostkowa w lewym górnym rogu powyższego układu układów D-Wave 2000Q wygląda następująco:
010 → 01 → 42 → 73 → 3hjot
J = {(0,4): 1, (4,3): 1, (3,7): 1, (7,0): 1}
h = [-1,0,0,0,0,0,0,0,0]
h
connection = RemoteConnection(DWAVE_SAPI_URL, DWAVE_TOKEN)
solver = connection.get_solver(DWAVE_SOLVER)
Teraz możemy zdefiniować liczbę odczytów i wybrać answer_mode
„histogram”, który już sortuje wyniki według liczby wystąpień dla nas. Jesteśmy teraz gotowi do rozwiązania instancji Isinga za pomocą kwantowego wyżarzacza D-Wave:
params = {"answer_mode": 'histogram', "num_reads": 10000}
results = solve_ising(solver, h, J, **params)
print results
Powinieneś uzyskać następujący wynik:
{
'timing': {
'total_real_time': 1655206,
'anneal_time_per_run': 20,
'post_processing_overhead_time': 13588,
'qpu_sampling_time': 1640000,
'readout_time_per_run': 123,
'qpu_delay_time_per_sample': 21,
'qpu_anneal_time_per_sample': 20,
'total_post_processing_time': 97081,
'qpu_programming_time': 8748,
'run_time_chip': 1640000,
'qpu_access_time': 1655206,
'qpu_readout_time_per_sample': 123
},
'energies': [-5.0],
'num_occurrences': [10000],
'solutions': [
[1, 3, 3, 1, -1, 3, 3, -1, {
lots of 3 's that I am omitting}]]}
energies
- 5.03)0 → 04 → 17 → 23 → 3 . Gotowy!
Osadzanie heurystyczne
joth następnie pozostawmy niezmienione w stosunku do naszych początkowych definicji:
J = {(0,1): 1, (0,2): 1, (1,3): 1, (2,3): 1}
h = [-1,0,0,0]
Ponownie ustanawiamy połączenie zdalne i otrzymujemy instancję solvera D-Wave 2000Q VFYC:
connection = RemoteConnection(DWAVE_SAPI_URL, DWAVE_TOKEN)
solver = connection.get_solver(DWAVE_SOLVER)
Aby znaleźć osadzenie naszego problemu, musimy najpierw uzyskać macierz przylegania bieżącego wykresu sprzętowego:
adjacency = get_hardware_adjacency(solver)
Teraz spróbujmy znaleźć osadzenie naszego problemu:
embedding = find_embedding(J.keys(), adjacency)
Jeśli masz do czynienia z dużymi instancjami Isinga, możesz poszukać osadzania w wielu wątkach (równolegle na wielu procesorach), a następnie wybrać osadzanie o najmniejszej długości łańcucha! Łańcuch jest, gdy wiele qubity są zmuszeni działać jako pojedynczy qubitu w celu zwiększenia stopnia łączności. Jednak im dłuższy łańcuch, tym bardziej prawdopodobne jest jego zerwanie. A zerwane łańcuchy dają złe wyniki!
Jesteśmy teraz gotowi do osadzenia naszego problemu na wykresie:
[h, j0, jc, embeddings] = embed_problem(h, J, embedding, adjacency)
j0
zawiera oryginalne sprzężenia, które zdefiniowaliśmy i jc
zawiera połączenia, które wymuszają integralność łańcuchów (korelują kubity w łańcuchach). Dlatego musimy połączyć je ponownie w jeden dużyjot słownik:
J = j0.copy()
J.update(jc)
Teraz jesteśmy gotowi rozwiązać osadzony problem:
params = {"answer_mode": 'histogram', "num_reads": 10000}
raw_results = solve_ising(solver, h, J, **params)
print 'Lowest energy found: {}'.format(raw_results['energies'])
print 'Number of occurences: {}'.format(raw_results['num_occurrences'])
Nie raw_results
będzie to dla nas sensowne, dopóki nie rozwiążemy problemu. W przypadku zerwania niektórych łańcuchów naprawiamy je większością głosów zgodnie z opcjonalnym argumentem broken_chains
:
unembedded_results = unembed_answer(raw_results['solutions'],
embedding, broken_chains='vote')
print 'Solution string: {}'.format(unembedded_results)
Jeśli uruchomisz to, powinieneś uzyskać poprawny wynik we wszystkich odczytach:
Lowest energy found: [-5.0]
Number of occurences: [10000]
Solution string: [[1, -1, -1, 1]]
Mam nadzieję, że to odpowiedziało na twoje pytanie i gorąco polecam sprawdzenie wszystkich dodatkowych parametrów, które możesz przekazać solve_ising
funkcji, aby poprawić jakość swoich rozwiązań, takich jak num_spin_reversal_transforms
lub postprocess
.