Dynamic Programming and Knapsack Application - java

Im studying dynamic programming and am looking to solve the following problem, which can be found here http://www.cs.berkeley.edu/~vazirani/algorithms/chap6.pdf:
You are given a rectangular piece of cloth with dimensions X by Y, where X and Y are positive integers, and a list of n products that can be made using the cloth. For each product i in [1,n] you know that a rectangle of cloth of dimensions ai by bi is needed and that the final selling price of the product is ci. Assume that ai, bi, and ci are all positive integers. You have a machine that can cut any rectangular piece of cloth into two pieces either horizontally or vertically. Design an algorithm that finds the best strategy for cutting an X by Y piece of cloth so that the products made from the resulting pieces give the maximum sum of selling prices. You are free to make as many copies of a given product as you wish, or none if desired. (From Algorithms by Dasgupta, Papadimitriou, and Vazirani.)
It seems we have a sort of 2-dimensional knapsack problem, but I'm thinking it may be possible to just solve it with the traditional knapsack algorithm by considering the weights as the areas of the rectangles. Does this seem like a reasonable approach?
This is a programming assignment for a course I'm taking so please only include conceptual discussion and/or pseudo-code to illustrate ideas.

So you start with a X * Y rectangle. Say the optimal solution involves making a vertical (or horizontal) cut, then you have two new rectangles with dimensions X * Y1 and X * Y2 with Y1 + Y2 = Y. Since you want to maximize your profit, you need to maximize the profit on these new rectangles (optimal substructure). So your initial recursion goes as follows: f(X, Y) = max(f(X, Y1) + f(X, Y2), f(X1, Y) + f(X2, Y)) for all posible values of X1, X2 (horizontal cut) and Y1, Y2 (vertical cut).
Now the question is when do I actually decide to make a product ? You can decide to make a product when one of its dimensions equals one of the dimensions of your current rectangle (why ? Because if this doesn't hold, and the optimal solution includes making this product, then sooner or later you will need to make a vertical (or horizontal) cut and this case is already handled in the initial recursion), so you make the appropriate cut and you have a new rectangle X * Y1 (or X1 * Y), depending on the cut you made to obtain the product), in this case the recursion becomes f(X, Y) = cost of product + f(X1, Y).
The solution of the original problem is f(X, Y). The running time of this dp solution would be O(X * Y * (X + Y + number of available products)): you have X * Y possible rectangles, for each of these you try every possible cut (X + Y) and you try to make one of the available products out of this rectangle.
Also, check out this similar problem: Sharing Chocolate from the 2010 ICPC World Finals.

I think you should focus on the fact that the machine cuts the cloth into two pieces. What can fit in each of those two pieces? Consider the following:
+-------------+-------------------+
| | Piece B |
| | |
| Piece A +----------+--------+
| | | |
| | | |
| | | Piece |
+-------------+----------+ C |
| | |
| Piece D | |
+------------------------+--------+
These four fit in the cloth, but not in a way that's possible to achieve with three cuts. (Possibly a different arrangement would allow that with these particular pieces; think of this as a conceptual diagram, not to scale. My ascii art skills are limited today.)
Focussing on "where is the cut" should give you the dynamic programming solution. Good luck.

Please include the necessary conditions for rectangle of size (0, something) or (something, 0) in the Rect() function.

optimize() {
Rectangle memo[width][height]
optimize(0,0,totalwidth, totalheight, memo)
}
optimize(x, y, width, height, memo) {
if memo[width][height] != null
return memo[width][height]
rect = new Rectangle(width, height, value = 0)
for each pattern {
//find vertical cut solution
leftVerticalRect = optimize (x, y + pattern.height, pattern.width, height-pattern.height,memo)
rightVerticalRect = optimize(x + pattern.width, y, width-pattern.width, height)
verticalcut = new Cut(x + pattern.width, y, x + pattern.width, y + height)
//find horizontal cut solution
topHorizontalRect = optimize ( --parameters-- )
bottomHortizonalRect = optimize( --parameters--)
horizontalcut = new Cut( --parameters--)
//see which solution is more optimal
if (leftVerticalRect.val + rightVerticalRect.val > topHorizontalRect.val + bottomHorizontalRect.val)
subprobsolution = vertical cut solution
else
subprobsolution = horizontal cut solution
//see if the solution found is greater than previous solutions to this subproblem
if (subprobsolution.value + pattern.value > rect.value) {
rect.subrect1 = subprobsolutionrect1
rect.subrect2 = subprobsolutionrect2
rect.pattern = pattern
rect.cut = subprobsolutioncut
rect.value = rect.subrect1.value + rect.subrect2.value + rect.pattern.value
}
}
memo[width][height] = rect
return rect
}

Related

java, determine if circle is inside an area

Hi im new to programming and im trying to code an algorithm in java to determine if a circle is in a rectangular area
I have the radius of the circle and the point in the middle of it(the center)
|_____________________________________________________
|
|
|
| circle
|
|
|
|
|(0,0)________________________________________________
the bottom left corner represent the coordinate (0,0)
this is what I have so far but I know I have an error somewhere which I can't find
if (mCenter.getmX() + mRadius > width ||
mCenter.getmY() + mRadius > height ||
mCenter.getmX() - mRadius < 0 ||
mCenter.getmY() - mRadius < 0) {
return false; //not inside area
}
else { return true; }
In this code mCenter is a Point with a x and y coordinate, mRadius is the circle radius and width and height are the width/height of the area
thanks
You didn't say what the symptom is, but your helpful diagram above uses the ordinary mathematical coordinate system while your posted code uses awt.image.BufferedImage. Swing and most 2D computer graphics systems use a different coordinate system that's more convenient for laying out content in reading order.
Per GraphicsConfiguration#getDefaultTransform():
Coordinates in the coordinate space defined by the default
AffineTransform for screen and printer devices have the origin in the
upper left-hand corner of the target region of the device, with X
coordinates increasing to the right and Y coordinates increasing
downwards.
I think it's possible to set up a GraphicsConfiguration with a different transform. (I don't know how to do it.) Not so for awt.image.BufferedImage:
All BufferedImage objects have an upper left corner coordinate of (0, 0).
javax.swing.SwingUtilities has coordinate conversion methods.
P.S. Calling image.setRGB() for each pixel will be slow compared to passing the entire image into setRGB(int startX, int startY, int w, int h, int[] rgbArray, int offset, int scansize) or setData(Raster r). Usually a frame buffer is held in a 1-D array that's treated like a 2-D array, with scansize indicating the width of a scan line within this buffer.

Drawing a rectangle inside a rectangle

I feel a little silly asking this but i'm not able to figure it out.. I am trying to draw a rectangle inside another rectangle and the math i'm using must be off. the inside rectangle is always one pixel to short.
b.fillRect( rectangleX+rectangleOutlineSize, rectangleY+rectangleOutlineSize, rectangleWidth-rectangleOutlineSize*2, rectangleHeight);
Its probably simple but I have been stuck on it for a hour and I have had trouble with it in the past.
In programming the coordinate system is a bit
weird, not exactly as (the usual one) in math.
*---------------------------------------> X +
|
|
|
|
|
|
|
v
Y +
I guess you're having a problem with that.
The * is the (0,0) which is usually the upper left
corner of your drawing area (e.g. of your screen).
Try something along these lines.
b.fillRect( x, y, width, height );
b.fillRect( x + (width-w)/2.0, y + (height-h)/2.0, w, h );
width - the width of the big rectangle
height - the height of the big rectangle
x,y - upper left corner of the big rectangle
w,h - width, height of the small rectangle

How to find the vertical and horizontal distance from the center of a rectangle

For my current Java project I have to compute the horizontal and vertical distance from the center of a rectangle. I tried using the formula from a previous project to find such a distance. Here is my code:
// Calculations; centerCoordinate = 0
formula = Math.sqrt(Math.pow(userXCoordinate - centerCoordinate, 2) + Math.pow(userYCoordinate - centerCoordinate, 2));
My professor gave the hint that a point is in the rectangle if its horizontal distance to (0, 0) is less than or equal to 10 / 2 and its vertical distance to (0, 0) is less than or equal to 5 / 2. I tried using 5 for horizontal distance and 2.5 for vertical distance and setting variables to these numbers. I then made an if-else loop saying if the result of the formula was less than or equal to the variables the coordinates were in the rectangle otherwise they were outside. This returned a wrong answer; what could I do differently?
So, let's say first, the coordinate of the center is:
(x=2.5, y=1.25)
See the below for explanation
<-10/2 ->
(0,0) _____________________
| | ^
| | |
| Center is (5/2, 2.5/2) | 5/2
| | |
|_________________________| v
The point is, you can not use the distance from the center to determine if the point is in the rectangle or not, because it is a rectangle not a circle.
Below is the right way to check if user coordinate is in rectangle or not.
if(userXCoordinate < 10/2 && userYCoordinate < 5/2 )
{
//user Coordinate is in the rectangle
}
// Calculations; centerCoordinate = 0
formula = Math.sqrt(Math.pow(userXCoordinate - centerCoordinate, 2) + Math.pow(userYCoordinate - centerCoordinate, 2), 2);
You almost got it. :)

Get coordinates of a point in 3D space from angles its vector makes with axis and its length

I have a magnitude of the vector pointing somewhere in 3D space from the origin (0x, 0y, 0z).
I also have an angle that projection of the vector in X and Z axis makes between itself and the Y axis. In other words I have a joystick that reads X angle (from -35 to 35 degrees) for left-right movement and Z angle (from -35 to 35 degrees) for front-back movement. It returns 0 when joystick is is in its initial position. I get a reading of magnitude (how far the string is pulled out from the joystick). I need to find the coordinates (assuming 1 cm of magnitude is equal to a unit vector) of the point at the end of the string. Point will always locate above x-z axis plane. Magnitude is never 0.
I would appreciate an algorithm or a piece of code on Java, even though a link to extra materials will be good too. There are Q&A talking about rotational angles and matrix, but it looks like I have a different problem.
UPD:
Angles are not between the vector and x,y,z axis. They are angles that projection of the vector onto axis makes with Y-axis.
UPD1:
Joystick can be moved right-left and front-back:
+z
|
-x -- -- +x -x --'-- +x
|
-z
Top view Side view (along z-axis)
As well as having an extendable string in the middle (s):
+z +s (+y)
| |
-x -- -- +x -x --'-- +x
|
-z
Top view Side view (along z-axis)
When string is extended a point (P) in 3D is formed
+z +y +y
| P | P | P
|/ | / | /
-x --/-- +x |/ |/
| -x --'-- +x -z --'-- +z
-z
Top view Side view Side view
(along z-axis) (along x-axis)
I receive coordinates in the following format:
- x-axis angle (call it alpha) [-1 1] in reality between [-35 and 35] degrees
- y-axis angle (call it theta) [-1 1] in reality between [-35 and 35] degrees
- magnitude of vector OP (call it magnitude) [-1 1] in reality between 0[ and 305] cm
It sounds like you have 2 angles and a magnitude, which is spherical coordinates. You're looking to convert spherical coordinates to cartesian coordinates:
More information here.
EDIT:
Upon further inspection of the question, I see that the problem is much more odd. You have the projections of two component vectors, (0,y,z) and (x,y,0), on the y axis which describe pitch and roll. I'm sure the joystick gives another component for yaw, however it was not specified in the OP. The weird part is that it is not possible for these components to actually be vector components of an (x,y,z) vector because then the y projections would be the same. I think what the OP is looking for is the normal of the new plane created by these given component points and origin. For this to work, I must be given the magnitudes of the vectors that the projections originate from. Since it is not specified, I assume they were unit vectors.
Vector xPrime=Vector(sqrt(1-xProj^2),xProj,0);
Vector zPrime=Vector(0,y,sqrt(1-zProj^2));
Vector ans=cross(zPrime,xPrime);
Equation for cross product. The answer may need to have some components negated depending on the sign conventions in the OP.
This does not seem to work as intended. I am trying to find the solution.
Let angle between Y axis and projection of vector in X axis be "alpha" and angle between Y axis and projection of vector in Z axis (theta).
Line (projection) in x-axis has an equation:
y = (1/tan(alpha) * x) + (0 * z)
Line (projection in z-axis has an equation:
y = (0 * x) + (1/tan(theta) * z)
So we can rearange them to get the following equations:
x = (z * tan(alpha)) / tan(theta)
z = (x * tan(theta)) / tan(alpha)
If we replace all unknowns but one in the equation of magnitude of the vector:
|v| = sqrt(x^2 + y^2 + z^2)
We get an equation that can be rearanged in terms of x:
/ magnitude^2 + tan^2(alpha) \
x = sqrt |---------------------------------|
\ tan^2(alpha) + tan^2(theta) + 1 /
Nice looking equation:
http://latex.codecogs.com/gif.latex?\sqrt{}\frac{\left%20|vector\right%20|^2%20+%20tan^2%28xy%29}{tan^2%28xy%29%20+%20tan^2%28zy%29%20+%201}
(copy - paste the link)
Then we can replace x in previous equations to get z and y.
Here's a solution from my case (different axis, but the principle is the same)
Assuming:
OK = LT' = x [unknown]
OL = T'K = y [unknown]
OT = 1 [unit vector]
^TKT' = ^a
^TLT' = ^b
We figure out relation between x and y:
y = x * (tan(b) / tan(a))
With OT being a unit vector, x can be found by:
x = sqrt{ tan^2(a) * cos^2(b) / (tan^2(a) + sin^2(b)) }
y = 1 / sqrt{ tan^2(a) / sin^2(b) + 1 }
And z (TT') is:
z = x * tan(b)

How do I draw thick lines with closely spaced points properly with Java2D graphics?

I'm trying to draw maps using Java2D. When my map is zoomed out my roads are full of drawing artefacts. This is a small part of the screen when drawing a complete US state:
This is a similar section of the road when zoomed closer in:
The line style used is a solid blue line with width scaled to be equivalent to 2 pixels.
I've tried various rendering hints and line joining rules and nothing seems to help.
I'm using Open JDK 1.7 on a Mac running the OS/X 10.8 and this is also reproducible on a Linux machine with a Sun JDK 1.6.
All shapes and transforms are double precision as far as possible with Java2D.
The geometry of the line has many closely spaced points and I suspect that the cause of the drawing artefacts is that the renderer is getting confused by consecutive points that are closer than a single pixel.
Is there a way to improve the appearance of the zoomed out shapes without thinning the points?
Edit
The drawing artefacts are at the points where separate line segments meet, so the missing pixels are something to do with the line caps (ends) not meeting, even when the end points are identical. This image shows the meeting point between two line segments. I have highlighted each line segment in a 7 pixel scaled line style (XOR-ed with white) but if you look very closely you can still see part of the original blue line (this is due to the rounded caps overlapping and the XOR draw mode.) At ordinary scales the ends seem to overlap, but when zoomed out and back in ordinary paint mode there is a broken line effect.
One workaround would be to join all the contiguous line segments together before drawing them, but I would still like to know the real cause of the drawing artefacts.
I am unable to recreate the situation you have using the OS X 1.6 JDK, but I still have some suggestions for you.
If you are just using this to outline states, consider using the GeneralPath class. You can use the lineTo(x,y) method to establish each of your points on the line. Again, because I can't recreate your problem using Line2D.Double, I don't know if this will actually be any different.
Second, and possibly more importantly, is how you are zooming in and out. I am using an AffineTransform (with setScaleTo(x,y)) on my Graphics2D object, and everything is working swimmingly. Compared to the alternative of scaling the points in your data by a zoom factor (or whatever else you could do), this is fairly easy. You'll also have to adjust the stroke of the lines by the factor, because it will scale everything down. I can post screenshots if you'd like.
Please check Xiaolin Wu's line algorithm it should answer you question!
Basic Concept
function plot(x, y, c) is
plot the pixel at (x, y) with brightness c (where 0 ≤ c ≤ 1)
function ipart(x) is
return integer part of x
function round(x) is
return ipart(x + 0.5)
function fpart(x) is
return fractional part of x
function rfpart(x) is
return 1 - fpart(x)
function drawLine(x1,y1,x2,y2) is
dx = x2 - x1
dy = y2 - y1
if abs(dx) < abs(dy) then
swap x1, y1
swap x2, y2
swap dx, dy
end if
if x2 < x1
swap x1, x2
swap y1, y2
end if
gradient = dy / dx
// handle first endpoint
xend = round(x1)
yend = y1 + gradient * (xend - x1)
xgap = rfpart(x1 + 0.5)
xpxl1 = xend // this will be used in the main loop
ypxl1 = ipart(yend)
plot(xpxl1, ypxl1, rfpart(yend) * xgap)
plot(xpxl1, ypxl1 + 1, fpart(yend) * xgap)
intery = yend + gradient // first y-intersection for the main loop
// handle second endpoint
xend = round (x2)
yend = y2 + gradient * (xend - x2)
xgap = fpart(x2 + 0.5)
xpxl2 = xend // this will be used in the main loop
ypxl2 = ipart (yend)
plot (xpxl2, ypxl2, rfpart (yend) * xgap)
plot (xpxl2, ypxl2 + 1, fpart (yend) * xgap)
// main loop
for x from xpxl1 + 1 to xpxl2 - 1 do
plot (x, ipart (intery), rfpart (intery))
plot (x, ipart (intery) + 1, fpart (intery))
intery = intery + gradient
end function

Categories