public TileGrid BuildRandomTileGrid() { //Clear the tilegrid. tileGrid = new TileGrid(gridDimension); Random RNG = new Random(); for (int row = 0; row < gridDimension; row++) { for (int col = 0; col < gridDimension; col++) { LPSolve.BuildInitialModel(minXFlux, maxXFlux, minYFlux, maxYFlux, tileGrid, boundaryConditions); List <FlowTile> validTiles = ValidTiles(row, col); FlowTile newTile = validTiles[RNG.Next(0, validTiles.Count - 1)]; /* * Console.WriteLine("(" + row + ", " + col + ")"); * Console.WriteLine("Top: " + newTile.Flux.topEdge); * Console.WriteLine("Right: " + newTile.Flux.rightEdge); * Console.WriteLine("Bottom: " + newTile.Flux.bottomEdge); * Console.WriteLine("Left: " + newTile.Flux.leftEdge); */ tileGrid.AddTile(row, col, newTile); LPSolve.FreeModel(); } } return(tileGrid); }
public List <int[]> ValidObstaclePositions() { /* * //Save the previous boundary conditions locally to reset after each test * int?[,][] previousBoundaryConditions = new int?[gridDimension, gridDimension][]; * * for (int row = 0; row < gridDimension; row++) * { * for (int col = 0; col < gridDimension; col++) * { * previousBoundaryConditions[row, col] = new int?[4]; * for (int i = 0; i < 4; i++) * { * previousBoundaryConditions[row, col][i] = * (boundaryConditions[row, col][i].HasValue ? (int?) boundaryConditions[row, col][i].Value : null); * } * } * } */ List <int[]> validObstaclePositions = new List <int[]>(); for (int row = 0; row < gridDimension; row++) { for (int col = 0; col < gridDimension; col++) { int?[] previousValues = new int?[4]; //Adds the obstacle to boundaryConditions. for (int i = 0; i < 4; i++) { previousValues[i] = (boundaryConditions[row, col][i].HasValue ? (int?)boundaryConditions[row, col][i].Value : null); boundaryConditions[row, col][i] = 0; } LPSolve.BuildInitialModel(minXFlux, maxXFlux, minYFlux, maxYFlux, tileGrid, boundaryConditions); if (LPSolve.IsFeasible()) { validObstaclePositions.Add(new int[] { row, col }); } //Free memory allocated to LP-model LPSolve.FreeModel(); //reset boundaryConditions for next test for (int i = 0; i < 4; i++) { boundaryConditions[row, col][i] = (previousValues[i].HasValue ? (int?)previousValues[i].Value : null); } } } foreach (int[] iArr in validObstaclePositions) { Console.WriteLine("row: " + iArr[0]); Console.WriteLine("col: " + iArr[1] + "\n"); } return(validObstaclePositions); }
/// <summary> /// Allows users to choose a valid flow tile in a given slot by plotting all the valid flow tiles using Python's matplotlib /// and having the user click on which tile they want to place in the slot. /// </summary> /// <param name="row"> Row index of the tile slot </param> /// <param name="col"> Column index of the tile slot </param> public FlowTile AskUserForTile(int row, int col) { LPSolve.BuildInitialModel(minXFlux, maxXFlux, minYFlux, maxYFlux, tileGrid, boundaryConditions); List <FlowTile> validTiles = ValidTiles(row, col); //If there is only one valid tile, there is no choice to be made so we simply add the tile to the tiling. if (validTiles.Count == 1) { Console.WriteLine("There was only one valid tile, so it was placed in the spot."); Console.WriteLine("Top flux: {0}, Right Flux: {1}, Bottom Flux: {2}, Left Flux {3}", validTiles[0].Flux.TopEdge, validTiles[0].Flux.RightEdge, validTiles[0].Flux.BottomEdge, validTiles[0].Flux.LeftEdge); Console.ReadLine(); return(validTiles[0]); } tileGrid.WriteToXML(PathToGridXML); WriteTilesToXML(validTiles, PathToValidTilesXML); //Settings for the plotting script in python. ProcessStartInfo start = new ProcessStartInfo(); start.FileName = Python; start.Arguments = string.Format("{0} {1} {2} {3} {4} {5}", PythonCreateTiling, gridDimension, row, col, PathToGridXML, PathToValidTilesXML); start.UseShellExecute = false; start.RedirectStandardOutput = true; string result; //Runs the python script for plotting using (Process process = Process.Start(start)) { using (StreamReader reader = process.StandardOutput) { result = reader.ReadToEnd(); Console.WriteLine(result); } } //Process python = Process.Start(start); //python.WaitForExit(); foreach (FlowTile tile in validTiles) { Console.WriteLine("Top flux: {0}, Right Flux: {1}, Bottom Flux: {2}, Left Flux {3}", tile.Flux.TopEdge, tile.Flux.RightEdge, tile.Flux.BottomEdge, tile.Flux.LeftEdge); } //Console.WriteLine("Which tile do you want at row {0}, column {1}. Type a number:", row, col); //var num = Convert.ToInt32(Console.ReadLine()); //python.Close(); //IMPORTANT! Frees allocated memory, removing this line will likely cause overflow errors. LPSolve.FreeModel(); return(validTiles[Convert.ToInt32(result)]); }
/// <summary> /// Finds the valid flow tiles to be put in a position given by row and column indices. /// The constraints are that edge fluxes should match and that the field needs to be divergence free. /// </summary> /// <param name="rowNumber">Row index in grid</param> /// <param name="colNumber">Column index in grid</param> /// <returns>List of valid tiles to put in that position</returns> /// <exception cref="ArgumentException"> /// If there already is a tile in the given position this exception is thrown. /// </exception> private List <FlowTile> ValidTiles(int rowNumber, int colNumber) { if (tileGrid.HasTile(rowNumber, colNumber)) { throw new ArgumentException("Tile already exists on that position"); } int[][] validFluxRanges = new int[4][]; for (int i = 0; i < 4; i++) { validFluxRanges[i] = new int[2]; } /* * int[] validTopFluxRange = new int[2]; * int[] validBottomFluxRange = new int[2]; * int[] validLeftFluxRange = new int[2]; * int[] validRightFluxRange = new int[2]; */ //Finds the restrictions on corner velocities Vector2?[] restrictions = velocityRestrictions(rowNumber, colNumber); //Finds all valid combinations of the allowed corner velocities. List <CornerVelocities> allowedCornerVelocities = cornerVelocityCombinations(restrictions); for (int i = 0; i < 4; i++) { LPSolve.SetEdgeToSolve(rowNumber, colNumber, (LPSolve.Direction)i, gridDimension, false); validFluxRanges[i][0] = LPSolve.SolveModel(); LPSolve.SetEdgeToSolve(rowNumber, colNumber, (LPSolve.Direction)i, gridDimension, true); validFluxRanges[i][1] = LPSolve.SolveModel(); } List <FlowTile> currentValidTiles = new List <FlowTile>(); //Create all possible FlowTiles given the bounds on flows. This set still needs to be filtered for (int i = validFluxRanges[0][0]; i <= validFluxRanges[0][1]; i++) { for (int j = validFluxRanges[1][0]; j <= validFluxRanges[1][1]; j++) { for (int k = validFluxRanges[2][0]; k <= validFluxRanges[2][1]; k++) { for (int l = validFluxRanges[3][0]; l <= validFluxRanges[3][1]; l++) { foreach (CornerVelocities cornerVelocities in allowedCornerVelocities) { Flux flux = new Flux(); flux.TopEdge = i; flux.RightEdge = j; flux.BottomEdge = k; flux.LeftEdge = l; currentValidTiles.Add(new FlowTile(innerTileGridDimension, flux, cornerVelocities)); } } } } } List <FlowTile> validTiles = LPSolve.FilterValidTiles(currentValidTiles, rowNumber, colNumber, gridDimension); Console.WriteLine("final number of tiles: " + validTiles.Count); foreach (FlowTile tile in validTiles) { Console.WriteLine("Top: " + tile.Flux.TopEdge); Console.WriteLine("Right: " + tile.Flux.RightEdge); Console.WriteLine("Bottom: " + tile.Flux.BottomEdge); Console.WriteLine("Left: " + tile.Flux.LeftEdge + "\n"); } return(validTiles); }