Commit a10fbd98 authored by lafabregue's avatar lafabregue

Add the constraints objects

parent 4f3d6e14
......@@ -428,7 +428,7 @@ public abstract class ClusteringResult implements Serializable, MemoryFlush {
return getClusterMap();
}
abstract protected int[] getClusterMap();
abstract public int[] getClusterMap();
/**
* Remplace le resultat du clustering via un tableau, a chaque objet est
......
......@@ -256,7 +256,7 @@ public class SimpleClusteringResult extends ClusteringResult {
* @return la carte de classification
*/
@Override
protected int[] getClusterMap() {
public int[] getClusterMap() {
return this.clusterMap;
}
......
package jcl.clustering.constraints;
/**
* Class that represent a cannot-link constraint.
* It specified that two objects shouldn't be assigned to the same class.
*
* @author Baptiste LAFABREGUE
*/
public class CannotLinkConstraint extends Constraint {
/** The indexes of the indexes that cannot be in the same class */
final private int firstIndex;
final private int secondIndex;
/**
* Constructor
*
* @param firstIndex
* the index of on of the objects
* @param secondIndex
* the index of the second object
*/
public CannotLinkConstraint(int firstIndex, int secondIndex) {
super();
this.firstIndex = firstIndex;
this.secondIndex = secondIndex;
}
@Override
public String toString() {
return Constraint.CANOT_LINK_TYPE+";"+firstIndex+";"+secondIndex;
}
/**
* Return the first object of the link relation
*
* @return the index of the object
*/
public int getFirstIndex() {
return firstIndex;
}
/**
* Return the second object of the link relation
*
* @return the index of the object
*/
public int getSecondIndex() {
return secondIndex;
}
}
package jcl.clustering.constraints;
/**
* Class that represent a generic constraint.
*
* @author Baptiste LAFABREGUE
*
*/
public abstract class Constraint {
/** All the types of possible constraints */
static final public int LABEL_TYPE = 1;
static final public int MUST_LINK_TYPE = 2;
static final public int CANOT_LINK_TYPE = 3;
public Constraint() {
}
/**
* Retrieve the sting representation of the constraints.
* This method is used for export purpose, so it should respect the following pattern :
* <type id of constraints>;<index(es) of elements>;<other properties>
*/
@Override
public abstract String toString();
}
package jcl.clustering.constraints;
/**
* Class that represent a label constraint.
* It indicates that an object should be assigned to a specified class.
*
* @author Baptiste LAFABREGUE
*
*/
public class LabelConstraint extends Constraint {
final private int index;
final private int classID;
public LabelConstraint(int index, int classID) {
super();
this.index = index;
this.classID = classID;
}
/**
* Return the object of the label relation
*
* @return the index of the object
*/
public int getIndex() {
return index;
}
@Override
public String toString() {
return Constraint.LABEL_TYPE+";"+index+";"+classID;
}
}
package jcl.clustering.constraints;
/**
* Class that represent a must-link constraint.
* It specified that two objects shouldn't be assigned to the same class.
*
* @author Baptiste LAFABREGUE
*/
public class MustLinkConstraint extends Constraint {
/** The indexes of the indexes that must be of the same class */
final private int firstIndex;
final private int secondIndex;
/**
* Constructor
*
* @param firstIndex
* the index of on of the objects
* @param secondIndex
* the index of the second object
*/
public MustLinkConstraint(int firstIndex, int secondIndex) {
super();
this.firstIndex = firstIndex;
this.secondIndex = secondIndex;
}
@Override
public String toString() {
return Constraint.MUST_LINK_TYPE+";"+firstIndex+";"+secondIndex;
}
/**
* Return the first object of the link relation
*
* @return the index of the object
*/
public int getFirstIndex() {
return firstIndex;
}
/**
* Return the second object of the link relation
*
* @return the index of the object
*/
public int getSecondIndex() {
return secondIndex;
}
}
......@@ -177,7 +177,7 @@ public class IntArrayMask implements Mask {
}
public boolean hasNext() {
return this.cursor < end;
return this.cursor <= end;
}
public Integer next() {
......
......@@ -45,6 +45,8 @@ public class ImageSampler extends Sampler {
private int startX = 0;
private int startY = 0;
private int[] mandatoriesIndexes = null;
/**
* Constructor from a sequence of images
......@@ -175,6 +177,10 @@ public class ImageSampler extends Sampler {
@Override
public DataObject[] getDataObjects() {
if (mandatoriesIndexes.length > sizeByCount) {
throw new IndexOutOfBoundsException("The number of mandatory pixels"
+ " is bigger than the expeted sample size");
}
updateRAMAvailable();
if (readers.size() > 1) {
return getDataFromImagesSequence();
......@@ -185,15 +191,30 @@ public class ImageSampler extends Sampler {
@Override
public DataObject[] getDataObjects(final Mask mask) {
int mandatoryPixelCount = unmaskedPixelsCount(mandatoriesIndexes, mask);
if (mandatoryPixelCount > sizeByCount) {
throw new IndexOutOfBoundsException("The number of mandatory pixels"
+ " is bigger than the expeted sample size");
}
if (mask.getCarinality() < sizeByCount) {
throw new IndexOutOfBoundsException("The nnumber of unmasked pixels"
throw new IndexOutOfBoundsException("The number of unmasked pixels"
+ " is lower than the expeted sample size");
}
if (readers.size() > 1) {
return getDataFromImagesSequence(mask);
return getDataFromImagesSequence(mask, mandatoryPixelCount);
} else {
return getDataFromOneImage(mask);
return getDataFromOneImage(mask, mandatoryPixelCount);
}
}
private int unmaskedPixelsCount(int[] mandatoriesIndexes, Mask mask) {
int count = 0;
for(int i : mandatoriesIndexes) {
if (!mask.isMaksed(i)) {
count++;
}
}
return count;
}
/**
......@@ -231,10 +252,12 @@ public class ImageSampler extends Sampler {
*
* @param mask
* the mask filter
* @param mandatoryPixelCount
* the number of mandatory pixels that will be added
*
* @return the sample
*/
private DataObject[] getDataFromOneImage(final Mask mask) {
private DataObject[] getDataFromOneImage(final Mask mask, int mandatoryPixelCount) {
DataObject[] result = new DataObject[sizeByCount];
int x = 0;
int y = 0;
......@@ -323,10 +346,12 @@ public class ImageSampler extends Sampler {
*
* @param mask
* the mask filter
* @param mandatoryPixelCount
* the number of mandatory pixels that will be added
*
* @return the sample
*/
private DataObject[] getDataFromImagesSequence(final Mask mask) {
private DataObject[] getDataFromImagesSequence(final Mask mask, int mandatoryPixelCount) {
DataObject[] result = new DataObject[sizeByCount];
int x = 0;
int y = 0;
......@@ -472,7 +497,7 @@ public class ImageSampler extends Sampler {
long allocatedMemory = (Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory());
long presumableFreeMemory = Runtime.getRuntime().maxMemory() - allocatedMemory;
// we just tack the 2/3rd of the memory available;
presumableFreeMemory *= 0.01;
presumableFreeMemory *= 0.05;
long memoryPerReader = presumableFreeMemory / readers.size();
for(StreamedImageReaderWrapper r : readers) {
......@@ -935,4 +960,10 @@ public class ImageSampler extends Sampler {
}
}
@Override
public void setMandatoriesIndex(int[] indexes) {
mandatoriesIndexes = indexes;
Arrays.sort(mandatoriesIndexes);
}
}
......@@ -154,7 +154,7 @@ public abstract class Sampler implements MemoryFlush, Cloneable, Serializable {
* Return an iterator that retrieve the whole source data representation
* between two indexes filtered by a mask.
* This method should retrieve the data in the most straight forward manner,
* refer to the implementation for more details
* refer to the implementation for more details.
*
* @param mask
* the mask filter
......@@ -167,15 +167,23 @@ public abstract class Sampler implements MemoryFlush, Cloneable, Serializable {
public abstract Iterator<DataObject> getWholeData(final Mask mask, int start, int end);
/**
* <p>
* Method to retrieve a specific element from the origin source data.
* Be aware that this method shouldn't be used to read the whole set,
* use the Iterator instead.
* </p>
*
* @param index
the index of the element to return
* @return the element at the index i in the source data
*/
abstract public DataObject getWholeDataDataObject(final int index);
/**
* Give a set of indexes to include in the sample.
* Note that the mask have priority over those indexes,
* so they will not be included if they are masked.
*
* @param indexes
* the set of indexes
*/
abstract public void setMandatoriesIndex(int[] indexes);
}
package jcl.learning.methods.monostrategy.kmeans;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Vector;
import org.joda.time.DateTime;
import org.joda.time.Seconds;
import jcl.clustering.ClusteringResult;
import jcl.data.Data;
import jcl.data.DataObject;
......@@ -137,12 +132,11 @@ public class LearningResultKmeans extends LearningResult {
*/
@Override
public ClusteringResult classify(Data data) {
DateFormat dtf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
DateTime startT = DateTime.now();
long startT = System.nanoTime();
System.out.println("start at "+startT);
int clusterMap[] = this.clusterAffectation(data,false);
DateTime endT = DateTime.now();
System.out.println("endat "+endT + " total of "+ Seconds.secondsBetween(startT, endT).getSeconds());
long endT = System.nanoTime();
System.out.println("endat "+ endT + " total of "+ (endT - startT)/1000000000l);
ClusteringResult result = null;
......
......@@ -120,6 +120,16 @@ public class LightHardSeed extends KmeansSeed implements Cloneable, Serializable
this.clusterMap = clusterMap;
this.count = count;
}
/**
* Set the current cluster affectation to use
*
* @param clusterMap
* the cluster affectation
*/
public void setClusterMap(int[] clusterMap) {
setClusterMap(clusterMap, IntArrayMask.objectInMask(clusterMap, id));
}
/**
* Return the current cluster affectation
......@@ -147,18 +157,6 @@ public class LightHardSeed extends KmeansSeed implements Cloneable, Serializable
this.id = id;
}
/**
* Set the current cluster affectation to use
*
* @param clusterMap
* the cluster affectation
* @param count
* the number of object in this cluster
*/
public void setClusterMap(int[] clusterMap) {
setClusterMap(clusterMap, IntArrayMask.objectInMask(clusterMap, id));
}
/**
* <p>
* Duplicate the Object
......@@ -193,7 +191,7 @@ public class LightHardSeed extends KmeansSeed implements Cloneable, Serializable
int nbAttributes = data.getOneDataObject().getNbAttributes();
final DataObject res = new DataObject(nbAttributes);
final AttributeSequence[][] tab = new AttributeSequence[nbAttributes][count];
final AttributeSequence[][] tab = new AttributeSequence[nbAttributes][mask.getCarinality()];
Iterator<DataObject> iter = data.iterator(mask);
int i = 0;
......@@ -215,7 +213,7 @@ public class LightHardSeed extends KmeansSeed implements Cloneable, Serializable
int nbAttributes = data.getOneDataObject().getNbAttributes();
final DataObject res = new DataObject(nbAttributes);
final AttributeMultiDimSequence[] tab = new AttributeMultiDimSequence[count];
final AttributeMultiDimSequence[] tab = new AttributeMultiDimSequence[mask.getCarinality()];
Iterator<DataObject> iter = data.iterator(mask);
int i = 0;
......
......@@ -442,7 +442,7 @@ public class StreamedImageReaderWrapper implements Iterable<double[]>, MemoryFlu
// on garde 4 MB pour les objets annexes, valeur estimee empiriquemnt
if (maxRAM < ramPerTile + 4000000) {
throw new IOException("The allowed RAM amout is too small to read this file. The minimum tile size is "+
throw new IOException("The allowed RAM ("+maxRAM/1000+"KB) amout is too small to read this file. The minimum tile size is "+
ramPerTile/1000+" KB + 4 MB for on side computing.");
} else {
int nbTiles = (int) ((maxRAM - 4000000)/ramPerTile);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment