コード例 #1
0
        public void ShortestPathFoundForGraphWithMultipleEdgesBetweenTwoVertices()
        {
            var vertices = new List <Vertex <object> >
            {
                new Vertex <object>(0),
                new Vertex <object>(1),
                new Vertex <object>(2),
                new Vertex <object>(3),
                new Vertex <object>(4)
            };
            var edges = new List <Edge <object> >
            {
                new Edge <object>(0, 0, 1),
                new Edge <object>(1, 1, 2),
                new Edge <object>(2, 1, 2), // Double edge
                new Edge <object>(3, 2, 3),
                new Edge <object>(4, 1, 4),
                new Edge <object>(5, 2, 4)
            };
            var graph = new Graph <object, object>(vertices, edges);

            Assert.That(() => GraphAlgorithms.ShortestPaths(graph, 0), Throws.Nothing);
            var shortestPathLookup = GraphAlgorithms.ShortestPaths(graph, 0);
            var pathToV3           = shortestPathLookup.PathTo(vertices.Single(v => v.Id == 3));

            Assert.That(pathToV3.PathLength, Is.EqualTo(3));
        }
コード例 #2
0
        public void ShortestPathThrowsExceptionIfAnyEdgeHasNegativeWeight()
        {
            // Remove this test if an algorithm with support for
            // negative weights has been implemented.

            var graph = CreateTestGraph();

            graph.Edges.First().Weight = -1;

            Assert.Throws <NotImplementedException>(() => GraphAlgorithms.ShortestPaths(graph, graph.GetVertexFromId(0)));
        }
コード例 #3
0
        public static void MarkBackbone(this Molecule molecule, MoleculeReference moleculeReference)
        {
            var pathsFromFirstAtom = GraphAlgorithms.ShortestPaths(molecule.MoleculeStructure, moleculeReference.FirstAtomId);
            var pathToLastAtom     = pathsFromFirstAtom.PathTo(molecule.MoleculeStructure.GetVertexFromId(moleculeReference.LastAtomId));
            var pathVertices       = pathToLastAtom.Path
                                     .SelectMany(edge => new[] { edge.Vertex1Id, edge.Vertex2Id })
                                     .Distinct()
                                     .Select(vId => molecule.MoleculeStructure.GetVertexFromId(vId))
                                     .Select(v => v.Object);

            pathVertices.ForEach(atom => atom.IsBackbone = true);
        }
コード例 #4
0
        public void ShortestPathFindsExpectedPathLengts()
        {
            var graph = CreateTestGraph();

            graph.Edges.Single(e => e.Vertex1Id == 1 && e.Vertex2Id == 3).Weight = 0.5;

            var shortestPathLookup = GraphAlgorithms.ShortestPaths(graph, graph.GetVertexFromId(0));

            Assert.That(shortestPathLookup.PathLengthTo(graph.GetVertexFromId(0)), Is.EqualTo(0));
            Assert.That(shortestPathLookup.PathLengthTo(graph.GetVertexFromId(1)), Is.EqualTo(1));
            Assert.That(shortestPathLookup.PathLengthTo(graph.GetVertexFromId(2)), Is.EqualTo(2));
            Assert.That(shortestPathLookup.PathLengthTo(graph.GetVertexFromId(3)), Is.EqualTo(1.5));
        }
コード例 #5
0
        public void ShortestPathFinishesWithinTimespan()
        {
            // This test is testing for possible deadlocks or inefficiencies
            // in the shortest path algorithm.

            var graph   = CreateTestGraph();
            var timeout = TimeSpan.FromMilliseconds(3000);

            ShortestPathLookup distanceDictionary = null;
            var thread = new Thread(() =>
            {
                distanceDictionary = GraphAlgorithms.ShortestPaths(graph, graph.GetVertexFromId(0));
            });

            thread.Start();
            thread.Join(timeout);

            Assert.That(distanceDictionary, Is.Not.Null);
        }
コード例 #6
0
        public void ShortestPathDoesntThrowIfGraphNotConnected()
        {
            var graph    = CreateTestGraph();
            var v1v2Edge = graph.Edges.Single(e => e.Vertex1Id == 0 && e.Vertex2Id == 1);

            graph.RemoveEdge(v1v2Edge);

            Assume.That(graph.GetVertexFromId(0).EdgeIds, Is.Empty);

            ShortestPathLookup shortestPathLookup = null;

            try
            {
                shortestPathLookup = GraphAlgorithms.ShortestPaths(graph, graph.GetVertexFromId(0));
            }
            catch (Exception)
            {
                Assert.Fail("GraphAlgorithm.ShortestPath should not throw exception for not connected test graph");
            }
            Assert.That(shortestPathLookup.PathLengthTo(graph.GetVertexFromId(1)), Is.EqualTo(double.PositiveInfinity));
        }
コード例 #7
0
        public static void PositionAtoms(Molecule molecule, uint firstAtomId = uint.MaxValue, uint lastAtomId = uint.MaxValue)
        {
            // Remove position information
            molecule.MoleculeStructure.Vertices
            .Select(v => v.Object)
            .ForEach(atom => atom.IsPositioned = false);

            var positionableVertices = new Queue <IVertex <Atom> >();

            // If first and last atom is specified, position atoms between those two first
            // Usually the case when a peptide is positioned, in which case the backbone
            // is oriented along the X-axis
            if (firstAtomId != uint.MaxValue && lastAtomId != uint.MaxValue)
            {
                // Position first atom
                var firstVertex = molecule.MoleculeStructure.GetVertexFromId(firstAtomId);
                var firstAtom   = firstVertex.Object;
                if (firstAtom.Position == null)
                {
                    firstAtom.Position = new UnitPoint3D(Unit.Meter, 0, 0, 0);
                }
                firstAtom.IsPositioned = true;
                positionableVertices.Enqueue(firstVertex);

                // Trace through molecule to last atom
                var lastVertex          = molecule.MoleculeStructure.GetVertexFromId(lastAtomId);
                var pathFromFirstVertex = GraphAlgorithms.ShortestPaths(molecule.MoleculeStructure, firstVertex);
                var pathToLastVertex    = pathFromFirstVertex.PathTo(lastVertex);

                // Position atoms between first and last along X-axis
                var currentEdge   = pathToLastVertex.Path.First;
                var currentVertex = firstVertex;
                while (currentEdge != null)
                {
                    var neighborId = currentEdge.Value.Vertex1Id == currentVertex.Id
                        ? currentEdge.Value.Vertex2Id
                        : currentEdge.Value.Vertex1Id;
                    var neighborVertex = molecule.MoleculeStructure.GetVertexFromId(neighborId);
                    PositionSpecificNeighborAlongXAxis(molecule, currentVertex, neighborVertex);
                    positionableVertices.Enqueue(neighborVertex);
                    currentEdge   = currentEdge.Next;
                    currentVertex = neighborVertex;
                }
            }
            else
            {
                var startVertex = firstAtomId != uint.MaxValue
                    ? molecule.MoleculeStructure.GetVertexFromId(firstAtomId)
                    : molecule.MoleculeStructure.Vertices.First();
                positionableVertices.Enqueue(startVertex);
                var startAtom = startVertex.Object;
                if (startAtom.Position == null)
                {
                    startAtom.Position = new UnitPoint3D(Unit.Meter, 0, 0, 0);
                }
                startAtom.IsPositioned = true;
            }
            while (positionableVertices.Any())
            {
                var vertex = positionableVertices.Dequeue();
                var positionableNeighbors = PositionNeighborsAndLonePairs(molecule, vertex);
                positionableNeighbors.ForEach(neighbor => positionableVertices.Enqueue(neighbor));
            }
        }