quantrs2_core/quantum_walk/
search.rs1use super::discrete::DiscreteQuantumWalk;
4use super::graph::{CoinOperator, Graph, SearchOracle};
5use scirs2_core::Complex64;
6
7pub struct QuantumWalkSearch {
9 #[allow(dead_code)]
10 graph: Graph,
11 oracle: SearchOracle,
12 walk: DiscreteQuantumWalk,
13}
14
15impl QuantumWalkSearch {
16 pub fn new(graph: Graph, oracle: SearchOracle) -> Self {
18 let walk = DiscreteQuantumWalk::new(graph.clone(), CoinOperator::Grover);
19 Self {
20 graph,
21 oracle,
22 walk,
23 }
24 }
25
26 fn apply_oracle(&mut self) {
28 for &vertex in &self.oracle.marked {
29 for coin in 0..self.walk.coin_dimension {
30 let idx = self.walk.state_index(vertex, coin);
31 if idx < self.walk.state.len() {
32 self.walk.state[idx] = -self.walk.state[idx]; }
34 }
35 }
36 }
37
38 pub fn run(&mut self, max_steps: usize) -> (usize, f64, usize) {
40 let amplitude = Complex64::new(1.0 / (self.walk.hilbert_dim as f64).sqrt(), 0.0);
42 self.walk.state.fill(amplitude);
43
44 let mut best_vertex = 0;
45 let mut best_prob = 0.0;
46 let mut best_step = 0;
47
48 for step in 1..=max_steps {
50 self.walk.step();
51 self.apply_oracle();
52
53 let probs = self.walk.position_probabilities();
55 for &marked in &self.oracle.marked {
56 if probs[marked] > best_prob {
57 best_prob = probs[marked];
58 best_vertex = marked;
59 best_step = step;
60 }
61 }
62
63 if best_prob > 0.5 {
65 break;
66 }
67 }
68
69 (best_vertex, best_prob, best_step)
70 }
71
72 pub fn vertex_probabilities(&self) -> Vec<f64> {
74 self.walk.position_probabilities()
75 }
76}