Loading src/main/java/Conflict.java +37 −0 Original line number Original line Diff line number Diff line Loading @@ -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; } } } src/main/java/Conflicts.java +176 −2 Original line number Original line Diff line number Diff line Loading @@ -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; } } Loading Loading @@ -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(); Loading src/main/java/ConnectionCosts.java +43 −2 Original line number Original line Diff line number Diff line Loading @@ -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, Loading Loading @@ -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 ( Loading @@ -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++){ Loading @@ -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, Loading Loading @@ -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 Loading @@ -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 Loading
src/main/java/Conflict.java +37 −0 Original line number Original line Diff line number Diff line Loading @@ -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; } } }
src/main/java/Conflicts.java +176 −2 Original line number Original line Diff line number Diff line Loading @@ -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; } } Loading Loading @@ -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(); Loading
src/main/java/ConnectionCosts.java +43 −2 Original line number Original line Diff line number Diff line Loading @@ -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, Loading Loading @@ -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 ( Loading @@ -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++){ Loading @@ -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, Loading Loading @@ -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 Loading @@ -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