Commit 374e3a1d authored by Christian MOMON's avatar Christian MOMON
Browse files

Import changes from puck-core-2.3.63-sources.zip.

parent 28de9fc1
......@@ -8,6 +8,5 @@ public enum GraphType {
OreGraph,
TipGraph,
PGraph,
BinaryRelationGraph,
BimodalRelationGraph;
BinaryRelationGraph;
}
......@@ -31,7 +31,6 @@ import org.tip.puck.net.Net;
import org.tip.puck.net.workers.NetUtils;
import org.tip.puck.segmentation.Segmentation;
import org.tip.puck.util.LogHelper;
import org.tip.puck.util.Numberable;
import org.tip.puck.util.PuckUtils;
import fr.devinsy.util.StringList;
......@@ -174,13 +173,6 @@ public class PAJFile {
pajekString = PuckUtils.writePajekNetwork(graph, partitionLabels).toString();
}
break;
case BimodalRelationGraph: {
Graph<Numberable> graph = NetUtils.createBimodalRelationGraph(segmentation);
partitionLabels.add("Mode");
partitionLabels.add("Type");
pajekString = PuckUtils.writePajekNetwork(graph, partitionLabels).toString();
}
break;
default:
throw PuckExceptions.INVALID_PARAMETER.create("Unknown GraphType: [" + graphType + "]");
}
......
......@@ -1002,7 +1002,7 @@ public class Individual implements Comparable<Individual>, Numberable, Attributa
if (this.name == null) {
result = null;
} else {
result = this.name.trim().replaceAll(" / ", " ");
result = this.name.trim().replaceAll(" / ", "");
}
//
return result;
......
......@@ -92,23 +92,6 @@ public class RelationModel {
public Roles roles() {
return this.roles;
}
public int getRoleIndex (Role role){
int result;
result = 0;
for (Role thisRole : roles){
if (thisRole.equals(role)){
break;
}
result++;
}
//
return result;
}
public void setName(final String name) {
this.name = name;
......
......@@ -10,27 +10,20 @@ import org.tip.puck.net.KinType;
* @since Version 0.6
* @see Net#getBicomponent(Stack<Edge>, Edge, boolean)
*/
public class KinLink {
public class BicomponentEdge {
private Individual source;
private Individual target;
private KinType type;
/**
* The default constructor
*/
private KinLink() {};
private KinType kinType;
private int back;
public BicomponentEdge (Individual source, Individual target, KinType kinType, int back){
public KinLink (Individual v, Individual w, KinType kinType, boolean sym){
if (sym || v.getId() < w.getId()){
this.source = v;
this.target = w;
this.type = kinType;
} else {
this.source = w;
this.target = v;
this.type = kinType.inverse();
}
this.source = source;
this.target = target;
this.kinType = kinType;
this.back = back;
}
/**
......@@ -40,7 +33,7 @@ public class KinLink {
*/
@Override
public boolean equals (Object o){
return Arrays.equals(getKey(),((KinLink)o).getKey());
return Arrays.equals(getKey(),((BicomponentEdge)o).getKey());
}
/**
......@@ -82,22 +75,32 @@ public class KinLink {
* inverts the arc (permutes ego and alter and changes the line value accordingly)
* @return the edge in inverse representation
*/
private KinLink inverse (){
KinLink e = new KinLink();
e.source = target;
e.target = source;
e.type = invType();
return e;
private BicomponentEdge inverse (){
BicomponentEdge result;
result = new BicomponentEdge(target, source, invType(), back);
//
return result;
}
/**
* inverts the arc if alter coincides with a given Individual
* @param v the Individual to be checked
* @param ego the Individual to be checked
* @return the inverse arc if v is equal to alter, the same arc else
*/
public KinLink inverse (Individual v){
if (v==target) return inverse();
return this;
public BicomponentEdge adjusted (Individual ego){
BicomponentEdge result;
if (ego==source) {
result = this;
} else if (ego==target) {
result = inverse();
} else {
result = null;
}
//
return result;
}
/**
......@@ -107,7 +110,7 @@ public class KinLink {
private KinType invType (){
KinType result;
switch (type){
switch (kinType){
case SPOUSE: {
result = KinType.SPOUSE;
break;
......@@ -128,9 +131,19 @@ public class KinLink {
return result;
}
public KinType getType() {
return type;
public KinType getKinType() {
return kinType;
}
public int getBack() {
return back;
}
public String toString(){
return source+" "+target+" "+kinType+" "+back;
}
}
package org.tip.puck.net.workers;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import java.util.TreeMap;
import oldcore.trash.OldIndividual;
import oldcore.trash.OldNet;
import org.tip.puck.PuckException;
import org.tip.puck.net.Individual;
import org.tip.puck.net.Individuals;
import org.tip.puck.net.KinType;
import org.tip.puck.net.Net;
import oldcore.trash.OldIndividual;
import oldcore.trash.OldNet;
public class BicomponentWorker {
/**
* the collection of individuals to be transformed
*/
private Individuals individuals;
/**
* the number of steps
* <p> used for dsf search procedures
......@@ -30,7 +27,7 @@ public class BicomponentWorker {
/**
* the stack of edges of the maximal bicomponent
*/
private Stack<KinLink> bicomax;
private Stack<BicomponentEdge> bicomax;
/**
* the map of bicomponent sizes
*/
......@@ -46,13 +43,44 @@ public class BicomponentWorker {
*/
private int number;
private Map<Individual, Status> status;
public BicomponentWorker(Net net){
step = 0;
bicomax = new Stack<KinLink>();
bicomponents = new TreeMap<Integer,Integer>();
individuals = net.individuals();
private Stack<BicomponentEdge> bicomponentStack;
private Stack<BicomponentEdge> workingStack;
private Map<Individual,Integer> discovery;
/**
* true if all bicomponents are to be kept, false if only the maximal bicomponent shall be guarded
*/
private boolean all;
/**
* matrimonial true if matrimonial bicomponents are computed, false if standard bicomponents are computed
*/
private boolean matrimonial;
private enum Status {
WAITING,
ONGOING,
DONE;
}
public BicomponentWorker(Net net, boolean matrimonial, boolean all){
this.matrimonial = matrimonial;
this.all = all;
step = 0;
bicomax = new Stack<BicomponentEdge>();
bicomponents = new TreeMap<Integer,Integer>();
status = new HashMap<Individual,Status>();
for (Individual individual : net.individuals()){
status.put(individual, Status.WAITING);
}
}
/**
......@@ -79,97 +107,161 @@ public class BicomponentWorker {
public static Net getCore(Net net){
Net result;
BicomponentWorker worker = new BicomponentWorker(net);
result = worker.getMaximalBicomponent(true,true);
result = new BicomponentWorker(net,true,true).getMaximalBicomponent();
//
return result;
}
//Check Parameter "all"
/**
* gets the maximal (standard or matrimonial) bicomponent of the Net
* @param matrimonial true if matrimonial bicomponents are computed, false if standard bicomponents are computed
* @param all true if all bicomponents are to be kept, false if only the maximal bicomponent shall be guarded
* @see OldNet.CopyOfNet#setColors(int)
*/
private Net getMaximalBicomponent (boolean matrimonial, boolean all){
private Net getMaximalBicomponent (){
Net result;
Stack<KinLink> stack = new Stack<KinLink>();
Map<Individual,Integer> colors = new HashMap<Individual,Integer>();
Map<Individual,Integer> discovery = new HashMap<Individual,Integer>();
workingStack = new Stack<BicomponentEdge>();
bicomponentStack = new Stack<BicomponentEdge>();
discovery = new HashMap<Individual,Integer>();
List<Individual> list = new ArrayList<Individual>(status.keySet());
Collections.sort(list);
for (Individual individual: individuals){
if (colors.get(individual)==null) {
bicomp (individual,null,stack,0,KinType.CHILD,colors, discovery, matrimonial,all);
for (Individual individual: list){
if (status.get(individual)==Status.WAITING && isPossibleStartingPoint(individual)) {
bicomp (new BicomponentEdge(null,individual,null,0));
}
}
getBicomponent(stack,null,all);
getBicomponent(bicomponentStack,null,all);
report(bicomponents,volume);
result = fromEdges(bicomax);
return result;
}
/**
* <p>Algorithm from {@link http://www.ecst.csuchico.edu/~juliano/csci356/JAWAA/Bicomponents.html}
* @see OldNet#getMaximalBicomponent(boolean, boolean)
* @see elements.nodes.NewIndividual#bicomp(Individual, Stack, int, int, OldNet, boolean, boolean)
*/
public int bicomp (Individual ego, Individual p, Stack<KinLink> stack, int back, KinType egoKinType, Map<Individual, Integer> colors, Map<Individual,Integer>discovery, boolean matrimonial,boolean all){
// public int bicomp (final Individual ego, final Individual predecessor, int back, final KinType egoKinType){
public int bicomp (BicomponentEdge edge){
int back;
// Preorder processing
step++;
colors.put(ego, 1);
discovery.put(ego, step);
back = discovery.get(ego);
System.out.println(step+"\t"+edge);
status.put(edge.getTarget(), Status.ONGOING);
discovery.put(edge.getTarget(), step);
back = discovery.get(edge.getTarget());
// Standard procedure
for (KinType alterKinType : KinType.basicTypes()){
if (matrimonial && alterKinType == KinType.PARENT && egoKinType==KinType.CHILD) continue;
if (ego.getKin(alterKinType)==null) continue;
for (Individual alter : ego.getKin(alterKinType)){
if (alter!=null && (p==null || !alter.equals(p)) && (colors.get(alter)==null || colors.get(alter)<2)) {
back = bicomp1 (ego,alter, stack, back, alterKinType, colors, discovery, matrimonial,all);
// Special condition for matrimonial bicomponents
if (!matrimonial || alterKinType != KinType.PARENT || edge.getKinType()!=KinType.CHILD) {
for (Individual successor : edge.getTarget().getKin(alterKinType)){
if (!successor.equals(edge.getSource()) && (status.get(successor)!=Status.DONE)) {
System.out.println("\tNormal\t"+successor);
back = bicomp1 (new BicomponentEdge(edge.getTarget(),successor,alterKinType,back));
}
}
}
}
}
if (matrimonial && back<discovery.get(ego) && egoKinType==KinType.CHILD) {
for (Individual alter : ego.getParents()){
if (alter!=null && (p==null || !alter.equals(p)) && (colors.get(alter)==null || colors.get(alter)<2)) {
back = bicomp1 (ego,alter, stack, back, KinType.PARENT, colors, discovery,matrimonial,all);
// Supplementary procedure for leftovers of matrimonial bicomponents
if (matrimonial && back<discovery.get(edge.getTarget()) && edge.getKinType()==KinType.CHILD) {
for (Individual successor : edge.getTarget().getParents()){
if (!successor.equals(edge.getSource()) && (status.get(successor)!=Status.DONE)) {
System.out.println("\tSupplementary\t"+successor);
back = bicomp1 (new BicomponentEdge(edge.getTarget(),successor,KinType.PARENT,back));
}
}
}
colors.put(ego,2);
// Postorder processing
status.put(edge.getTarget(),Status.DONE);
System.out.println(step+"\t"+edge+" "+back);
//
return back;
}
public int bicomp1 (Individual ego, Individual a, Stack<KinLink> stack, int back, KinType type, Map<Individual, Integer> colors, Map<Individual,Integer>discovery, boolean matrimonial, boolean all){
KinLink e = new KinLink(ego,a,type,true);
stack.push(e);
if (colors.get(a)==null) { //0
int cback = bicomp (a,ego,stack,back,type,colors, discovery,matrimonial,all);
if (cback>discovery.get(ego)) {
// System.out.println("cut tail until "+e.getEgo());
clear(stack,e);
} else if (cback==discovery.get(ego)) {
if (matrimonial && e.inverse(ego).getType()==KinType.PARENT && stack.peek().inverse(ego).getType()==KinType.PARENT) {
// System.out.println("xcut tail until "+e.getEgo());
clear(stack,e);
// public int bicomp1 (Individual ego, Individual successor, int back, KinType alterKinType){
public int bicomp1 (BicomponentEdge edge){
int result;
// Inorder processing
bicomponentStack.push(edge);
if (status.get(edge.getTarget())==Status.WAITING) {
int cback = bicomp (edge);
// int cback = bicomp (successor,ego,back,alterKinType);
if (cback>discovery.get(edge.getSource())) {
System.out.println("\tcut tail until "+edge+" "+
clear(bicomponentStack,edge));
} else if (cback==discovery.get(edge.getSource())) {
// if (matrimonial && isStructuralChild(edge,bicomponentStack)) {
if (matrimonial && edge.adjusted(edge.getSource())!=null && edge.adjusted(edge.getSource()).getKinType()==KinType.PARENT && bicomponentStack.peek().adjusted(edge.getSource())!=null && bicomponentStack.peek().adjusted(edge.getSource()).getKinType()==KinType.PARENT) {
System.out.println("\txcut tail until "+edge+" "+
clear(bicomponentStack,edge));
} else {
// System.out.println("get Bicomponent until "+e.getEgo());
getBicomponent(stack,e,all);
/**
* Problem: edge source may be structural child within the bicomponent; so recursive bicomponent extraction may be necessary...
*/
System.out.println("\tget Bicomponent until "+edge+": "+bicomponentStack);
getBicomponent(bicomponentStack,edge,all);
}
}
back = Math.min(back, cback);
result = Math.min(edge.getBack(), cback);
} else {
back = Math.min(back, discovery.get(a));
System.out.println("\tOld "+edge);
result = Math.min(edge.getBack(), discovery.get(edge.getTarget()));
}
return back;
//
return result;
}
/**
* Starting condition for matrimonial bicomponents. Starting with structural children may lead to parental triads (when they are always accessed from elsewhere they are necessarily cut)
* @param individual
* @return
*/
private boolean isPossibleStartingPoint(Individual individual){
boolean result;
result = !matrimonial ||
(individual.numberOfParents()+individual.spouses().size()+individual.children().size() > 1 &&
(individual.isFertile() || individual.isNotSingle()));
//
return result;
}
......@@ -206,9 +298,7 @@ public class BicomponentWorker {
public static Net getMaximalBicomponent(Net net){
Net result;
BicomponentWorker worker = new BicomponentWorker(net);
result = worker.getMaximalBicomponent(false,false);
result = new BicomponentWorker(net,false,false).getMaximalBicomponent();
//
return result;
......@@ -218,26 +308,23 @@ public class BicomponentWorker {
public static Net getKernel(Net net){
Net result;
BicomponentWorker worker = new BicomponentWorker(net);
result = worker.getMaximalBicomponent(true,false);
result = new BicomponentWorker(net,true,false).getMaximalBicomponent();
//
return result;
}
public Net fromEdges (Stack<KinLink> edges) {
public Net fromEdges (Stack<BicomponentEdge> edges) {
Net result;
result = new Net();
while (!edges.isEmpty()){
KinLink edge = edges.pop();
BicomponentEdge edge = edges.pop();
Individual ego = result.getCloneWithAttributes(edge.getSource());
Individual alter = result.getCloneWithAttributes(edge.getTarget());
try {
NetUtils.setKin(result, ego, alter, edge.getType().inverse());
NetUtils.setKin(result, ego, alter, edge.getKinType().inverse());
} catch (PuckException e) {
// TODO Auto-generated catch block
e.printStackTrace();
......@@ -258,8 +345,8 @@ public class BicomponentWorker {
* @see OldNet.CopyOfNet#getMaximalBicomponent(boolean, boolean)
* @see elements.nodes.NewIndividual#bicomp(Individual, Stack, int, int, OldNet, boolean, boolean)
*/
public void getBicomponent (Stack<KinLink> stack, KinLink e, boolean all){
Stack<KinLink> bico = new Stack<KinLink>();
public void getBicomponent (Stack<BicomponentEdge> stack, BicomponentEdge e, boolean all){
Stack<BicomponentEdge> bico = new Stack<BicomponentEdge>();
if (e==null) bico = stack;
else {
bico.push(stack.pop());
......@@ -280,8 +367,22 @@ public class BicomponentWorker {
* @param e the limiting element
* @see OldIndividual#bicomp(OldIndividual, Stack, int, int, Net, boolean, boolean)
*/
private static <E>void clear (Stack<E> stack, E e){
/* private static <E>void clear (Stack<E> stack, E e){
while (stack.pop()!=e){};
} */
private static <E> List<E> clear (Stack<E> stack, E e){
List<E> result;
result = new ArrayList<E>();
E last = null;
while (last!=e){
last = stack.pop();
result.add(last);
}
//
return result;
}
......
......@@ -55,7 +55,6 @@ import org.tip.puck.report.Report;
import org.tip.puck.segmentation.Segment;
import org.tip.puck.segmentation.Segmentation;
import org.tip.puck.statistics.StatisticsWorker;
import org.tip.puck.util.Numberable;
import org.tip.puck.util.NumberablesHashMap.IdStrategy;
import org.tip.puck.util.PuckUtils;
import org.tip.puck.util.Value;
......@@ -929,13 +928,13 @@ public class NetUtils {
Individuals individuals = relation.getIndividuals();
// if (individuals.size()==2){
if (individuals.size()==2){
RelationModel model = relation.getModel();
Integer edgeValue = edgeValues.get(model);
Integer arcValue = arcValues.get(model);
if (edgeValue == null && arcValue == null){
if (model.roles().size()==1){
......@@ -943,53 +942,25 @@ public class NetUtils {
edgeValues.put(model, edgeValues.size()+1);
edgeValue = edgeValues.get(model);
} else if (model.roles().size()>1){
} else if (model.roles().size()==2){
arcValues.put(model, arcValues.size()+1);
arcValue = arcValues.get(model);
}
}