예제 #1
0
        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);
        }
예제 #2
0
        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);
        }
예제 #3
0
        /// <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)]);
        }
예제 #4
0
        /// <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);
        }