                if (clustering.clusters[network.neighbors[k]] == j)
                    quality += network.edgeWeights[k];
        }
        quality += network.totalEdgeWeightSelfLinks;

        clusterWeights = new double[clustering.nClusters];
        for (i = 0; i < network.nNodes; i++)
            clusterWeights[clustering.clusters[i]] += network.nodeWeights[i];
        for (i = 0; i < clustering.nClusters; i++)
            quality -= clusterWeights[i] * clusterWeights[i] * resolution;

        quality /= 2 * network.getTotalEdgeWeight() + network.totalEdgeWeightSelfLinks;

        return quality;
    }
}
        Clustering finalClustering = null;
        double maxQuality = Double.NEGATIVE_INFINITY;
        for (int i = 0; i < nRandomStarts; i++)
        {
            Clustering clustering = initialClustering.clone();
            algorithm.improveClustering(network, clustering);
            double quality = algorithm.calcQuality(network, clustering);
            if (nRandomStarts > 1)
                System.err.println("Quality function in random start " + (i + 1) + " equals " + quality + ".");
            if (quality > maxQuality)
            {
                finalClustering = clustering;
                maxQuality = quality;
            }
        }
        System.err.println("Running algorithm took " + (System.currentTimeMillis() - startTimeAlgorithm) / 1000 + "s.");
        if (nRandomStarts > 1)
            System.err.println("Maximum value of quality function in " + nRandomStarts + " random starts equals " + maxQuality + ".");
        else
            System.err.println("Quality function equals " + maxQuality + ".");
        System.err.println("Final clustering consists of " + finalClustering.getNClusters() + " clusters.");

        // Write final clustering to file (or to standard output).
        System.err.println("Writing final clustering to " + ((finalClusteringFilename == null) ? "standard output." : "'" + finalClusteringFilename + "'."));
        writeClustering(finalClusteringFilename, finalClustering);
    }

    /**
     * Reads an edge list from a file and creates a network.
