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}