1use crate::error::{QuantRS2Error, QuantRS2Result};
7use scirs2_core::ndarray::{Array1, Array2};
8use scirs2_core::Complex64;
9use std::collections::{HashMap, HashSet};
10use std::f64::consts::PI;
11
12#[derive(Debug, Clone, Copy, PartialEq)]
14pub enum MeasurementBasis {
15 Computational,
17 X,
19 Y,
21 XY(f64),
23 XZ(f64),
25 YZ(f64),
27}
28
29impl MeasurementBasis {
30 pub fn operator(&self) -> Array2<Complex64> {
32 match self {
33 MeasurementBasis::Computational => {
34 Array2::from_shape_vec(
36 (2, 2),
37 vec![
38 Complex64::new(1.0, 0.0),
39 Complex64::new(0.0, 0.0),
40 Complex64::new(0.0, 0.0),
41 Complex64::new(0.0, 0.0),
42 ],
43 )
44 .expect(
45 "Failed to create computational basis operator in MeasurementBasis::operator",
46 )
47 }
48 MeasurementBasis::X => {
49 Array2::from_shape_vec(
51 (2, 2),
52 vec![
53 Complex64::new(0.5, 0.0),
54 Complex64::new(0.5, 0.0),
55 Complex64::new(0.5, 0.0),
56 Complex64::new(0.5, 0.0),
57 ],
58 )
59 .expect("Failed to create X basis operator in MeasurementBasis::operator")
60 }
61 MeasurementBasis::Y => {
62 Array2::from_shape_vec(
64 (2, 2),
65 vec![
66 Complex64::new(0.5, 0.0),
67 Complex64::new(0.0, -0.5),
68 Complex64::new(0.0, 0.5),
69 Complex64::new(0.5, 0.0),
70 ],
71 )
72 .expect("Failed to create Y basis operator in MeasurementBasis::operator")
73 }
74 MeasurementBasis::XY(theta) => {
75 let c = (theta / 2.0).cos();
77 let s = (theta / 2.0).sin();
78 Array2::from_shape_vec(
79 (2, 2),
80 vec![
81 Complex64::new(c * c, 0.0),
82 Complex64::new(c * s, 0.0),
83 Complex64::new(c * s, 0.0),
84 Complex64::new(s * s, 0.0),
85 ],
86 )
87 .expect("Failed to create XY basis operator in MeasurementBasis::operator")
88 }
89 MeasurementBasis::XZ(theta) => {
90 let c = (theta / 2.0).cos();
92 let s = (theta / 2.0).sin();
93 Array2::from_shape_vec(
94 (2, 2),
95 vec![
96 Complex64::new(c * c, 0.0),
97 Complex64::new(c, 0.0) * Complex64::new(0.0, -s),
98 Complex64::new(c, 0.0) * Complex64::new(0.0, s),
99 Complex64::new(s * s, 0.0),
100 ],
101 )
102 .expect("Failed to create XZ basis operator in MeasurementBasis::operator")
103 }
104 MeasurementBasis::YZ(theta) => {
105 let c = (theta / 2.0).cos();
107 let s = (theta / 2.0).sin();
108 Array2::from_shape_vec(
109 (2, 2),
110 vec![
111 Complex64::new(c * c, 0.0),
112 Complex64::new(s, 0.0) * Complex64::new(1.0, 0.0),
113 Complex64::new(s, 0.0) * Complex64::new(1.0, 0.0),
114 Complex64::new(s * s, 0.0),
115 ],
116 )
117 .expect("Failed to create YZ basis operator in MeasurementBasis::operator")
118 }
119 }
120 }
121}
122
123#[derive(Debug, Clone)]
125pub struct Graph {
126 pub num_vertices: usize,
128 pub edges: HashMap<usize, HashSet<usize>>,
130}
131
132impl Graph {
133 pub fn new(num_vertices: usize) -> Self {
135 let mut edges = HashMap::new();
136 for i in 0..num_vertices {
137 edges.insert(i, HashSet::new());
138 }
139
140 Self {
141 num_vertices,
142 edges,
143 }
144 }
145
146 pub fn add_edge(&mut self, u: usize, v: usize) -> QuantRS2Result<()> {
148 if u >= self.num_vertices || v >= self.num_vertices {
149 return Err(QuantRS2Error::InvalidInput(
150 "Vertex index out of bounds".to_string(),
151 ));
152 }
153
154 if u != v {
155 self.edges
156 .get_mut(&u)
157 .expect("Vertex u should exist in edges map in Graph::add_edge")
158 .insert(v);
159 self.edges
160 .get_mut(&v)
161 .expect("Vertex v should exist in edges map in Graph::add_edge")
162 .insert(u);
163 }
164
165 Ok(())
166 }
167
168 pub fn neighbors(&self, v: usize) -> Option<&HashSet<usize>> {
170 self.edges.get(&v)
171 }
172
173 pub fn linear_cluster(n: usize) -> Self {
175 let mut graph = Self::new(n);
176 for i in 0..n - 1 {
177 graph
178 .add_edge(i, i + 1)
179 .expect("Failed to add edge in Graph::linear_cluster (indices should be valid)");
180 }
181 graph
182 }
183
184 pub fn rectangular_cluster(rows: usize, cols: usize) -> Self {
186 let n = rows * cols;
187 let mut graph = Self::new(n);
188
189 for r in 0..rows {
190 for c in 0..cols {
191 let idx = r * cols + c;
192
193 if c < cols - 1 {
195 graph
196 .add_edge(idx, idx + 1)
197 .expect("Failed to add horizontal edge in Graph::rectangular_cluster");
198 }
199
200 if r < rows - 1 {
202 graph
203 .add_edge(idx, idx + cols)
204 .expect("Failed to add vertical edge in Graph::rectangular_cluster");
205 }
206 }
207 }
208
209 graph
210 }
211
212 pub fn complete(n: usize) -> Self {
214 let mut graph = Self::new(n);
215 for i in 0..n {
216 for j in i + 1..n {
217 graph
218 .add_edge(i, j)
219 .expect("Failed to add edge in Graph::complete");
220 }
221 }
222 graph
223 }
224
225 pub fn star(n: usize) -> Self {
227 let mut graph = Self::new(n);
228 for i in 1..n {
229 graph
230 .add_edge(0, i)
231 .expect("Failed to add edge in Graph::star");
232 }
233 graph
234 }
235}
236
237#[derive(Debug, Clone)]
239pub struct MeasurementPattern {
240 pub measurements: HashMap<usize, MeasurementBasis>,
242 pub order: Vec<usize>,
244 pub x_corrections: HashMap<usize, Vec<(usize, bool)>>, pub z_corrections: HashMap<usize, Vec<(usize, bool)>>,
247 pub inputs: HashSet<usize>,
249 pub outputs: HashSet<usize>,
251}
252
253impl MeasurementPattern {
254 pub fn new() -> Self {
256 Self {
257 measurements: HashMap::new(),
258 order: Vec::new(),
259 x_corrections: HashMap::new(),
260 z_corrections: HashMap::new(),
261 inputs: HashSet::new(),
262 outputs: HashSet::new(),
263 }
264 }
265
266 pub fn add_measurement(&mut self, qubit: usize, basis: MeasurementBasis) {
268 self.measurements.insert(qubit, basis);
269 if !self.order.contains(&qubit) {
270 self.order.push(qubit);
271 }
272 }
273
274 pub fn add_x_correction(&mut self, target: usize, source: usize, sign: bool) {
276 self.x_corrections
277 .entry(target)
278 .or_insert_with(Vec::new)
279 .push((source, sign));
280 }
281
282 pub fn add_z_correction(&mut self, target: usize, source: usize, sign: bool) {
284 self.z_corrections
285 .entry(target)
286 .or_insert_with(Vec::new)
287 .push((source, sign));
288 }
289
290 pub fn set_inputs(&mut self, inputs: Vec<usize>) {
292 self.inputs = inputs.into_iter().collect();
293 }
294
295 pub fn set_outputs(&mut self, outputs: Vec<usize>) {
297 self.outputs = outputs.into_iter().collect();
298 }
299
300 pub fn single_qubit_rotation(angle: f64) -> Self {
302 let mut pattern = Self::new();
303
304 pattern.set_inputs(vec![0]);
306 pattern.set_outputs(vec![2]);
307
308 pattern.add_measurement(1, MeasurementBasis::XY(angle));
310
311 pattern.add_measurement(0, MeasurementBasis::X);
313
314 pattern.add_x_correction(2, 0, true);
316 pattern.add_z_correction(2, 1, true);
317
318 pattern
319 }
320
321 pub fn cnot() -> Self {
323 let mut pattern = Self::new();
324
325 pattern.set_inputs(vec![0, 1]);
329 pattern.set_outputs(vec![13, 14]);
330
331 for i in 2..13 {
333 pattern.add_measurement(i, MeasurementBasis::XY(PI / 2.0));
334 }
335
336 pattern.add_x_correction(13, 0, true);
338 pattern.add_x_correction(14, 1, true);
339
340 pattern
341 }
342}
343
344impl Default for MeasurementPattern {
345 fn default() -> Self {
346 Self::new()
347 }
348}
349
350pub struct ClusterState {
352 pub graph: Graph,
354 pub state: Array1<Complex64>,
356 pub measurements: HashMap<usize, bool>,
358}
359
360impl ClusterState {
361 pub fn from_graph(graph: Graph) -> QuantRS2Result<Self> {
363 let n = graph.num_vertices;
364 let dim = 1 << n;
365
366 let mut state = Array1::zeros(dim);
368 state[0] = Complex64::new(1.0, 0.0);
369
370 for i in 0..n {
372 state = Self::apply_hadamard(&state, i, n)?;
373 }
374
375 for (u, neighbors) in &graph.edges {
377 for &v in neighbors {
378 if u < &v {
379 state = Self::apply_cz(&state, *u, v, n)?;
380 }
381 }
382 }
383
384 let norm = state.iter().map(|c| c.norm_sqr()).sum::<f64>().sqrt();
386 state = state / Complex64::new(norm, 0.0);
387
388 Ok(Self {
389 graph,
390 state,
391 measurements: HashMap::new(),
392 })
393 }
394
395 fn apply_hadamard(
397 state: &Array1<Complex64>,
398 qubit: usize,
399 n: usize,
400 ) -> QuantRS2Result<Array1<Complex64>> {
401 let dim = 1 << n;
402 let mut new_state = Array1::zeros(dim);
403 let h_factor = Complex64::new(1.0 / 2.0_f64.sqrt(), 0.0);
404
405 for i in 0..dim {
406 let bit = (i >> qubit) & 1;
407 if bit == 0 {
408 new_state[i] += h_factor * state[i];
410 new_state[i | (1 << qubit)] += h_factor * state[i];
411 } else {
412 new_state[i & !(1 << qubit)] += h_factor * state[i];
414 new_state[i] -= h_factor * state[i];
415 }
416 }
417
418 Ok(new_state)
419 }
420
421 fn apply_cz(
423 state: &Array1<Complex64>,
424 q1: usize,
425 q2: usize,
426 n: usize,
427 ) -> QuantRS2Result<Array1<Complex64>> {
428 let dim = 1 << n;
429 let mut new_state = state.clone();
430
431 for i in 0..dim {
432 let bit1 = (i >> q1) & 1;
433 let bit2 = (i >> q2) & 1;
434 if bit1 == 1 && bit2 == 1 {
435 new_state[i] *= -1.0;
436 }
437 }
438
439 Ok(new_state)
440 }
441
442 pub fn measure(&mut self, qubit: usize, basis: MeasurementBasis) -> QuantRS2Result<bool> {
444 if qubit >= self.graph.num_vertices {
445 return Err(QuantRS2Error::InvalidInput(
446 "Qubit index out of bounds".to_string(),
447 ));
448 }
449
450 if self.measurements.contains_key(&qubit) {
451 return Err(QuantRS2Error::InvalidInput(
452 "Qubit already measured".to_string(),
453 ));
454 }
455
456 let state = match basis {
458 MeasurementBasis::Computational => self.state.clone(),
459 MeasurementBasis::X => {
460 Self::apply_hadamard(&self.state, qubit, self.graph.num_vertices)?
461 }
462 MeasurementBasis::Y => {
463 let mut state = self.state.clone();
465 for i in 0..state.len() {
466 if (i >> qubit) & 1 == 1 {
467 state[i] *= Complex64::new(0.0, -1.0);
468 }
469 }
470 Self::apply_hadamard(&state, qubit, self.graph.num_vertices)?
471 }
472 MeasurementBasis::XY(theta) => {
473 let mut state = self.state.clone();
475 for i in 0..state.len() {
476 if (i >> qubit) & 1 == 1 {
477 state[i] *= Complex64::from_polar(1.0, -theta);
478 }
479 }
480 Self::apply_hadamard(&state, qubit, self.graph.num_vertices)?
481 }
482 _ => {
483 return Err(QuantRS2Error::UnsupportedOperation(
484 "Measurement basis not yet implemented".to_string(),
485 ));
486 }
487 };
488
489 let mut prob_0 = 0.0;
491 let mut prob_1 = 0.0;
492
493 for i in 0..state.len() {
494 let bit = (i >> qubit) & 1;
495 let prob = state[i].norm_sqr();
496 if bit == 0 {
497 prob_0 += prob;
498 } else {
499 prob_1 += prob;
500 }
501 }
502
503 use scirs2_core::random::prelude::*;
505 let outcome = if thread_rng().gen::<f64>() < prob_0 / (prob_0 + prob_1) {
506 false
507 } else {
508 true
509 };
510
511 let norm = if outcome {
513 prob_1.sqrt()
514 } else {
515 prob_0.sqrt()
516 };
517 let mut new_state = Array1::zeros(state.len());
518
519 for i in 0..state.len() {
520 let bit = (i >> qubit) & 1;
521 if (bit == 1) == outcome {
522 new_state[i] = state[i] / norm;
523 }
524 }
525
526 self.state = new_state;
527 self.measurements.insert(qubit, outcome);
528
529 Ok(outcome)
530 }
531
532 pub fn apply_corrections(
534 &mut self,
535 x_corrections: &HashMap<usize, Vec<(usize, bool)>>,
536 z_corrections: &HashMap<usize, Vec<(usize, bool)>>,
537 ) -> QuantRS2Result<()> {
538 let _n = self.graph.num_vertices;
539
540 for (target, sources) in x_corrections {
542 let mut apply_x = false;
543 for (source, sign) in sources {
544 if let Some(&outcome) = self.measurements.get(source) {
545 if outcome && *sign {
546 apply_x = !apply_x;
547 }
548 }
549 }
550
551 if apply_x && !self.measurements.contains_key(target) {
552 for i in 0..self.state.len() {
554 let bit = (i >> target) & 1;
555 if bit == 0 {
556 let j = i | (1 << target);
557 self.state.swap(i, j);
558 }
559 }
560 }
561 }
562
563 for (target, sources) in z_corrections {
565 let mut apply_z = false;
566 for (source, sign) in sources {
567 if let Some(&outcome) = self.measurements.get(source) {
568 if outcome && *sign {
569 apply_z = !apply_z;
570 }
571 }
572 }
573
574 if apply_z && !self.measurements.contains_key(target) {
575 for i in 0..self.state.len() {
577 if (i >> target) & 1 == 1 {
578 self.state[i] *= -1.0;
579 }
580 }
581 }
582 }
583
584 Ok(())
585 }
586
587 pub fn get_output_state(&self, output_qubits: &[usize]) -> QuantRS2Result<Array1<Complex64>> {
589 let n_out = output_qubits.len();
590 let dim_out = 1 << n_out;
591 let mut output_state = Array1::zeros(dim_out);
592
593 let mut qubit_map = HashMap::new();
595 for (i, &q) in output_qubits.iter().enumerate() {
596 qubit_map.insert(q, i);
597 }
598
599 for i in 0..self.state.len() {
601 let mut out_idx = 0;
602 let mut valid = true;
603
604 for (&q, &outcome) in &self.measurements {
606 let bit = (i >> q) & 1;
607 if (bit == 1) != outcome {
608 valid = false;
609 break;
610 }
611 }
612
613 if valid {
614 for (j, &q) in output_qubits.iter().enumerate() {
616 if (i >> q) & 1 == 1 {
617 out_idx |= 1 << j;
618 }
619 }
620
621 output_state[out_idx] += self.state[i];
622 }
623 }
624
625 let norm = output_state
627 .iter()
628 .map(|c: &Complex64| c.norm_sqr())
629 .sum::<f64>()
630 .sqrt();
631 if norm > 0.0 {
632 output_state = output_state / Complex64::new(norm, 0.0);
633 }
634
635 Ok(output_state)
636 }
637}
638
639pub struct MBQCComputation {
641 pub cluster: ClusterState,
643 pub pattern: MeasurementPattern,
645 pub current_step: usize,
647}
648
649impl MBQCComputation {
650 pub fn new(graph: Graph, pattern: MeasurementPattern) -> QuantRS2Result<Self> {
652 let cluster = ClusterState::from_graph(graph)?;
653
654 Ok(Self {
655 cluster,
656 pattern,
657 current_step: 0,
658 })
659 }
660
661 pub fn step(&mut self) -> QuantRS2Result<Option<(usize, bool)>> {
663 if self.current_step >= self.pattern.order.len() {
664 return Ok(None);
665 }
666
667 let qubit = self.pattern.order[self.current_step];
668 self.current_step += 1;
669
670 if self.pattern.outputs.contains(&qubit) && self.current_step == self.pattern.order.len() {
672 return self.step();
673 }
674
675 let basis = self
677 .pattern
678 .measurements
679 .get(&qubit)
680 .copied()
681 .unwrap_or(MeasurementBasis::Computational);
682
683 let outcome = self.cluster.measure(qubit, basis)?;
685
686 self.cluster
688 .apply_corrections(&self.pattern.x_corrections, &self.pattern.z_corrections)?;
689
690 Ok(Some((qubit, outcome)))
691 }
692
693 pub fn run(&mut self) -> QuantRS2Result<HashMap<usize, bool>> {
695 while self.step()?.is_some() {}
696 Ok(self.cluster.measurements.clone())
697 }
698
699 pub fn output_state(&self) -> QuantRS2Result<Array1<Complex64>> {
701 let outputs: Vec<usize> = self.pattern.outputs.iter().copied().collect();
702 self.cluster.get_output_state(&outputs)
703 }
704}
705
706pub struct CircuitToMBQC {
708 #[allow(dead_code)]
710 qubit_map: HashMap<usize, usize>,
711 #[allow(dead_code)]
713 cluster_size: usize,
714}
715
716impl CircuitToMBQC {
717 pub fn new() -> Self {
719 Self {
720 qubit_map: HashMap::new(),
721 cluster_size: 0,
722 }
723 }
724
725 pub fn convert_single_qubit_gate(
727 &mut self,
728 _qubit: usize,
729 angle: f64,
730 ) -> (Graph, MeasurementPattern) {
731 let mut graph = Graph::new(3);
732 graph
733 .add_edge(0, 1)
734 .expect("Failed to add edge 0-1 in CircuitToMBQC::convert_single_qubit_gate");
735 graph
736 .add_edge(1, 2)
737 .expect("Failed to add edge 1-2 in CircuitToMBQC::convert_single_qubit_gate");
738
739 let pattern = MeasurementPattern::single_qubit_rotation(angle);
740
741 (graph, pattern)
742 }
743
744 pub fn convert_cnot(&mut self, _control: usize, _target: usize) -> (Graph, MeasurementPattern) {
746 let mut graph = Graph::new(15);
748
749 for i in 0..5 {
751 for j in 0..3 {
752 let idx = i * 3 + j;
753 if j < 2 {
754 graph
755 .add_edge(idx, idx + 1)
756 .expect("Failed to add horizontal edge in CircuitToMBQC::convert_cnot");
757 }
758 if i < 4 {
759 graph
760 .add_edge(idx, idx + 3)
761 .expect("Failed to add vertical edge in CircuitToMBQC::convert_cnot");
762 }
763 }
764 }
765
766 let pattern = MeasurementPattern::cnot();
767
768 (graph, pattern)
769 }
770}
771
772impl Default for CircuitToMBQC {
773 fn default() -> Self {
774 Self::new()
775 }
776}
777
778#[cfg(test)]
779mod tests {
780 use super::*;
781
782 #[test]
783 fn test_graph_construction() {
784 let mut graph = Graph::new(4);
785 graph
786 .add_edge(0, 1)
787 .expect("Failed to add edge 0-1 in test_graph_construction");
788 graph
789 .add_edge(1, 2)
790 .expect("Failed to add edge 1-2 in test_graph_construction");
791 graph
792 .add_edge(2, 3)
793 .expect("Failed to add edge 2-3 in test_graph_construction");
794
795 assert_eq!(
796 graph
797 .neighbors(1)
798 .expect("Failed to get neighbors of vertex 1 in test_graph_construction")
799 .len(),
800 2
801 );
802 assert!(graph
803 .neighbors(1)
804 .expect(
805 "Failed to get neighbors of vertex 1 for contains check in test_graph_construction"
806 )
807 .contains(&0));
808 assert!(graph.neighbors(1).expect("Failed to get neighbors of vertex 1 for second contains check in test_graph_construction").contains(&2));
809 }
810
811 #[test]
812 fn test_linear_cluster() {
813 let graph = Graph::linear_cluster(5);
814 assert_eq!(graph.num_vertices, 5);
815 assert_eq!(
816 graph
817 .neighbors(2)
818 .expect("Failed to get neighbors of vertex 2 in test_linear_cluster")
819 .len(),
820 2
821 );
822 assert_eq!(
823 graph
824 .neighbors(0)
825 .expect("Failed to get neighbors of vertex 0 in test_linear_cluster")
826 .len(),
827 1
828 );
829 assert_eq!(
830 graph
831 .neighbors(4)
832 .expect("Failed to get neighbors of vertex 4 in test_linear_cluster")
833 .len(),
834 1
835 );
836 }
837
838 #[test]
839 fn test_rectangular_cluster() {
840 let graph = Graph::rectangular_cluster(3, 3);
841 assert_eq!(graph.num_vertices, 9);
842
843 assert_eq!(
845 graph
846 .neighbors(0)
847 .expect("Failed to get neighbors of vertex 0 in test_rectangular_cluster")
848 .len(),
849 2
850 );
851
852 assert_eq!(
854 graph
855 .neighbors(4)
856 .expect("Failed to get neighbors of vertex 4 in test_rectangular_cluster")
857 .len(),
858 4
859 );
860 }
861
862 #[test]
863 fn test_cluster_state_creation() {
864 let graph = Graph::linear_cluster(3);
865 let cluster = ClusterState::from_graph(graph)
866 .expect("Failed to create cluster state in test_cluster_state_creation");
867
868 let norm: f64 = cluster.state.iter().map(|c| c.norm_sqr()).sum();
870 assert!((norm - 1.0).abs() < 1e-10);
871
872 assert_eq!(cluster.state.len(), 8); }
875
876 #[test]
877 fn test_measurement_pattern() {
878 let mut pattern = MeasurementPattern::new();
879 pattern.add_measurement(0, MeasurementBasis::X);
880 pattern.add_measurement(1, MeasurementBasis::XY(PI / 4.0));
881 pattern.add_x_correction(2, 0, true);
882 pattern.add_z_correction(2, 1, true);
883
884 assert_eq!(pattern.measurements.len(), 2);
885 assert_eq!(pattern.order.len(), 2);
886 assert!(pattern.x_corrections.contains_key(&2));
887 }
888
889 #[test]
890 fn test_single_qubit_measurement() {
891 let graph = Graph::new(1);
892 let mut cluster = ClusterState::from_graph(graph)
893 .expect("Failed to create cluster state in test_single_qubit_measurement");
894
895 let outcome = cluster
897 .measure(0, MeasurementBasis::X)
898 .expect("Failed to measure qubit 0 in test_single_qubit_measurement");
899
900 assert!(cluster.measurements.contains_key(&0));
902 assert_eq!(cluster.measurements[&0], outcome);
903 }
904
905 #[test]
906 fn test_mbqc_computation() {
907 let graph = Graph::linear_cluster(3);
908 let pattern = MeasurementPattern::single_qubit_rotation(PI / 4.0);
909
910 let mut computation = MBQCComputation::new(graph, pattern)
911 .expect("Failed to create MBQC computation in test_mbqc_computation");
912
913 let outcomes = computation
915 .run()
916 .expect("Failed to run MBQC computation in test_mbqc_computation");
917
918 assert!(outcomes.contains_key(&0));
920 assert!(outcomes.contains_key(&1));
921 }
922
923 #[test]
924 fn test_circuit_conversion() {
925 let mut converter = CircuitToMBQC::new();
926
927 let (graph, pattern) = converter.convert_single_qubit_gate(0, PI / 2.0);
929 assert_eq!(graph.num_vertices, 3);
930 assert_eq!(pattern.measurements.len(), 2);
931
932 let (graph, _pattern) = converter.convert_cnot(0, 1);
934 assert_eq!(graph.num_vertices, 15);
935 }
936}