org.openprovenance.prov.validation.matrix.SparseMatrix Maven / Gradle / Ivy
The newest version!
package org.openprovenance.prov.validation.matrix;
import java.io.Serializable;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.List;
import java.util.ArrayList;
/**
* Generic Class for sparsely populated matrices. The size of the matrix is dynamic, i.e.
* you can specify arbitrary row and column parameters.
*
* Another way to look at this class is as a "two-dimensional" map. Instead of a single key
* it uses a row and a column element to store and retrieve data elements.
*
* The public Interface Traverser allows to traverse the matrix generically. The Traverser object is passed
* into traverse(Traverser)
and is given the opportunity to work with each element of the matrix.
*/
public final class SparseMatrix //implements Serializable
{
private final int size1;
private final int size2;
final private List [] rows;
final private List [] cols;
public SparseMatrix(int size1, int size2) {
this.size1=size1;
this.size2=size2;
rows = new List[size1];
cols = new List[size2];
for (int i=0; i();
}
for (int j=0; j();
}
}
public List getRow(int row) {
return rows[row];
}
public List getCol(int col) {
return cols[col];
}
// The map where all matrix elements are stored.
private final Map matrixMap = new HashMap();
/**
* Returns the value found at the specified row and column of the matrix.
* Returns null if there's no value for the specified row and column.
* @param row Object
* @param col Object
* @return Object
*/
public Pair g(int row, int col)
{
Pair res=matrixMap.get(new Pair(row, col));
return res;
}
/**
* Sets the value of the matrix at the specified row and column.
* @param row Object
* @param col Object
* @param value a value
*/
public void set(int row, int col, int value)
{
Pair p=new Pair(row, col,value);
matrixMap.put(p, p);
rows[row].add(p);
cols[col].add(p);
}
public void setNoUpdate(int row, int col, int value)
{
Pair p=new Pair(row, col,value);
matrixMap.put(p, p);
}
public void remove(int row, int col)
{
Pair p=new Pair(row, col);
matrixMap.remove(p);
rows[row].remove(p);
cols[col].remove(p);
}
/**
* Returns a Set of all used "columns" in the matrix.
* @return Set
*/
public Set colSet()
{
Set colSet = new HashSet();
for (Iterator iterator = matrixMap.keySet().iterator(); iterator.hasNext();)
{
Pair pair = iterator.next();
colSet.add(pair.getSecond());
}
return colSet;
}
/**
* Returns a Set of all used "rows" in the matrix.
* @return Set
*/
public Set rowSet()
{
Set rowSet = new HashSet();
for (Iterator iterator = matrixMap.keySet().iterator(); iterator.hasNext();)
{
Pair pair = iterator.next();
rowSet.add(pair.getFirst());
}
return rowSet;
}
public void clear()
{
matrixMap.clear();
}
public boolean equals(Object obj)
{
if (this == obj)
{
return true;
}
if (!(obj instanceof SparseMatrix))
{
return false;
}
SparseMatrix other = (SparseMatrix) obj;
return this.matrixMap.equals(other.matrixMap);
}
public int hashCode()
{
return matrixMap.hashCode();
}
public String toString()
{
return "SparseMatrix (" + size1 + "," + size2 + " (" + matrixMap.size() + " ," + matrixMap + ") elements)";
}
public void floydWarshall (SparseMatrix next) {
floydWarshallWithIterator (next);
//System.out.println(" ---------------> maximum " + maximum);
}
/*
public void floydWarshallWithoutIterator (SparseMatrix next) {
for (int k=0; k col_k=getCol(k);
for (Pair pair_i_k: col_k) { // new ArrayList(col_k)
int i=pair_i_k.getFirst();
int count=0;
int d_i_k=pair_i_k.getValue();
List row_k=getRow(k);
for (Pair pair_k_j: row_k) {
int j=pair_k_j.getSecond();
int d_k_j=pair_k_j.getValue();
if ((i==k) || (k==j)) break;
int d_i_j=addAndPreserveStrictOrdering(d_i_k, d_k_j);
Pair m_i_j;
/* The following test is a deviation of the original Floyd-Warshall algorithm.
* Originally, one updates the matrix if it contains nothing in g(i,j), or if the new
* values is smaller (this allows to find the shortest path).
* Here instead, we update if we have a strict path d_i_j than can replace a non strict path.
* It is not guaranteed to be the shortest.
*/
if ((m_i_j=g(i,j))==null
//|| d_i_k+d_k_j < m_i_j // original algorithm: no need to find the optimum
)
{
// only remember we did an update, if we have have actually added something.
setNoUpdate(i,j,d_i_j); // avoid invalidating with row iterators
col[count]=j;
val[count]=d_i_j;
count++;
maximum=Math.max(maximum,d_i_j);
} else {
if (isStrictOrdering(d_i_j)) {
if (!(isStrictOrdering(m_i_j.getValue()))) {
m_i_j.value=d_i_j; //update the value in the matrix directly
maximum=Math.max(maximum,d_i_j);
}
}
}
}
for (int c=0; c maximum " + maximum);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy