/*
 * Copyright (C) 2008-2015 by Holger Arndt
 *
 * This file is part of the Universal Java Matrix Package (UJMP).
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership and licensing.
 *
 * UJMP is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * UJMP is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with UJMP; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA  02110-1301  USA
 */

package org.ujmp.core.graphmatrix;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.ujmp.core.Coordinates;
import org.ujmp.core.collections.list.ArrayIndexList;
import org.ujmp.core.enums.ValueType;
import org.ujmp.core.util.CoordinateSetToLongWrapper;

public class DefaultGraphMatrix extends AbstractGraphMatrix {
	private static final long serialVersionUID = -6103776352324576412L;

	private boolean directed = true;

	private final List nodes = new ArrayIndexList();

	private final Map edges = new HashMap();

	private final Map> parents = new HashMap>();

	private final Map> children = new HashMap>();

	public DefaultGraphMatrix() {
	}

	public DefaultGraphMatrix(List nodes) {
		this.nodes.addAll(nodes);
	}

	public Collection getEdgeList() {
		return edges.values();
	}

	public Iterable availableCoordinates() {
		return new CoordinateSetToLongWrapper(edges.keySet());
	}

	public List getNodeList() {
		return nodes;
	}

	public void addNode(N o) {
		nodes.add(o);
	}

	public void removeNode(N o) {
		nodes.remove(o);
	}

	public int getEdgeCount() {
		return edges.size();
	}

	public int getNodeCount() {
		return nodes.size();
	}

	public void clear() {
		edges.clear();
		parents.clear();
		children.clear();
	}

	public int getChildCount(long nodeIndex) {
		List indices = children.get(nodeIndex);
		return indices == null ? 0 : indices.size();
	}

	public N getNode(long index) {
		return nodes.get((int) index);
	}

	public int getParentCount(long nodeIndex) {
		List indices = parents.get(nodeIndex);
		return indices == null ? 0 : indices.size();
	}

	@SuppressWarnings("unchecked")
	public List getParentIndices(long index) {
		List indices = parents.get(index);
		return indices == null ? Collections.EMPTY_LIST : indices;
	}

	@SuppressWarnings("unchecked")
	public List getChildIndices(long index) {
		List indices = children.get(index);
		return indices == null ? Collections.EMPTY_LIST : indices;
	}

	public void removeNode(long node) {
		nodes.remove((int) node);
	}

	public boolean isDirected() {
		return directed;
	}

	public void setDirected(boolean directed) {
		this.directed = directed;
	}

	public void setNode(N node, long index) {
		nodes.set((int) index, node);
	}

	public synchronized void setEdge(E edge, long nodeIndex1, long nodeIndex2) {
		int nmbOfNodes = nodes.size();
		if (nodeIndex1 >= nmbOfNodes) {
			throw new RuntimeException("accessed node " + nodeIndex1 + ", but only " + nmbOfNodes
					+ " available");
		}
		if (nodeIndex2 >= nmbOfNodes) {
			throw new RuntimeException("accessed node " + nodeIndex2 + ", but only " + nmbOfNodes
					+ " available");
		}
		if (edge == null) {
			edges.remove(Coordinates.wrap(nodeIndex1, nodeIndex2));
			List childrenNode1 = children.get(nodeIndex1);
			if (childrenNode1 != null) {
				childrenNode1.remove(nodeIndex1);
			}
			List parentsNode2 = parents.get(nodeIndex2);
			if (parentsNode2 != null) {
				parentsNode2.remove(nodeIndex2);
			}
		} else {
			edges.put(Coordinates.wrap(nodeIndex1, nodeIndex2), edge);
			List childrenNode1 = children.get(nodeIndex1);
			if (childrenNode1 == null) {
				childrenNode1 = new ArrayList();
				children.put(nodeIndex1, childrenNode1);
			}
			childrenNode1.add(nodeIndex2);

			List parentsNode2 = parents.get(nodeIndex2);
			if (parentsNode2 == null) {
				parentsNode2 = new ArrayList();
				parents.put(nodeIndex2, parentsNode2);
			}
			parentsNode2.add(nodeIndex1);
		}
	}

	public void setEdge(E edge, N node1, N node2) {
		long index1 = getIndexOfNode(node1);
		if (index1 == -1) {
			addNode(node1);
			index1 = getIndexOfNode(node1);
		}
		long index2 = getIndexOfNode(node2);
		if (index2 == -1) {
			addNode(node2);
			index2 = getIndexOfNode(node2);
		}
		setEdge(edge, index1, index2);
	}

	public ValueType getValueType() {
		return ValueType.OBJECT;
	}

	public E getEdge(long nodeIndex1, long nodeIndex2) {
		return edges.get(Coordinates.wrap(nodeIndex1, nodeIndex2));
	}

	public void removeEdge(E edge) {
		List coordinatesToDelete = new ArrayList();
		for (Coordinates c : edges.keySet()) {
			E e = edges.get(c);
			if (e == edge) {
				coordinatesToDelete.add(c);
			}
		}
		for (Coordinates c : coordinatesToDelete) {
			edges.remove(c);
		}
	}

	public void removeEdge(N node1, N node2) {
		setEdge(null, node1, node2);
	}

	public void removeEdge(long nodeIndex1, long nodeIndex2) {
		setEdge(null, nodeIndex1, nodeIndex2);
	}

}

 

Ads help maintain this website.