Skip to main content

ruvector_mincut/
lib.rs

1//! # RuVector MinCut
2//!
3//! Subpolynomial-time dynamic minimum cut algorithm with real-time monitoring.
4//!
5//! This crate provides efficient algorithms for maintaining minimum cuts in
6//! dynamic graphs with edge insertions and deletions.
7//!
8//! ## Features
9//!
10//! - **Exact Algorithm**: O(n^{o(1)}) amortized update time for cuts up to 2^{O((log n)^{3/4})}
11//! - **Approximate Algorithm**: (1+ε)-approximate cuts via graph sparsification
12//! - **Real-Time Monitoring**: Event-driven notifications with configurable thresholds
13//! - **Thread-Safe**: Concurrent reads with exclusive writes
14//!
15//! ## Quick Start
16//!
17//! ```rust,no_run
18//! use ruvector_mincut::{MinCutBuilder, DynamicMinCut};
19//!
20//! // Create a dynamic minimum cut structure
21//! let mut mincut = MinCutBuilder::new()
22//!     .exact()
23//!     .with_edges(vec![(1, 2, 1.0), (2, 3, 1.0), (3, 1, 1.0)])
24//!     .build()
25//!     .expect("Failed to build");
26//!
27//! // Query the minimum cut
28//! println!("Min cut: {}", mincut.min_cut_value());
29//!
30//! // Insert a new edge
31//! mincut.insert_edge(3, 4, 1.0).expect("Insert failed");
32//!
33//! // Delete an existing edge
34//! let _ = mincut.delete_edge(2, 3);
35//! ```
36//!
37//! ## Architecture
38//!
39//! The crate is organized into several modules:
40//!
41//! - [`graph`]: Dynamic graph representation with efficient operations
42//! - [`algorithm`]: Core minimum cut algorithms (exact and approximate)
43//! - [`tree`]: Hierarchical decomposition for subpolynomial updates
44//! - [`linkcut`]: Link-cut trees for dynamic connectivity
45//! - [`euler`]: Euler tour trees for tree operations
46//! - [`sparsify`]: Graph sparsification for approximate cuts
47//! - [`expander`]: Expander decomposition for subpolynomial updates
48//! - `monitoring`: Real-time event monitoring (feature-gated)
49//!
50//! ## Feature Flags
51//!
52//! - `exact` - Exact minimum cut algorithm (enabled by default)
53//! - `approximate` - (1+ε)-approximate algorithm (enabled by default)
54//! - `monitoring` - Real-time monitoring with callbacks (optional)
55//! - `integration` - GraphDB integration (optional)
56//! - `simd` - SIMD optimizations (optional)
57//!
58//! ## Examples
59//!
60//! ### Basic Usage
61//!
62//! ```rust
63//! use ruvector_mincut::prelude::*;
64//!
65//! let mut mincut = MinCutBuilder::new()
66//!     .with_edges(vec![
67//!         (1, 2, 1.0),
68//!         (2, 3, 1.0),
69//!         (3, 1, 1.0),
70//!     ])
71//!     .build()
72//!     .unwrap();
73//!
74//! assert_eq!(mincut.min_cut_value(), 2.0);
75//! ```
76//!
77//! ### Approximate Algorithm
78//!
79//! ```rust
80//! use ruvector_mincut::prelude::*;
81//!
82//! let mincut = MinCutBuilder::new()
83//!     .approximate(0.1) // 10% approximation
84//!     .with_edges(vec![(1, 2, 1.0), (2, 3, 1.0)])
85//!     .build()
86//!     .unwrap();
87//!
88//! let result = mincut.min_cut();
89//! assert!(!result.is_exact);
90//! assert_eq!(result.approximation_ratio, 1.1);
91//! ```
92//!
93//! ### Real-Time Monitoring
94//!
95//! ```rust,ignore
96//! #[cfg(feature = "monitoring")]
97//! use ruvector_mincut::{MinCutBuilder, MonitorBuilder, EventType};
98//!
99//! let mut mincut = MinCutBuilder::new()
100//!     .with_edges(vec![(1, 2, 1.0)])
101//!     .build()
102//!     .unwrap();
103//!
104//! let monitor = MonitorBuilder::new()
105//!     .threshold("low", 0.5, true)
106//!     .on_event(|event| {
107//!         println!("Cut changed: {:?}", event.event_type);
108//!     })
109//!     .build();
110//!
111//! // Monitor will fire callbacks on updates
112//! mincut.insert_edge(2, 3, 1.0).unwrap();
113//! ```
114
115#![deny(missing_docs)]
116#![cfg_attr(not(feature = "wasm"), deny(unsafe_code))]
117#![warn(clippy::all)]
118#![warn(clippy::pedantic)]
119#![allow(clippy::module_name_repetitions)]
120#![allow(clippy::missing_errors_doc)]
121#![allow(clippy::missing_panics_doc)]
122
123// Core modules
124pub mod algorithm;
125pub mod certificate;
126pub mod cluster;
127pub mod compact;
128pub mod connectivity;
129pub mod error;
130pub mod euler;
131pub mod expander;
132pub mod fragment;
133pub mod fragmentation;
134pub mod graph;
135pub mod instance;
136pub mod integration;
137pub mod linkcut;
138pub mod localkcut;
139pub mod parallel;
140pub mod pool;
141pub mod sparsify;
142pub mod tree;
143pub mod witness;
144pub mod wrapper;
145
146/// Performance optimizations for j-Tree + BMSSP implementation.
147///
148/// Provides SOTA optimizations achieving 10x combined speedup.
149pub mod optimization;
150
151/// Spiking Neural Network integration for deep MinCut optimization.
152///
153/// This module implements a six-layer integration architecture combining
154/// neuromorphic computing with subpolynomial graph algorithms:
155///
156/// 1. **Temporal Attractors**: Energy landscapes for graph optimization
157/// 2. **Strange Loop**: Self-modifying meta-cognitive protocols
158/// 3. **Causal Discovery**: Spike-timing based inference
159/// 4. **Time Crystal CPG**: Central pattern generators for coordination
160/// 5. **Morphogenetic Networks**: Bio-inspired self-organizing growth
161/// 6. **Neural Optimizer**: Reinforcement learning on graph structures
162///
163/// ## Quick Start
164///
165/// ```rust,no_run
166/// use ruvector_mincut::snn::{CognitiveMinCutEngine, EngineConfig, OperationMode};
167/// use ruvector_mincut::graph::DynamicGraph;
168///
169/// // Create a graph
170/// let graph = DynamicGraph::new();
171/// graph.insert_edge(0, 1, 1.0).unwrap();
172/// graph.insert_edge(1, 2, 1.0).unwrap();
173///
174/// // Create the cognitive engine
175/// let config = EngineConfig::default();
176/// let mut engine = CognitiveMinCutEngine::new(graph, config);
177///
178/// // Run optimization
179/// engine.set_mode(OperationMode::Optimize);
180/// let spikes = engine.run(100);
181/// ```
182pub mod snn;
183
184/// Subpolynomial-time dynamic minimum cut algorithm.
185///
186/// This module implements the December 2024 breakthrough achieving n^{o(1)} update time.
187/// Integrates multi-level hierarchy, deterministic LocalKCut, and fragmenting algorithm.
188pub mod subpolynomial;
189
190/// Dynamic Hierarchical j-Tree Decomposition for Approximate Cut Structure
191///
192/// This module implements the two-tier dynamic cut architecture from ADR-002:
193///
194/// - **Tier 1 (j-Tree)**: O(n^ε) amortized updates, poly-log approximation
195/// - **Tier 2 (Exact)**: SubpolynomialMinCut for exact verification
196///
197/// Key features:
198/// - BMSSP WASM integration for O(m·log^(2/3) n) path-cut duality queries
199/// - Vertex-split-tolerant cut sparsifier with O(log² n / ε²) recourse
200/// - Lazy hierarchical evaluation (demand-paging)
201///
202/// ## Example
203///
204/// ```rust,no_run
205/// use ruvector_mincut::jtree::{JTreeHierarchy, JTreeConfig};
206/// use ruvector_mincut::graph::DynamicGraph;
207/// use std::sync::Arc;
208///
209/// let graph = Arc::new(DynamicGraph::new());
210/// graph.insert_edge(1, 2, 1.0).unwrap();
211/// graph.insert_edge(2, 3, 1.0).unwrap();
212///
213/// let mut jtree = JTreeHierarchy::build(graph, JTreeConfig::default()).unwrap();
214/// let approx = jtree.approximate_min_cut().unwrap();
215/// ```
216#[cfg(feature = "jtree")]
217pub mod jtree;
218
219// Internal modules
220mod core;
221
222// Optional feature-gated modules
223#[cfg(feature = "monitoring")]
224pub mod monitoring;
225
226#[cfg(feature = "canonical")]
227pub mod canonical;
228
229#[cfg(feature = "wasm")]
230pub mod wasm;
231
232// Re-exports for convenient access
233pub use algorithm::approximate::{
234    ApproxMinCut, ApproxMinCutConfig, ApproxMinCutResult, ApproxMinCutStats,
235};
236pub use algorithm::{AlgorithmStats, DynamicMinCut, MinCutBuilder, MinCutConfig, MinCutResult};
237pub use certificate::{
238    AuditData, AuditEntry, AuditEntryType, AuditLogger, CertLocalKCutQuery, CertificateError,
239    CutCertificate, LocalKCutResponse, LocalKCutResultSummary, UpdateTrigger, UpdateType,
240};
241pub use cluster::hierarchy::{
242    Expander, HierarchyCluster, HierarchyConfig, HierarchyStats, MirrorCut, Precluster,
243    ThreeLevelHierarchy,
244};
245pub use cluster::{Cluster, ClusterHierarchy};
246pub use compact::{
247    BitSet256, CompactAdjacency, CompactCoreState, CompactEdge, CompactEdgeId, CompactVertexId,
248    CompactWitness, CoreResult, MAX_EDGES_PER_CORE, MAX_VERTICES_PER_CORE,
249};
250pub use connectivity::polylog::{PolylogConnectivity, PolylogStats};
251pub use connectivity::DynamicConnectivity;
252pub use error::{MinCutError, Result};
253pub use euler::EulerTourTree;
254pub use expander::{Conductance, ExpanderComponent, ExpanderDecomposition};
255pub use fragment::{Fragment, FragmentResult, FragmentingAlgorithm};
256pub use fragmentation::{
257    Fragment as FragmentationFragment, Fragmentation, FragmentationConfig, TrimResult,
258};
259pub use graph::{DynamicGraph, Edge, EdgeId, GraphStats, VertexId, Weight};
260pub use instance::{
261    BoundedInstance, InstanceResult, ProperCutInstance, StubInstance, WitnessHandle,
262};
263pub use integration::{CommunityDetector, GraphPartitioner, RuVectorGraphAnalyzer};
264pub use linkcut::LinkCutTree;
265pub use localkcut::{
266    ColorMask, DeterministicFamilyGenerator, DeterministicLocalKCut, EdgeColor, ForestPacking,
267    LocalCutResult, LocalKCut, LocalKCutOracle, LocalKCutQuery,
268    LocalKCutResult as PaperLocalKCutResult,
269};
270pub use parallel::{
271    compute_core_range, CoreDistributor, CoreExecutor, CoreMessage, CoreStrategy, ResultAggregator,
272    SharedCoordinator, WorkItem, NUM_CORES, RANGES_PER_CORE, RANGE_FACTOR, TOTAL_RANGES,
273};
274pub use sparsify::{SparseGraph, SparsifyConfig};
275pub use subpolynomial::{
276    HierarchyLevel, HierarchyStatistics, LevelExpander, MinCutQueryResult, RecourseStats,
277    SubpolyConfig, SubpolynomialMinCut,
278};
279pub use tree::{DecompositionNode, HierarchicalDecomposition, LevelInfo};
280pub use witness::{EdgeWitness, LazyWitnessTree, WitnessTree};
281pub use wrapper::MinCutWrapper;
282
283// Optimization re-exports (SOTA j-Tree + BMSSP performance improvements)
284pub use optimization::{
285    BatchConfig,
286    BenchmarkResult,
287    // Benchmarking
288    BenchmarkSuite,
289    CacheConfig,
290    CacheStats,
291    // DSpar: 5.9x speedup via degree-based presparse
292    DegreePresparse,
293    DistanceArray,
294    LazyLevel,
295    // Pool: 50-75% memory reduction
296    LevelPool,
297    OptimizationBenchmark,
298    ParallelConfig,
299    // Parallel: Rayon-based work-stealing
300    ParallelLevelUpdater,
301    // Cache: 10x for repeated distance queries
302    PathDistanceCache,
303    PoolConfig,
304    PoolStats,
305    PrefetchHint,
306    PresparseConfig,
307    PresparseResult,
308    PresparseStats,
309    // SIMD: 2-4x for distance operations
310    SimdDistanceOps,
311    TypedArrayTransfer,
312    // WASM Batch: 10x FFI overhead reduction
313    WasmBatchOps,
314    WorkStealingScheduler,
315};
316
317// J-Tree re-exports (feature-gated)
318#[cfg(feature = "jtree")]
319pub use jtree::{
320    ApproximateCut, BmsspJTreeLevel, ContractedGraph, CutResult as JTreeCutResult,
321    DynamicCutSparsifier, EscalationPolicy, EscalationTrigger, JTreeConfig, JTreeError,
322    JTreeHierarchy, JTreeLevel, JTreeStatistics, LevelConfig, LevelStatistics, PathCutResult,
323    QueryResult as CoordinatorQueryResult, RecourseTracker, SparsifierConfig, SparsifierStatistics,
324    Tier, TierMetrics, TwoTierCoordinator, VertexSplitResult,
325};
326
327// Re-export ForestPacking with explicit disambiguation (also defined in localkcut)
328#[cfg(feature = "jtree")]
329pub use jtree::ForestPacking as JTreeForestPacking;
330
331// SNN Integration re-exports
332pub use snn::{
333    AttractorConfig,
334    // Layer 1: Attractors
335    AttractorDynamics,
336    CPGConfig,
337    CausalConfig,
338    // Layer 3: Causal Discovery
339    CausalDiscoverySNN,
340    CausalGraph,
341    CausalRelation,
342    // Unified Engine
343    CognitiveMinCutEngine,
344    EnergyLandscape,
345    EngineConfig,
346    EngineMetrics,
347    GrowthRules,
348    // Core SNN types
349    LIFNeuron,
350    LayerConfig,
351    MetaAction,
352    // Layer 2: Strange Loop
353    MetaCognitiveMinCut,
354    MetaLevel,
355    MorphConfig,
356    // Layer 5: Morphogenetic
357    MorphogeneticSNN,
358    NetworkConfig,
359    // Layer 6: Neural Optimizer
360    NeuralGraphOptimizer,
361    NeuronConfig,
362    NeuronState,
363    OptimizationResult,
364    OptimizerConfig,
365    OscillatorNeuron,
366    PhaseTopology,
367    PolicySNN,
368    SNNMinCutConfig,
369    STDPConfig,
370    SimTime,
371    // Utilities
372    Spike,
373    SpikeTrain,
374    SpikingNetwork,
375    StrangeLoopConfig,
376    Synapse,
377    SynapseMatrix,
378    // Layer 4: Time Crystal
379    TimeCrystalCPG,
380    TuringPattern,
381    ValueNetwork,
382};
383
384#[cfg(feature = "agentic")]
385pub use integration::AgenticAnalyzer;
386
387#[cfg(feature = "canonical")]
388pub use canonical::{
389    CactusGraph, CactusCycle, CactusEdge, CactusVertex, CanonicalCutResult, CanonicalMinCut,
390    CanonicalMinCutImpl, FixedWeight, WitnessReceipt,
391};
392
393#[cfg(feature = "monitoring")]
394pub use monitoring::{
395    EventType, MinCutEvent, MinCutMonitor, MonitorBuilder, MonitorConfig, MonitorMetrics, Threshold,
396};
397
398/// Crate version
399pub const VERSION: &str = env!("CARGO_PKG_VERSION");
400
401/// Crate name
402pub const NAME: &str = env!("CARGO_PKG_NAME");
403
404/// Prelude module for convenient imports
405///
406/// Import this module to get all the commonly used types and traits:
407///
408/// ```rust
409/// use ruvector_mincut::prelude::*;
410///
411/// let mincut = MinCutBuilder::new()
412///     .exact()
413///     .build()
414///     .unwrap();
415/// ```
416pub mod prelude {
417    //! Prelude module with commonly used types
418
419    pub use crate::{
420        compute_core_range,
421        AlgorithmStats,
422        ApproxMinCut,
423        ApproxMinCutConfig,
424        AttractorConfig,
425        AttractorDynamics,
426        AuditLogger,
427        BitSet256,
428        BoundedInstance,
429        CPGConfig,
430        CertificateError,
431        Cluster,
432        ClusterHierarchy,
433        // SNN Integration types
434        CognitiveMinCutEngine,
435        ColorMask,
436        CommunityDetector,
437        CompactAdjacency,
438        CompactCoreState,
439        CompactEdge,
440        CompactEdgeId,
441        CompactVertexId,
442        CompactWitness,
443        Conductance,
444        CoreDistributor,
445        CoreExecutor,
446        CoreResult,
447        CoreStrategy,
448        CutCertificate,
449        DeterministicFamilyGenerator,
450        DeterministicLocalKCut,
451        DynamicConnectivity,
452        DynamicGraph,
453        DynamicMinCut,
454        Edge,
455        EdgeColor,
456        EdgeId,
457        EngineConfig,
458        EngineMetrics,
459        ExpanderComponent,
460        ExpanderDecomposition,
461        ForestPacking,
462        Fragment,
463        FragmentResult,
464        FragmentingAlgorithm,
465        GraphPartitioner,
466        InstanceResult,
467        LocalCutResult,
468        LocalKCut,
469        LocalKCutOracle,
470        LocalKCutQuery,
471        MinCutBuilder,
472        MinCutConfig,
473        MinCutError,
474        MinCutResult,
475        MinCutWrapper,
476        NeuralGraphOptimizer,
477        OptimizerConfig,
478        PaperLocalKCutResult,
479        PolylogConnectivity,
480        PolylogStats,
481        ProperCutInstance,
482        RecourseStats,
483        Result,
484        ResultAggregator,
485        RuVectorGraphAnalyzer,
486        SharedCoordinator,
487        SimTime,
488        Spike,
489        StubInstance,
490        SubpolyConfig,
491        // Subpolynomial min-cut
492        SubpolynomialMinCut,
493        TimeCrystalCPG,
494        VertexId,
495        Weight,
496        WitnessHandle,
497        MAX_EDGES_PER_CORE,
498        MAX_VERTICES_PER_CORE,
499        NUM_CORES,
500        RANGES_PER_CORE,
501    };
502
503    #[cfg(feature = "agentic")]
504    pub use crate::AgenticAnalyzer;
505
506    #[cfg(feature = "monitoring")]
507    pub use crate::{EventType, MinCutEvent, MinCutMonitor, MonitorBuilder};
508
509    #[cfg(feature = "canonical")]
510    pub use crate::{
511        CactusGraph, CactusCycle, CactusEdge, CactusVertex, CanonicalCutResult, CanonicalMinCut,
512        CanonicalMinCutImpl, FixedWeight, WitnessReceipt,
513    };
514
515    #[cfg(feature = "jtree")]
516    pub use crate::{
517        ApproximateCut, BmsspJTreeLevel, ContractedGraph, CoordinatorQueryResult,
518        DynamicCutSparsifier, EscalationPolicy, EscalationTrigger, JTreeConfig, JTreeCutResult,
519        JTreeError, JTreeForestPacking, JTreeHierarchy, JTreeLevel, JTreeStatistics, LevelConfig,
520        LevelStatistics, PathCutResult, RecourseTracker, SparsifierConfig, SparsifierStatistics,
521        Tier, TierMetrics, TwoTierCoordinator, VertexSplitResult,
522    };
523}
524
525#[cfg(test)]
526mod tests {
527    use super::*;
528
529    #[test]
530    fn test_version_constant() {
531        assert!(!VERSION.is_empty());
532        assert!(!NAME.is_empty());
533        assert_eq!(NAME, "ruvector-mincut");
534    }
535
536    #[test]
537    fn test_basic_workflow() {
538        // Test the main API works correctly
539        let mut mincut = MinCutBuilder::new()
540            .exact()
541            .with_edges(vec![(1, 2, 1.0), (2, 3, 1.0), (3, 1, 1.0)])
542            .build()
543            .unwrap();
544
545        // Verify initial state
546        assert_eq!(mincut.num_vertices(), 3);
547        assert_eq!(mincut.num_edges(), 3);
548        assert_eq!(mincut.min_cut_value(), 2.0);
549
550        // Test insert
551        let new_cut = mincut.insert_edge(1, 4, 2.0).unwrap();
552        assert!(new_cut.is_finite());
553        assert_eq!(mincut.num_edges(), 4);
554
555        // Test delete
556        let new_cut = mincut.delete_edge(1, 2).unwrap();
557        assert!(new_cut.is_finite());
558        assert_eq!(mincut.num_edges(), 3);
559    }
560
561    #[test]
562    fn test_prelude_imports() {
563        use crate::prelude::*;
564
565        // Ensure all prelude items are accessible
566        let mincut = MinCutBuilder::new().build().unwrap();
567
568        assert_eq!(mincut.min_cut_value(), f64::INFINITY);
569    }
570
571    #[test]
572    fn test_approximate_mode() {
573        let mincut = MinCutBuilder::new()
574            .approximate(0.1)
575            .with_edges(vec![(1, 2, 1.0)])
576            .build()
577            .unwrap();
578
579        let result = mincut.min_cut();
580        assert!(!result.is_exact);
581        assert_eq!(result.approximation_ratio, 1.1);
582    }
583
584    #[test]
585    fn test_exact_mode() {
586        let mincut = MinCutBuilder::new()
587            .exact()
588            .with_edges(vec![(1, 2, 1.0)])
589            .build()
590            .unwrap();
591
592        let result = mincut.min_cut();
593        assert!(result.is_exact);
594        assert_eq!(result.approximation_ratio, 1.0);
595    }
596
597    #[test]
598    fn test_min_cut_result() {
599        let mincut = MinCutBuilder::new()
600            .with_edges(vec![(1, 2, 1.0), (2, 3, 1.0), (3, 1, 1.0)])
601            .build()
602            .unwrap();
603
604        let result = mincut.min_cut();
605        assert_eq!(result.value, 2.0);
606        assert!(result.cut_edges.is_some());
607        assert!(result.partition.is_some());
608
609        if let Some((s, t)) = result.partition {
610            assert_eq!(s.len() + t.len(), 3);
611            assert!(!s.is_empty());
612            assert!(!t.is_empty());
613        }
614    }
615
616    #[test]
617    fn test_graph_stats() {
618        let mincut = MinCutBuilder::new()
619            .with_edges(vec![(1, 2, 2.0), (2, 3, 3.0), (3, 1, 1.0)])
620            .build()
621            .unwrap();
622
623        let graph = mincut.graph();
624        let stats = graph.read().stats();
625
626        assert_eq!(stats.num_vertices, 3);
627        assert_eq!(stats.num_edges, 3);
628        assert_eq!(stats.total_weight, 6.0);
629        assert_eq!(stats.min_degree, 2);
630        assert_eq!(stats.max_degree, 2);
631    }
632
633    #[test]
634    fn test_algorithm_stats() {
635        let mut mincut = MinCutBuilder::new()
636            .with_edges(vec![(1, 2, 1.0)])
637            .build()
638            .unwrap();
639
640        mincut.insert_edge(2, 3, 1.0).unwrap();
641        mincut.delete_edge(1, 2).unwrap();
642        let _ = mincut.min_cut_value();
643
644        let stats = mincut.stats();
645        assert_eq!(stats.insertions, 1);
646        assert_eq!(stats.deletions, 1);
647        assert_eq!(stats.queries, 1);
648        assert!(stats.avg_update_time_us > 0.0);
649    }
650
651    #[test]
652    fn test_dynamic_updates() {
653        let mut mincut = MinCutBuilder::new().build().unwrap();
654
655        // Start empty
656        assert_eq!(mincut.min_cut_value(), f64::INFINITY);
657
658        // Add edges dynamically
659        mincut.insert_edge(1, 2, 1.0).unwrap();
660        assert_eq!(mincut.min_cut_value(), 1.0);
661
662        mincut.insert_edge(2, 3, 1.0).unwrap();
663        assert_eq!(mincut.min_cut_value(), 1.0);
664
665        mincut.insert_edge(3, 1, 1.0).unwrap();
666        assert_eq!(mincut.min_cut_value(), 2.0);
667    }
668
669    #[test]
670    fn test_disconnected_graph() {
671        let mincut = MinCutBuilder::new()
672            .with_edges(vec![(1, 2, 1.0), (3, 4, 1.0)])
673            .build()
674            .unwrap();
675
676        assert!(!mincut.is_connected());
677        assert_eq!(mincut.min_cut_value(), 0.0);
678    }
679
680    #[test]
681    fn test_builder_pattern() {
682        let mincut = MinCutBuilder::new()
683            .exact()
684            .max_cut_size(500)
685            .parallel(true)
686            .with_edges(vec![(1, 2, 1.0)])
687            .build()
688            .unwrap();
689
690        assert!(!mincut.config().approximate);
691        assert_eq!(mincut.config().max_exact_cut_size, 500);
692        assert!(mincut.config().parallel);
693    }
694
695    #[test]
696    fn test_weighted_graph() {
697        let mincut = MinCutBuilder::new()
698            .with_edges(vec![(1, 2, 5.0), (2, 3, 3.0), (3, 1, 2.0)])
699            .build()
700            .unwrap();
701
702        assert_eq!(mincut.min_cut_value(), 5.0);
703    }
704
705    #[test]
706    fn test_error_handling() {
707        let mut mincut = MinCutBuilder::new()
708            .with_edges(vec![(1, 2, 1.0)])
709            .build()
710            .unwrap();
711
712        // Try to insert duplicate edge
713        let result = mincut.insert_edge(1, 2, 2.0);
714        assert!(result.is_err());
715        assert!(matches!(result, Err(MinCutError::EdgeExists(1, 2))));
716
717        // Try to delete non-existent edge
718        let result = mincut.delete_edge(3, 4);
719        assert!(result.is_err());
720        assert!(matches!(result, Err(MinCutError::EdgeNotFound(3, 4))));
721    }
722
723    #[test]
724    fn test_large_graph() {
725        let mut edges = Vec::new();
726        for i in 0..99 {
727            edges.push((i, i + 1, 1.0));
728        }
729
730        let mincut = MinCutBuilder::new().with_edges(edges).build().unwrap();
731
732        assert_eq!(mincut.num_vertices(), 100);
733        assert_eq!(mincut.num_edges(), 99);
734        assert_eq!(mincut.min_cut_value(), 1.0);
735    }
736
737    #[cfg(feature = "monitoring")]
738    #[test]
739    fn test_monitoring_feature() {
740        use crate::monitoring::EventType;
741
742        // Ensure monitoring types are accessible when feature is enabled
743        let _ = EventType::CutIncreased;
744        let _ = EventType::CutDecreased;
745    }
746}