Browse Source

added mol-math/IntAdjacencyGraph UniqueEdgeBuilder

David Sehnal 6 years ago
parent
commit
014c009eaa

+ 30 - 1
src/mol-math/graph/int-adjacency-graph.ts

@@ -5,7 +5,7 @@
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
 
-import { arrayPickIndices } from 'mol-data/util';
+import { arrayPickIndices, cantorPairing } from 'mol-data/util';
 import { LinkedIndex } from 'mol-data/int';
 
 /**
@@ -160,6 +160,35 @@ export namespace IntAdjacencyGraph {
         }
     }
 
+    export class UniqueEdgeBuilder {
+        private xs: number[] = [];
+        private ys: number[] = [];
+        private included = new Set<number>();
+
+        addEdge(i: number, j: number) {
+            let u = i, v = j;
+            if (i > j) { u = j; v = i; }
+            const id = cantorPairing(u, v);
+            if (this.included.has(id)) return false;
+            this.included.add(id);
+            this.xs[this.xs.length] = u;
+            this.ys[this.ys.length] = v;
+            return true;
+        }
+
+        getGraph(): IntAdjacencyGraph {
+            return fromVertexPairs(this.vertexCount, this.xs, this.ys);
+        }
+
+        // if we cant to add custom props as well
+        getEdgeBuiler() {
+            return new EdgeBuilder(this.vertexCount, this.xs, this.ys);
+        }
+
+        constructor(public vertexCount: number) {
+        }
+    }
+
     export function fromVertexPairs(vertexCount: number, xs: number[], ys: number[]) {
         const graphBuilder = new IntAdjacencyGraph.EdgeBuilder(vertexCount, xs, ys);
         graphBuilder.addAllEdges();

+ 6 - 16
src/mol-model/structure/structure/unit/rings/compute.ts

@@ -4,13 +4,12 @@
  * @author David Sehnal <david.sehnal@gmail.com>
  */
 
-import Unit from '../../unit';
-import { IntraUnitLinks } from '../links/data';
 import { Segmentation } from 'mol-data/int';
+import { IntAdjacencyGraph } from 'mol-math/graph';
 import { LinkType } from '../../../model/types';
 import { StructureElement } from '../../../structure';
-import { sortedCantorPairing } from 'mol-data/util';
-import { IntAdjacencyGraph } from 'mol-math/graph';
+import Unit from '../../unit';
+import { IntraUnitLinks } from '../links/data';
 
 export function computeRings(unit: Unit.Atomic) {
     const size = largestResidue(unit);
@@ -262,9 +261,7 @@ export function createIndex(rings: StructureElement.UnitIndex[][]) {
     }
 
     // create a graph where vertices are rings, edge if two rings share at least one atom
-    const addedEdges = new Set<number>();
-    const xs: RingIndex[] = [], ys: RingIndex[] = [];
-
+    const graph = new IntAdjacencyGraph.UniqueEdgeBuilder(rings.length);
     for (let rI = 0 as RingIndex, _rI = rings.length; rI < _rI; rI++) {
         const r = rings[rI];
 
@@ -278,19 +275,12 @@ export function createIndex(rings: StructureElement.UnitIndex[][]) {
             for (let j = 0, _j = containedRings.length; j < _j; j++) {
                 const rJ = containedRings[j];
                 if (rI >= rJ) continue;
-
-                const edgeIndex = sortedCantorPairing(rI, rJ);
-                if (addedEdges.has(edgeIndex)) continue;
-
-                addedEdges.add(edgeIndex);
-                xs[xs.length] = rI;
-                ys[ys.length] = rJ;
+                graph.addEdge(rI, rJ);
             }
         }
     }
 
-    const graph = IntAdjacencyGraph.fromVertexPairs(rings.length, xs, ys);
-    const components = IntAdjacencyGraph.connectedComponents(graph);
+    const components = IntAdjacencyGraph.connectedComponents(graph.getGraph());
 
     const ringComponentIndex = components.componentIndex as any as RingComponentIndex[];
     const ringComponents: RingIndex[][] = [];