def test_cost_graph_error(self): """Tests that the cost Hamiltonians throw the correct error""" graph = [(0, 1), (1, 2)] with pytest.raises(ValueError, match=r"Input graph must be a nx\.Graph"): qaoa.maxcut(graph) with pytest.raises(ValueError, match=r"Input graph must be a nx\.Graph"): qaoa.max_independent_set(graph) with pytest.raises(ValueError, match=r"Input graph must be a nx\.Graph"): qaoa.min_vertex_cover(graph) with pytest.raises(ValueError, match=r"Input graph must be a nx\.Graph"): qaoa.max_clique(graph)
def test_mis_output(self, graph, constrained, cost_hamiltonian, mixer_hamiltonian): """Tests that the output of the Max Indepenent Set method is correct""" cost_h, mixer_h = qaoa.max_independent_set(graph, constrained=constrained) assert decompose_hamiltonian(cost_hamiltonian) == decompose_hamiltonian(cost_h) assert decompose_hamiltonian(mixer_hamiltonian) == decompose_hamiltonian(mixer_h)
def find_max_independent_set(graph, params): """Find the maximum independent set of an input graph given some optimized QAOA parameters. The code you write for this challenge should be completely contained within this function between the # QHACK # comment markers. You should create a device, set up the QAOA ansatz circuit and measure the probabilities of that circuit using the given optimized parameters. Your next step will be to analyze the probabilities and determine the maximum independent set of the graph. Return the maximum independent set as an ordered list of nodes. Args: graph (nx.Graph): A NetworkX graph params (np.ndarray): Optimized QAOA parameters of shape (2, 10) Returns: list[int]: the maximum independent set, specified as a list of nodes in ascending order """ max_ind_set = [] # QHACK # from pennylane import qaoa cost_h, mixer_h = qaoa.max_independent_set(graph, constrained=True) # A single layer of QAOA def qaoa_layer(gamma, alpha): qaoa.cost_layer(gamma, cost_h) qaoa.mixer_layer(alpha, mixer_h) # Now, create the layered circuit def circuit(params, **kwargs): qml.layer(qaoa_layer, N_LAYERS, params[0], params[1]) # Device and eval of cost function dev = qml.device("default.qubit", wires=NODES) @qml.qnode(dev) def probability_circuit(gamma, alpha): circuit([gamma, alpha]) return qml.probs(wires=[i for i in range(NODES)]) probs = probability_circuit(params[0], params[1]) # Get the nodes with the highest prob max_index = np.argmax(probs) bin_max = "{0:06b}".format(max_index) for count, val in enumerate(bin_max): if val == '1': max_ind_set.append(count) # QHACK # return max_ind_set
def find_max_independent_set(graph, params): """Find the maximum independent set of an input graph given some optimized QAOA parameters. The code you write for this challenge should be completely contained within this function between the # QHACK # comment markers. You should create a device, set up the QAOA ansatz circuit and measure the probabilities of that circuit using the given optimized parameters. Your next step will be to analyze the probabilities and determine the maximum independent set of the graph. Return the maximum independent set as an ordered list of nodes. Args: graph (nx.Graph): A NetworkX graph params (np.ndarray): Optimized QAOA parameters of shape (2, 10) Returns: list[int]: the maximum independent set, specified as a list of nodes in ascending order """ max_ind_set = [] # QHACK # dev = qml.device('default.qubit', wires=NODES) # Defines the QAOA cost and mixer Hamiltonians cost_h, mixer_h = qaoa.max_independent_set(graph, constrained=True) # Defines a layer of the QAOA ansatz from the cost and mixer Hamiltonians def qaoa_layer(gamma, alpha): qaoa.cost_layer(gamma, cost_h) qaoa.mixer_layer(alpha, mixer_h) # Repeatedly applies layers of the QAOA ansatz @qml.qnode(dev) def circuit(params, **kwargs): #for w in range(NODES): # qml.Hadamard(wires=w) qml.layer(qaoa_layer, N_LAYERS, params[0, :], params[1, :]) return qml.probs(wires=[0, 1, 2, 3, 4, 5]) probs = circuit(params) ind = np.argmax(probs) lst = list(itertools.product([0, 1], repeat=NODES)) nods = lst[ind] max_ind_set = [i for i, val in enumerate(nods) if val != 0] #np.nonzero(nods) # QHACK # return max_ind_set
def find_max_independent_set(graph, params): """Find the maximum independent set of an input graph given some optimized QAOA parameters. The code you write for this challenge should be completely contained within this function between the # QHACK # comment markers. You should create a device, set up the QAOA ansatz circuit and measure the probabilities of that circuit using the given optimized parameters. Your next step will be to analyze the probabilities and determine the maximum independent set of the graph. Return the maximum independent set as an ordered list of nodes. Args: graph (nx.Graph): A NetworkX graph params (np.ndarray): Optimized QAOA parameters of shape (2, 10) Returns: list[int]: the maximum independent set, specified as a list of nodes in ascending order """ max_ind_set = [] # QHACK # from pennylane import qaoa dev = qml.device('default.qubit', wires=NODES) cost_h, mixer_h = qaoa.max_independent_set(graph, constrained=True) def qaoa_layer(gamma, alpha): qaoa.cost_layer(gamma, cost_h) qaoa.mixer_layer(alpha, mixer_h) def circuit(params, **kwargs): qml.layer(qaoa_layer, N_LAYERS, params[0], params[1]) @qml.qnode(dev) def probability_circuit(gamma, alpha): circuit([gamma, alpha]) return qml.probs(wires=range(NODES)) probs = probability_circuit(params[0], params[1]) top_state = np.argmax(probs) bit_string = '{0:06b}'.format(top_state) for n, b in enumerate(bit_string): if b == '1': max_ind_set.append(n) # print(top_state, bit_string, result) # QHACK # return max_ind_set
def find_max_independent_set(graph, params): """Find the maximum independent set of an input graph given some optimized QAOA parameters. The code you write for this challenge should be completely contained within this function between the # QHACK # comment markers. You should create a device, set up the QAOA ansatz circuit and measure the probabilities of that circuit using the given optimized parameters. Your next step will be to analyze the probabilities and determine the maximum independent set of the graph. Return the maximum independent set as an ordered list of nodes. Args: graph (nx.Graph): A NetworkX graph params (np.ndarray): Optimized QAOA parameters of shape (2, 10) Returns: list[int]: the maximum independent set, specified as a list of nodes in ascending order """ cost_h, mixer_h = qaoa.max_independent_set(graph) def qaoa_layer(gamma, alpha): qaoa.cost_layer(gamma, cost_h) qaoa.mixer_layer(alpha, mixer_h) def circuit(params, **kwargs): for w in range(NODES): qml.Hadamard(wires=w) qml.layer(qaoa_layer, N_LAYERS, params[0], params[1]) dev = qml.device('default.qubit', wires=NODES) cost_function = qml.ExpvalCost(circuit, cost_h, dev) optimizer = qml.NesterovMomentumOptimizer() for i in range(3): params = optimizer.step(cost_function, params) @qml.qnode(dev) def probability_circuit(gamma, alpha): circuit([gamma, alpha]) return qml.probs(wires=[x for x in range(NODES)]) probs = probability_circuit(params[0], params[1]) most_freq_bit_string = np.argmax(probs) result = [] for i in reversed(range(NODES)): if most_freq_bit_string & (1 << i) != 0: result.append(NODES - 1 - i) return result
def find_max_independent_set(graph, params): """Find the maximum independent set of an input graph given some optimized QAOA parameters. The code you write for this challenge should be completely contained within this function between the # QHACK # comment markers. You should create a device, set up the QAOA ansatz circuit and measure the probabilities of that circuit using the given optimized parameters. Your next step will be to analyze the probabilities and determine the maximum independent set of the graph. Return the maximum independent set as an ordered list of nodes. Args: graph (nx.Graph): A NetworkX graph params (np.ndarray): Optimized QAOA parameters of shape (2, 10) Returns: list[int]: the maximum independent set, specified as a list of nodes in ascending order """ # QHACK # np.set_printoptions(formatter={'float': lambda x: "{0:0.5f}".format(x)}) n_wires = graph.number_of_nodes() wires = range(n_wires) depth = 10 # create a device, dev = qml.device("default.qubit", wires=n_wires) # set up the QAOA ansatz circuit # and measure the probabilities of that circuit using the given optimized parameters. cost_h, mixer_h = qaoa.max_independent_set(graph, constrained=True) def qaoa_layer(gamma, alpha): qaoa.cost_layer(gamma, cost_h) qaoa.mixer_layer(alpha, mixer_h) def circuit(params, **kwargs): qml.layer(qaoa_layer, depth, params[0], params[1]) # You will be provided with optimized parameters and will not need to optimize further. # cost_function = qml.ExpvalCost(circuit, cost_h, dev) # optimizer = qml.GradientDescentOptimizer() # # optimizer = qml.AdamOptimizer() # # steps = 20 # # steps = 16 # steps = 2 # for i in range(steps): # # params = optimizer.step(cost_function, params) # params, prev_cost = optimizer.step_and_cost(cost_function, params) # if i % 1 == 0: # print(f"#{i}\t cost: {prev_cost}") # Your next step will be to analyze the probabilities # and determine the maximum independent set of the # graph. # @qml.qnode(dev) def probability_circuit(gamma, alpha): circuit([gamma, alpha]) return qml.probs(wires=wires) probs = probability_circuit(params[0], params[1]) max_index = np.argmax(probs) # print(f"probs: {probs}") # max_prob = max(probs) # print(f"max_prob: {max_prob}") # print(f"max_index: {max_index}") # Return the maximum independent set as an ordered list of nodes. max_ind_set = [] # print(wires) for w in wires: if max_index & (1 << (n_wires-w-1)): max_ind_set.append(w) # QHACK # return max_ind_set