All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.metacsp.spatial.RCC.RCCConstraintSolver Maven / Gradle / Ivy

There is a newer version: 1.3.5
Show newest version
/*******************************************************************************
 * Copyright (c) 2010-2013 Federico Pecora 
 * 
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 * 
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 ******************************************************************************/
package org.metacsp.spatial.RCC;

import java.util.HashMap;
import java.util.Vector;

import org.metacsp.framework.Constraint;
import org.metacsp.framework.ConstraintSolver;
import org.metacsp.framework.Variable;

/**
 * This {@link ConstraintSolver} implements a path consistency algorithm
 * to check the consistency of constraint networks with RCC-8 (Region Connection Calculus) constraints.
 * 
 * @author Iran Mansouri
 *
 */
public class RCCConstraintSolver extends ConstraintSolver{

	/**
	 * 
	 */
	private static final long serialVersionUID = 9130340233823443991L;
	private int IDs = 0;
	private HashMap getVaribaleById = new HashMap();
	
	public RCCConstraintSolver() {
		super(new Class[]{RCCConstraint.class}, Region.class);
		this.setOptions(OPTIONS.AUTO_PROPAGATE);
	}

	@Override
	public boolean propagate() {
		
		if(this.getConstraints().length == 0) return true;
		for (int i = 0; i < this.getVariables().length; i++) {
			getVaribaleById.put(this.getVariables()[i].getID(), this.getVariables()[i]);
		}
		Vector> rccRels = createRCCCompleteNetwork(this.getConstraints());
		//System.out.println(PrintSpatialRelation(rccRels));
		if(RCCPathConsistency(rccRels)) 
			return true;
		//RCCPathConsistency(rccRels);
		//System.out.println(PrintSpatialRelation(rccRels));
		return false;
	}
	
	private boolean RCCPathConsistency(
			Vector> rccRels) {
		int numVars = this.getVariables().length;
		//need to cycle at least (numVars^2 - numVars) times
		int counter = numVars*numVars - numVars;
		boolean[][] mark = new boolean[numVars][numVars];
		
		for(int i = 0; i < numVars; i++) {
			for(int j = 0; j < numVars; j++) {
				if(i == j) mark[i][j] = false;
				else mark[i][j] = true;
			}
		}	
		
		while(counter != 0) { // while the set is not empty
			for(int i = 0; i < numVars; i++) {
				for(int j = 0; j < numVars; j++) {
					if(i == j) continue;
					if(mark[i][j]){
						mark[i][j] = false;	
						counter--; //remove from set
						for(int k = 0; k < numVars; k++) {
							if(k == i || k == j) continue;
							//process relation (k,j)
							//back up relation (k,j)
							RCCConstraint rcctmp = (RCCConstraint) rccRels.get(k).get(j).clone();
							//(k,j) <-- (k,j) n (k,i) + (i,j) 

							if(!updateRelation(rccRels.get(k).get(j), generateComposition(rccRels.get(k).get(i), rccRels.get(i).get(j))))
								return false;
							//if changed, must re-process (k,j)
							
							if(!compareRelation(rcctmp, rccRels.get(k).get(j))) {
								if(!mark[k][j]) {
									mark[k][j] = true;
									counter++;
								}
							}
							//process relation (i,k)
							//back up relation (i,k)
							rcctmp = (RCCConstraint)rccRels.get(i).get(k).clone();
							//(i,k) <-- (i,k) n (i,j) + (j,k)
							
							if(!updateRelation(rccRels.get(i).get(k), generateComposition(rccRels.get(i).get(j), rccRels.get(j).get(k))))
								return false;
							
							//if changed, must re-process (i,k)
							if(!compareRelation(rcctmp, rccRels.get(i).get(k))) {
								if(!mark[i][k]) {
									mark[i][k] = true;
									counter++;
								}
							}
						}//end of k loop	
					}
				}
			}
		}

		return true;
	}
	
	//return true when they are equal
	private boolean compareRelation(RCCConstraint first,
			RCCConstraint second) {
		
		boolean existed = false;
		for (int i = 0; i < first.types.length; i++) {
			existed = false;
			for (int j = 0; j < second.types.length; j++) {
				if(first.types[i] == second.types[j])
					existed = true;
			}
			if(!existed) return false;
		}
		
		return true;
	}

	private boolean updateRelation(RCCConstraint originalRealtions,
			Vector generateComposition) {
		

		Vector nonexists = new Vector();
		boolean exist = false;
		for (int i = 0; i < originalRealtions.getTypes().length; i++) {
			exist = false;
			for (int j = 0; j < generateComposition.size(); j++) {
				if(originalRealtions.getTypes()[i].equals(generateComposition.get(j))){
					exist = true;
					break;
				}
			}
			if(!exist) nonexists.add(i);
		}
		
		
		RCCConstraint.Type[] t = new RCCConstraint.Type[originalRealtions.getTypes().length - nonexists.size()]; 
		int j = 0;
		for (int i = 0; i < originalRealtions.getTypes().length; i++) {
			if(!nonexists.contains(i)){
				t[j] = originalRealtions.getTypes()[i];
				j++;
			}
		}		
		originalRealtions.setTypes(t);
		if(originalRealtions.getTypes().length == 0) return false;
//		for (int i = originalRealtions.getTypes().length - 1; i >= 0; i--) {
//			if(nonexists.contains(i))
//				originalRealtions.remove(i);
//		}
		return true;
	}

	private Vector generateComposition(RCCConstraint o1,
			RCCConstraint o2) {
		Vector cmprelation =  new Vector();
		for (int t = 0; t < o1.types.length; t++) {
			for (int t2 = 0; t2 < o2.types.length; t2++) {
				RCCConstraint.Type[] tmpType = RCCConstraint.transitionTable[o1.types[t].ordinal()][o2.types[t2].ordinal()];
				for(RCCConstraint.Type t3: tmpType){
					if(!cmprelation.contains(t3))				
						cmprelation.add(t3);
					
				}	
			}
		}
		return cmprelation;
	}
	
	private String PrintSpatialRelation(Vector> rccRels) {
		String ret = "";
		for(int i = 0; i < rccRels.size(); i++){
			for(int j = 0; j < rccRels.size(); j++){
					if(i == j) continue;
					ret += (i + " --> " +  j + " :");
						ret += (rccRels.get(i).get(j)+ "\n");
				}
		}
		return ret;
	}


	private Vector> createRCCCompleteNetwork(
			Constraint[] c) {
		
		Vector> rccRels = new Vector>();
		
		final class Coord {
			public int x, y;
			public Coord(int x, int y) { this.x = x; this.y = y; }
			public boolean equals(Object o) {
				if (!(o instanceof Coord)) return false;
				Coord oc = (Coord)o;
				return ((oc.x == x) && (oc.y == y));
			}
			public int hashCode() {
				return (x*31)^y;
			}
		}
		
		HashMap> multiple = new HashMap>();
		RCCConstraint[][] tmp = new RCCConstraint[this.getVariables().length][this.getVariables().length];
		int row = 0 , col = 0;
		for(int i = 0; i < c.length; i++){
			
			row = this.getID(c[i].getScope()[0]);
			col = this.getID(c[i].getScope()[1]);
			if (tmp[row][col] == null)
				tmp[row][col] = ((RCCConstraint)c[i]);
			else {
				Coord coord = new Coord(row,col);
				Vector vec = multiple.get(coord);
				if (vec == null) {
					vec = new Vector();
					vec.add(tmp[row][col]);
					multiple.put(coord, vec);
				}
				vec.add((RCCConstraint)c[i]);
			}
		}
		

		
		for(int i = 0; i < tmp.length; i++){
			Vector con = new Vector(); 
			for(int j = 0; j < tmp.length; j++){
				if(tmp[i][j] != null) {
					Coord coord = new Coord(i,j);
					if (!multiple.containsKey(coord)) {
						con.add(tmp[i][j]);
					}
					else{//if (a u b u c) u d = (a u b u c u d)
						Vector t = new Vector();
						for (int k = 0; k < multiple.get(coord).size(); k++) {
							for (int k2 = 0; k2 < multiple.get(coord).get(k).getTypes().length; k2++)
								t.add(multiple.get(coord).get(k).getTypes()[k2]);							
						} 
						tmp[i][j].setTypes(t.toArray(new RCCConstraint.Type[t.size()]));
						con.add(tmp[i][j]);
					}
				}
				else if (tmp[j][i] != null) {
					Coord coord = new Coord(j,i);
					if (!multiple.containsKey(coord)) {
						Vector t = new Vector();
						for (int k = 0; k < tmp[j][i].types.length; k++) {
							t.add(RCCConstraint.getInverseRelation(tmp[j][i].types[k]));
						}
						RCCConstraint inverse = new RCCConstraint(t.toArray(new RCCConstraint.Type[t.size()]));
						inverse.setFrom(tmp[j][i].getTo());
						inverse.setTo(tmp[j][i].getFrom());
						con.add(inverse);
					}
					else{
						Vector t = new Vector();
						for (int k = 0; k < multiple.get(coord).size(); k++) {
							for (int k2 = 0; k2 < multiple.get(coord).get(k).types.length; k2++) {
								t.add(RCCConstraint.getInverseRelation(multiple.get(coord).get(k).types[k2]));
							}
						}
						RCCConstraint inverse = new RCCConstraint(t.toArray(new RCCConstraint.Type[t.size()]));
						inverse.setFrom(tmp[j][i].getTo());
						inverse.setTo(tmp[j][i].getFrom());
						con.add(inverse);
					}
				}				
				//if no relation exists
				else{ 
					RCCConstraint universe = new RCCConstraint(createAllRCCRelation());
					universe.setFrom(getVaribaleById.get(i));
					universe.setTo(getVaribaleById.get(j));
					con.add(universe);
				}
			}
			rccRels.add(con);
		}	
		return rccRels;
	}

	private RCCConstraint.Type[] createAllRCCRelation() {
		
		Vector allRCCConstraint = new Vector();
		for (int i = 0; i < RCCConstraint.Type.values().length; i++) {
			allRCCConstraint.add(RCCConstraint.Type.values()[i]);
		}
		return allRCCConstraint.toArray(new RCCConstraint.Type[allRCCConstraint.size()]);
	}

	@Override
	protected boolean addConstraintsSub(Constraint[] c) {
		// TODO Auto-generated method stub
		return true;
	}

	@Override
	protected void removeConstraintsSub(Constraint[] c) {
		// TODO Auto-generated method stub
		
	}
	
	@Override
	protected Variable[] createVariablesSub(int num) {
		Region[] ret = new Region[num];
		for (int i = 0; i < num; i++) ret[i] = new Region(this, IDs++);
			return ret;
	}

	@Override
	protected void removeVariablesSub(Variable[] v) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void registerValueChoiceFunctions() {
		// TODO Auto-generated method stub
		
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy