how to find the best postions in a matrix? - java

I need to build a seating system for a Java course I am attending.
Given the amount of seats required, the system needs to give the best positions in the hall.
By best positions I mean that the seats have to be as close as possible to one another, and as close as possible to the mid row.
Now, some definitions:
Distance between seats - The minimal number of cells in the matrix that separates the two cells. For example, the distance between the cell [3,3] and [2,2] is 1.
I thought about doing a recursive backtracking function that will give me a list of all possible positions, which I'll then iterate through, grading it by the distance between all the positions and the distance of all the seats from the mid row.
This solution would be extremely inefficient. Does anyone have a better idea?

I am not sure how Dijkstra applies here, unless i misunderstand the problem.
Is your preference is first to adjacent seating, and then to distance to middle row?
i.e. Say you need to find 5 seats, and you have five consecutive seats available in first row, and then 4 available seats in middle row, then I am assuming the solution would be to choose 5 seats in first row.
So, given a required seat number N...
What I would do, is to start with middle row, pick an empty seat, and "grow" a region by flagging all adjacent empty seats. If the region is size N, then you are done. If its not, then I would push this region on a stack (say location of the "start of growth" and number of empty seats in that cluster). Then I would move on along the middle row marking/growing such regions. After middle row I would move one up and then one below. Then two up and two below, etc, until entire matrix is covered. The trick is, keep finding empty clusters until you hit one that is of size N. If you process the entire matrix and no such cluster exists, you can comeback to the stack and "smartly" pick empty clusters that add up to at least N.
Hope that helps. Fun problem.

Related

How to generate random board for a game in java but according to specefic conditions?

I am making a board game for college project and it needs to be done in java,
the part that i'm stuck in is generating the board game now imagine with me we have a square shaped board and its size is variable meaning the player decides at the beginning of the game,
and the board is composed of Cells i have a class defined that represents the cell (UML of class below)
and the board is just a 2 dimension array of cells (UML of the game class) and each cell has a biome (MOUNTAIN, PLAIN, DESERT, FOREST, OCEAN) the biomes are defined in a enum,
now my problem is i need to generate a random board for each game and the borad needs to fulfill two conditions:
2/3 of the board must be OCEAN
a MOUNTAIN or PLAIN or FOREST or DESERT must have at least one neighbor that is not OCEAN biome and by neighbor i mean in its north, south, east or west.
The first condition is easy to implement but the second one i don't know how to i looked around on the net but nothing is similar to my condition.
There is an example of a board in the image below (blue cells are OCEAN, yellow is DESERT, light green is PLAIN, green is FOREST and brown is MOUNTAIN).
Code of enum of biomes
public enum Biome {
MOUNTAIN, PLAIN, DESERT, FOREST, OCEAN;
}
I guess you will fill your board row by row or column by column.
You know:
Size of the board
How much must be ocean
How much can be other (save how much can be other ie int nonOceanBiomeLeft)
how much you have already filled
while you fill up, for each field you decide randomly (depending on its weight) what you will set. When you place a non-Ocean biome you reduce nonOceanBiomeLeft by one. If it is already nearby another non-Ocean you stop here for that field, otherwise you need to reduce nonOceanBiomeLeft one more time and add one to something like int nonOceanBlocked (if your new field is without neighbor), this is to make sure you do not create a new noOcean biome somewhere and have none left to have the conditions fulfilled. So wenn you have none left you cannot create a noOcean biome.
If you have nonOceanBlocked > 0 you need to watch for the neighbor in the row above if it is an alone nonOcean biome (so save the neighbor info for each field or calculate it on the fly). If your neighbor in the row above is alone you need to add a noOcean and you remove one from nonOceanBlocked Since this one has a neighbor you don't need to increase nonOceanBlocked again.
Additionally if you create a new noOcean biome and the last field was an alone noOcean you can decrease nnoOceanBlocked too.
Be careful with
The last row: there you need to give the neighbors immediately and cannot wait for the next row, since there will be none.
If only nonOceanBiomeLeft is equal to one you cannot place it somewhere it has no neighbor, since you would need to d
This is only a theoretical description of what you could do, but for a college project I guess you should do most of the work yourself ;)
I hope it helps you as a starting point for the filling of the board.

Coin collector’s problem with two backtracking steps allowed

So I have the coin collector’s problem where several coins are placed in a cells of a matrix with dimensions n x m. With varying amount of coins on each cell. A man in the upper left cell of the matrix (meaning 0,0) and he has to collect as many coins as possible but he can only move to the cell to the right of him(i,j+1) or down (i+1,j) and the task is to get to cell (n,m) with as many coins as possible.
I know that the solution to this problem can be found by using dynamic programming and
Setting up the recurrence
F(0,0) = F(0,0)
F(0,j) = F(0,j) + F(0,j-1) for 1<=j<=m
F(i,0) = F(i,0) + F(i-1,0) for 1<=i<=n
F(i,j) = F(i,j) + max(F(i-1,j) + F(i,j-1)) for 1<=i<=n, 1<=j<=m
And we iterate over all the cells and then we simply get the value that is at F(n,m)
I forgot to mention this but we know how much coins there are in each cell. So we don't need to discover this information by traveling.
However the twist now is, the man is allowed to backtrack two steps, these two steps either separately as one step each at two different points or as one big step together at one single point. Meaning at some point along the road, he can either go forward or down and collect the coins on that cell, and then go backwards again. How would I go about modeling this? What’s the right approach to have? I'm not necessarily interested in the code required to make this work as much as I am in what the proper theory or way to go about this is, that said I don't mind reading code in any language.
Thanks in advance

Issues with simple algorithm for automatic assembly of jigsaw puzzles (with rectangular tiles) in Swing

I needed to design solver for puzzle, that is splitted in rectangular tiles (several rows and columns) with:
BufferedImage subImage =
image.getSubimage(y, x, dWidth, dHeight)
then resized with some ratio < 1.0:
BufferedImage resized = new BufferedImage(newWidth, newHeight, original.getType());
The idea behind my algorithm is to sum the difference between every appropriate pixels of current tile side and all other opposite tiles sides -
for example for right edge - I define such code:
for(Side s:reverseSides) { ...
{for(int i=0;i<height;i++) //checking current tile's right side
int rgbValue1=image.getRGB(width-1,i); //right side rgb values of current tile
int rgbValue2=imageN.getRGB(0,i); //left side rgb values of other tiles
....
int diff=|rgbValue1-rgbValue2|;
sum+=diff;
}
}
According to some algorithm, I start with some side whose sum of
rgbvalues is in the very midth of the whole range of such sums of all
sides (sortinglistBySum/2). Then I find minimal sum for with all
opposites sides, and traverse all other 3 sides of this Tile, then go
for Tiles, that has at least one already processed side, stored in
queue untill all sides are processed in consecutive fashion.
But first big issue, not expected, is in that this minimal sum for
about 80 pixels (in width or height) is around 50-70 000 000
units(RGB), when maximal could be more over 1000 000 000. So this
minimal sum, and even one difference for example first/second/Npixel
getRGB(width-1,1) - getRGB(0,1) -- is big enough. Indeed before splitting -
the difference between pixel position in adjacent edges
should be just 1 pixel??
So, in this case if left tile "right edge index" width-1=80, then 0
index in matching left side of right tile should be 81. Or at least
difference could be 2- if one vertical pixel line is lost when image
is splitted, and division of image width by number of columns does
not produce integer value (I suppose that it is not real image so no
pixels should be lost technically, just mathematically).
But when I calculate sum of diff. of two adjacent vertical (or
horizontal) lines of pixels in one tile - getRGB(width-2,i) -
getRGB(width-1,i) - it produce far lower values - some about 5-7 000
000. getRGB(width-3,i) - getRGB(width-1,i) - 30-40 000 000. So I do not undestand why such big difference between adjacent pixels sets of
original image?
The another issue is that when I found reverse side with minimal
difference I check minimal sum of difference for this opposite side
with reverse sides for it - and only if there is mutual match of sum
of diff. I define these sides as adjacent, also restricted if this
common minimal sum are less then some threshhold value defined
empirically by myself - in my case I suppose it about 150 000 000
(RGB diff.), but it is just approximation.
But there is third, probably most difficult issue - how check if this
matched side(s) is not edge side of the whole image, even there is
mutual match of sums, and less then threshold but in practice these
sides should not be matched as they are not adjacent in original
picture?!
This approach works relatively fine, except a lot of aspects to take
into account, as well as difficulties of moving and changing grid
cells in Java Swing layout.For example matching of the "single edge"
issue happened in my third testing image, in one of the last
iteration, but it could happened also at the start.Threshold value is
in some infrequent cases above for no-mathcing sides (that indeed
mutually matched with minimal sums), or under the really matching
sides.
So what are suggestions and references for simple assured
algorithms, what more reliable edges checking and patterns to use? Why so big sum of difference of rgb values of adjacent sides??
I have read even before, that it should sum difference of square rgb values, but what it changes? Also read suggestions to have some statistically based algorithm so probably check all combinations - checking combination of edge traversing from every present edge (not just one) and then choose optimal combination.

2D Arrays Battleship place random ships

Hi, I just started to create a battleship game and I would like to know how to place random ships in my 2D Array. Here is the code for 2D Array.
public class javaapplication24 {
public static void main(String[] args) {
int[][] table = new int[10][10];
int i,j,k;
for(i=0;i<table.length;i++){
for(j=0;j<table.length;j++){
System.out.print(table[i][j]+" ");
}
System.out.println();
}
}
}
The problem that you have undoubtedly noticed is that as each ship is placed, it rules out possibilities of where subsequent ships can be placed. The easiest way around the difficulty is just trial and error. First write a function for randomly placing a ship of a given size somewhere on the board. Place the ships using a nested loop. The outer loop could be a for-loop which iterates through the ships to be placed. The inner loop can be a while loop (or maybe a do-loop) that repeatedly calls the ship-placing function to get a candidate placement, then checks if it clashes with previous choices, looping until a clash-free placement is found.
As far as placing a single ship goes:
1) First generate a random number which is either 0 or 1 to determine if the ship will be placed horizontally or vertically
2) Then pick a random number to determine what the row or column it will be in
3) Finally, pick a random number for the first square in the row or column that contains the ship. The size of the ship will enter in here. If it has length 3, for example, then there are only 10-3 = 7 possible choices for the first square (assuming a standard 10x10 board).
On Edit: #Manus raised a good point about difficulties that would be encountered if the number of ships are above a certain threshold. If you have a massive fleet of ships on a small board it is possible that certain partial placements (of some of the ships) would rule out any valid placement of the remaining ships. The only way I see around this difficulty is to use a back-tracking approach that checks if there is enough room for a ship before trying to place it and, if not, revisit the placement of previous ships until you get something that works. But -- the work involved in checking if there is any valid position can be done in such a way that you simultaneously determine the set of valid positions, in which case you might as well directly pick from that set rather than use trial and error. My approach is essentially a quick-and-dirty approach for simulating the child's game. You would need a more sophisticated approach if you want a more flexible game.

Number of ways to fill a nxm grid

I encountered the following problem in my programming book which I could not solve:
Given a nxm grid, write a recursive algorithm to find the number of ways that this grid could be filled by 3x1 and 1x3 blocks.
My logic for 3 x M grids:
Find the number of block combinations that could be used to fill side M of the grid.
I do not know how to change the logic to solve the question above.
Could someone please advise? Thanks.
Let position be the upper left corner, and thereafter the first unfilled slot of the grid (left to right then top to bottom). There are up to two ways to place a block at postion. Try placing a 1x3 horizontal block at position, and call the recursive function on the remaining grid. Try placing a 3x1 vertical block at position, and call the recursive function on that. Observe that if there is no legal way to place a block (at the end, for instance, say there are is only a 2x2 square left), this branch of the program failed to find a solution. That's because the grid has to be filled by 3x1 blocks.
Your logic isn't recursive - it's a combinatorial approach, trying to count. But as long a the grid isn't huge, the computer has enough memory to actually try all the combinations. If you could relate this approach to other problems solved recursively in the book that would be great.
Here's an idea of the method signature
int blockFillings(boolean[][] grid, int posx, int posy)

Categories

Resources