Commit 960d054f authored by Andrey Filippov's avatar Andrey Filippov
Browse files

tested conflicts with variable costs

parent 364204c4
Loading
Loading
Loading
Loading
+37 −0
Original line number Original line Diff line number Diff line
@@ -248,5 +248,42 @@ public class Conflict{
		return num_dual;
		return num_dual;
	}
	}


	/**
	 * Get directions from center and layers of the 2 non-center tiles involved in each triangular conflict
	 * Full triangle is center:nl1 -> dir1 -> dir2 -> center:nl2
	 * @return array of 2-tuples:{dir1, dir2}
	 */
	public int [][] getInvolvedTiles(){
		int [][] involved = new int [getNumConflicts()][2];
		int nt = 0;
		for (int i = 0; i < 4; i++){
			if (start_dirs[i + 0]) {
				involved[nt][0] =   i * 2;
				involved[nt++][1] = ((i * 2) + 2) % 8;
			}
			if (start_dirs[i + 4]) {
				involved[nt][0] =   ((i * 2) + 2) % 8;
				involved[nt++][1] = i * 2;
			}
			if (start_dirs[i + 8]) {
				involved[nt][0] =   i * 2;
				involved[nt++][1] = ((i * 2) + 1) % 8;
			}
			if (start_dirs[i + 12]) {
				involved[nt][0] =   ((i * 2) + 1) % 8;
				involved[nt++][1] = i * 2;
			}

			if (start_dirs[i + 16]) {
				involved[nt][0] =   i * 2;
				involved[nt++][1] = ((i * 2) + 7) % 8;
			}
			if (start_dirs[i + 20]) {
				involved[nt][0] =   ((i * 2) + 7) % 8;
				involved[nt++][1] = i * 2;
			}
		}
		return involved;
	}


}
}
+176 −2
Original line number Original line Diff line number Diff line
@@ -198,6 +198,34 @@ public class Conflicts {
			if (better? (num_ortho_dual < 0) : (num_ortho_dual > 0)) num++;
			if (better? (num_ortho_dual < 0) : (num_ortho_dual > 0)) num++;


		}
		}
		if (use_ood) {
			for (int i = 0; i < num_ortho_ortho_diag.length; i++){
				if (better?(num_ortho_ortho_diag[i] < 0):(num_ortho_ortho_diag[i] > 0)) num++;
			}
		}
		return num;
	}
	public int sumConflicts(
			boolean use_all,
			boolean use_odo,
			boolean use_ood)
	{
		int num = 0;
		if (use_all) {
			for (int i = 0; i < num_all_conflicts.length; i++){
				num += num_all_conflicts[i];
			}
		}
		if (use_odo) {
			for (int i = 0; i < num_ortho_diag_ortho.length; i++){
				num +=num_ortho_diag_ortho[i];
			}
		}
		if (use_ood) {
			for (int i = 0; i < num_ortho_ortho_diag.length; i++){
				num +=num_ortho_ortho_diag[i];
			}
		}
		return num;
		return num;
	}
	}
	
	
@@ -286,11 +314,157 @@ public class Conflicts {
		return conflicts;
		return conflicts;
	}
	}
	
	
	/**
	 * Calculate cost of all conflicts around supertile nsTile0 by adding "star" weight of each tile involved.
	 * Tile weight can be either from the planes[][] array or from the replacement values in replacement_val_weights
	 * (when the tiles configuration is not yet committed)
	 * @param nsTile0 supertile index to process
	 * @param scaleStartEnd for each conflict triangle add start and end tiles (at the center nsTile0) scaled by this value
	 * @param conflicts array of calculated conflicts (each is {start_layer, end_layer, direction/type bitmask} or null,
	 * in that case it will be calculated
	 * @param replacement_tiles a map of supertile indices to replacement indices (for replacement_neibs and
	 *        replacement_val_weights) or null. If not null, and entry for the supertile full index exists, 
	 *        replacement_neibs and replacement_val_weights will be used, otherwise planes[][] data.
	 *        replacement_tiles may be null, in that case planes[][] data will be used unconditionally.
	 * @param replacement_neibs array of neighbors to use instead of the planes data. First index is an index
	 *        of the replacement supertile (values in the  replacement_tiles map), second - layer number and
	 *        the 3-rd one - direction index for 8 connections: N, NE, E...NW. Value is the destination layer
	 *        number. Can be null if not used (when replacement_tiles is null)
	 * @param replacement_val_weights similar array for tile value/weight data (per-tile index, per layer).
	 *  The innermost data is a tuple {value, weight}
	 * @param tnSurface TileNeibs instance to navigate through the 2-d array encoded in linescan order
	 * @return sum ao the weights of all conflicts fro this tile
	 */
	
	public double getConflictsCost(
			int           nsTile0,
			double        scaleStartEnd, // include start and and layer tiles in the center in overall cost for each triangle (1.0)
			int [][]      conflicts, //
			HashMap<Integer,Integer> replacement_tiles, // null is OK
			int [][][]    replacement_neibs,               // null OK if  replacement_tiles == null
			double [][][] replacement_val_weights,
			TileSurface.TileNeibs tnSurface)
	{
		TilePlanes.PlaneData [][] planes = st.getPlanes();
		// generate conflicts if not provided
		if (conflicts == null) {
			conflicts = detectTriangularTileConflicts(
					nsTile0,
					replacement_tiles, //
					replacement_neibs,
					tnSurface);
		}
		double cost = 0.0;
		if (conflicts != null){
			Integer isTile = (replacement_tiles != null) ? replacement_tiles.get(nsTile0) : null;
			for (int nConfl = 0; nConfl < conflicts.length; nConfl++){
				Conflict conflict = new Conflict(nsTile0, conflicts[nConfl]);
				int start_layer = conflict.getStartLayer();
				int end_layer =   conflict.getEndLayer();
				int [] neibs1 = ((isTile == null) ?
						planes[nsTile0][start_layer].getNeibBest() :
							replacement_neibs[isTile][start_layer]);
				int [] neibs2 = ((isTile == null) ?
						planes[nsTile0][end_layer].getNeibBest() :
							replacement_neibs[isTile][end_layer]);

				int [][] involved = conflict.getInvolvedTiles();
				for (int nTri = 0; nTri < involved.length; nTri++){
					int [] nsTiles = {
							tnSurface.getNeibIndex(nsTile0, involved[nTri][0]),
							tnSurface.getNeibIndex(nsTile0, involved[nTri][1])};
					int [] layers = {neibs1[involved[nTri][0]], neibs2[involved[nTri][1]]};
					for (int it = 0; it < nsTiles.length; it++){
						Integer isTile1 = (replacement_tiles != null) ? replacement_tiles.get(nsTiles[it]) : null;
						if (isTile1 != null){
							cost += replacement_val_weights[isTile1][layers[it]][1];
						} else {
							cost += planes[nsTiles[it]][layers[it]].getStarValueWeight()[1];
						}
					}
				}
				if (scaleStartEnd != 0.0) {
					if (isTile != null){
						cost += scaleStartEnd * (replacement_val_weights[isTile][start_layer][1]+
								replacement_val_weights[isTile][end_layer][1]);
					} else {
						cost += scaleStartEnd * (planes[nsTile0][start_layer].getStarValueWeight()[1]+
								planes[nsTile0][end_layer].getStarValueWeight()[1]);
					}
				}
			}
		}
		return cost;
	}


	public double getConflictsCost(
			int           nsTile0,
			double        scaleStartEnd, // include start and and layer tiles in the center in overall cost for each triangle (1.0)
			int [][]      conflicts, //
			HashMap<Integer,Integer> replacement_tiles, // null is OK
			int [][][]    replacement_neibs,               // null OK if  replacement_tiles == null
			ConnectionCosts connectionCosts,
			TileSurface.TileNeibs tnSurface)
	{
		TilePlanes.PlaneData [][] planes = st.getPlanes();
		// generate conflicts if not provided
		if (conflicts == null) {
			conflicts = detectTriangularTileConflicts(
					nsTile0,
					replacement_tiles, //
					replacement_neibs,
					tnSurface);
		}
		double cost = 0.0;
		if (conflicts != null){
			Integer isTile = (replacement_tiles != null) ? replacement_tiles.get(nsTile0) : null;
			for (int nConfl = 0; nConfl < conflicts.length; nConfl++){
				Conflict conflict = new Conflict(nsTile0, conflicts[nConfl]);
				int start_layer = conflict.getStartLayer();
				int end_layer =   conflict.getEndLayer();
				int [] neibs1 = ((isTile == null) ?
						planes[nsTile0][start_layer].getNeibBest() :
							replacement_neibs[isTile][start_layer]);
				int [] neibs2 = ((isTile == null) ?
						planes[nsTile0][end_layer].getNeibBest() :
							replacement_neibs[isTile][end_layer]);

				int [][] involved = conflict.getInvolvedTiles();
				for (int nTri = 0; nTri < involved.length; nTri++){
					int [] nsTiles = {
							tnSurface.getNeibIndex(nsTile0, involved[nTri][0]),
							tnSurface.getNeibIndex(nsTile0, involved[nTri][1])};
					int [] layers = {neibs1[involved[nTri][0]], neibs2[involved[nTri][1]]};
					for (int it = 0; it < nsTiles.length; it++){
						cost += connectionCosts. getValWeightLast(
								nsTiles[it], // int nsTile,
								layers[it], // int nl,
								false)[1]; // boolean initialValue)
					}
				}
				if (scaleStartEnd != 0.0) {
					cost += scaleStartEnd * connectionCosts. getValWeightLast(
							nsTile0,     // int nsTile,
							start_layer, // int nl,
							false)[1];   // boolean initialValue)
					cost += scaleStartEnd * connectionCosts. getValWeightLast(
							nsTile0,     // int nsTile,
							end_layer, // int nl,
							false)[1];   // boolean initialValue)
				}
			}
		}
		return cost;
	}


	
	
	
	public int [][] detectTriangularTileConflicts(
	public int [][] detectTriangularTileConflicts(
			int nsTile0,
			int nsTile0,
			HashMap<Integer,Integer> replacement_tiles, //
			HashMap<Integer,Integer> replacement_tiles, // null is OK - will use only planes data
			int [][][] replacement_neibs,
			int [][][] replacement_neibs,               // null OK if  replacement_tiles == null
			TileSurface.TileNeibs tnSurface)
			TileSurface.TileNeibs tnSurface)
	{
	{
		TilePlanes.PlaneData [][] planes = st.getPlanes();
		TilePlanes.PlaneData [][] planes = st.getPlanes();
+43 −2
Original line number Original line Diff line number Diff line
@@ -36,10 +36,12 @@ public class ConnectionCosts {
	int [][][]     neibs_init;
	int [][][]     neibs_init;
	int []         mod_tiles;
	int []         mod_tiles;
	int []         all_tiles;
	int []         all_tiles;
	double [][][]  val_weights;
	double [][][]  val_weights; // initial values/weights
	double         init_val;
	double         init_val;
	double         init_weight;
	double         init_weight;
	double [][][]  last_val_weights; // last calculated
	HashMap<Integer,Integer> tile_map; // map from tile full index to index in neibs[] and 
	HashMap<Integer,Integer> tile_map; // map from tile full index to index in neibs[] and 
	HashMap<Integer,Integer> all_tile_map; // map from tile full index to index in val_weights[] and 


	public ConnectionCosts(
	public ConnectionCosts(
			double         orthoWeight,
			double         orthoWeight,
@@ -93,6 +95,11 @@ public class ConnectionCosts {
			tile_map.put(mod_tiles[i], i);
			tile_map.put(mod_tiles[i], i);
		}
		}
		
		
		all_tile_map = new HashMap<Integer,Integer>();
		for (int i = 0; i < all_tiles.length; i++){
			all_tile_map.put(all_tiles[i], i);
		}
		
		switch (steps){
		switch (steps){
		case 1:
		case 1:
			val_weights = getConnectionsCostSingleStep (
			val_weights = getConnectionsCostSingleStep (
@@ -110,6 +117,8 @@ public class ConnectionCosts {
					-1); // int        debugLevel)			
					-1); // int        debugLevel)			
		}
		}
		
		
		last_val_weights = val_weights;

		init_val = 0.0;
		init_val = 0.0;
		init_weight = 0.0; // should not change during update
		init_weight = 0.0; // should not change during update
		for (int isTile = 0; isTile < all_tiles.length; isTile++){
		for (int isTile = 0; isTile < all_tiles.length; isTile++){
@@ -125,6 +134,35 @@ public class ConnectionCosts {
		
		
		return neibs_init; // neighbors to clone
		return neibs_init; // neighbors to clone
	}
	}
	public double [] getValWeightLast(
			int nsTile,
			int nl,
			boolean initialValue)
	{
		Integer isTile = all_tile_map.get(nsTile);
		if ((isTile != null) && (isTile < 0)){
			System.out.println("isTile < 0");
		}
		if (nl < 0){
			System.out.println(" nl < 0");
		}
		if ((isTile != null) && (isTile >= 0)){
			return initialValue? val_weights[isTile][nl] : last_val_weights[isTile][nl];
		} else {
			return planes[nsTile][nl].getStarValueWeight();
		}
	}
	
	
	public double [] getValWeight()
	{
		double [] val_weight = {init_val,init_weight};
		return val_weight;
	}
	public double [][][] getValWeights()
	{
		return val_weights;
	}
	
	
	public double [][][] getConnectionsCostSingleStep (
	public double [][][] getConnectionsCostSingleStep (
			int [][][] neibs,	
			int [][][] neibs,	
@@ -272,7 +310,7 @@ public class ConnectionCosts {
					neibs,	
					neibs,	
					-1); // int        debugLevel)			
					-1); // int        debugLevel)			
		}
		}

		last_val_weights = vw;
		// calculate new cost
		// calculate new cost
		double new_value = 0.0;
		double new_value = 0.0;
		double new_weight = 0.0; // should not change during update
		double new_weight = 0.0; // should not change during update
@@ -288,6 +326,9 @@ public class ConnectionCosts {
		return new_value - init_val; // negative - improvement
		return new_value - init_val; // negative - improvement
	}
	}
	
	
	double [][][] getLastValueWeight(){
		return last_val_weights;
	}
	/**
	/**
	 * Calculate main eigenvalue of the current plane and all connected ones - used to estimate advantage of connection swap
	 * Calculate main eigenvalue of the current plane and all connected ones - used to estimate advantage of connection swap
	 * @param nsTile supertile index
	 * @param nsTile supertile index
Loading