All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.googlecode.blaisemath.graph.modules.metrics.GlobalMetrics Maven / Gradle / Ivy

The newest version!
/*
 * GlobalMetrics.java
 * Created May 12, 2010
 */
package com.googlecode.blaisemath.graph.modules.metrics;

/*
 * #%L
 * BlaiseGraphTheory
 * --
 * Copyright (C) 2009 - 2016 Elisha Peterson
 * --
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */

import com.googlecode.blaisemath.graph.GraphMetric;
import java.util.HashMap;
import java.util.Set;
import java.util.Stack;
import com.googlecode.blaisemath.graph.Graph;
import com.googlecode.blaisemath.graph.GraphUtils;

/**
 * 

Contains several implementations of * GraphMetric that can be used to compute metrics for a given * graph.

* * @author Elisha Peterson */ public final class GlobalMetrics { private GlobalMetrics() { } /** * Number of components in the graph */ public static final GraphMetric COMPONENTS = new GraphMetric() { public String getName() { return "Components"; } public String getDescription() { return "Number of connected components in the graph."; } public boolean supportsGraph(boolean directed) { return true; } public Integer apply(Graph graph) { return GraphUtils.components(graph).size(); } }; /** * Global metric describing the order of the graph */ public static final GraphMetric ORDER = new GraphMetric() { public String getName() { return "Order"; } public String getDescription() { return "Number of vertices in the graph."; } public boolean supportsGraph(boolean directed) { return true; } public Integer apply(Graph graph) { return graph.nodeCount(); } }; /** * Global metric describing the # edges in a graph */ public static final GraphMetric EDGE_NUMBER = new GraphMetric() { public String getName() { return "Edge Number"; } public String getDescription() { return "Number of edges in the graph."; } public boolean supportsGraph(boolean directed) { return true; } public Integer apply(Graph graph) { return graph.edgeCount(); } }; /** * Global metric describing the density of the graph (# edges divided by # * possible) */ public static final GraphMetric DENSITY = new GraphMetric() { public String getName() { return "Link Density"; } public String getDescription() { return "Number of edges in the graph divided by the total number possible."; } public boolean supportsGraph(boolean directed) { return true; } public Double apply(Graph graph) { int n = graph.nodeCount(); return graph.isDirected() ? graph.edgeCount() / (n * (n - 1)) : graph.edgeCount() / (n * (n - 1) / 2.0); } }; /** * Global metric describing the average degree of the graph */ public static final GraphMetric DEGREE_AVERAGE = new GraphMetric() { public String getName() { return "Average Degree"; } public String getDescription() { return "Average degree of vertices in the graph. Uses average indegree or outdegree for a directed graph."; } public boolean supportsGraph(boolean directed) { return true; } public Double apply(Graph graph) { return graph.isDirected() ? graph.edgeCount() / (double) graph.nodeCount() : 2.0 * graph.edgeCount() / (double) graph.nodeCount(); } }; /** * Global metric describes the diameter of the graph, or the largest * diameter of one of its subcomponents. */ public static final GraphMetric DIAMETER = new GraphMetric() { public String getName() { return "Diameter"; } public String getDescription() { return "Diameter of the graph (longest path between two vertices)."; } public boolean supportsGraph(boolean directed) { return true; } public Integer apply(Graph graph) { return applyTyped(graph); } private Integer applyTyped(Graph graph) { if (graph.nodeCount() == 0) { return 0; } int maxLength = 0; HashMap lengths = new HashMap(); for (V node : graph.nodes()) { GraphUtils.breadthFirstSearch(graph, node, new HashMap(), lengths, new Stack(), new HashMap>()); for (Integer i : lengths.values()) { if (i > maxLength) { maxLength = i; } } } return maxLength; } }; /** * Global metric describes the radius of the graph, or the largest diameter * of one of its subcomponents. */ public static final GraphMetric RADIUS = new GraphMetric() { public String getName() { return "Radius"; } public String getDescription() { return "Radius of the graph (minimum number r such that all vertices are within r links of a particular vertex)."; } public boolean supportsGraph(boolean directed) { return true; } public Integer apply(Graph graph) { return applyTyped(graph); } private Integer applyTyped(Graph graph) { if (graph.nodeCount() == 0) { return 0; } int minMaxLength = Integer.MAX_VALUE; HashMap lengths = new HashMap(); for (V node : graph.nodes()) { int maxLength = 0; GraphUtils.breadthFirstSearch(graph, node, new HashMap(), lengths, new Stack(), new HashMap>()); for (Integer i : lengths.values()) { if (i > maxLength) { maxLength = i; } } if (maxLength > 0) { minMaxLength = Math.min(maxLength, minMaxLength); } } return minMaxLength; } }; /** * Global metric describing the clustering coefficient of the graph; in the * directed case, measures "transitivity", i.e. when a-%gt;b,b-%gt;c implies a-%gt;c */ public static final GraphMetric CLUSTERING_A = new GraphMetric() { public String getName() { return "Clustering A"; } public String getDescription() { return "Computes the clustering coefficient:" + " Out of all triples of vertices with at least two edges, how many have three edges?"; } public boolean supportsGraph(boolean directed) { return true; } public Double apply(Graph graph) { int[] tri = triples(graph); int triangles = tri[0], triples = tri[1]; if (!graph.isDirected()) { triangles /= 3; triples -= 2 * triangles; } return triangles / (double) triples; } }; /** * Global metric describing the clustering coefficient of the graph; in the * directed case, measures "transitivity", i.e. when a-%gt;b,b-%gt;c implies a-%gt;c */ public static final GraphMetric CLUSTERING_B = new GraphMetric() { public String getName() { return "Clustering B"; } public String getDescription() { return "Computes the clustering coefficient:" + " Out of all length-3 paths, how many are enclosed by a triangle?"; } public boolean supportsGraph(boolean directed) { return true; } public Double apply(Graph graph) { int[] tri = triples(graph); int triangles = tri[0], triples = tri[1]; if (!graph.isDirected()) { triangles /= 3; } return triangles / (double) triples; } }; /** * Computes triple characteristics of a graph * * @param coordinate type of graph * @param graph the graph * @return int[] array where first entry is number of triangles and second * is number of path triples (i.e., when three nodes are connected together) */ public static int[] triples(Graph graph) { int triangles = 0; int triples = 0; for (V node : graph.nodes()) { Set g1 = graph.neighbors(node); int dist1 = g1.size(); int aDist1 = GraphUtils.copySubgraph(graph, g1).edgeCount(); Set g2 = GraphUtils.neighborhood(graph, node, 2); int dist2 = g2.size() - 1 - g1.size(); if (graph.isDirected()) { // in the directed case, potential triples are connected nodes at distance 1 and nodes at distance 2 // ... each node at distance 2 contributes a triple, but no triangle triples += aDist1 + dist2; triangles += aDist1; } else { // in copyUndirected case, each pair of nodes @ distance 1 contributes to a triple // ... each edge in this neighborhood indicates a triangle // corrections for later: each triangle is counted 3 times triples += dist1 * (dist1 - 1) / 2; triangles += aDist1; } } return new int[]{triangles, triples}; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy