001    /*
002     * Copyright (C) 2008-2010 by Holger Arndt
003     *
004     * This file is part of the Universal Java Matrix Package (UJMP).
005     * See the NOTICE file distributed with this work for additional
006     * information regarding copyright ownership and licensing.
007     *
008     * UJMP is free software; you can redistribute it and/or modify
009     * it under the terms of the GNU Lesser General Public License as
010     * published by the Free Software Foundation; either version 2
011     * of the License, or (at your option) any later version.
012     *
013     * UJMP is distributed in the hope that it will be useful,
014     * but WITHOUT ANY WARRANTY; without even the implied warranty of
015     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016     * GNU Lesser General Public License for more details.
017     *
018     * You should have received a copy of the GNU Lesser General Public
019     * License along with UJMP; if not, write to the
020     * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
021     * Boston, MA  02110-1301  USA
022     */
023    
024    package org.ujmp.core.graphmatrix;
025    
026    import java.util.ArrayList;
027    import java.util.Collection;
028    import java.util.Collections;
029    import java.util.HashMap;
030    import java.util.List;
031    import java.util.Map;
032    
033    import org.ujmp.core.Coordinates;
034    import org.ujmp.core.collections.ArrayIndexList;
035    import org.ujmp.core.enums.ValueType;
036    import org.ujmp.core.exceptions.MatrixException;
037    import org.ujmp.core.util.CoordinateSetToLongWrapper;
038    
039    public class DefaultGraphMatrix<N, E> extends AbstractGraphMatrix<N, E> {
040            private static final long serialVersionUID = -6103776352324576412L;
041    
042            private final List<N> nodes = new ArrayIndexList<N>();
043    
044            private final Map<Coordinates, E> edges = new HashMap<Coordinates, E>();
045    
046            private final Map<Long, List<Long>> parents = new HashMap<Long, List<Long>>();
047    
048            private final Map<Long, List<Long>> children = new HashMap<Long, List<Long>>();
049    
050            public DefaultGraphMatrix() {
051            }
052    
053            public DefaultGraphMatrix(List<N> nodes) {
054                    this.nodes.addAll(nodes);
055            }
056    
057            public Collection<E> getEdgeList() {
058                    return edges.values();
059            }
060    
061            
062            public Iterable<long[]> availableCoordinates() {
063                    return new CoordinateSetToLongWrapper(edges.keySet());
064            }
065    
066            public List<N> getNodeList() {
067                    return nodes;
068            }
069    
070            public void setDirectedEdge(E value, long node1, long node2) {
071                    edges.put(new Coordinates(new long[] { node1, node2 }), value);
072            }
073    
074            public void addNode(N o) {
075                    nodes.add(o);
076            }
077    
078            public void removeEdge(long node1, long node2) {
079                    edges.remove(new Coordinates(new long[] { node1, node2 }));
080            }
081    
082            public void removeNode(N o) {
083                    nodes.remove(o);
084            }
085    
086            public E getEdgeValue(long node1, long node2) {
087                    return edges.get(new Coordinates(new long[] { node1, node2 }));
088            }
089    
090            public int getEdgeCount() {
091                    return edges.size();
092            }
093    
094            public int getNodeCount() {
095                    return nodes.size();
096            }
097    
098            
099            public void addDirectedEdge(long node1, long node2) {
100                    throw new MatrixException("not implemented!");
101            }
102    
103            
104            public void addUndirectedEdge(long node1, long node2) {
105                    throw new MatrixException("not implemented!");
106            }
107    
108            
109            public void clear() {
110                    // nodes.clear();
111                    edges.clear();
112                    parents.clear();
113                    children.clear();
114            }
115    
116            public void addChild(N node, N child) {
117                    throw new MatrixException("not implemented!");
118            }
119    
120            public int getChildCount(long nodeIndex) {
121                    List<Long> indices = children.get(nodeIndex);
122                    return indices == null ? 0 : indices.size();
123            }
124    
125            public N getNode(long index) {
126                    return nodes.get((int) index);
127            }
128    
129            public int getParentCount(long nodeIndex) {
130                    List<Long> indices = parents.get(nodeIndex);
131                    return indices == null ? 0 : indices.size();
132            }
133    
134            @SuppressWarnings("unchecked")
135            public List<Long> getParentIndices(long index) {
136                    List<Long> indices = parents.get(index);
137                    return indices == null ? Collections.EMPTY_LIST : indices;
138            }
139    
140            @SuppressWarnings("unchecked")
141            public List<Long> getChildIndices(long index) {
142                    List<Long> indices = children.get(index);
143                    return indices == null ? Collections.EMPTY_LIST : indices;
144            }
145    
146            public void insertNode(N node, long index) {
147                    nodes.add((int) index, node);
148            }
149    
150            public void removeDirectedEdge(long nodeIndex1, long nodeIndex2) {
151                    edges.remove(new Coordinates(new long[] { nodeIndex1, nodeIndex2 }));
152            }
153    
154            public void removeNode(long node) {
155                    nodes.remove((int) node);
156            }
157    
158            public boolean isDirected() {
159                    return directed;
160            }
161    
162            public void setDirected(boolean directed) {
163                    this.directed = directed;
164            }
165    
166            private boolean directed = true;
167    
168            public void setNode(N node, long index) {
169                    nodes.set((int) index, node);
170            }
171    
172            public void setObject(Object o, long row, long column) throws MatrixException {
173                    throw new MatrixException("not implemented!");
174            }
175    
176            public void setObject(Object o, int row, int column) throws MatrixException {
177                    throw new MatrixException("not implemented!");
178            }
179    
180            public void addEdge(N node1, N node2) {
181                    throw new MatrixException("not implemented!");
182            }
183    
184            public void addEdge(long nodeIndex1, long nodeIndex2) {
185                    throw new MatrixException("not implemented!");
186            }
187    
188            public void removeEdge(N node1, N node2) {
189                    throw new MatrixException("not implemented!");
190            }
191    
192            public void setEdge(E edgeObject, long nodeIndex1, long nodeIndex2) {
193                    int nmbOfNodes = nodes.size();
194                    if (nodeIndex1 >= nmbOfNodes)
195                            throw new MatrixException("accessed node " + nodeIndex1 + ", but only " + nmbOfNodes
196                                            + " available");
197                    if (nodeIndex2 >= nmbOfNodes)
198                            throw new MatrixException("accessed node " + nodeIndex2 + ", but only " + nmbOfNodes
199                                            + " available");
200                    edges.put(new Coordinates(nodeIndex1, nodeIndex2), edgeObject);
201                    List<Long> list = children.get(nodeIndex1);
202                    if (list == null) {
203                            list = new ArrayList<Long>();
204                            children.put(nodeIndex1, list);
205                    }
206                    list.add(nodeIndex2);
207    
208                    list = parents.get(nodeIndex2);
209                    if (list == null) {
210                            list = new ArrayList<Long>();
211                            parents.put(nodeIndex2, list);
212                    }
213                    list.add(nodeIndex1);
214    
215            }
216    
217            public void setEdge(E edgeObject, N node1, N node2) {
218                    throw new MatrixException("not implemented!");
219            }
220    
221            
222            public ValueType getValueType() {
223                    return ValueType.OBJECT;
224            }
225    
226    }