/// <summary>
        /// Calculates the total distance between two graphs, only
        /// accounting for vertices.
        /// </summary>
        protected double TotalVertexDistance(IGraphChromosome g1, IGraphChromosome g2)
        {
            double nMismatch = 0;
            double nMatch    = 0;
            double totalDist = 0;

            foreach (var vert in g1.Vertices)
            {
                if (g2.ContainsVertex(vert.ID))
                {
                    totalDist += VertexDistance(g2[vert.ID], vert.Value);
                    nMatch++;
                }
                else
                {
                    nMismatch++;
                }
            }
            foreach (var vert in g2.Vertices)
            {
                if (!g1.ContainsVertex(vert.ID))
                {
                    nMismatch++;
                }
            }

            int N = Math.Max(g1.VertexCount, g2.VertexCount);

            return((VertexMismatchWeight * nMismatch / N) + (VertexMatchWeight * totalDist / nMatch));
        }
        protected override IGraphChromosome PerformCrossover(IGraphChromosome p1, IGraphChromosome p2)
        {
            IList <IChromosome> parents = new IChromosome[2];

            // "Disjoint genes are inherited from the more fit parent."
            var child = p1.Clone() as IGraphChromosome;

            foreach (var vert in p1.Vertices)
            {
                if (p2.ContainsVertex(vert.ID))
                {
                    parents[0]     = vert.Value;
                    parents[1]     = p2[vert.ID];
                    child[vert.ID] = VertexCrossover.Cross(parents)[0];
                }
            }

            foreach (var edge in p1.Edges)
            {
                if (p2.ContainsEdge(edge.IDFrom, edge.IDTo))
                {
                    parents[0] = edge.Value;
                    parents[1] = p2[edge.IDFrom, edge.IDTo];
                    child[edge.IDFrom, edge.IDTo] = EdgeCrossover.Cross(parents)[0];
                }
            }

            return(child);
        }