
com.github.rinde.rinsim.geom.AbstractGraph Maven / Gradle / Ivy
/*
* Copyright (C) 2011-2016 Rinde van Lon, iMinds-DistriNet, KU Leuven
*
* 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.
*/
package com.github.rinde.rinsim.geom;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;
import java.util.Set;
import javax.annotation.Nullable;
import org.apache.commons.math3.random.RandomGenerator;
import com.google.common.base.Optional;
/**
* Abstract graph implementation providing basic implementations of several
* graph functions.
* @author Rinde van Lon
* @param The type of {@link ConnectionData} that is used at the
* {@link Connection}s.
*/
public abstract class AbstractGraph implements
Graph {
/**
* Create a new empty graph.
*/
public AbstractGraph() {
super();
}
@Override
public double connectionLength(Point from, Point to) {
checkArgument(hasConnection(from, to),
"Can not get connection length from a non-existing connection.");
final Optional connData = connectionData(from, to);
return connData.isPresent() && connData.get().getLength().isPresent()
? connData.get().getLength().get()
: Point.distance(from, to);
}
@Override
public void addConnection(Point from, Point to) {
addConnection(from, to, Optional.absent());
}
@Override
public void addConnection(Connection c) {
addConnection(c.from(), c.to(), c.data());
}
@Override
public void addConnections(Iterable extends Connection> connections) {
for (final Connection connection : connections) {
addConnection(connection);
}
}
@Override
public void merge(Graph other) {
addConnections(other.getConnections());
}
@Override
public void addConnection(Point from, Point to, E connData) {
addConnection(from, to, Optional.of(connData));
}
/**
* Adds a connection.
* @param from Start of the connection.
* @param to End of the connection.
* @param connData The connection data wrapped in an optional.
*/
protected void addConnection(Point from, Point to, Optional connData) {
checkArgument(!from.equals(to),
"A connection cannot be circular: %s -> %s ", from, to);
checkArgument(!hasConnection(from, to),
"Connection already exists: %s -> %s ", from, to);
doAddConnection(from, to, connData);
}
/**
* Must be overridden by implementors. It should add a connection between from
* and to. It can be assumed that the connection does not yet exist and that
* it is not circular.
* @param from Starting point of the connection.
* @param to End point of the connection.
* @param connData The data to be associated to the connection.
*/
protected abstract void doAddConnection(Point from, Point to,
Optional connData);
@Override
public boolean equals(@Nullable Object other) {
return Graphs.equal(this, other);
}
@Override
public abstract int hashCode();
@Override
public Point getRandomNode(RandomGenerator generator) {
checkState(!isEmpty(), "Can not find a random node in an empty graph.");
final Set nodes = getNodes();
final int idx = generator.nextInt(nodes.size());
int index = 0;
for (final Point point : nodes) {
if (idx == index++) {
return point;
}
}
throw new IllegalStateException();
}
@Override
public Optional setConnectionData(Point from, Point to, E connData) {
return changeConnectionData(from, to, Optional.of(connData));
}
@Override
public Optional removeConnectionData(Point from, Point to) {
return changeConnectionData(from, to, Optional.absent());
}
/**
* Change connection data. Precondition: connection from -> to exists.
* @param from Start point of connection.
* @param to End point of connection.
* @param connData The connection data used for the connection.
* @return old connection data or {@link Optional#absent()} if there was no
* connection data.
* @throws IllegalArgumentException if the connection between the nodes does
* not exist.
*/
protected Optional changeConnectionData(Point from, Point to,
Optional connData) {
checkArgument(hasConnection(from, to),
"The connection %s->%s does not exist.", from, to);
return doChangeConnectionData(from, to, connData);
}
/**
* Change connection data. It can be assumed that the connection exists.
* @param from Start point of connection.
* @param to End point of connection.
* @param connData The connection data used for the connection.
* @return old connection data or {@link Optional#absent()} if there was no
* connection data.
*/
protected abstract Optional doChangeConnectionData(Point from, Point to,
Optional connData);
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy