import logging
import math
from copy import deepcopy
from typing import Dict, List, Optional
import multiprocessing as mp  # 使用别名以避免命名冲突
from functools import partial

import numpy as np
from qiskit import QuantumCircuit, QuantumRegister, transpile
from qiskit.circuit.library import RYGate, QFT
from qiskit.quantum_info import Operator
from qiskit_aer import AerSimulator

from qiskit_optimization.algorithms.optimization_algorithm import (
    OptimizationResultStatus,
)

# 设置日志记录
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)


class GroverOptimizationResult:
    def __init__(self, keys, values, operation_counts, n_input_qubits, n_output_qubits, threshold, num_solutions):
        self.keys = keys
        self.values = values
        self.operation_counts = operation_counts
        self.n_input_qubits = n_input_qubits
        self.n_output_qubits = n_output_qubits
        self.threshold = threshold
        self.num_solutions = num_solutions
        self.status = OptimizationResultStatus.SUCCESS
        # 生成一个解决方案列表，每个解决方案都是一个由 0 和 1 组成的列表，表示键的二进制形式
        self.solutions = [[1 if i == key else 0 for i in range(num_solutions)] for key in keys]


class GroverOptimizer:
    def __init__(
            self,
            num_value_qubits: int,
            num_key_qubits: int,
            num_ancil_qubits: int = 1,
            num_iterations: int = 5,
            sampler: Optional = None,  # 移除类型注解以避免多进程pickle问题
    ) -> None:
        self._num_ancil_qubits = num_ancil_qubits
        self._num_value_qubits = num_value_qubits
        self._num_key_qubits = num_key_qubits
        self._n_iterations = num_iterations
        self._circuit_results = {}  # type: dict
        self._sampler = sampler
        self._MIN_PROBABILITY = 1e-15  # 调整最小概率以避免浮点误差

    def get_compatibility_msg(self, problem):
        return ""

    def _get_a_operator_gate(self, numbers, qr_key, qr_value, qr_ancil, oracle_bit):
        # 初始化量子电路，包括 oracle_bit
        a_operator = QuantumCircuit(qr_key, qr_value, qr_ancil, oracle_bit)

        # 将key和value寄存器的量子比特置于叠加态
        a_operator.h(qr_key)
        a_operator.h(qr_value)

        # 对辅助量子比特进行操作
        a_operator.rx(np.pi / 2, qr_ancil)
        a_operator.z(qr_ancil)
        a_operator.x(qr_ancil)

        # 对每个数字进行编码
        for idx, number in enumerate(numbers):
            applied_x = []
            # 对qr_key进行X门操作以对应正确的编号
            bin_index = format(idx, '0' + str(self._num_key_qubits) + 'b')[::-1]
            for i, bit in enumerate(bin_index):
                if bit == '0':
                    a_operator.x(qr_key[i])
                    applied_x.append(i)

            # 对每个qr_value的量子比特进行控制旋转门操作
            for i in range(self._num_value_qubits):
                # 计算旋转角度
                angle = 4 * np.pi * number / (2 ** self._num_value_qubits)
                # 创建控制旋转门RY
                ry_gate = RYGate(angle).control(len(qr_key) + 1)
                # 重复添加控制旋转门RY 2**i次
                for _ in range(2 ** i):
                    a_operator.append(ry_gate, qr_key[:] + [qr_value[i], qr_ancil[0]])

            # 重置已经添加过X门的qr_key量子比特
            for i in applied_x:
                a_operator.x(qr_key[i])

        # 对辅助量子比特进行操作
        a_operator.x(qr_ancil)
        a_operator.z(qr_ancil)
        a_operator.rx(-np.pi / 2, qr_ancil)

        # 将量子电路转换为 Gate 对象
        a_operator_gate = a_operator.to_gate(label="A")
        return a_operator_gate

    def _get_oracle_gate(self, qr_key, qr_value, qr_ancil, oracle_bit):
        # 定义矩阵
        custom_matrix = np.array([[-1, 0], [0, 1]])
        # 创建一个 Operator
        custom_gate = Operator(custom_matrix)
        oracle = QuantumCircuit(qr_key, qr_value, qr_ancil, oracle_bit)
        # 应用自定义门到 oracle_bit 上
        oracle.unitary(custom_gate, [self._num_key_qubits + self._num_value_qubits + self._num_ancil_qubits],
                       label='Oracle')
        # 将量子电路转换为 Gate 对象
        oracle_gate = oracle.to_gate(label="Oracle")
        return oracle_gate

    def _apply_threshold_rotation_gate(self, threshold_complement, numbers, qr_key, qr_value, qr_ancil, oracle_bit):
        # 初始化量子电路，包括 oracle_bit
        rotation_circuit = QuantumCircuit(qr_key, qr_value, qr_ancil, oracle_bit)

        # 对辅助量子比特进行操作
        rotation_circuit.rx(np.pi / 2, qr_ancil)
        rotation_circuit.z(qr_ancil)
        rotation_circuit.x(qr_ancil)

        # 对每个数字进行编码
        for idx, number in enumerate(numbers):
            applied_x = []
            # 对qr_key进行X门操作以对应正确的编号
            bin_index = format(idx, '0' + str(self._num_key_qubits) + 'b')[::-1]
            for i, bit in enumerate(bin_index):
                if bit == '0':
                    rotation_circuit.x(qr_key[i])
                    applied_x.append(i)

            # 对每个qr_value的量子比特进行控制旋转门操作
            for i in range(self._num_value_qubits):
                # 计算旋转角度
                angle = 4 * np.pi * threshold_complement / (2 ** self._num_value_qubits)
                # 创建控制旋转门RY
                ry_gate = RYGate(angle).control(len(qr_key) + 1)
                # 重复添加控制旋转门RY 2**i次
                for _ in range(2 ** i):
                    rotation_circuit.append(ry_gate, qr_key[:] + [qr_value[i], qr_ancil[0]])

            # 重置已经添加过X门的qr_key量子比特
            for i in applied_x:
                rotation_circuit.x(qr_key[i])

        # 对value寄存器应用逆量子傅里叶变换并对辅助量子比特进行操作
        rotation_circuit.append(QFT(self._num_value_qubits).inverse(), qr_value[:])
        rotation_circuit.x(qr_ancil)
        rotation_circuit.z(qr_ancil)
        rotation_circuit.rx(-np.pi / 2, qr_ancil)

        # 将量子电路转换为 Gate 对象
        rotation_gate = rotation_circuit.to_gate(label="ThresholdRotation")
        return rotation_gate

    def solve(self, numbers: List[int], N: int):
        # 初始化量子寄存器
        qr_key = QuantumRegister(self._num_key_qubits, 'key')
        qr_value = QuantumRegister(self._num_value_qubits, 'value')
        qr_ancil = QuantumRegister(self._num_ancil_qubits, 'ancil')
        oracle_bit = QuantumRegister(1, 'oracle')

        # 创建主量子电路
        main_circuit = QuantumCircuit(qr_key, qr_value, qr_ancil, oracle_bit)

        # 获取 Oracle 和 A Operator Gate
        oracle_gate = self._get_oracle_gate(qr_key, qr_value, qr_ancil, oracle_bit)
        a_operator_gate = self._get_a_operator_gate(numbers, qr_key, qr_value, qr_ancil, oracle_bit)

        # 预排序，获取初始最大的N个值和键
        n_largest_values_and_keys = sorted([(numbers[i], i) for i in range(len(numbers))], key=lambda x: x[0],
                                           reverse=True)[:N]
        n_largest_values = [item[0] for item in n_largest_values_and_keys]
        n_largest_keys = [item[1] for item in n_largest_values_and_keys]

        keys_measured = [item[1] for item in n_largest_values_and_keys]

        # 变量初始化
        optimum_found = False
        threshold = 0
        n_key = self._num_key_qubits
        n_value = self._num_value_qubits

        num_solutions = 2 ** n_key

        operation_count = {}
        iteration = 0

        rotations = 0
        max_rotations = int(math.ceil(100 * math.pi / 4))

        measurement = True

        # 初始化模拟器，利用多线程
        simulator = AerSimulator(max_parallel_threads=math.floor(mp.cpu_count() * 0.8))  # 使用80%的CPU核心

        # 将 A operator 添加到主电路
        main_circuit.append(a_operator_gate, qr_key[:] + qr_value[:] + [qr_ancil[0]] + oracle_bit[:])

        while not optimum_found:
            m = 1
            improvement_found = False

            # 获取当前阈值的补码
            if threshold == 0:
                threshold_complement = 0
            else:
                threshold_complement = self._decimal_to_twos_complement(-threshold, self._num_value_qubits)

            # 应用阈值旋转 Gate
            rotation_gate = self._apply_threshold_rotation_gate(threshold_complement, numbers, qr_key, qr_value,
                                                                qr_ancil, oracle_bit)
            main_circuit.append(rotation_gate, qr_key[:] + qr_value[:] + [qr_ancil[0]] + oracle_bit[:])

            # 迭代直到找到改进
            loops_with_no_improvement = 0
            while not improvement_found:
                loops_with_no_improvement += 1
                rotation_count = np.random.randint(0, m + 1)
                rotations += rotation_count

                # 构建Grover迭代电路
                grover_circuit = deepcopy(main_circuit)
                for _ in range(rotation_count):
                    grover_circuit.append(oracle_gate, qr_key[:] + qr_value[:] + [qr_ancil[0]] + oracle_bit[:])
                    grover_circuit.append(a_operator_gate.inverse(),
                                          qr_key[:] + qr_value[:] + [qr_ancil[0]] + oracle_bit[:])
                    grover_circuit.append(oracle_gate, qr_key[:] + qr_value[:] + [qr_ancil[0]] + oracle_bit[:])
                    grover_circuit.append(a_operator_gate, qr_key[:] + qr_value[:] + [qr_ancil[0]] + oracle_bit[:])

                # 添加测量
                grover_circuit.measure_all()

                # 获取测量结果
                outcome = self._measure(grover_circuit, simulator)

                # 提取键和值
                k = int(outcome[2 + n_value: n_key + 2 + n_value], 2)
                v = outcome[2: 2 + n_value]
                int_v = GroverOptimizer._bin_to_int(v, n_value) + threshold

                logger.info("Outcome: %s", outcome)
                logger.info("Value Q(x): %s", int_v)

                # 检查是否满足条件
                if int_v in numbers and (len(n_largest_values) < N or int_v > n_largest_values[-1]):
                    if k not in keys_measured:
                        # 更新最大的N个值和对应的键
                        if len(n_largest_values) == N:
                            removed_value = n_largest_values.pop(-1)
                            removed_key = n_largest_keys.pop(-1)
                            logger.info(f"Removed Value: {removed_value}, Key: {removed_key}")
                        n_largest_values.append(int_v)
                        n_largest_keys.append(k)
                        keys_measured.append(k)

                        # 保持降序排列
                        sorted_pairs = sorted(zip(n_largest_values, n_largest_keys), reverse=True)
                        n_largest_values, n_largest_keys = zip(*sorted_pairs)
                        n_largest_values = list(n_largest_values)
                        n_largest_keys = list(n_largest_keys)

                        logger.info("Updated n_largest_values: %s", n_largest_values)
                        logger.info("Updated n_largest_keys: %s", n_largest_keys)

                        # 更新阈值
                        threshold = n_largest_values[-1]
                        improvement_found = True
                else:
                    # 增加m
                    m = int(math.ceil(min(m * 8 / 7, 2 ** (n_key / 2))))
                    logger.info("No Improvement. M: %s", m)

                    if k not in keys_measured:
                        keys_measured.append(k)

                    # 检查停止条件
                    if (
                            loops_with_no_improvement >= self._n_iterations
                            or len(keys_measured) == len(numbers)
                            or rotations >= max_rotations
                    ):
                        improvement_found = True
                        optimum_found = True

                # 记录操作计数
                operations = grover_circuit.count_ops()
                operation_count[iteration] = operations
                iteration += 1
                logger.info("Operation Count: %s\n", operations)

        # 构建结果对象
        result = GroverOptimizationResult(
            keys=n_largest_keys,
            values=n_largest_values,
            operation_counts=operation_count,
            n_input_qubits=n_key,
            n_output_qubits=n_value,
            threshold=threshold,
            num_solutions=len(numbers)
        )
        return result

    def _measure(self, circuit: QuantumCircuit, simulator: AerSimulator) -> str:
        """使用AerSimulator执行电路模拟，并获取测量结果。"""
        # 转译电路
        transpiled_circuit = transpile(circuit, simulator)

        # 运行模拟
        result = simulator.run(transpiled_circuit, shots=1).result()
        counts = result.get_counts()

        # 因为 shots=1，所以直接获取单一结果
        outcome = list(counts.keys())[0]
        return outcome

    @staticmethod
    def _bin_to_int(v: str, num_value_bits: int) -> int:
        """将一个使用二进制补码形式表示的字符串转换为一个整数。"""
        if v.startswith("1"):
            int_v = int(v, 2) - 2 ** num_value_bits
        else:
            int_v = int(v, 2)
        return int_v

    def _decimal_to_twos_complement(self, negative_decimal, num_bits):
        """将负整数转换为二进制补码表示的整数。"""
        mask = 2 ** num_bits - 1
        twos_complement = (abs(negative_decimal) ^ mask) + 1
        return twos_complement


def simulate_measurement(circuit_serialized):
    """在子进程中反序列化电路并执行测量。"""
    simulator = AerSimulator()
    transpiled_circuit = transpile(circuit_serialized, simulator)
    result = simulator.run(transpiled_circuit, shots=1).result()
    counts = result.get_counts()
    outcome = list(counts.keys())[0]
    return outcome


# 示例用法
if __name__ == "__main__":
    numbers = [55, 6, 83, 2, 94, 53, 28, 64, 75, 47, 93, 36, 23, 89, 84, 91, 76, 12, 40, 38, 86, 51, 25, 21, 72, 48, 31,
               18,
               62, 66, 77, 13, 82, 61, 92, 81, 35, 71, 74, 98, 22, 96, 44, 43, 5, 100, 45, 30, 65, 85]

    num_value_qubits = 7  # 根据最大数字调整
    num_key_qubits = 7  # 根据数字数量调整

    optimizer = GroverOptimizer(num_value_qubits=num_value_qubits, num_key_qubits=num_key_qubits)

    # 设置进程池，限制为4个进程
    pool = mp.Pool(processes=4)

    try:
        result = optimizer.solve(numbers, N=5)
        print("Keys:", result.keys)
        print("Values:", result.values)
    finally:
        pool.close()
        pool.join()
代码出现报错Traceback (most recent call last):
  File "G:\Hellyc\Iris-简化QNN自适应经验回放-2\GAS\minitest.py", line 361, in <module>
    result = optimizer.solve(numbers, N=5)
  File "G:\Hellyc\Iris-简化QNN自适应经验回放-2\GAS\minitest.py", line 214, in solve
    rotation_gate = self._apply_threshold_rotation_gate(threshold_complement, numbers, qr_key, qr_value,
  File "G:\Hellyc\Iris-简化QNN自适应经验回放-2\GAS\minitest.py", line 156, in _apply_threshold_rotation_gate
    rotation_gate = rotation_circuit.to_gate(label="ThresholdRotation")
  File "G:\anaconda3\envs\pennylane2\lib\site-packages\qiskit\circuit\quantumcircuit.py", line 1618, in to_gate
    return circuit_to_gate(self, parameter_map, label=label)
  File "G:\anaconda3\envs\pennylane2\lib\site-packages\qiskit\converters\circuit_to_gate.py", line 64, in circuit_to_gate
    raise QiskitError(
qiskit.exceptions.QiskitError: 'One or more instructions cannot be converted to a gate. "IQFT" is not a gate instruction'
如何进行解决