Технології AI Написано практикуючими розробниками

Quantum-Edge Hybrid Computing: коли кубіти зустрічають edge

Оновлено: 15 хв читання 15 переглядів

Квантові комп'ютери — в лабораторіях. При температурі близькій до абсолютного нуля. 15 мілікельвінів — холодніше, ніж відкритий космос. Їх не поставиш на base station.


Квантові комп'ютери — в лабораторіях. При температурі близькій до абсолютного нуля. 15 мілікельвінів — холодніше, ніж відкритий космос. Їх не поставиш на base station.

Але що якщо квантовий процесор у cloud, а edge devices — класичні? Квант робить те, що квант робить найкраще: optimization, sampling, simulation. Edge — все інше: real-time inference, data preprocessing, actuation.

Quantum-edge hybrid — це не про «квант всюди». Це про правильний розподіл задач. І це єдиний реалістичний шлях до практичного використання квантових комп'ютерів у найближчі 10 років.


Квантові обмеження vs Edge реальність

Квантові вимоги:

  • Температура: 15 mK (холодніше за космос в 180 разів)
  • Ізоляція від електромагнітного шуму (Faraday cage)
  • Coherence time: мікросекунди (qubits «забувають» стан)
  • Error rates: 0.1-1% per gate operation
  • Розмір: кімната обладнання на 100 кубітів
  • Вартість: $10-50 мільйонів за систему

Edge реальність:

  • Кімнатна температура (-20°C до +50°C)
  • Шумне RF середовище (WiFi, 5G, Bluetooth)
  • Latency-critical applications (< 10ms)
  • Battery-powered devices (3-20W power budget)
  • Мільярди пристроїв globally

Очевидно: Квант не замінить edge. Квант доповнить edge для специфічних задач, де є quantum advantage.


Що квантові комп'ютери роблять краще

1. Combinatorial Optimization (QAOA, VQE)

Класичний підхід: O(2^n) для NP-hard problems
Квантовий підхід: Potential polynomial speedup

Приклади:
- Network routing: знайти оптимальний шлях через 1000 nodes
- Portfolio optimization: вибрати найкращу комбінацію активів
- Supply chain: оптимізувати логістику по тисячах точок
- Drug discovery: знайти оптимальну молекулярну структуру

2. Sampling від складних розподілів

Boltzmann machines, generative models
Quantum sampling може бути експоненційно швидшим
для специфічних probability distributions

3. Linear Algebra (HHL Algorithm)

Solving Ax = b для sparse matrices
Potential exponential speedup
Критично для ML (regression, PCA, SVD)

4. Quantum Simulation

Симуляція квантових систем (molecules, materials)
Класичний комп'ютер: експоненційно складно
Квантовий: природньо polynomial

Архітектура Quantum-Edge Hybrid

┌─────────────────────────────────────────────────────────────┐
│                      EDGE LAYER                              │
│  ┌───────────────────────────────────────────────────────┐ │
│  │ - Real-time AI inference (classification, detection)  │ │
│  │ - Sensor data preprocessing                           │ │
│  │ - Local decision making (milliseconds)                │ │
│  │ - Privacy-preserving local compute                    │ │
│  └───────────────────────────────────────────────────────┘ │
│  Hardware: NPU, GPU, FPGA | Latency: <10ms | Power: 1-50W  │
└─────────────────────────────────┬───────────────────────────┘
                                  │ HTTP/gRPC
                                  ▼
┌─────────────────────────────────────────────────────────────┐
│                   CLASSICAL CLOUD                            │
│  ┌───────────────────────────────────────────────────────┐ │
│  │ - Preprocessing for quantum (problem encoding)        │ │
│  │ - Post-processing quantum results (decoding)          │ │
│  │ - Orchestration & scheduling                          │ │
│  │ - Classical ML training                               │ │
│  │ - Result caching & optimization                       │ │
│  └───────────────────────────────────────────────────────┘ │
│  Hardware: CPU/GPU clusters | Latency: 50-200ms            │
└─────────────────────────────────┬───────────────────────────┘
                                  │ Quantum API
                                  ▼
┌─────────────────────────────────────────────────────────────┐
│                    QUANTUM CLOUD                             │
│  ┌───────────────────────────────────────────────────────┐ │
│  │ - Optimization (QAOA, VQE)                            │ │
│  │ - Quantum sampling (QSVM, QNN)                        │ │
│  │ - Molecular simulation                                 │ │
│  │ - Cryptographic primitives (QKD)                      │ │
│  └───────────────────────────────────────────────────────┘ │
│  Hardware: IBM/Google/IonQ QPU | Latency: seconds-minutes  │
└─────────────────────────────────────────────────────────────┘

QAOA для Edge Network Optimization

Quantum Approximate Optimization Algorithm — найпопулярніший variational quantum algorithm для combinatorial optimization.

import numpy as np
from qiskit import QuantumCircuit, transpile
from qiskit_aer import AerSimulator
from qiskit.circuit import Parameter
from qiskit.primitives import Sampler
from scipy.optimize import minimize
from typing import List, Tuple, Dict

class QAOAOptimizer:
    """QAOA для оптимізації розміщення compute на edge nodes."""

    def __init__(
        self,
        num_nodes: int,
        adjacency_matrix: np.ndarray,
        p: int = 3  # QAOA depth
    ):
        self.num_nodes = num_nodes
        self.adj = adjacency_matrix
        self.p = p

        # Create parameterized circuit
        self.gamma = [Parameter(f'γ_{i}') for i in range(p)]
        self.beta = [Parameter(f'β_{i}') for i in range(p)]

        self.circuit = self._build_circuit()
        self.sampler = Sampler()

    def _build_circuit(self) -> QuantumCircuit:
        """Build QAOA circuit."""
        qc = QuantumCircuit(self.num_nodes)

        # Initial superposition
        qc.h(range(self.num_nodes))

        for layer in range(self.p):
            # Cost unitary (encodes problem)
            self._add_cost_layer(qc, self.gamma[layer])

            # Mixer unitary (explores solution space)
            self._add_mixer_layer(qc, self.beta[layer])

        qc.measure_all()
        return qc

    def _add_cost_layer(self, qc: QuantumCircuit, gamma: Parameter):
        """Add cost Hamiltonian layer (encodes graph structure)."""
        for i in range(self.num_nodes):
            for j in range(i + 1, self.num_nodes):
                if self.adj[i, j] != 0:
                    # ZZ interaction weighted by edge
                    weight = self.adj[i, j]
                    qc.rzz(2 * gamma * weight, i, j)

    def _add_mixer_layer(self, qc: QuantumCircuit, beta: Parameter):
        """Add mixer Hamiltonian layer (X rotations)."""
        for i in range(self.num_nodes):
            qc.rx(2 * beta, i)

    def compute_expectation(
        self,
        params: np.ndarray,
        shots: int = 1000
    ) -> float:
        """Compute expected cost for given parameters."""
        # Bind parameters
        gamma_vals = params[:self.p]
        beta_vals = params[self.p:]

        param_dict = {}
        for i in range(self.p):
            param_dict[self.gamma[i]] = gamma_vals[i]
            param_dict[self.beta[i]] = beta_vals[i]

        bound_circuit = self.circuit.assign_parameters(param_dict)

        # Run simulation
        backend = AerSimulator()
        compiled = transpile(bound_circuit, backend)
        job = backend.run(compiled, shots=shots)
        counts = job.result().get_counts()

        # Compute expectation value
        expectation = 0.0
        for bitstring, count in counts.items():
            cost = self._compute_cost(bitstring)
            expectation += cost * count / shots

        return expectation

    def _compute_cost(self, bitstring: str) -> float:
        """Compute cost for a given solution bitstring."""
        bits = [int(b) for b in bitstring[::-1]]  # Reverse for Qiskit convention
        cost = 0.0

        for i in range(self.num_nodes):
            for j in range(i + 1, self.num_nodes):
                if self.adj[i, j] != 0:
                    # Max-Cut: cost when nodes in different partitions
                    if bits[i] != bits[j]:
                        cost += self.adj[i, j]

        return cost

    def optimize(
        self,
        max_iter: int = 100,
        method: str = 'COBYLA'
    ) -> Tuple[np.ndarray, float]:
        """Run classical optimization of quantum parameters."""

        # Initial parameters
        init_params = np.random.uniform(0, np.pi, 2 * self.p)

        # Minimize negative expectation (maximize cut)
        result = minimize(
            lambda x: -self.compute_expectation(x),
            init_params,
            method=method,
            options={'maxiter': max_iter}
        )

        return result.x, -result.fun

    def get_best_solution(
        self,
        optimal_params: np.ndarray,
        shots: int = 5000
    ) -> str:
        """Get most likely solution from optimized circuit."""
        # Bind parameters
        gamma_vals = optimal_params[:self.p]
        beta_vals = optimal_params[self.p:]

        param_dict = {}
        for i in range(self.p):
            param_dict[self.gamma[i]] = gamma_vals[i]
            param_dict[self.beta[i]] = beta_vals[i]

        bound_circuit = self.circuit.assign_parameters(param_dict)

        # Sample many times
        backend = AerSimulator()
        compiled = transpile(bound_circuit, backend)
        job = backend.run(compiled, shots=shots)
        counts = job.result().get_counts()

        # Return most frequent bitstring
        best_bitstring = max(counts, key=counts.get)
        return best_bitstring


class EdgeNetworkOptimizer:
    """Оптимізація edge network за допомогою QAOA."""

    def __init__(self, network_graph: Dict):
        self.graph = network_graph
        self.num_nodes = len(network_graph['nodes'])

        # Build adjacency matrix from latency/bandwidth
        self.adj = self._build_adjacency_matrix()

    def _build_adjacency_matrix(self) -> np.ndarray:
        """Create adjacency matrix from network graph."""
        adj = np.zeros((self.num_nodes, self.num_nodes))

        for edge in self.graph['edges']:
            i, j = edge['source'], edge['target']
            # Weight = inverse latency (minimize latency = maximize weight)
            adj[i, j] = 1.0 / edge['latency']
            adj[j, i] = adj[i, j]

        return adj

    def optimize_task_placement(
        self,
        qaoa_depth: int = 3
    ) -> Dict:
        """Find optimal task placement across edge nodes."""

        qaoa = QAOAOptimizer(self.num_nodes, self.adj, p=qaoa_depth)

        # Run optimization
        optimal_params, optimal_cost = qaoa.optimize()

        # Get solution
        solution = qaoa.get_best_solution(optimal_params)

        # Interpret solution
        partition_a = [i for i, b in enumerate(solution[::-1]) if b == '0']
        partition_b = [i for i, b in enumerate(solution[::-1]) if b == '1']

        return {
            'partition_a': partition_a,
            'partition_b': partition_b,
            'cut_value': optimal_cost,
            'optimal_params': optimal_params.tolist()
        }


# Приклад використання
if __name__ == "__main__":
    # Define edge network
    network = {
        'nodes': ['edge_1', 'edge_2', 'edge_3', 'edge_4', 'edge_5'],
        'edges': [
            {'source': 0, 'target': 1, 'latency': 5},
            {'source': 0, 'target': 2, 'latency': 10},
            {'source': 1, 'target': 2, 'latency': 3},
            {'source': 1, 'target': 3, 'latency': 8},
            {'source': 2, 'target': 4, 'latency': 2},
            {'source': 3, 'target': 4, 'latency': 7},
        ]
    }

    optimizer = EdgeNetworkOptimizer(network)
    result = optimizer.optimize_task_placement(qaoa_depth=3)

    print(f"Optimal partitioning:")
    print(f"  Group A: {result['partition_a']}")
    print(f"  Group B: {result['partition_b']}")
    print(f"  Cut value: {result['cut_value']:.4f}")

Variational Quantum Neural Networks

Hybrid quantum-classical neural network з PennyLane:

import pennylane as qml
from pennylane import numpy as np
import torch
import torch.nn as nn
from typing import List, Tuple

# Quantum device
n_qubits = 4
dev = qml.device('default.qubit', wires=n_qubits)

@qml.qnode(dev, interface='torch', diff_method='backprop')
def quantum_circuit(inputs: torch.Tensor, weights: torch.Tensor):
    """
    Variational quantum circuit.

    Args:
        inputs: [n_qubits] classical input features
        weights: [n_layers, n_qubits, 3] trainable parameters
    """
    n_layers = weights.shape[0]

    # Data encoding layer (angle encoding)
    for i in range(n_qubits):
        qml.RY(inputs[i], wires=i)

    # Variational layers
    for layer in range(n_layers):
        # Single-qubit rotations
        for i in range(n_qubits):
            qml.RX(weights[layer, i, 0], wires=i)
            qml.RY(weights[layer, i, 1], wires=i)
            qml.RZ(weights[layer, i, 2], wires=i)

        # Entanglement (ring topology)
        for i in range(n_qubits):
            qml.CNOT(wires=[i, (i + 1) % n_qubits])

    # Measurement
    return [qml.expval(qml.PauliZ(i)) for i in range(n_qubits)]


class HybridQuantumClassicalNet(nn.Module):
    """
    Hybrid neural network з quantum layer.

    Architecture:
    Input → Classical(Linear) → Quantum(VQC) → Classical(Linear) → Output
    """

    def __init__(
        self,
        input_dim: int,
        output_dim: int,
        n_qubits: int = 4,
        n_quantum_layers: int = 2
    ):
        super().__init__()
        self.n_qubits = n_qubits
        self.n_quantum_layers = n_quantum_layers

        # Classical pre-processing
        self.pre_process = nn.Sequential(
            nn.Linear(input_dim, 32),
            nn.ReLU(),
            nn.Linear(32, n_qubits),
            nn.Tanh()  # Bound to [-1, 1] for angle encoding
        )

        # Quantum weights
        self.quantum_weights = nn.Parameter(
            torch.randn(n_quantum_layers, n_qubits, 3) * 0.1
        )

        # Classical post-processing
        self.post_process = nn.Sequential(
            nn.Linear(n_qubits, 16),
            nn.ReLU(),
            nn.Linear(16, output_dim)
        )

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        batch_size = x.shape[0]

        # Classical pre-processing
        x = self.pre_process(x)

        # Scale for angle encoding [0, π]
        x = (x + 1) * np.pi / 2

        # Quantum layer (process each sample)
        quantum_outputs = []
        for i in range(batch_size):
            qout = quantum_circuit(x[i], self.quantum_weights)
            quantum_outputs.append(torch.stack(qout))

        x = torch.stack(quantum_outputs)

        # Classical post-processing
        x = self.post_process(x)

        return x


class QuantumKernelSVM:
    """
    Quantum Kernel SVM — використовує квантовий комп'ютер
    для обчислення kernel matrix.
    """

    def __init__(self, n_qubits: int = 4):
        self.n_qubits = n_qubits
        self.dev = qml.device('default.qubit', wires=n_qubits)
        self.training_data = None

    def _feature_map(self, x: np.ndarray) -> qml.QNode:
        """Quantum feature map circuit."""
        @qml.qnode(self.dev)
        def circuit():
            # First layer
            for i in range(self.n_qubits):
                qml.Hadamard(wires=i)
                qml.RZ(x[i % len(x)], wires=i)

            # Entangling layer
            for i in range(self.n_qubits - 1):
                qml.CNOT(wires=[i, i + 1])
                qml.RZ(x[i % len(x)] * x[(i + 1) % len(x)], wires=i + 1)
                qml.CNOT(wires=[i, i + 1])

            # Second layer
            for i in range(self.n_qubits):
                qml.RZ(x[i % len(x)], wires=i)

            return qml.state()

        return circuit

    def kernel(self, x1: np.ndarray, x2: np.ndarray) -> float:
        """Compute quantum kernel between two data points."""
        @qml.qnode(self.dev)
        def kernel_circuit():
            # Encode x1
            for i in range(self.n_qubits):
                qml.Hadamard(wires=i)
                qml.RZ(x1[i % len(x1)], wires=i)

            # Encode x2 (adjoint)
            for i in range(self.n_qubits):
                qml.RZ(-x2[i % len(x2)], wires=i)
                qml.Hadamard(wires=i)

            # Measure probability of |00...0⟩
            return qml.probs(wires=range(self.n_qubits))

        probs = kernel_circuit()
        return probs[0]  # Probability of all zeros = |⟨φ(x1)|φ(x2)⟩|²

    def compute_kernel_matrix(self, X: np.ndarray) -> np.ndarray:
        """Compute full kernel matrix for training data."""
        n = len(X)
        K = np.zeros((n, n))

        for i in range(n):
            for j in range(i, n):
                K[i, j] = self.kernel(X[i], X[j])
                K[j, i] = K[i, j]

        return K

    def fit(self, X: np.ndarray, y: np.ndarray):
        """Train quantum kernel SVM."""
        from sklearn.svm import SVC

        self.training_data = X

        # Compute quantum kernel matrix
        K_train = self.compute_kernel_matrix(X)

        # Train classical SVM with quantum kernel
        self.svm = SVC(kernel='precomputed')
        self.svm.fit(K_train, y)

    def predict(self, X_test: np.ndarray) -> np.ndarray:
        """Predict using trained quantum kernel SVM."""
        n_test = len(X_test)
        n_train = len(self.training_data)

        # Compute kernel between test and training points
        K_test = np.zeros((n_test, n_train))
        for i in range(n_test):
            for j in range(n_train):
                K_test[i, j] = self.kernel(X_test[i], self.training_data[j])

        return self.svm.predict(K_test)

Quantum-Enhanced Federated Learning

import numpy as np
import torch
import torch.nn as nn
from typing import List, Dict
import pennylane as qml

class QuantumSecureAggregation:
    """
    Quantum-based secure aggregation для Federated Learning.

    Використовує квантові властивості для privacy-preserving aggregation.
    """

    def __init__(self, num_clients: int, model_dim: int):
        self.num_clients = num_clients
        self.model_dim = model_dim

        # Quantum device for secure operations
        self.n_qubits = min(10, model_dim)  # Practical limit
        self.dev = qml.device('default.qubit', wires=self.n_qubits)

    def encode_gradient(self, gradient: np.ndarray) -> np.ndarray:
        """Encode gradient into quantum-safe representation."""
        # Normalize gradient
        norm = np.linalg.norm(gradient)
        if norm > 0:
            normalized = gradient / norm
        else:
            normalized = gradient

        # Truncate/pad to quantum dimension
        if len(normalized) > self.n_qubits:
            encoded = normalized[:self.n_qubits]
        else:
            encoded = np.pad(normalized, (0, self.n_qubits - len(normalized)))

        return encoded, norm

    def quantum_aggregate(
        self,
        encoded_gradients: List[np.ndarray],
        norms: List[float]
    ) -> np.ndarray:
        """Aggregate gradients using quantum circuit."""

        @qml.qnode(self.dev)
        def aggregation_circuit(gradients):
            # Encode each client's gradient
            for client_idx, grad in enumerate(gradients):
                # Rotate based on gradient values
                for i, val in enumerate(grad):
                    # Use controlled rotation for aggregation
                    angle = np.arcsin(np.clip(val, -1, 1))
                    qml.RY(angle / len(gradients), wires=i)

            # Measure expectation values
            return [qml.expval(qml.PauliZ(i)) for i in range(self.n_qubits)]

        # Run quantum aggregation
        aggregated = np.array(aggregation_circuit(encoded_gradients))

        # Scale by average norm
        avg_norm = np.mean(norms)
        aggregated = aggregated * avg_norm

        return aggregated

    def secure_aggregate(
        self,
        client_gradients: List[np.ndarray]
    ) -> np.ndarray:
        """Full secure aggregation pipeline."""
        # Encode all gradients
        encoded = []
        norms = []
        for grad in client_gradients:
            enc, norm = self.encode_gradient(grad)
            encoded.append(enc)
            norms.append(norm)

        # Quantum aggregation
        aggregated_encoded = self.quantum_aggregate(encoded, norms)

        # Decode to full dimension
        if self.model_dim > self.n_qubits:
            # Simple extension (in practice, would use more sophisticated method)
            aggregated = np.zeros(self.model_dim)
            aggregated[:self.n_qubits] = aggregated_encoded

            # Approximate remaining dimensions classically
            for i, grad in enumerate(client_gradients):
                aggregated[self.n_qubits:] += grad[self.n_qubits:] / len(client_gradients)
        else:
            aggregated = aggregated_encoded[:self.model_dim]

        return aggregated


class QuantumFederatedLearning:
    """Complete Quantum-Enhanced Federated Learning system."""

    def __init__(
        self,
        model: nn.Module,
        num_clients: int,
        use_quantum_aggregation: bool = True
    ):
        self.global_model = model
        self.num_clients = num_clients

        model_dim = sum(p.numel() for p in model.parameters())
        self.aggregator = QuantumSecureAggregation(num_clients, model_dim)
        self.use_quantum = use_quantum_aggregation

    def client_update(
        self,
        client_data: torch.utils.data.DataLoader,
        local_epochs: int = 1,
        lr: float = 0.01
    ) -> np.ndarray:
        """Train locally and return gradient."""
        # Clone global model
        local_model = type(self.global_model)()
        local_model.load_state_dict(self.global_model.state_dict())

        optimizer = torch.optim.SGD(local_model.parameters(), lr=lr)
        criterion = nn.CrossEntropyLoss()

        initial_params = self._get_params(local_model)

        for _ in range(local_epochs):
            for x, y in client_data:
                optimizer.zero_grad()
                output = local_model(x)
                loss = criterion(output, y)
                loss.backward()
                optimizer.step()

        final_params = self._get_params(local_model)

        # Return gradient (difference)
        gradient = final_params - initial_params
        return gradient

    def aggregate_and_update(
        self,
        client_gradients: List[np.ndarray]
    ):
        """Aggregate gradients and update global model."""
        if self.use_quantum:
            aggregated = self.aggregator.secure_aggregate(client_gradients)
        else:
            # Classical averaging
            aggregated = np.mean(client_gradients, axis=0)

        # Apply to global model
        self._apply_gradient(aggregated)

    def _get_params(self, model: nn.Module) -> np.ndarray:
        """Extract parameters as flat array."""
        return np.concatenate([
            p.detach().numpy().flatten()
            for p in model.parameters()
        ])

    def _apply_gradient(self, gradient: np.ndarray):
        """Apply gradient to global model."""
        offset = 0
        for param in self.global_model.parameters():
            numel = param.numel()
            update = gradient[offset:offset + numel].reshape(param.shape)
            param.data += torch.from_numpy(update).float()
            offset += numel

Quantum Key Distribution для Edge Security

import numpy as np
from typing import Tuple, List
from dataclasses import dataclass

@dataclass
class QKDResult:
    """Result of QKD protocol."""
    shared_key: bytes
    key_rate: float  # bits per second
    error_rate: float
    secure: bool

class BB84Protocol:
    """
    BB84 Quantum Key Distribution protocol simulation.

    Alice та Bob обмінюються ключем через квантовий канал.
    Eve (eavesdropper) не може підслухати без detection.
    """

    def __init__(self, key_length: int = 256):
        self.key_length = key_length
        self.raw_key_multiplier = 4  # Need more raw bits due to losses

    def alice_prepare(self, n_bits: int) -> Tuple[np.ndarray, np.ndarray]:
        """Alice prepares random bits and bases."""
        bits = np.random.randint(0, 2, n_bits)
        bases = np.random.randint(0, 2, n_bits)  # 0=Z, 1=X
        return bits, bases

    def quantum_channel(
        self,
        bits: np.ndarray,
        alice_bases: np.ndarray,
        noise_rate: float = 0.0,
        eve_present: bool = False
    ) -> Tuple[np.ndarray, float]:
        """
        Simulate quantum channel transmission.

        If Eve intercepts, she introduces ~25% error rate.
        """
        transmitted_bits = bits.copy()
        introduced_errors = 0

        if eve_present:
            # Eve measures in random basis
            eve_bases = np.random.randint(0, 2, len(bits))

            for i in range(len(bits)):
                if eve_bases[i] != alice_bases[i]:
                    # Wrong basis measurement randomizes result
                    if np.random.random() < 0.5:
                        transmitted_bits[i] = 1 - transmitted_bits[i]
                        introduced_errors += 1

        # Channel noise
        for i in range(len(transmitted_bits)):
            if np.random.random() < noise_rate:
                transmitted_bits[i] = 1 - transmitted_bits[i]
                introduced_errors += 1

        error_rate = introduced_errors / len(bits)
        return transmitted_bits, error_rate

    def bob_measure(
        self,
        received_bits: np.ndarray
    ) -> Tuple[np.ndarray, np.ndarray]:
        """Bob measures in random bases."""
        bob_bases = np.random.randint(0, 2, len(received_bits))
        # In real quantum, measurement in different basis gives random result
        # Here we simulate: if bases match, we get correct bit
        measured_bits = received_bits.copy()

        return measured_bits, bob_bases

    def sift_keys(
        self,
        alice_bits: np.ndarray,
        alice_bases: np.ndarray,
        bob_bits: np.ndarray,
        bob_bases: np.ndarray
    ) -> Tuple[np.ndarray, np.ndarray]:
        """Keep only bits where Alice and Bob used same basis."""
        matching = alice_bases == bob_bases

        alice_sifted = alice_bits[matching]
        bob_sifted = bob_bits[matching]

        return alice_sifted, bob_sifted

    def estimate_error_rate(
        self,
        alice_key: np.ndarray,
        bob_key: np.ndarray,
        sample_fraction: float = 0.1
    ) -> float:
        """Estimate error rate by comparing subset of bits."""
        n_sample = int(len(alice_key) * sample_fraction)
        sample_indices = np.random.choice(
            len(alice_key), n_sample, replace=False
        )

        alice_sample = alice_key[sample_indices]
        bob_sample = bob_key[sample_indices]

        error_rate = np.mean(alice_sample != bob_sample)
        return error_rate

    def run_protocol(
        self,
        channel_noise: float = 0.01,
        eve_present: bool = False
    ) -> QKDResult:
        """Run complete BB84 protocol."""

        n_raw_bits = self.key_length * self.raw_key_multiplier

        # Alice prepares
        alice_bits, alice_bases = self.alice_prepare(n_raw_bits)

        # Quantum channel transmission
        received_bits, channel_error = self.quantum_channel(
            alice_bits, alice_bases, channel_noise, eve_present
        )

        # Bob measures
        bob_bits, bob_bases = self.bob_measure(received_bits)

        # Public discussion: exchange bases (classical channel)
        alice_sifted, bob_sifted = self.sift_keys(
            alice_bits, alice_bases, bob_bits, bob_bases
        )

        # Estimate error rate
        error_rate = self.estimate_error_rate(alice_sifted, bob_sifted)

        # Security check
        # If error rate > 11%, Eve likely present
        secure = error_rate < 0.11

        if secure and len(alice_sifted) >= self.key_length:
            # Privacy amplification (simplified)
            final_key = alice_sifted[:self.key_length]
            key_bytes = np.packbits(final_key).tobytes()
        else:
            key_bytes = b''

        return QKDResult(
            shared_key=key_bytes,
            key_rate=len(alice_sifted) / n_raw_bits,
            error_rate=error_rate,
            secure=secure
        )


class EdgeQuantumSecureChannel:
    """Secure channel для edge devices з QKD."""

    def __init__(self, edge_id: str, cloud_endpoint: str):
        self.edge_id = edge_id
        self.cloud_endpoint = cloud_endpoint
        self.qkd = BB84Protocol(key_length=256)
        self.current_key = None

    def establish_key(self) -> bool:
        """Establish quantum-secure key with cloud."""
        result = self.qkd.run_protocol(
            channel_noise=0.02,
            eve_present=False
        )

        if result.secure:
            self.current_key = result.shared_key
            print(f"Secure key established. Error rate: {result.error_rate:.2%}")
            return True
        else:
            print(f"Key exchange failed! Error rate: {result.error_rate:.2%}")
            print("Possible eavesdropping detected!")
            return False

    def encrypt_data(self, data: bytes) -> bytes:
        """Encrypt data with current key (simplified XOR)."""
        if self.current_key is None:
            raise ValueError("No key established")

        # Extend key if needed (in practice, use proper stream cipher)
        key_extended = (self.current_key * (len(data) // len(self.current_key) + 1))[:len(data)]

        encrypted = bytes(a ^ b for a, b in zip(data, key_extended))
        return encrypted

Практичні виклики Quantum-Edge Integration

| Challenge | Current Status | Timeline |

|-----------|---------------|----------|

| Qubit count | 1000+ noisy qubits | 2024 |

| Error rates | 0.1-1% per gate | 10x improvement by 2027 |

| Coherence time | Microseconds | Milliseconds by 2028 |

| Operating temp | 15 mK | Room-temp ions exploring |

| Network latency | Seconds to QPU | Sub-second by 2026 |

| Cost | $10M+ per system | Cloud access $1/min |


Ідеї для наукових досліджень

Для бакалаврської роботи:

  • QAOA simulation для small optimization (5-10 qubits)
  • Порівняння quantum vs classical для MaxCut
  • QKD protocol simulation та error analysis

Для магістерської дисертації:

  • Hybrid quantum-classical neural network для classification
  • Quantum-enhanced federated learning prototype
  • Error mitigation techniques для NISQ devices

Для PhD досліджень:

  • Novel quantum algorithms для edge optimization
  • Theoretical quantum advantage bounds для practical problems
  • Fault-tolerant quantum-edge architecture design

Квантові комп'ютери не замінять класичні. Вони їх доповнять для специфічних задач. Edge AI буде скрізь. Quantum advantages — для specific high-value problems. Intersection — quantum-enhanced edge — це frontier, який визначить системи 2030-х років.

Ті, хто зрозуміє обидва світи — класичний ML та квантові обчислення — будуть проектувати інфраструктуру майбутнього. Починати розбиратись — сьогодні. Якщо ви плануєте дослідження на перетині quantum computing та edge AI — фахівці SKP-Degree готові допомогти з формулюванням теми, реалізацією симуляцій та науковим оформленням. Звертайтесь на skp-degree.com.ua або пишіть у Telegram: @kursovi_diplomy — від квантової ідеї до успішного захисту.

Ключові слова: quantum computing, QAOA, VQE, hybrid quantum-classical, edge computing, quantum machine learning, QKD, PennyLane, Qiskit, variational quantum algorithms, quantum federated learning, дипломна робота, магістерська, PhD-дослідження.

Про автора

Команда SKP-Degree

Верифікований автор

Розробники та дослідники AI · Python, TensorFlow, PyTorch · Досвід у промисловій розробці

Команда SKP-Degree — професійні розробники з досвідом 7+ років у промисловій розробці. Виконали 1000+ проєктів для студентів з України, Польщі та країн Балтії.

Python Django Java ML/AI React C# / .NET JavaScript

Потрібна допомога з роботою?

Замовте курсову чи дипломну роботу з програмування. Оплата після демонстрації!

Без передоплати Відеодемонстрація Автономна робота 24/7
Написати в Telegram