1extern crate fixedbitset;
2extern crate rand;
3
4mod cycle_detector;
5
6use cycle_detector::CycleDetector;
7use fixedbitset::FixedBitSet;
8use rand::Rng;
9use std::fmt::Debug;
10
11pub trait NodeType: Clone + Debug + Send + Sized + PartialEq + Eq {
12 fn accept_incoming_links(&self) -> bool;
14
15 fn accept_outgoing_links(&self) -> bool;
17}
18
19#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
22pub struct ExternalId(pub usize);
23
24#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
28pub struct NodeIndex(usize);
29
30#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
32pub struct LinkIndex(usize);
33
34impl NodeIndex {
35 #[inline(always)]
36 pub fn index(&self) -> usize {
37 self.0
38 }
39
40 pub fn new(index: usize) -> Self {
41 NodeIndex(index)
42 }
43}
44
45impl LinkIndex {
46 #[inline(always)]
47 pub fn index(&self) -> usize {
48 self.0
49 }
50}
51
52#[derive(Clone, Debug)]
54struct LinkItem<L, EXTID>
55where
56 L: Copy + Debug + Send + Sized,
57 EXTID: Copy + Debug + Send + Sized + Ord,
58{
59 prev: Option<LinkIndex>,
60 next: Option<LinkIndex>,
61 link: Link<L, EXTID>,
62}
63
64pub struct LinkIter<'a, L, EXTID>
65where
66 L: Copy + Debug + Send + Sized + 'a,
67 EXTID: Copy + Debug + Send + Sized + Ord + 'a,
68{
69 next_link_idx: Option<LinkIndex>,
70 link_array: &'a [LinkItem<L, EXTID>],
71}
72
73impl<'a, L, EXTID> LinkIter<'a, L, EXTID>
74where
75 L: Copy + Debug + Send + Sized + 'a,
76 EXTID: Copy + Debug + Send + Sized + Ord + 'a,
77{
78 fn new(link_idx_opt: Option<LinkIndex>, link_array: &'a [LinkItem<L, EXTID>]) -> Self {
79 LinkIter {
80 next_link_idx: link_idx_opt,
81 link_array: link_array,
82 }
83 }
84}
85
86impl<'a, L, EXTID> Iterator for LinkIter<'a, L, EXTID>
87where
88 L: Copy + Debug + Send + Sized + 'a,
89 EXTID: Copy + Debug + Send + Sized + Ord + 'a,
90{
91 type Item = (LinkIndex, &'a Link<L, EXTID>);
92
93 fn next(&mut self) -> Option<Self::Item> {
94 match self.next_link_idx {
95 Some(idx) => {
96 let item = &self.link_array[idx.index()];
97 self.next_link_idx = item.next;
98 return Some((idx, &item.link));
99 }
100 None => {
101 return None;
102 }
103 }
104 }
105}
106
107pub struct LinkRefIter<'a, N, L, EXTID>
108where
109 N: NodeType + 'a,
110 L: Copy + Debug + Send + Sized + 'a,
111 EXTID: Copy + Debug + Send + Sized + Ord + 'a,
112{
113 next_link_idx: Option<LinkIndex>,
114 network: &'a Network<N, L, EXTID>,
115}
116
117pub struct LinkRefItem<'a, N, L, EXTID>
120where
121 N: NodeType + 'a,
122 L: Copy + Debug + Send + Sized + 'a,
123 EXTID: Copy + Debug + Send + Sized + Ord + 'a,
124{
125 link: &'a Link<L, EXTID>,
126 network: &'a Network<N, L, EXTID>,
127}
128
129impl<'a, N, L, EXTID> LinkRefItem<'a, N, L, EXTID>
130where
131 N: NodeType + 'a,
132 L: Copy + Debug + Send + Sized + 'a,
133 EXTID: Copy + Debug + Send + Sized + Ord + 'a,
134{
135 pub fn link(&self) -> &Link<L, EXTID> {
136 self.link
137 }
138
139 pub fn network(&self) -> &Network<N, L, EXTID> {
140 self.network
141 }
142
143 pub fn external_link_id(&self) -> EXTID {
144 self.link.external_link_id()
145 }
146
147 pub fn source_node(&self) -> &Node<N, EXTID> {
148 self.network.node(self.link.source_node_idx)
149 }
150
151 pub fn target_node(&self) -> &Node<N, EXTID> {
152 self.network.node(self.link.target_node_idx)
153 }
154
155 pub fn external_source_node_id(&self) -> EXTID {
156 self.source_node().external_node_id()
157 }
158
159 pub fn external_target_node_id(&self) -> EXTID {
160 self.target_node().external_node_id()
161 }
162}
163
164impl<'a, N, L, EXTID> LinkRefIter<'a, N, L, EXTID>
165where
166 N: NodeType + 'a,
167 L: Copy + Debug + Send + Sized + 'a,
168 EXTID: Copy + Debug + Send + Sized + Ord + 'a,
169{
170 fn new(link_idx_opt: Option<LinkIndex>, network: &'a Network<N, L, EXTID>) -> Self {
171 LinkRefIter {
172 next_link_idx: link_idx_opt,
173 network: network,
174 }
175 }
176}
177
178impl<'a, N, L, EXTID> Iterator for LinkRefIter<'a, N, L, EXTID>
179where
180 N: NodeType + 'a,
181 L: Copy + Debug + Send + Sized + 'a,
182 EXTID: Copy + Debug + Send + Sized + Ord + 'a,
183{
184 type Item = (LinkRefItem<'a, N, L, EXTID>);
185
186 fn next(&mut self) -> Option<Self::Item> {
187 match self.next_link_idx {
188 Some(idx) => {
189 let item = &self.network.links[idx.index()];
190 self.next_link_idx = item.next;
191 return Some(LinkRefItem {
192 link: &item.link,
193 network: &self.network,
194 });
195 }
196 None => {
197 return None;
198 }
199 }
200 }
201}
202
203#[derive(Clone, Debug)]
204pub struct Link<L, EXTID>
205where
206 L: Copy + Debug + Send + Sized,
207 EXTID: Copy + Debug + Send + Sized + Ord,
208{
209 source_node_idx: NodeIndex,
210 target_node_idx: NodeIndex,
211 weight: L,
212 external_link_id: EXTID,
213
214 active: bool,
217}
218
219impl<L, EXTID> Link<L, EXTID>
220where
221 L: Copy + Debug + Send + Sized,
222 EXTID: Copy + Debug + Send + Sized + Ord,
223{
224 #[inline(always)]
225 pub fn external_link_id(&self) -> EXTID {
226 self.external_link_id
227 }
228
229 #[inline(always)]
230 pub fn source_node_index(&self) -> NodeIndex {
231 self.source_node_idx
232 }
233
234 #[inline(always)]
235 pub fn target_node_index(&self) -> NodeIndex {
236 self.target_node_idx
237 }
238
239 #[inline(always)]
240 pub fn is_active(&self) -> bool {
241 self.active
242 }
243
244 #[inline(always)]
245 pub fn weight(&self) -> L {
246 self.weight
247 }
248
249 #[inline(always)]
250 pub fn set_weight(&mut self, new_weight: L) {
251 self.weight = new_weight;
252 }
253}
254
255#[derive(Clone, Debug)]
256struct List {
257 head: Option<LinkIndex>,
258 tail: Option<LinkIndex>,
259}
260
261impl List {
262 fn empty() -> Self {
263 List {
264 head: None,
265 tail: None,
266 }
267 }
268
269 fn iter<'a, L, EXTID>(&self, link_array: &'a [LinkItem<L, EXTID>]) -> LinkIter<'a, L, EXTID>
270 where
271 L: Copy + Debug + Send + Sized + 'a,
272 EXTID: Copy + Debug + Send + Sized + Ord + 'a,
273 {
274 LinkIter::new(self.head, link_array)
275 }
276}
277
278#[derive(Clone, Debug)]
279pub struct Node<N: NodeType, EXTID: Copy + Debug + Send + Sized + Ord = ExternalId> {
280 node_type: N,
281 external_node_id: EXTID,
282 links: List,
283 in_degree: u32,
285 out_degree: u32,
286}
287
288impl<N: NodeType, EXTID: Copy + Debug + Send + Sized + Ord> Node<N, EXTID> {
289 pub fn node_type(&self) -> &N {
290 &self.node_type
291 }
292
293 pub fn set_node_type(&mut self, node_type: N) {
294 self.node_type = node_type;
295 }
296
297 pub fn external_node_id(&self) -> EXTID {
298 self.external_node_id
299 }
300
301 pub fn degree(&self) -> usize {
302 self.in_degree as usize + self.out_degree as usize
303 }
304
305 pub fn in_degree(&self) -> u32 {
306 self.in_degree
307 }
308
309 pub fn out_degree(&self) -> u32 {
310 self.out_degree
311 }
312
313 pub fn in_out_degree(&self) -> (u32, u32) {
314 (self.in_degree, self.out_degree)
315 }
316}
317
318#[derive(Clone, Debug)]
320pub struct Network<
321 N: NodeType,
322 L: Copy + Debug + Send + Sized,
323 EXTID: Copy + Debug + Send + Sized + Ord = ExternalId,
324> {
325 nodes: Vec<Node<N, EXTID>>,
326 links: Vec<LinkItem<L, EXTID>>, link_count: usize,
328 active_link_count: usize,
329}
330
331impl<N: NodeType, L: Copy + Debug + Send + Sized, EXTID: Copy + Debug + Send + Sized + Ord>
332 Network<N, L, EXTID> {
333 pub fn new() -> Network<N, L, EXTID> {
334 Network {
335 nodes: Vec::new(),
336 links: Vec::new(),
337 link_count: 0,
338 active_link_count: 0,
339 }
340 }
341
342 #[inline]
343 pub fn node_count(&self) -> usize {
344 self.nodes.len()
345 }
346
347 #[inline]
348 pub fn link_count(&self) -> usize {
349 self.link_count
350 }
351
352 #[inline(always)]
353 pub fn node(&self, node_idx: NodeIndex) -> &Node<N, EXTID> {
354 &self.nodes[node_idx.index()]
355 }
356
357 #[inline(always)]
358 pub fn node_mut(&mut self, node_idx: NodeIndex) -> &mut Node<N, EXTID> {
359 &mut self.nodes[node_idx.index()]
360 }
361
362 #[inline(always)]
363 fn link_item(&self, link_idx: LinkIndex) -> &LinkItem<L, EXTID> {
364 &self.links[link_idx.index()]
365 }
366
367 #[inline(always)]
368 pub fn link(&self, link_idx: LinkIndex) -> &Link<L, EXTID> {
369 &self.link_item(link_idx).link
370 }
371
372 #[inline(always)]
373 pub fn link_mut(&mut self, link_idx: LinkIndex) -> &mut Link<L, EXTID> {
374 &mut (self.links[link_idx.index()].link)
375 }
376
377 #[inline(always)]
378 pub fn nodes(&self) -> &[Node<N, EXTID>] {
379 &self.nodes
380 }
381
382 #[inline]
383 pub fn each_node_with_index<F>(&self, mut f: F)
384 where
385 F: FnMut(&Node<N, EXTID>, NodeIndex),
386 {
387 for (i, node) in self.nodes.iter().enumerate() {
388 f(node, NodeIndex(i));
389 }
390 }
391
392 #[inline]
393 pub fn link_iter_for_node<'a>(&'a self, node_idx: NodeIndex) -> LinkIter<'a, L, EXTID> {
394 self.node(node_idx).links.iter(&self.links)
395 }
396
397 #[inline]
398 pub fn link_ref_iter_for_node<'a>(
399 &'a self,
400 node_idx: NodeIndex,
401 ) -> LinkRefIter<'a, N, L, EXTID> {
402 LinkRefIter::new(self.node(node_idx).links.head, self)
403 }
404
405 #[inline]
406 pub fn each_active_forward_link_of_node<F>(&self, node_idx: NodeIndex, mut f: F)
407 where
408 F: FnMut(NodeIndex, L),
409 {
410 for (_, link) in self.link_iter_for_node(node_idx) {
411 if link.active {
412 f(link.target_node_idx, link.weight);
413 }
414 }
415 }
416
417 #[inline]
418 pub fn each_link_ref<F>(&self, mut f: F)
419 where
420 F: FnMut(LinkRefItem<N, L, EXTID>),
421 {
422 for link_item in &self.links[..] {
423 f(LinkRefItem {
424 link: &&link_item.link,
425 network: self,
426 });
427 }
428 }
429
430 #[inline]
431 pub fn each_link_mut<F>(&mut self, mut f: F)
432 where
433 F: FnMut(&mut Link<L, EXTID>),
434 {
435 for link_item in &mut self.links[..] {
436 f(&mut link_item.link);
437 }
438 }
439
440 fn inactive_link_count(&self) -> usize {
441 assert!(self.link_count >= self.active_link_count);
442 self.link_count - self.active_link_count
443 }
444
445 pub fn random_inactive_link_index<R: Rng>(&self, rng: &mut R) -> Option<LinkIndex> {
450 let n = self.inactive_link_count();
451 assert!(n <= self.link_count);
452 if n > 0 {
453 let mut nth_link: usize = rng.gen_range(0, n);
454
455 for node in self.nodes.iter() {
456 for (link_idx, link) in node.links.iter(&self.links) {
457 if !link.is_active() {
458 if nth_link > 0 {
459 nth_link -= 1;
460 } else {
461 return Some(link_idx);
462 }
463 }
464 }
465 }
466 }
467
468 return None;
469 }
470
471 pub fn random_active_link_index<R: Rng>(&self, rng: &mut R) -> Option<LinkIndex> {
476 let n = self.active_link_count;
477 assert!(n <= self.link_count);
478 if n > 0 {
479 let mut nth_link: usize = rng.gen_range(0, n);
480
481 for node in self.nodes.iter() {
482 for (link_idx, link) in node.links.iter(&self.links) {
483 if link.is_active() {
484 if nth_link > 0 {
485 nth_link -= 1;
486 } else {
487 return Some(link_idx);
488 }
489 }
490 }
491 }
492 }
493
494 return None;
495 }
496
497 pub fn random_link_index<R: Rng>(&self, rng: &mut R) -> Option<LinkIndex> {
502 let n = self.link_count;
503 if n > 0 {
504 let link_idx: usize = rng.gen_range(0, n);
505 return Some(LinkIndex(link_idx));
506 }
507 return None;
508 }
509
510 pub fn remove_all_outgoing_links_of_node(&mut self, node_idx: NodeIndex) {
519 let n = self.node(node_idx).out_degree as usize;
520
521 for _ in 0..n {
522 let link_index = self.node(node_idx).links.head.unwrap();
523 self.remove_link_at(link_index);
524 }
525 assert!(self.node(node_idx).links.head.is_none());
526 assert!(self.node(node_idx).links.tail.is_none());
527 assert!(self.node(node_idx).out_degree == 0);
528 }
529
530 pub fn remove_all_incoming_links_of_node(&mut self, node_idx: NodeIndex) {
535 let n = self.node(node_idx).in_degree as usize;
536
537 if n == 0 {
538 return;
540 }
541
542 for src in 0..self.node_count() {
544 let src_idx = NodeIndex(src);
545 if src_idx != node_idx {
546 if let Some(link_index) = self.find_link_index_exact(src_idx, node_idx) {
547 self.remove_link_at(link_index);
548 }
549 }
550 }
551
552 assert!(self.node(node_idx).in_degree == 0);
553 }
554
555 pub fn remove_all_inout_links_of_node(&mut self, node_idx: NodeIndex) {
558 self.remove_all_outgoing_links_of_node(node_idx);
559 self.remove_all_incoming_links_of_node(node_idx);
560 }
561
562 pub fn remove_node(&mut self, node_idx: NodeIndex) {
578 let node_count = self.nodes.len();
579 assert!(node_idx.index() < node_count);
580 assert!(node_count > 0);
581 self.remove_all_inout_links_of_node(node_idx);
582 let last_idx = NodeIndex(node_count - 1);
583 if node_idx == last_idx {
584 let _node = self.nodes.pop();
586 } else {
587 let _node = self.nodes.swap_remove(node_idx.index());
589 for link_item in self.links.iter_mut() {
592 if link_item.link.target_node_idx == last_idx {
593 link_item.link.target_node_idx = node_idx;
594 }
595 if link_item.link.source_node_idx == last_idx {
596 link_item.link.source_node_idx = node_idx;
597 }
598 }
599 }
600 assert!(self.node_count() == node_count - 1);
601 }
602
603 pub fn add_node(&mut self, node_type: N, external_node_id: EXTID) -> NodeIndex {
608 let node_idx = NodeIndex(self.nodes.len());
609 self.nodes.push(Node {
610 node_type: node_type,
611 external_node_id: external_node_id,
612 links: List::empty(),
613 in_degree: 0,
614 out_degree: 0,
615 });
616 return node_idx;
617 }
618
619 pub fn find_random_unconnected_link_no_cycle<R: Rng>(
623 &self,
624 rng: &mut R,
625 ) -> Option<(NodeIndex, NodeIndex)> {
626 let n = self.nodes.len();
627
628 let idx = &|i, j| i * n + j;
629
630 let mut adj_matrix = FixedBitSet::with_capacity(n * n);
631
632 for (i, node) in self.nodes.iter().enumerate() {
635 for (_, link) in node.links.iter(&self.links) {
636 let j = link.target_node_idx.index();
637 adj_matrix.insert(idx(i, j));
638 adj_matrix.insert(idx(j, i));
641 }
642 }
643
644 let adj_matrix = adj_matrix; let mut node_order: Vec<_> = (0..n).into_iter().collect();
651 let mut edge_order: Vec<_> = (0..n).into_iter().collect();
652 rng.shuffle(&mut node_order);
653
654 let node_order = node_order; let mut cycler = CycleDetector::new(self);
657 for &i in &node_order {
658 rng.shuffle(&mut edge_order);
659 for &j in &edge_order {
660 if i != j && !adj_matrix.contains(idx(i, j)) {
661 let ni = NodeIndex(i);
663 let nj = NodeIndex(j);
664 if self.valid_link(ni, nj).is_ok() && !cycler.link_would_cycle(ni, nj) {
665 return Some((ni, nj));
667 }
668 }
669 }
670 }
671
672 return None;
673 }
674
675 pub fn link_would_cycle(&self, source_node_idx: NodeIndex, target_node_idx: NodeIndex) -> bool {
678 if source_node_idx == target_node_idx {
679 return true;
680 }
681
682 CycleDetector::new(self).link_would_cycle(source_node_idx, target_node_idx)
683 }
684
685 pub fn valid_link(
687 &self,
688 source_node_idx: NodeIndex,
689 target_node_idx: NodeIndex,
690 ) -> Result<(), &'static str> {
691 if source_node_idx == target_node_idx {
692 return Err("Loops are not allowed");
693 }
694
695 if !self.nodes[source_node_idx.index()]
696 .node_type
697 .accept_outgoing_links()
698 {
699 return Err("Node does not allow outgoing links");
700 }
701
702 if !self.nodes[target_node_idx.index()]
703 .node_type
704 .accept_incoming_links()
705 {
706 return Err("Node does not allow incoming links");
707 }
708
709 Ok(())
710 }
711
712 fn allocate_link_item(&mut self, link_item: LinkItem<L, EXTID>) -> LinkIndex {
713 let new_link_idx = LinkIndex(self.links.len());
714 self.links.push(link_item);
715 return new_link_idx;
716 }
717
718 pub fn disable_link_index(&mut self, link_idx: LinkIndex) -> bool {
719 if self.link(link_idx).is_active() {
720 self.active_link_count -= 1;
721 self.link_mut(link_idx).active = false;
722 return true;
723 } else {
724 return false;
725 }
726 }
727
728 pub fn enable_link_index(&mut self, link_idx: LinkIndex) -> bool {
729 if !self.link(link_idx).is_active() {
730 self.active_link_count += 1;
731 self.link_mut(link_idx).active = true;
732 return true;
733 } else {
734 return false;
735 }
736 }
737
738 pub fn disable_link(&mut self, source_node_idx: NodeIndex, target_node_idx: NodeIndex) -> bool {
739 if let Some(link_idx) = self.find_link_index_exact(source_node_idx, target_node_idx) {
740 return self.disable_link_index(link_idx);
741 }
742 return false;
743 }
744
745 pub fn enable_link(&mut self, source_node_idx: NodeIndex, target_node_idx: NodeIndex) -> bool {
746 if let Some(link_idx) = self.find_link_index_exact(source_node_idx, target_node_idx) {
747 return self.enable_link_index(link_idx);
748 }
749 return false;
750 }
751
752 pub fn first_link_of_node(&self, node_idx: NodeIndex) -> Option<&Link<L, EXTID>> {
753 self.node(node_idx)
754 .links
755 .head
756 .map(|link_idx| self.link(link_idx))
757 }
758
759 pub fn last_link_of_node(&self, node_idx: NodeIndex) -> Option<&Link<L, EXTID>> {
760 self.node(node_idx)
761 .links
762 .tail
763 .map(|link_idx| self.link(link_idx))
764 }
765
766 fn append(&mut self, node_idx: NodeIndex, link: Link<L, EXTID>) -> LinkIndex {
767 match (
768 self.node(node_idx).links.head,
769 self.node(node_idx).links.tail,
770 ) {
771 (None, None) => {
772 let new_link_idx = self.allocate_link_item(LinkItem {
774 link: link,
775 prev: None,
776 next: None,
777 });
778 self.node_mut(node_idx).links = List {
779 head: Some(new_link_idx),
780 tail: Some(new_link_idx),
781 };
782 return new_link_idx;
783 }
784 (Some(_), Some(tail)) => {
785 let new_link_idx = self.allocate_link_item(LinkItem {
786 link: link,
787 prev: Some(tail),
788 next: None,
789 });
790 assert!(self.links[tail.index()].next == None);
791 self.links[tail.index()].next = Some(new_link_idx);
792 self.node_mut(node_idx).links.tail = Some(new_link_idx);
793 return new_link_idx;
794 }
795 _ => panic!(),
796 }
797 }
798
799 fn prepend(&mut self, node_idx: NodeIndex, link: Link<L, EXTID>) -> LinkIndex {
800 match (
801 self.node(node_idx).links.head,
802 self.node(node_idx).links.tail,
803 ) {
804 (None, None) => {
805 let new_link_idx = self.allocate_link_item(LinkItem {
807 link: link,
808 prev: None,
809 next: None,
810 });
811 self.node_mut(node_idx).links = List {
812 head: Some(new_link_idx),
813 tail: Some(new_link_idx),
814 };
815 return new_link_idx;
816 }
817 (Some(head), Some(_tail)) => {
818 let new_link_idx = self.allocate_link_item(LinkItem {
819 link: link,
820 prev: None,
821 next: Some(head),
822 });
823 assert!(self.links[head.index()].prev == None);
824 self.links[head.index()].prev = Some(new_link_idx);
825 self.node_mut(node_idx).links.head = Some(new_link_idx);
826 return new_link_idx;
827 }
828 _ => panic!(),
829 }
830 }
831
832 pub fn add_link(
833 &mut self,
834 source_node_idx: NodeIndex,
835 target_node_idx: NodeIndex,
836 weight: L,
837 external_link_id: EXTID,
838 ) -> LinkIndex {
839 self.add_link_with_active(
840 source_node_idx,
841 target_node_idx,
842 weight,
843 external_link_id,
844 true,
845 )
846 }
847
848 pub fn add_link_unordered(
852 &mut self,
853 source_node_idx: NodeIndex,
854 target_node_idx: NodeIndex,
855 weight: L,
856 external_link_id: EXTID,
857 ) -> LinkIndex {
858 if let Err(err) = self.valid_link(source_node_idx, target_node_idx) {
859 panic!(err);
860 }
861
862 self.link_count += 1;
863 self.active_link_count += 1;
864
865 self.node_mut(source_node_idx).out_degree += 1;
866 self.node_mut(target_node_idx).in_degree += 1;
867
868 let link = Link {
869 source_node_idx: source_node_idx,
870 target_node_idx: target_node_idx,
871 external_link_id: external_link_id,
872 weight: weight,
873 active: true,
874 };
875
876 return self.append(source_node_idx, link);
877 }
878
879 pub fn add_link_with_active(
884 &mut self,
885 source_node_idx: NodeIndex,
886 target_node_idx: NodeIndex,
887 weight: L,
888 external_link_id: EXTID,
889 active: bool,
890 ) -> LinkIndex {
891 if let Err(err) = self.valid_link(source_node_idx, target_node_idx) {
892 panic!(err);
893 }
894
895 self.link_count += 1;
896 if active {
897 self.active_link_count += 1;
898 }
899 self.node_mut(source_node_idx).out_degree += 1;
900 self.node_mut(target_node_idx).in_degree += 1;
901
902 let link = Link {
903 source_node_idx: source_node_idx,
904 target_node_idx: target_node_idx,
905 external_link_id: external_link_id,
906 weight: weight,
907 active: active,
908 };
909
910 match self.find_link_index_insert_before(source_node_idx, target_node_idx, external_link_id)
911 {
912 None => {
913 if let Some(tail) = self.node(source_node_idx).links.tail {
914 if self.link(tail).target_node_idx == target_node_idx {
916 assert!(self.link(tail).external_link_id == external_link_id);
917 panic!("Duplicate link");
918 }
919 }
920 return self.append(source_node_idx, link);
922 }
923 Some(idx) => {
924 match self.link_item(idx).prev {
925 None => {
926 return self.prepend(source_node_idx, link);
927 }
928 Some(insert_after) => {
929 if self.link(insert_after).target_node_idx == target_node_idx {
931 assert!(self.link(insert_after).external_link_id == external_link_id);
932 panic!("Duplicate link");
933 }
934
935 let new_link_idx = self.allocate_link_item(LinkItem {
936 link: link,
937 prev: Some(insert_after),
938 next: Some(idx),
939 });
940
941 self.links[insert_after.index()].next = Some(new_link_idx);
942 self.links[idx.index()].prev = Some(new_link_idx);
943
944 return new_link_idx;
945 }
946 }
947 }
948 }
949 }
950
951 fn find_link_index_insert_before(
954 &self,
955 source_node_idx: NodeIndex,
956 _target_node_idx: NodeIndex,
957 external_link_id: EXTID,
958 ) -> Option<LinkIndex> {
959 let mut link_iter = self.link_iter_for_node(source_node_idx);
961 for (idx, link) in &mut link_iter {
962 if link.external_link_id() > external_link_id {
963 return Some(idx);
964 }
965 }
966 return None;
967 }
968
969 pub fn has_link(&self, source_node_idx: NodeIndex, target_node_idx: NodeIndex) -> bool {
970 self.find_link_index_exact(source_node_idx, target_node_idx)
971 .is_some()
972 }
973
974 fn find_link_index_exact(
975 &self,
976 source_node_idx: NodeIndex,
977 target_node_idx: NodeIndex,
978 ) -> Option<LinkIndex> {
979 for (link_idx, link) in self.link_iter_for_node(source_node_idx) {
980 if link.target_node_idx == target_node_idx {
982 return Some(link_idx);
983 }
984 }
985 return None;
986 }
987
988 pub fn remove_link_at(&mut self, link_index: LinkIndex) {
990 let found_idx = link_index;
991 let source_node_idx = self.link(found_idx).source_node_idx;
992 let target_node_idx = self.link(found_idx).target_node_idx;
993
994 if self.link(found_idx).is_active() {
995 self.active_link_count -= 1;
996 }
997
998 match (
1001 self.link_item(found_idx).prev,
1002 self.link_item(found_idx).next,
1003 ) {
1004 (None, None) => {
1005 assert!(self.node(source_node_idx).links.head == Some(found_idx));
1007 assert!(self.node(source_node_idx).links.tail == Some(found_idx));
1008 self.node_mut(source_node_idx).links = List::empty();
1009 }
1010
1011 (None, Some(next)) => {
1012 assert!(self.links[next.index()].prev == Some(found_idx));
1014 assert!(self.node(source_node_idx).links.head == Some(found_idx));
1015 assert!(self.node(source_node_idx).links.tail != Some(found_idx));
1016 self.node_mut(source_node_idx).links.head = Some(next);
1017 self.links[next.index()].prev = None;
1018 }
1019
1020 (Some(prev), None) => {
1021 assert!(self.links[prev.index()].next == Some(found_idx));
1023 assert!(self.node(source_node_idx).links.tail == Some(found_idx));
1024 assert!(self.node(source_node_idx).links.head != Some(found_idx));
1025
1026 self.node_mut(source_node_idx).links.tail = Some(prev);
1028 self.links[prev.index()].next = None;
1029 }
1030
1031 (Some(prev), Some(next)) => {
1032 assert!(self.node(source_node_idx).links.head != Some(found_idx));
1035 assert!(self.node(source_node_idx).links.tail != Some(found_idx));
1036
1037 assert!(self.links[prev.index()].next == Some(found_idx));
1038 assert!(self.links[next.index()].prev == Some(found_idx));
1039
1040 self.links[prev.index()].next = Some(next);
1041 self.links[next.index()].prev = Some(prev);
1042 }
1043 }
1044
1045 self.links[found_idx.index()].next = None;
1046 self.links[found_idx.index()].prev = None;
1047
1048 let old_idx = LinkIndex(self.links.len() - 1);
1050
1051 if found_idx == old_idx {
1052 let old = self.links.pop().unwrap();
1054 debug_assert!(old.link.source_node_idx == source_node_idx);
1055 debug_assert!(old.link.target_node_idx == target_node_idx);
1056 } else {
1057 let old = self.links.swap_remove(found_idx.index());
1058 debug_assert!(old.link.source_node_idx == source_node_idx);
1059 debug_assert!(old.link.target_node_idx == target_node_idx);
1060
1061 let new_idx = found_idx;
1064 let new_source_node_idx = self.link(new_idx).source_node_idx;
1066
1067 match (self.link_item(new_idx).prev, self.link_item(new_idx).next) {
1068 (None, None) => {
1069 assert!(self.node(new_source_node_idx).links.head == Some(old_idx));
1071 assert!(self.node(new_source_node_idx).links.tail == Some(old_idx));
1072
1073 self.node_mut(new_source_node_idx).links = List {
1075 head: Some(new_idx),
1076 tail: Some(new_idx),
1077 };
1078 }
1079
1080 (None, Some(next)) => {
1081 assert!(self.links[next.index()].prev == Some(old_idx));
1083 assert!(self.node(new_source_node_idx).links.head == Some(old_idx));
1084 assert!(self.node(new_source_node_idx).links.tail != Some(old_idx));
1085 self.node_mut(new_source_node_idx).links.head = Some(new_idx);
1086 self.links[next.index()].prev = Some(new_idx);
1087 }
1088
1089 (Some(prev), None) => {
1090 assert!(self.links[prev.index()].next == Some(old_idx));
1092 assert!(self.node(new_source_node_idx).links.tail == Some(old_idx));
1093 assert!(self.node(new_source_node_idx).links.head != Some(old_idx));
1094
1095 self.node_mut(new_source_node_idx).links.tail = Some(new_idx);
1097 self.links[prev.index()].next = Some(new_idx);
1098 }
1099
1100 (Some(prev), Some(next)) => {
1101 assert!(self.node(new_source_node_idx).links.head != Some(old_idx));
1104 assert!(self.node(new_source_node_idx).links.tail != Some(old_idx));
1105
1106 assert!(self.links[prev.index()].next == Some(old_idx));
1107 assert!(self.links[next.index()].prev == Some(old_idx));
1108
1109 self.links[prev.index()].next = Some(new_idx);
1110 self.links[next.index()].prev = Some(new_idx);
1111 }
1112 }
1113 }
1114
1115 assert!(self.node(source_node_idx).out_degree > 0);
1116 assert!(self.node(target_node_idx).in_degree > 0);
1117 self.node_mut(source_node_idx).out_degree -= 1;
1118 self.node_mut(target_node_idx).in_degree -= 1;
1119 self.link_count -= 1;
1120 }
1121
1122 pub fn remove_link(&mut self, source_node_idx: NodeIndex, target_node_idx: NodeIndex) -> bool {
1125 if let Some(found_idx) = self.find_link_index_exact(source_node_idx, target_node_idx) {
1126 debug_assert!(self.link(found_idx).source_node_idx == source_node_idx);
1127 debug_assert!(self.link(found_idx).target_node_idx == target_node_idx);
1128 self.remove_link_at(found_idx);
1129 return true;
1130 } else {
1131 return false;
1133 }
1134 }
1135}
1136
1137#[cfg(test)]
1138mod tests {
1139 use rand;
1140 use super::{ExternalId, Network, NodeIndex, NodeType};
1141
1142 #[derive(Clone, Debug, PartialEq, Eq)]
1143 enum NodeT {
1144 Input,
1145 Hidden,
1146 Output,
1147 }
1148
1149 impl NodeType for NodeT {
1150 fn accept_incoming_links(&self) -> bool {
1151 match *self {
1152 NodeT::Input => false,
1153 _ => true,
1154 }
1155 }
1156 fn accept_outgoing_links(&self) -> bool {
1157 match *self {
1158 NodeT::Output => false,
1159 _ => true,
1160 }
1161 }
1162 }
1163
1164 #[test]
1165 fn test_cycle() {
1166 let mut g = Network::new();
1167 let i1 = g.add_node(NodeT::Input, ExternalId(1));
1168 let h1 = g.add_node(NodeT::Hidden, ExternalId(2));
1169 let h2 = g.add_node(NodeT::Hidden, ExternalId(3));
1170 assert_eq!(true, g.valid_link(i1, i1).is_err());
1171 assert_eq!(true, g.valid_link(h1, h1).is_err());
1172
1173 assert_eq!(true, g.valid_link(h1, i1).is_err());
1174 assert_eq!(Ok(()), g.valid_link(i1, h1));
1175 assert_eq!(Ok(()), g.valid_link(i1, h2));
1176 assert_eq!(Ok(()), g.valid_link(h1, h2));
1177
1178 assert_eq!((0, 0), g.node(i1).in_out_degree());
1179 assert_eq!((0, 0), g.node(h1).in_out_degree());
1180 assert_eq!((0, 0), g.node(h2).in_out_degree());
1181
1182 g.add_link(i1, h1, 0.0, ExternalId(1));
1183 assert_eq!((0, 1), g.node(i1).in_out_degree());
1184 assert_eq!((1, 0), g.node(h1).in_out_degree());
1185 assert_eq!((0, 0), g.node(h2).in_out_degree());
1186
1187 assert_eq!(true, g.link_would_cycle(h1, i1));
1188 assert_eq!(false, g.link_would_cycle(i1, h1));
1189 assert_eq!(false, g.link_would_cycle(i1, h2));
1190 assert_eq!(true, g.link_would_cycle(i1, i1));
1191 assert_eq!(false, g.link_would_cycle(h1, h2));
1192 assert_eq!(false, g.link_would_cycle(h2, h1));
1193 assert_eq!(false, g.link_would_cycle(h2, i1));
1194
1195 g.add_link(h1, h2, 0.0, ExternalId(2));
1196 assert_eq!((0, 1), g.node(i1).in_out_degree());
1197 assert_eq!((1, 1), g.node(h1).in_out_degree());
1198 assert_eq!((1, 0), g.node(h2).in_out_degree());
1199
1200 assert_eq!(true, g.link_would_cycle(h2, i1));
1201 assert_eq!(true, g.link_would_cycle(h1, i1));
1202 assert_eq!(true, g.link_would_cycle(h2, h1));
1203 assert_eq!(false, g.link_would_cycle(i1, h2));
1204 }
1205
1206 #[test]
1207 fn test_find_random_unconnected_link_no_cycle() {
1208 let mut g = Network::new();
1209 let i1 = g.add_node(NodeT::Input, ExternalId(1));
1210 let o1 = g.add_node(NodeT::Output, ExternalId(2));
1211 let o2 = g.add_node(NodeT::Output, ExternalId(3));
1212
1213 let mut rng = rand::thread_rng();
1214
1215 let link = g.find_random_unconnected_link_no_cycle(&mut rng);
1216 assert_eq!(true, link.is_some());
1217 let l = link.unwrap();
1218 assert!((i1, o1) == l || (i1, o2) == l);
1219
1220 g.add_link(i1, o2, 0.0, ExternalId(1));
1221 let link = g.find_random_unconnected_link_no_cycle(&mut rng);
1222 assert_eq!(true, link.is_some());
1223 assert_eq!((i1, o1), link.unwrap());
1224
1225 g.add_link(i1, o1, 0.0, ExternalId(2));
1226 let link = g.find_random_unconnected_link_no_cycle(&mut rng);
1227 assert_eq!(false, link.is_some());
1228 }
1229
1230 #[test]
1231 fn test_remove_link() {
1232 let mut g = Network::new();
1233 let i1 = g.add_node(NodeT::Input, ExternalId(1));
1234 let h1 = g.add_node(NodeT::Hidden, ExternalId(2));
1235 let h2 = g.add_node(NodeT::Hidden, ExternalId(3));
1236
1237 g.add_link(i1, h1, 0.0, ExternalId(2));
1238 g.add_link(i1, h2, 0.0, ExternalId(1));
1239
1240 assert_eq!(
1241 ExternalId(1),
1242 g.first_link_of_node(i1).unwrap().external_link_id()
1243 );
1244 assert_eq!(
1245 ExternalId(2),
1246 g.last_link_of_node(i1).unwrap().external_link_id()
1247 );
1248
1249 assert_eq!(2, g.node(i1).out_degree());
1250 assert_eq!(1, g.node(h1).in_degree());
1251 assert_eq!(1, g.node(h2).in_degree());
1252 assert_eq!(2, g.link_count());
1253
1254 assert_eq!(true, g.remove_link(i1, h1));
1255 assert_eq!(1, g.node(i1).out_degree());
1256 assert_eq!(0, g.node(h1).in_degree());
1257 assert_eq!(1, g.node(h2).in_degree());
1258 assert_eq!(1, g.link_count());
1259
1260 assert_eq!(
1261 ExternalId(1),
1262 g.first_link_of_node(i1).unwrap().external_link_id()
1263 );
1264 assert_eq!(
1265 ExternalId(1),
1266 g.last_link_of_node(i1).unwrap().external_link_id()
1267 );
1268
1269 assert_eq!(false, g.remove_link(i1, h1));
1270 assert_eq!(1, g.node(i1).out_degree());
1271 assert_eq!(0, g.node(h1).in_degree());
1272 assert_eq!(1, g.node(h2).in_degree());
1273 assert_eq!(1, g.link_count());
1274
1275 assert_eq!(
1276 ExternalId(1),
1277 g.first_link_of_node(i1).unwrap().external_link_id()
1278 );
1279 assert_eq!(
1280 ExternalId(1),
1281 g.last_link_of_node(i1).unwrap().external_link_id()
1282 );
1283
1284 assert_eq!(true, g.remove_link(i1, h2));
1285 assert_eq!(0, g.node(i1).out_degree());
1286 assert_eq!(0, g.node(h1).in_degree());
1287 assert_eq!(0, g.node(h2).in_degree());
1288 assert_eq!(0, g.link_count());
1289
1290 assert!(g.first_link_of_node(i1).is_none());
1291 assert!(g.last_link_of_node(i1).is_none());
1292
1293 }
1295
1296 #[test]
1297 fn test_add_remove_link_unordered() {
1298 let mut g = Network::new();
1299 let i1 = g.add_node(NodeT::Input, ());
1300 let h1 = g.add_node(NodeT::Hidden, ());
1301 let h2 = g.add_node(NodeT::Hidden, ());
1302
1303 g.add_link_unordered(i1, h1, 0.0, ());
1304 g.add_link_unordered(i1, h2, 0.0, ());
1305
1306 assert_eq!(h1, g.first_link_of_node(i1).unwrap().target_node_idx);
1307 assert_eq!(h2, g.last_link_of_node(i1).unwrap().target_node_idx);
1308
1309 assert_eq!(2, g.node(i1).out_degree());
1310 assert_eq!(1, g.node(h1).in_degree());
1311 assert_eq!(1, g.node(h2).in_degree());
1312 assert_eq!(2, g.link_count());
1313
1314 assert_eq!(true, g.remove_link(i1, h1));
1315 assert_eq!(1, g.node(i1).out_degree());
1316 assert_eq!(0, g.node(h1).in_degree());
1317 assert_eq!(1, g.node(h2).in_degree());
1318 assert_eq!(1, g.link_count());
1319
1320 assert_eq!(h2, g.first_link_of_node(i1).unwrap().target_node_idx);
1321 assert_eq!(h2, g.last_link_of_node(i1).unwrap().target_node_idx);
1322
1323 assert_eq!(false, g.remove_link(i1, h1));
1324 assert_eq!(1, g.node(i1).out_degree());
1325 assert_eq!(0, g.node(h1).in_degree());
1326 assert_eq!(1, g.node(h2).in_degree());
1327 assert_eq!(1, g.link_count());
1328
1329 assert_eq!(h2, g.first_link_of_node(i1).unwrap().target_node_idx);
1330 assert_eq!(h2, g.last_link_of_node(i1).unwrap().target_node_idx);
1331
1332 assert_eq!(true, g.remove_link(i1, h2));
1333 assert_eq!(0, g.node(i1).out_degree());
1334 assert_eq!(0, g.node(h1).in_degree());
1335 assert_eq!(0, g.node(h2).in_degree());
1336 assert_eq!(0, g.link_count());
1337
1338 assert!(g.first_link_of_node(i1).is_none());
1339 assert!(g.last_link_of_node(i1).is_none());
1340 }
1341
1342 #[test]
1343 fn test_remove_all_outgoing_links() {
1344 let mut g = Network::new();
1345 let i1 = g.add_node(NodeT::Input, ());
1346 let h1 = g.add_node(NodeT::Hidden, ());
1347 let h2 = g.add_node(NodeT::Hidden, ());
1348 let o1 = g.add_node(NodeT::Output, ());
1349
1350 g.add_link_unordered(i1, h1, 0.0, ());
1351 g.add_link_unordered(i1, h2, 0.0, ());
1352 g.add_link_unordered(h1, o1, 0.0, ());
1353 g.add_link_unordered(h2, o1, 0.0, ());
1354
1355 assert_eq!(2, g.node(i1).out_degree());
1356 assert_eq!(1, g.node(h1).in_degree());
1357 assert_eq!(1, g.node(h2).in_degree());
1358 assert_eq!(1, g.node(h1).out_degree());
1359 assert_eq!(1, g.node(h2).out_degree());
1360 assert_eq!(2, g.node(o1).in_degree());
1361 assert_eq!(0, g.node(o1).out_degree());
1362 assert_eq!(4, g.link_count());
1363
1364 g.remove_all_outgoing_links_of_node(i1);
1365
1366 assert!(g.first_link_of_node(i1).is_none());
1367 assert!(g.last_link_of_node(i1).is_none());
1368
1369 assert_eq!(0, g.node(i1).out_degree());
1370 assert_eq!(0, g.node(h1).in_degree());
1371 assert_eq!(0, g.node(h2).in_degree());
1372 assert_eq!(1, g.node(h1).out_degree());
1373 assert_eq!(1, g.node(h2).out_degree());
1374 assert_eq!(2, g.node(o1).in_degree());
1375 assert_eq!(0, g.node(o1).out_degree());
1376 assert_eq!(2, g.link_count());
1377 }
1378
1379 #[test]
1380 fn test_remove_all_incoming_links() {
1381 let mut g = Network::new();
1382 let i1 = g.add_node(NodeT::Input, ());
1383 let h1 = g.add_node(NodeT::Hidden, ());
1384 let h2 = g.add_node(NodeT::Hidden, ());
1385 let o1 = g.add_node(NodeT::Output, ());
1386
1387 g.add_link_unordered(i1, h1, 0.0, ());
1388 g.add_link_unordered(i1, h2, 0.0, ());
1389 g.add_link_unordered(h1, o1, 0.0, ());
1390 g.add_link_unordered(h2, o1, 0.0, ());
1391
1392 assert_eq!(2, g.node(i1).out_degree());
1393 assert_eq!(1, g.node(h1).in_degree());
1394 assert_eq!(1, g.node(h2).in_degree());
1395 assert_eq!(1, g.node(h1).out_degree());
1396 assert_eq!(1, g.node(h2).out_degree());
1397 assert_eq!(2, g.node(o1).in_degree());
1398 assert_eq!(0, g.node(o1).out_degree());
1399 assert_eq!(4, g.link_count());
1400 assert!(g.first_link_of_node(i1).is_some());
1401 assert!(g.last_link_of_node(i1).is_some());
1402
1403 g.remove_all_incoming_links_of_node(i1);
1404
1405 assert_eq!(2, g.node(i1).out_degree());
1406 assert_eq!(1, g.node(h1).in_degree());
1407 assert_eq!(1, g.node(h2).in_degree());
1408 assert_eq!(1, g.node(h1).out_degree());
1409 assert_eq!(1, g.node(h2).out_degree());
1410 assert_eq!(2, g.node(o1).in_degree());
1411 assert_eq!(0, g.node(o1).out_degree());
1412 assert_eq!(4, g.link_count());
1413 assert!(g.first_link_of_node(i1).is_some());
1414 assert!(g.last_link_of_node(i1).is_some());
1415
1416 g.remove_all_incoming_links_of_node(h1);
1417
1418 assert_eq!(1, g.node(i1).out_degree());
1419 assert_eq!(0, g.node(h1).in_degree());
1420 assert_eq!(1, g.node(h2).in_degree());
1421 assert_eq!(1, g.node(h1).out_degree());
1422 assert_eq!(1, g.node(h2).out_degree());
1423 assert_eq!(2, g.node(o1).in_degree());
1424 assert_eq!(0, g.node(o1).out_degree());
1425 assert_eq!(3, g.link_count());
1426 assert!(g.first_link_of_node(i1).is_some());
1427 assert!(g.last_link_of_node(i1).is_some());
1428
1429 g.remove_all_incoming_links_of_node(h2);
1430
1431 assert_eq!(0, g.node(i1).out_degree());
1432 assert_eq!(0, g.node(h1).in_degree());
1433 assert_eq!(0, g.node(h2).in_degree());
1434 assert_eq!(1, g.node(h1).out_degree());
1435 assert_eq!(1, g.node(h2).out_degree());
1436 assert_eq!(2, g.node(o1).in_degree());
1437 assert_eq!(0, g.node(o1).out_degree());
1438 assert_eq!(2, g.link_count());
1439 assert!(g.first_link_of_node(i1).is_none());
1440 assert!(g.last_link_of_node(i1).is_none());
1441 }
1442
1443 #[test]
1444 fn test_remove_all_inout_links() {
1445 let mut g = Network::new();
1446 let i1 = g.add_node(NodeT::Input, ());
1447 let h1 = g.add_node(NodeT::Hidden, ());
1448 let h2 = g.add_node(NodeT::Hidden, ());
1449 let o1 = g.add_node(NodeT::Output, ());
1450
1451 g.add_link_unordered(i1, h1, 0.0, ());
1452 g.add_link_unordered(i1, h2, 0.0, ());
1453 g.add_link_unordered(h1, o1, 0.0, ());
1454 g.add_link_unordered(h2, o1, 0.0, ());
1455
1456 assert_eq!(2, g.node(i1).out_degree());
1457 assert_eq!(1, g.node(h1).in_degree());
1458 assert_eq!(1, g.node(h2).in_degree());
1459 assert_eq!(1, g.node(h1).out_degree());
1460 assert_eq!(1, g.node(h2).out_degree());
1461 assert_eq!(2, g.node(o1).in_degree());
1462 assert_eq!(0, g.node(o1).out_degree());
1463 assert_eq!(4, g.link_count());
1464
1465 g.remove_all_inout_links_of_node(i1);
1466
1467 assert!(g.first_link_of_node(i1).is_none());
1468 assert!(g.last_link_of_node(i1).is_none());
1469
1470 assert_eq!(0, g.node(i1).out_degree());
1471 assert_eq!(0, g.node(h1).in_degree());
1472 assert_eq!(0, g.node(h2).in_degree());
1473 assert_eq!(1, g.node(h1).out_degree());
1474 assert_eq!(1, g.node(h2).out_degree());
1475 assert_eq!(2, g.node(o1).in_degree());
1476 assert_eq!(0, g.node(o1).out_degree());
1477 assert_eq!(2, g.link_count());
1478
1479 g.remove_all_inout_links_of_node(h1);
1480
1481 assert_eq!(0, g.node(i1).out_degree());
1482 assert_eq!(0, g.node(h1).in_degree());
1483 assert_eq!(0, g.node(h2).in_degree());
1484 assert_eq!(0, g.node(h1).out_degree());
1485 assert_eq!(1, g.node(h2).out_degree());
1486 assert_eq!(1, g.node(o1).in_degree());
1487 assert_eq!(0, g.node(o1).out_degree());
1488 assert_eq!(1, g.link_count());
1489
1490 g.remove_all_inout_links_of_node(o1);
1491
1492 assert_eq!(0, g.node(i1).out_degree());
1493 assert_eq!(0, g.node(h1).in_degree());
1494 assert_eq!(0, g.node(h2).in_degree());
1495 assert_eq!(0, g.node(h1).out_degree());
1496 assert_eq!(0, g.node(h2).out_degree());
1497 assert_eq!(0, g.node(o1).in_degree());
1498 assert_eq!(0, g.node(o1).out_degree());
1499 assert_eq!(0, g.link_count());
1500 }
1501
1502 #[test]
1503 fn test_remove_node() {
1504 let mut g = Network::new();
1505 let i1 = g.add_node(NodeT::Input, ());
1506 let h1 = g.add_node(NodeT::Hidden, ());
1507 let h2 = g.add_node(NodeT::Hidden, ());
1508 let o1 = g.add_node(NodeT::Output, ());
1509
1510 g.add_link_unordered(i1, h1, 0.0, ());
1511 g.add_link_unordered(i1, h2, 0.0, ());
1512 g.add_link_unordered(h1, o1, 0.0, ());
1513 g.add_link_unordered(h2, o1, 0.0, ());
1514
1515 assert_eq!(2, g.node(i1).out_degree());
1516 assert_eq!(1, g.node(h1).in_degree());
1517 assert_eq!(1, g.node(h2).in_degree());
1518 assert_eq!(1, g.node(h1).out_degree());
1519 assert_eq!(1, g.node(h2).out_degree());
1520 assert_eq!(2, g.node(o1).in_degree());
1521 assert_eq!(0, g.node(o1).out_degree());
1522 assert_eq!(4, g.link_count());
1523 assert_eq!(4, g.node_count());
1524
1525 assert_eq!(NodeIndex(0), i1);
1526 assert_eq!(NodeIndex(3), o1);
1527 g.remove_node(i1);
1528 let o1 = i1;
1529 drop(i1);
1530 assert_eq!(NodeIndex(0), o1);
1531
1532 assert_eq!(0, g.node(h1).in_degree());
1533 assert_eq!(0, g.node(h2).in_degree());
1534 assert_eq!(1, g.node(h1).out_degree());
1535 assert_eq!(1, g.node(h2).out_degree());
1536 assert_eq!(2, g.node(o1).in_degree());
1537 assert_eq!(0, g.node(o1).out_degree());
1538 assert_eq!(2, g.link_count());
1539 assert_eq!(3, g.node_count());
1540
1541 assert_eq!(NodeIndex(2), h2);
1542 g.remove_node(h2);
1543 drop(h2);
1544
1545 assert_eq!(0, g.node(h1).in_degree());
1546 assert_eq!(1, g.node(h1).out_degree());
1547 assert_eq!(1, g.node(o1).in_degree());
1548 assert_eq!(0, g.node(o1).out_degree());
1549 assert_eq!(1, g.link_count());
1550 assert_eq!(2, g.node_count());
1551
1552 assert_eq!(NodeIndex(0), o1);
1553 g.remove_node(o1);
1554 let h1 = o1;
1555 drop(o1);
1556 assert_eq!(NodeIndex(0), h1);
1557
1558 assert_eq!(0, g.node(h1).in_degree());
1559 assert_eq!(0, g.node(h1).out_degree());
1560 assert_eq!(0, g.link_count());
1561 assert_eq!(1, g.node_count());
1562
1563 assert_eq!(NodeIndex(0), h1);
1564 g.remove_node(h1);
1565 assert_eq!(0, g.node_count());
1566 }
1567
1568}