#![allow(
unused_must_use,
clippy::pedantic,
clippy::unnecessary_wraps,
clippy::match_same_arms
)]
use quantrs2_tytan::sampler::{SASampler, Sampler};
use quantrs2_tytan::solution_debugger::{
ConstraintInfo, ConstraintType, DebuggerConfig, ProblemInfo, Solution, SolutionDebugger,
};
use scirs2_core::ndarray::Array2;
use std::collections::HashMap;
use std::io::{self, Write};
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("=== Interactive Solution Debugger Demo ===\n");
let problem_info = create_test_problem();
let mut config = DebuggerConfig::default();
let mut debugger = SolutionDebugger::new(problem_info, config);
println!("Problem: Graph 3-Coloring");
println!("Variables: 4 nodes × 3 colors = 12 binary variables");
println!("Constraints: Adjacent nodes must have different colors\n");
let solution = solve_problem()?;
println!("Analyzing solution...");
let debug_report = debugger.debug_solution(&solution);
println!("\n=== Debug Report ===");
println!("Overall Score: {:.2}", debug_report.summary.overall_score);
if let Some(constraint_analysis) = &debug_report.constraint_analysis {
println!("\nConstraint Analysis:");
println!(
" Total constraints: {}",
constraint_analysis.total_constraints
);
println!(" Satisfied: {}", constraint_analysis.satisfied);
println!(" Violated: {}", constraint_analysis.violated);
println!(
" Satisfaction rate: {:.1}%",
constraint_analysis.satisfaction_rate * 100.0
);
println!(
" Penalty incurred: {:.4}",
constraint_analysis.penalty_incurred
);
}
if let Some(energy_analysis) = &debug_report.energy_analysis {
println!("\nEnergy Analysis:");
println!(" Total energy: {:.4}", energy_analysis.total_energy);
println!(
" Improvement potential: {:.2}%",
energy_analysis.improvement_potential * 100.0
);
println!("\n Critical variables:");
for (i, (var, contrib)) in energy_analysis
.critical_variables
.iter()
.take(5)
.enumerate()
{
println!(" {}: {} (contribution: {:.4})", i + 1, var, contrib);
}
}
println!("\nIssues found: {}", debug_report.issues.len());
for (i, issue) in debug_report.issues.iter().enumerate() {
println!(
" {}: [{:?}] {} - {}",
i + 1,
issue.severity,
issue.category,
issue.description
);
}
println!("\nSuggestions: {}", debug_report.suggestions.len());
for (i, suggestion) in debug_report.suggestions.iter().enumerate() {
println!(
" {}: {} (impact: {:.4})",
i + 1,
suggestion.description,
suggestion.impact
);
}
Ok(())
}
fn create_test_problem() -> ProblemInfo {
let n_nodes = 4;
let n_colors = 3;
let n_vars = n_nodes * n_colors;
let mut qubo = Array2::zeros((n_vars, n_vars));
let penalty = 10.0;
for node in 0..n_nodes {
for c1 in 0..n_colors {
for c2 in c1 + 1..n_colors {
let var1 = node * n_colors + c1;
let var2 = node * n_colors + c2;
qubo[[var1, var2]] = penalty;
qubo[[var2, var1]] = penalty;
}
let var = node * n_colors + c1;
qubo[[var, var]] = -penalty;
}
}
let edges = vec![(0, 1), (1, 2), (2, 3), (0, 2)];
for (n1, n2) in &edges {
for color in 0..n_colors {
let var1 = n1 * n_colors + color;
let var2 = n2 * n_colors + color;
qubo[[var1, var2]] += penalty;
qubo[[var2, var1]] += penalty;
}
}
let mut var_map = HashMap::new();
let mut reverse_var_map = HashMap::new();
for node in 0..n_nodes {
for color in 0..n_colors {
let var_name = format!("x_{node}_{color}");
let idx = node * n_colors + color;
var_map.insert(var_name.clone(), idx);
reverse_var_map.insert(idx, var_name);
}
}
let mut constraints = Vec::new();
for node in 0..n_nodes {
let variables: Vec<String> = (0..n_colors).map(|c| format!("x_{node}_{c}")).collect();
constraints.push(ConstraintInfo {
name: Some(format!("one_color_node_{node}")),
constraint_type: ConstraintType::ExactlyOne,
variables,
parameters: HashMap::new(),
penalty,
description: Some("Each node must have exactly one color".to_string()),
});
}
for (n1, n2) in &edges {
for color in 0..n_colors {
constraints.push(ConstraintInfo {
name: Some(format!("edge_{n1}_{n2}_{color}")),
constraint_type: ConstraintType::AtMostOne,
variables: vec![format!("x_{}_{}", n1, color), format!("x_{}_{}", n2, color)],
parameters: HashMap::new(),
penalty,
description: Some("Adjacent nodes cannot have the same color".to_string()),
});
}
}
ProblemInfo {
name: "Graph 3-Coloring".to_string(),
problem_type: "CSP".to_string(),
num_variables: n_vars,
var_map,
reverse_var_map,
qubo,
constraints,
optimal_solution: None,
metadata: {
let mut meta = HashMap::new();
meta.insert("nodes".to_string(), n_nodes.to_string());
meta.insert("colors".to_string(), n_colors.to_string());
meta.insert("edges".to_string(), edges.len().to_string());
meta
},
}
}
fn solve_problem() -> Result<Solution, Box<dyn std::error::Error>> {
let mut assignments = HashMap::new();
for node in 0..4 {
for color in 0..3 {
let var_name = format!("x_{node}_{color}");
let should_assign = match node {
0 => color == 0, 1 => color == 1, 2 => color == 2, 3 => color == 0, _ => false,
};
assignments.insert(var_name, should_assign);
}
}
Ok(Solution {
assignments,
energy: -1.0, quality_metrics: HashMap::new(),
metadata: HashMap::new(),
sampling_stats: None,
})
}