Calculating total weight of MST using Prim's and a heap - java

Attempting to implement a method that builds a MST using prim's and a min heap (using priority queue) and returns the total weight of the MST.
My code seems to produce different results to what is expected, however, looking at my code it seems to be fundamentally correct and follows closely to other examples online.
for (int v = 0; v < size; v++) {
key[v] = Integer.MAX_VALUE;
pred[v] = null;
visited[v] = false;
}
int s = 0;
key[s] = 0;
for (int v = 0; v < size; v++) {
minHeap.add(new T(v, key[v], pred[v]));
}
while (!minHeap.isEmpty()) {
int u = minHeap.poll().vertex;
for (int v = 0; v < size; v++) {
if (g.getWeight(u, v) > 0 && !visited[v]) {
if (g.getWeight(u, v) < key[v]) {
key[v] = g.getWeight(u, v);
pred[v] = u;
minHeap.add(new T(v, key[v], pred[u]));
}
}
}
visited[u] = true;
}
int distance = 0;
for (int i = 0; i < size; i++) {
distance += key[i];
if (!visited[i])
return -1;
}
return distance;
current input is an adjacency array:
5 16 5 8 19 9 8 1 5 8
16 10 19 7 7 5 15 4 7 18
5 19 1 7 1 20 12 15 9 2
8 7 7 14 11 18 13 5 11 14
19 7 1 11 0 15 10 17 0 8
9 5 20 18 15 0 11 20 10 7
8 15 12 13 10 11 8 14 20 20
1 4 15 5 17 20 14 12 0 8
5 7 9 11 0 10 20 0 5 7
8 18 2 14 8 7 20 8 7 15
expected output is: 36
current output is: 32

Perhaps your minHeap is sorting items to the largest key[v] rather than smallest. Maybe try
minHeap.add(new T(v, Integer.MAXVALUE - key[v], pred[u]));

The problem was in where the visited[u] = true statement was.
moving that statement to after polling for vertex with highest priority in minHeap and before the loop checking for adjacent vertices fixed it.

Related

Creating Triangular Multiplication Table using Do-while Loop

I want to ask a question or a probable favor on how am I going to make my program coding "do-while loop" in creating a Triangular Multiplication. Is there a probable way on to create such thing without using any other statement?
public class Main {
static void ssbr(int n) {
int i = 1;
do{
System.out.printf("%4d", n * i);
i = i + 1;
} while(i <= 7);
System.out.println("");
}
public static void main(String[] args) {
int i = 1;
do{
ssbr(i);
i = i + 1;
} while (i <= 7);
}
}
Output it gave:
1 2 3 4 5 6 7
2 4 6 8 10 11 12
3 6 9 12 15 18 21
4 8 12 16 20 24 30
5 10 15 20 25 30 35
6 12 18 24 30 36 42
7 14 21 28 35 42 49
Output I wanted:
1
2 4
3 6 9
4 8 12 16
5 10 15 20 25
6 12 18 24 30 36
7 14 21 28 35 42 49
You can do it with the following algorithm:
You have to do it 7 times and therefore you can use a loop that should run 7 times.
Each row starts with the row number, and run for row number * row number times with a step-value equal to the row number.
Given below is the implementation of this algorithm using for loop and I leave it to you to implement it using the do-while loop (as it seems to be your homework 😀)
public class Main {
public static void main(String[] args) {
int n = 7;
for (int row = 1; row <= n; row++) {
for (int col = row; col <= row * row; col += row) {
System.out.printf("%-4d", col);
}
System.out.println();
}
}
}
Output:
1
2 4
3 6 9
4 8 12 16
5 10 15 20 25
6 12 18 24 30 36
7 14 21 28 35 42 49

Format of Pascal's triangle [duplicate]

This question already has answers here:
Pascal's Triangle Format [duplicate]
(8 answers)
Closed 3 years ago.
I have to print Pascal's Triangle, so it should have number 1 on each side, and format of triangle should be even on each side (now it's longer on the right side). My code:
public static void main(String[] args) {
printPascalTriangle(10);
}
public static void printPascalTriangle(int size) {
for (int i = 0; i <= size; i++) {
System.out.println();
for (int j = 0; j <= (size - i); j++) {
System.out.print(" ");
}
for (int j = 0; j <= i; j++) {
System.out.print(" " + (i + j));
}
}
}
And the output is:
0
1 2
2 3 4
3 4 5 6
4 5 6 7 8
5 6 7 8 9 10
6 7 8 9 10 11 12
7 8 9 10 11 12 13 14
8 9 10 11 12 13 14 15 16
9 10 11 12 13 14 15 16 17 18
10 11 12 13 14 15 16 17 18 19 20
Why it doesn't sum up? And why loop doesn't format spaces properly?
You should use printf method instead of print with proper arguments to format your output:
public static void main(String[] args) {
printPascalTriangle(10);
}
public static void printPascalTriangle(int rows) {
for (int i = 0; i < rows; i++) {
int number = 1;
System.out.printf("%" + (rows - i) * 2 + "s", "");
for (int j = 0; j <= i; j++) {
System.out.printf("%4d", number);
number = number * (i - j) / (j + 1);
}
System.out.println();
}
}
Output:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1

Nested for loop not incrementing by 1

In the below code block:
public static void main(String[] args) {
int i;
int x = 0;
int count;
int sum = 0;
Scanner scan = new Scanner(System.in);
System.out.println("Enter The Table Operator (+, -, *, /, %, or R)");
String operator = scan.nextLine();
System.out.println("Enter The Smallest Operand For the Table:");
int small = scan.nextInt();
System.out.println("Enter The Largest Operand For the Table");
int large = scan.nextInt();
for(i = 0; i < 12; i++) {
for(x = 0; x <= large; x ++)
System.out.printf("%4d", x + small);
System.out.printf("\n");
x++;
large++;
}
}
The code outputs:
1 2 3 4 5 6 7 8 9 10 11 12 13
1 2 3 4 5 6 7 8 9 10 11 12 13
1 2 3 4 5 6 7 8 9 10 11 12 13
1 2 3 4 5 6 7 8 9 10 11 12 13
1 2 3 4 5 6 7 8 9 10 11 12 13
1 2 3 4 5 6 7 8 9 10 11 12 13
1 2 3 4 5 6 7 8 9 10 11 12 13
1 2 3 4 5 6 7 8 9 10 11 12 13
1 2 3 4 5 6 7 8 9 10 11 12 13
1 2 3 4 5 6 7 8 9 10 11 12 13
1 2 3 4 5 6 7 8 9 10 11 12 13
1 2 3 4 5 6 7 8 9 10 11 12 13
but I want it to look like this:
1 2 3 4 5 6 7 8 9 10 11 12 13
2 3 4 5 6 7 8 9 10 11 12 13 14
3 4 5 6 7 8 9 10 11 12 13 14 15
4 5 6 7 8 9 10 11 12 13 14 15 16
5 6 7 8 9 10 11 12 13 14 15 16 17
6 7 8 9 10 11 12 13 14 15 16 17 18
7 8 9 10 11 12 13 14 15 16 17 18 19
8 9 10 11 12 13 14 15 16 17 18 19 20
9 10 11 12 13 14 15 16 17 18 19 20 21
10 11 12 13 14 15 16 17 18 19 20 21 22
11 12 13 14 15 16 17 18 19 20 21 22 23
12 13 14 15 16 17 18 19 20 21 22 23 24
It's basically an addition table. I'm trying to get the x value and the value of "large" to implement by one on each loop. I'm pretty sure I'm using the for loop incorrectly but I haven't been able to find out how.
for (int row = 1; row <= 12; row++) {
for (int col = row; col < row + 13; col++)
System.out.print(col != row ? " " + col : col);
System.out.println();
}
This pretty simple trianlge. Just inline all temporary variables like row and 'col' into the loops. Be simple.
int large = 10;
int small = 0;
int x,i;
for( i = 0; i < large; i++) {
for( x = 1; x <= large; x ++)
System.out.printf("%d ", x + small);
System.out.printf("\n");
x++;
small++;
}
Change "%4d" to "%d ". %4d makes every number 4 spaces long no matter what but you wanted the number and one space.
The last line in your outer for-loop should be small++ instead of large++ to offset the start value each time.
Your loop looks right. You are incrementing the wrong variables.
for(i = 0; i < large; i++) {
for(x = 0; x <= large; x ++){
System.out.printf("%4d", x + small);
}
System.out.printf("\n");
small++;
}
output:
1 2 3 4 5 6 7 8 9 10 11 12 13
2 3 4 5 6 7 8 9 10 11 12 13 14
3 4 5 6 7 8 9 10 11 12 13 14 15
4 5 6 7 8 9 10 11 12 13 14 15 16
5 6 7 8 9 10 11 12 13 14 15 16 17
6 7 8 9 10 11 12 13 14 15 16 17 18
7 8 9 10 11 12 13 14 15 16 17 18 19
8 9 10 11 12 13 14 15 16 17 18 19 20
9 10 11 12 13 14 15 16 17 18 19 20 21
10 11 12 13 14 15 16 17 18 19 20 21 22
11 12 13 14 15 16 17 18 19 20 21 22 23
12 13 14 15 16 17 18 19 20 21 22 23 24
int small = 1;
int large = 12;
for(int i = 0; i < 12; i++) {
for(int x = i; x <= i + large; x ++)
{
System.out.printf("%4d", x + small);
}
System.out.printf("\n");
}
checkout this simple change by changing the x ranges from i -> i + large which will avoid increment large ( because it is not need as in every iteration i also increase)
what you are trying to is in every iteration of i and x you are increment it at the end of the print operation that wont effect exactly as you want because for every iteration the value you print should iterate and print so change the x value to i, which will get incremented in every iteration and use it till i + large (where large is the number you obtain as maximum limit)
Note this can be achieved since small, and large are constant through out the loop

MergeSort - ArrayIndexOutOfBoundsException

I am sorry if this has already been answered somewhere, I have spent over an hour searching through many previous questions and none of them were able to help me with this error.
I randomly receive an error, probably 70% of the time:
--------------------Configuration: MergeSort - JDK version 1.7.0_45 <Default> - <Default>- -------------------
Random array: 17 14 3 4 1 10 13 9 3 1 6 9 10 2 17 8 10 5 7 8
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 20
at MergeSort.merge(MergeSort.java:64)
at MergeSort.mergeSort(MergeSort.java:26)
at Driver.main(Driver.java:18)
Process completed.
Line 64 would refer to: "scratch[scratch_index] = list[i];"
public void merge(int[] list, int first, int middle, int last)
{
int[] scratch = new int[list.length];
int midpoint = (first+last)/2;
int left_index = first;
int right_index = middle + 1;
int scratch_index = left_index;
while((left_index <= midpoint) && (right_index <= last))
{
if(list[left_index] <= list[right_index])
{
scratch[scratch_index] = list[left_index];
left_index +=1;
}
else
{
scratch[scratch_index] = list[right_index];
right_index +=1;
}
scratch_index +=1;
}
for(int i=left_index;i<=midpoint;i++)
{
scratch[scratch_index] = list[i];
scratch_index +=1;
}
for(int i=right_index;right_index<=last;i++) // I am line 64
{
scratch[scratch_index] = list[i];
scratch_index +=1;
}
for(int i=0;i<list.length;i++)
{
list[i] = scratch[i];
}
}
This is my first question ever on this site, sorry if I have not formatted this question correctly, any advice is appreciated.
If any other information is needed to help me with solving this error, just let me know.
Thank you!
At the comment // I am line 64 You are incrementing the i and not the right_index which will cause the index to keep increasing until reaching index out of bound, so replace this,
for(int i=right_index;right_index<=last;i++) // I am line 64
by this:
for(int i=right_index; i<=last;i++)
Indexes use "zero-based numbering" >> https://en.wikipedia.org/wiki/Zero-based_numbering
String example = "01234";
System.out.println(example.size()); //Prints out 5
System.out.println(exmaple.indexOf("1")); //Prints out 1
Your for statement needs to be checking up TO the last index
for(int i=right_index;right_index<last;i++)
OR (not recommended)
for(int i=right_index;right_index<=last-1;i++) //Works, but not recommended due to conventions
//index 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
Random array: 17 14 3 4 1 10 13 9 3 1 6 9 10 2 17 8 10 5 7 8
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 20

enumerate grouped columns vertically

If I have a matrix that is iterated horizontally and then vertically it would enumerate like this:
0 1 2 3 4 5 6 7 8 9
------------------------------
0 | 1 2 3 4 5 6 7 8 9 10
1 | 11 12 13 14 15 16 17 18 19 20
2 | 21 22 23 24 25 26 27 28 29 30
if I want to enumerate vertically I could do this:
total_rows * coln+ rown+ 1
0 1 2 3 4 5 6 7 8 9
--------------------------
0 |1 4 7 10 13 16 19 22 25 28
1 |2 5 8 11 14 17 20 23 26 29
2 |3 6 9 12 15 18 21 24 27 30
anybody have the algorithm handy to enumerate grouped columns vertically?
????
0 1 2 3 4 5 6 7 8 9
------------------------------
0 |1 2 7 8 13 14 19 20 25 26
1 |3 4 9 10 15 16 21 22 27 28
2 |5 6 11 12 17 18 23 24 29 30
cols_per_group=2;
(total_rows*cols_per_group)*((int)(coln/cols_per_group))
+(coln%cols_per_group)+cols_per_group*rown +1
i.e. (total size of group)*(which group you're in)
+ (horizontal position in group) + (width of group) * (vertical position in group) +1
Something like this perhaps?
for(group = 0; group < maxCol/2; group += 2)
{
for(row = group; row < maxRows; row++)
{
for(col = 0; col < group + 2; col++)
{
matrix[col][row];
}
}
}
This was fun to think about ^_^
Usually you iterate on a matrix with a nested loop
for (int i = 0; i < rows; ++i)
for (int j = 0; j < cols; ++j)
doSomething(matrix[i][j]);
This will enumerate rows, if you swap indices:
for (int i = 0; i < rows; ++i)
for (int j = 0; j < cols; ++j)
doSomething(matrix[j][i]);
Then you will enumerate by colums.
In your case you seem to have a matrix that is stored as a plain array so you can get from the two loops which is your addressing function, normal row access is (x/row_size)*row_size + x%row_size, so you iterate row_size elements before switching to the next row.
If you change it slightly: (x%col_size)*row_size + x/col_size you obtain a function that ad every iteration adds row_size (reching nth row) and then a value that is increased every col_size elements (so every time you finish a column). This should work..
EDIT: Oh wait missed that grouping factor, let me update my answer.. you can do something like
assert (cols % n == 0); /* we don't like not precise matrices */
for (int i = 0; i < cols / n; ++i)
for (int j = 0; j < rows; ++j)
for (int k = 0; k < n; ++n)
doSomething(matrix[j][i+k]);
Or in plain array style:
(x%n) + row_size*(x/n) + (x / (col_size*n))*n
^ ^ ^
| | |
| | reposition after a group of columns
| moves vertically in the same group
moves horizontally on the group
where n is the number of columns per group

Categories