#![allow(
clippy::pedantic,
clippy::unnecessary_wraps,
clippy::needless_range_loop,
clippy::useless_vec,
clippy::needless_collect,
clippy::too_many_arguments
)]
use quantrs2_anneal::{
embedding::{HardwareGraph, MinorMiner},
ising::IsingModel,
layout_embedding::{LayoutAwareEmbedder, LayoutConfig},
penalty_optimization::{AdvancedPenaltyOptimizer, PenaltyConfig, PenaltyOptimizer},
simulator::{AnnealingParams, ClassicalAnnealingSimulator},
};
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("=== Advanced Graph Embedding Demo ===\n");
println!("1. Creating logical problem graph (K3)...");
let num_vars = 3;
let logical_edges = vec![(0, 1), (0, 2), (1, 2)];
println!(
" Logical graph: {} variables, {} edges",
num_vars,
logical_edges.len()
);
println!("\n2. Creating Chimera hardware graph...");
let hardware = HardwareGraph::new_chimera(2, 2, 4)?;
println!(" Hardware graph: {} qubits", hardware.num_qubits);
println!("\n3. Finding embedding with MinorMiner...");
let standard_embedder = MinorMiner::default();
let standard_embedding =
standard_embedder.find_embedding(&logical_edges, num_vars, &hardware)?;
println!(" Standard embedding found:");
for (var, chain) in &standard_embedding.chains {
println!(
" Variable {}: chain {:?} (length {})",
var,
chain,
chain.len()
);
}
println!("\n4. Finding layout-aware embedding...");
let layout_config = LayoutConfig {
distance_weight: 1.0,
chain_length_weight: 2.0,
chain_degree_weight: 0.5,
max_chain_length: 4,
use_spectral_placement: true,
refinement_iterations: 5,
};
let mut layout_embedder = LayoutAwareEmbedder::new(layout_config);
let (layout_embedding, layout_stats) =
layout_embedder.find_embedding(&logical_edges, num_vars, &hardware)?;
println!(" Layout-aware embedding found:");
println!(
" - Average chain length: {:.2}",
layout_stats.avg_chain_length
);
println!(
" - Maximum chain length: {}",
layout_stats.max_chain_length
);
println!(
" - Long chains (>{} qubits): {}",
4, layout_stats.long_chains
);
println!(" - Quality score: {:.2}", layout_stats.quality_score);
println!("\n5. Creating Ising model...");
let mut ising = IsingModel::new(hardware.num_qubits);
for (var, chain) in &layout_embedding.chains {
for &qubit in chain {
if qubit < hardware.num_qubits {
ising.set_bias(qubit, 0.5 * (*var as f64 - 2.0))?;
}
}
}
for &(i, j) in &logical_edges {
if let (Some(chain_i), Some(chain_j)) = (
layout_embedding.chains.get(&i),
layout_embedding.chains.get(&j),
) {
'outer: for &qi in chain_i {
for &qj in chain_j {
if qi < hardware.num_qubits
&& qj < hardware.num_qubits
&& hardware.are_connected(qi, qj)
{
ising.set_coupling(qi, qj, -1.0)?;
break 'outer;
}
}
}
}
}
println!("\n6. Solving without penalty optimization...");
let mut params = AnnealingParams::new();
params.num_sweeps = 1000;
params.num_repetitions = 100;
params.initial_temperature = 10.0;
params.temperature_schedule = quantrs2_anneal::simulator::TemperatureSchedule::Exponential(3.0);
let simulator = ClassicalAnnealingSimulator::new(params)?;
let initial_result = simulator.solve(&ising)?;
println!(" Initial solution:");
println!(" - Best energy: {:.4}", initial_result.best_energy);
let mut samples: Vec<Vec<i8>> = Vec::new();
for _ in 0..10 {
let result = simulator.solve(&ising)?;
samples.push(result.best_spins);
}
println!("\n7. Applying penalty optimization...");
let penalty_config = PenaltyConfig {
initial_chain_strength: 1.0,
min_chain_strength: 0.5,
max_chain_strength: 5.0,
chain_strength_scale: 1.2,
constraint_penalty: 1.0,
adaptive: true,
learning_rate: 0.1,
};
let mut penalty_optimizer = PenaltyOptimizer::new(penalty_config.clone());
let penalty_stats =
penalty_optimizer.optimize_ising_penalties(&mut ising, &layout_embedding, &samples)?;
println!(" Penalty optimization complete:");
println!(" - Iterations: {}", penalty_stats.iterations);
println!(
" - Chain break rate: {:.2}%",
penalty_stats.chain_break_rate * 100.0
);
println!("\n8. Solving with optimized penalties...");
let optimized_result = simulator.solve(&ising)?;
println!(" Optimized solution:");
println!(" - Best energy: {:.4}", optimized_result.best_energy);
println!(
" - Energy improvement: {:.4}",
initial_result.best_energy - optimized_result.best_energy
);
println!("\n9. Applying gradient-based penalty optimization...");
let mut advanced_optimizer = AdvancedPenaltyOptimizer::new(penalty_config);
let advanced_stats = advanced_optimizer.optimize_with_gradients(
&mut ising,
&layout_embedding,
&samples,
20, )?;
println!(" Advanced optimization complete:");
println!(" - Final chain strengths:");
for (var, strength) in &advanced_stats.chain_strengths {
println!(" Variable {var}: {strength:.3}");
}
println!("\n=== Demo Complete ===");
Ok(())
}