Skip to main content

quantrs2_sim/qaoa_optimization/
qaoaoptimizer_check_methods.rs

1//! # QAOAOptimizer - check_methods Methods
2//!
3//! This module contains method implementations for `QAOAOptimizer`.
4//!
5//! 🤖 Generated with [SplitRS](https://github.com/cool-japan/splitrs)
6
7use crate::error::Result;
8use scirs2_core::random::prelude::*;
9
10use super::types::{QAOAConstraint, QAOAProblemType};
11
12use super::qaoaoptimizer_type::QAOAOptimizer;
13
14impl QAOAOptimizer {
15    pub(super) fn check_feasibility(&self, solution: &str) -> Result<bool> {
16        let bits: Vec<bool> = solution.chars().map(|c| c == '1').collect();
17        match self.problem_type {
18            QAOAProblemType::MaxWeightIndependentSet => {
19                for i in 0..self.graph.num_vertices {
20                    if bits[i] {
21                        for j in 0..self.graph.num_vertices {
22                            if i != j && bits[j] && self.graph.adjacency_matrix[[i, j]] > 0.0 {
23                                return Ok(false);
24                            }
25                        }
26                    }
27                }
28            }
29            QAOAProblemType::TSP => {
30                let num_cities = (self.graph.num_vertices as f64).sqrt() as usize;
31                let mut city_counts = vec![0; num_cities];
32                let mut time_counts = vec![0; num_cities];
33                for city in 0..num_cities {
34                    for time in 0..num_cities {
35                        let qubit = city * num_cities + time;
36                        if qubit < bits.len() && bits[qubit] {
37                            city_counts[city] += 1;
38                            time_counts[time] += 1;
39                        }
40                    }
41                }
42                if !city_counts.iter().all(|&count| count == 1)
43                    || !time_counts.iter().all(|&count| count == 1)
44                {
45                    return Ok(false);
46                }
47            }
48            _ => {}
49        }
50        for constraint in &self.graph.constraints {
51            match constraint {
52                QAOAConstraint::Cardinality { target } => {
53                    let count = bits.iter().filter(|&&b| b).count();
54                    if count != *target {
55                        return Ok(false);
56                    }
57                }
58                QAOAConstraint::UpperBound { max_vertices } => {
59                    let count = bits.iter().filter(|&&b| b).count();
60                    if count > *max_vertices {
61                        return Ok(false);
62                    }
63                }
64                QAOAConstraint::LowerBound { min_vertices } => {
65                    let count = bits.iter().filter(|&&b| b).count();
66                    if count < *min_vertices {
67                        return Ok(false);
68                    }
69                }
70                QAOAConstraint::Parity { even } => {
71                    let count = bits.iter().filter(|&&b| b).count();
72                    if (count % 2 == 0) != *even {
73                        return Ok(false);
74                    }
75                }
76                QAOAConstraint::LinearConstraint {
77                    coefficients,
78                    bound,
79                } => {
80                    let mut sum = 0.0;
81                    for (i, &coeff) in coefficients.iter().enumerate() {
82                        if i < bits.len() && bits[i] {
83                            sum += coeff;
84                        }
85                    }
86                    if (sum - bound).abs() > 1e-10 {
87                        return Ok(false);
88                    }
89                }
90            }
91        }
92        Ok(true)
93    }
94}