package uk.ac.rhul.cs.cl1.seeding;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.Serializable;
import java.io.StringReader;
import uk.ac.rhul.cs.cl1.growth.ClusterGrowthProcess;
import uk.ac.rhul.cs.graph.Graph;
import uk.ac.rhul.cs.graph.GraphAlgorithm;
import uk.ac.rhul.cs.utils.StringUtils;
/**
* Abstract seed nodeset generator class.
*
* A seed nodeset generator is an abstract algorithm that produces a set of candidate
* seed nodesets from a graph. These candidate nodesets will be passed on to a
* {@link ClusterGrowthProcess} during a {@link ClusterONEAlgorithm} to produce
* the clusters.
*
* Seed nodeset generators implement the {@link Iterable} interface, so the easiest
* way to get the set of seed nodesets is to iterate over it in a for loop.
*
* @author tamas
*/
public abstract class SeedGenerator extends GraphAlgorithm
implements Iterable<Seed>, Serializable {
/**
* Constructs a seed generator that is not associated to any graph yet.
*/
public SeedGenerator() {
this(null);
}
/**
* Constructs a seed generator that is associated to a given graph.
* @param graph the graph the seed generator will operate on
*/
public SeedGenerator(Graph graph) {
super(graph);
}
/**
* Returns the number of seeds that will be generated.
* If the number of seeds cannot be known in advance, -1 will be returned.
* @return the expected number of seeds generated by the generator, or -1 if the
* number of seeds is not known in advance.
*/
public abstract int size();
/**
* Returns an iterator that will generate seeds
*/
public abstract SeedIterator iterator();
/**
* Factory method that can construct seed generators from a simple string description.
* The following specifiers are recognised at the moment:
*
* <ul>
* <li><tt>nodes</tt> - generates a singleton seed for each node of the graph</li>
* <li><tt>edges</tt> - generates a seed containing the two endpoints for each edge of the graph</li>
* <li><tt>cliques</tt> - generates a seed for every maximal clique in the graph</li>
* <li><tt>stdin</tt> - reads seeds from the standard input. Each line in the standard
* input must contain node names spearated by spaces.
* <li><tt>file(<i>filename.txt</i>)</tt> - opens <tt>filename.txt</tt> and interprets
* each line as a seed set. Lines in the file must contain node names separated by
* spaces.</li>
* <li><tt>single(<i>node1</i>,<i>node2</i>,[...],<i>nodeN</i>)</tt> - generates a
* single seed with the given nodes.</li>
* </ul>
*
* @param specification the specification string
* @param graph the graph used by the constructed seed generator
* @throws InstantiationException if the specification string is invalid or some error
* occurred (e.g., file not found for a file based seed
* generator)
*/
public static SeedGenerator fromString(String specification, Graph graph) throws InstantiationException {
if (specification.equals("nodes"))
return new EveryNodeSeedGenerator(graph);
if (specification.equals("edges"))
return new EveryEdgeSeedGenerator(graph);
if (specification.equals("cliques"))
return new MaximalCliqueSeedGenerator(graph);
if (specification.equals("stdin"))
return new StreamBasedSeedGenerator(graph, System.in);
if (specification.startsWith("single(") && specification.endsWith(")")) {
String seeds = StringUtils.substring(specification, 7, -1);
StreamBasedSeedGenerator result = new StreamBasedSeedGenerator(
graph, new BufferedReader(new StringReader(seeds))
);
result.setDelimiters(", \n\t\r");
return result;
}
if (specification.startsWith("file(") && specification.endsWith(")")) {
String filename = StringUtils.substring(specification, 5, -1);
try {
return new FileBasedSeedGenerator(graph, filename);
} catch (FileNotFoundException ex) {
throw new InstantiationException("file not found: "+filename);
} catch (IOException ex) {
throw new InstantiationException("IO error while reading file: "+filename);
}
}
throw new InstantiationException("unknown seed generator type: "+specification);
}
/**
* Factory method that can construct seed generators from a simple string description.
*
* The constructed seed generator will not be associated to any given graph yet.
*
* @param specification the specification string
* @throws InstantiationException if the specification string is invalid
*/
public static SeedGenerator fromString(String specification) throws InstantiationException {
return fromString(specification, null);
}
}