001/* 002 * Copyright (C) 2016 The Guava Authors 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package com.google.common.graph; 018 019import com.google.common.annotations.Beta; 020import java.util.ConcurrentModificationException; 021import java.util.Map; 022import javax.annotation.Nullable; 023 024/** 025 * An interface for <a href="https://en.wikipedia.org/wiki/Graph_(discrete_mathematics)">graph</a> 026 * data structures. A graph is composed of a set of nodes (sometimes called vertices) and a set of 027 * edges connecting pairs of nodes. Graphs are useful for modeling many kinds of relations. If the 028 * relation to be modeled is symmetric (such as "distance between cities"), that can be represented 029 * with an undirected graph, where an edge that connects node U to node V also connects node V to 030 * node U. If the relation to be modeled is asymmetric (such as "employees managed"), that can be 031 * represented with a directed graph, where edges are strictly one-way. 032 * 033 * <p>There are three main interfaces provided to represent graphs. In order of increasing 034 * complexity they are: {@link Graph}, {@link ValueGraph}, and {@link Network}. You should generally 035 * prefer the simplest interface that satisfies your use case. 036 * 037 * <p>To choose the right interface, answer these questions: 038 * 039 * <ol> 040 * <li>Do you have data (objects) that you wish to associate with edges? 041 * <p>Yes: Go to question 2. No: Use {@link Graph}. 042 * <li>Are the objects you wish to associate with edges unique within the scope of a graph? That is, 043 * no two objects would be {@link Object#equals(Object) equal} to each other. A common example 044 * where this would <i>not</i> be the case is with weighted graphs. 045 * <p>Yes: Go to question 3. No: Use {@link ValueGraph}. 046 * <li>Do you need to be able to query the graph for an edge associated with a particular object? 047 * For example, do you need to query what nodes an edge associated with a particular object 048 * connects, or whether an edge associated with that object exists in the graph? 049 * <p>Yes: Use {@link Network}. No: Go to question 4. 050 * <li>Do you need explicit support for parallel edges? For example, do you need to remove one edge 051 * connecting a pair of nodes while leaving other edges connecting those same nodes intact? 052 * <p>Yes: Use {@link Network}. No: Use {@link ValueGraph}. 053 * </ol> 054 * 055 * <p>Although {@link MutableValueGraph} and {@link MutableNetwork} both require users to provide 056 * objects to associate with edges when adding them, the differentiating factor is that in {@link 057 * ValueGraph}s, these objects can be any arbitrary data. Like the values in a {@link Map}, they do 058 * not have to be unique, and can be mutated while in the graph. In a {@link Network}, these objects 059 * serve as keys into the data structure. Like the keys in a {@link Map}, they must be unique, and 060 * cannot be mutated in a way that affects their equals/hashcode or the data structure will become 061 * corrupted. 062 * 063 * <p>In all three interfaces, nodes have all the same requirements as keys in a {@link Map}. 064 * 065 * <p>The {@link Graph} interface does not support parallel {@link #edges()}, and forbids 066 * implementations or extensions with parallel edges. It is possible to encode a notion of edge 067 * multiplicity into the values of a {@link ValueGraph} (e.g. with an integer or a list of values), 068 * but this will not be reflected in methods such as {@link Graph#degree(Object)}. For that 069 * functionality, see {@link Network}. 070 * 071 * <p>All mutation methods live on the subinterface {@link MutableValueGraph}. If you do not need to 072 * mutate a graph (e.g. if you write a method than runs a read-only algorithm on the graph), you 073 * should prefer the non-mutating {@link ValueGraph} interface. 074 * 075 * <p>We provide an efficient implementation of this interface via {@link ValueGraphBuilder}. When 076 * using the implementation provided, all collection-returning methods provide live, unmodifiable 077 * views of the graph. In other words, you cannot add an element to the collection, but if an 078 * element is added to the {@link ValueGraph} that would affect the collection, the collection will 079 * be updated automatically. This also means that you cannot mutate a {@link ValueGraph} in a way 080 * that would affect a collection while iterating over that collection. For example, you cannot 081 * remove either {@code foo} or any successors of {@code foo} from the graph while iterating over 082 * {@code successors(foo)} (unless you first make a copy of the successors), just as you could not 083 * remove keys from a {@link Map} while iterating over its {@link Map#keySet()}. Behavior in such a 084 * case is undefined, and may result in {@link ConcurrentModificationException}. 085 * 086 * <p>Example of use: 087 * 088 * <pre><code> 089 * MutableValueGraph<String, Double> synonymGraph = ValueGraphBuilder.undirected().build(); 090 * synonymGraph.putEdgeValue("large", "big", 0.9); 091 * synonymGraph.putEdgeValue("large", "huge", 0.9); 092 * synonymGraph.putEdgeValue("large", "grand", 0.6); 093 * synonymGraph.putEdgeValue("large", "cold", 0.0); 094 * synonymGraph.putEdgeValue("large", "small", -1.0); 095 * for (String word : synonymGraph.adjacentNodes("large")) { 096 * if (synonymGraph.edgeValue(word, "large") > 0.5) { 097 * System.out.println(word + " is a synonym for large"); 098 * } 099 * } 100 * </code></pre> 101 * 102 * @author James Sexton 103 * @param <N> Node parameter type 104 * @param <V> Value parameter type 105 * @since 20.0 106 */ 107@Beta 108public interface ValueGraph<N, V> extends Graph<N> { 109 110 /** 111 * If there is an edge connecting {@code nodeU} to {@code nodeV}, returns the non-null value 112 * associated with that edge. 113 * 114 * <p>In an undirected graph, this is equal to {@code edgeValue(nodeV, nodeU)}. 115 * 116 * @throws IllegalArgumentException if there is no edge connecting {@code nodeU} to {@code nodeV}. 117 */ 118 V edgeValue(Object nodeU, Object nodeV); 119 120 /** 121 * If there is an edge connecting {@code nodeU} to {@code nodeV}, returns the non-null value 122 * associated with that edge; otherwise, returns {@code defaultValue}. 123 * 124 * <p>In an undirected graph, this is equal to {@code edgeValueOrDefault(nodeV, nodeU, 125 * defaultValue)}. 126 */ 127 V edgeValueOrDefault(Object nodeU, Object nodeV, @Nullable V defaultValue); 128 129 // 130 // ValueGraph identity 131 // 132 133 /** 134 * For the default {@link ValueGraph} implementations, returns true iff {@code this == object} 135 * (reference equality). External implementations are free to define this method as they see fit, 136 * as long as they satisfy the {@link Object#equals(Object)} contract. 137 * 138 * <p>To compare two {@link ValueGraph}s based on their contents rather than their references, see 139 * {@link Graphs#equivalent(ValueGraph, ValueGraph)}. 140 */ 141 @Override 142 boolean equals(@Nullable Object object); 143 144 /** 145 * For the default {@link ValueGraph} implementations, returns {@code 146 * System.identityHashCode(this)}. External implementations are free to define this method as they 147 * see fit, as long as they satisfy the {@link Object#hashCode()} contract. 148 */ 149 @Override 150 int hashCode(); 151}