MPI.Send and MPI.Recv are not working properly - java

I am new to distributed parallel programming. In the following code the process 0 gets stuck on MPI.Recv method execution..
if (me != 0) {
if (finalTour != null) {
Node[] nodes = new Node[5];
nodes[0] = finalTour;
MPI.COMM_WORLD.Send(nodes, 0, 5, MPI.OBJECT, 0, 0);
}
}
if (me == 0) {
for (int i = 1; i < processes; i++) {
Node[] nodes = new Node[5];
MPI.COMM_WORLD.Recv(nodes, 0, 5, MPI.OBJECT, MPI.ANY_SOURCE, MPI.ANY_TAG);
if (nodes[0] != null) {
if (finalTour != null) {
if (finalTour.cost > nodes[0].cost) {
finalTour = nodes[0];
}
minCostPath = finalTour;
} else {
finalTour = nodes[0];
minCostPath = finalTour;
}
}
}
}
MPI.Finalize();
if (minCostPath != null) {
print(size, minCostPath);
}
When I debugged this snippet, I observed the following:
1. Sometimes the Recv method is executed before the corresponding send method does. Could this pose a problem?
2. All the processes except 0 send a message to process 0 and execute their MPI.Finalize() method, while process 0 is waiting on a Recv. Could the problem be because of this?

Related

Why does the printing stop with no errors?

I try to print the result of boolean insert(K) in a for loop but after the first insertion the printing stops, that indicates the second insertion is not fully successful.
and inside method insert(K), the method "retrieves(K)" is called, to check if K has been already inserted.
for (int i = 100; i > 0; i--) {
System.out.println(m.insert(i +1, 22));
System.out.println("dd");
System.out.println(m.retrieve(i+1).first + ",,,"+m.retrieve(i+1).second);
System.out.println(i + " insertion done");
System.out.println("---------");
}
and the result is
-------------------
true
dd
true,,,22
100 insertion done
---------
true
dd
After removing the "retrieves(K)" call in the insert() method, the print runs just fine, so i am assuming there is an issues with the method "retrieves(K)", and since there is no error + cpu usage is higher, it might be an infinite loop, the problem is, i don't see it.
here is the method "retrieves(K)"
public Pair<Boolean, T> retrieve(K k) {
Pair<Boolean, T> ff = new Pair<Boolean, T>(false, null);
BSTMapNode<K, T> p = root;
if(root==null) {
return new Pair<Boolean,T>(false,null);
}
else
while (p != null) {
if (k.compareTo(p.key) == 0) {
ff.first=true;
ff.second=p.data;
return new Pair<Boolean,T>(true,p.data);
} else if (k.compareTo(p.key) < 0) {
p = p.left;
} else
p = p.right;
}
return new Pair<Boolean,T>(false,null);
}
EDIT: added insert method
public boolean insert(K k, T e) {
BSTMapNode<K, T> p = current;
BSTMapNode<K, T> q = current;
// ISSUE HERE
if (retrieve(k).first == true) {
current = q;
return false;
//
}
BSTMapNode<K, T> tmp = new BSTMapNode<K, T>(k, e);
if (root == null) {
root = current = tmp;
return true;
} else {
if (k.compareTo(current.key) < 0)
current.left = p;
else
current.right = p;
current = p;
return true;
}
The issue is with the insert() method. When it is called for the second time, root is non-null, so execution gets into the else branch. There, it sets current.left = p with current == p, so p is now its own p.left. When the retrieve() method arrives at that node, it sets p = p.left which changes nothing, causing the infinite loop.
Your approach using a current node does not work. In insert(), you have to search the insertion position of the new node from the root every time, similar to what you do in retrieve(). Just keep going down until you reach a leaf. Then insert the new node there.
The code could look like this:
public boolean insert (K key, T value) {
if (root == null) {
root = new BSTMapNode<>(key, value);
return true;
} else {
BSTMapNode<K, T> p = root;
while (true) {
if (key.compareTo(p.key) == 0) {
return false; // Already in BST
} else if (key.compareTo(p.key) < 0) {
if (p.left == null) {
p.left = new BSTMapNode<>(key, value);
return true;
} else {
p = p.left;
}
} else {
// Analogous for right sub-tree
}
}
}
}

delete odd numbers in queue

i am trying to delete odd numbers in the queue linked list but I am struggling to make function to
delete the odd here my code for better understanding ;
public class queueLinked {
private Node rear;
private Node front;
private int siz;
public boolean isEmpty() {//function return boolean if is empty or not
boolean response = false;
if (siz == 0) {
response = true;
}
return response;
}
public void enqueue(int element) { // inserting the value type of int
Node node = new Node(element);
if (front == null) {
rear = node;
front = node;
} else {
rear.setNext(node);
rear = node;
siz++;
}
}
public queueLinked() {
front = null;
rear = null;
siz = 0;
}
public Node dequeue() { // to remove the a element in the queue
Node response = null;
if (front != null) ;
if (front.getNext() != null) {
response = new Node(front.getData());
front = front.getNext();
siz--;
} else {
response = new Node(front.getData());
front = null;
rear = null;
}
return response;
}
public Node peak() {
Node response = null;
if (!isEmpty()) {
response = new Node(front.getData());
}
return response;
}
public int getSiz() { // to get the size
return siz;
}
public void display() { // display the queue function
System.out.print("\nQueue = ");
if (siz == 0) {
System.out.print("Empty\n");
return;
}
Node ptr = front;
while (ptr != rear.getNext()) {
System.out.print(ptr.getData() + " ");
ptr = ptr.getNext();
}
System.out.println();
}
public void deleteOdd() { // delete odd number in the queue
System.out.print("\nQueue = ");
if (siz == 0) { //make sure if it is empty or not
System.out.print("Empty\n");
return;
}
Node tempe = front;
if (front.getData() % 2 != 0){
enqueue(front.getData());
front = front.getNext();
rear = rear.getNext();
}
}
}
in function deleteOdd() i tried to make sure if is it empty and then I tried more than way to get the right one if the first one is odd delete it and front = front.next and I do not know if it is right
First, there are some issues in other methods in your code:
Issues
enqueue should also increase the size of the list when adding to an empty list.
dequeue should also decrease the size of the list when removing the last node from it.
dequeue has a wrong semi-colon after if (front != null) ; and so you can get a null pointer exception on the line below it.
Here is a possible correction with minimal changes:
public void enqueue(int element) {
Node node = new Node(element);
if (front == null) {
rear = node;
front = node;
} else {
rear.setNext(node);
rear = node;
}
siz++; // size should be updated in both cases
}
public Node dequeue() {
Node response = null;
if (front != null) { // correction of misplaced semi-colon
response = new Node(front.getData());
front = front.getNext();
if (front == null) {
rear = null;
}
siz--; // size should be updated in both cases
}
return response;
}
deleteOdd
I chose to only use public methods of the class, so that this function can be easily coded outside of the class, if desired.
The current size of the queue is used for a count down, so every node is visited exactly once. The nodes with even data are appended to the queue again, but this count down will prevent us from visiting those again (and again, ...):
public void deleteOdd() {
for (int count = getSiz(); count > 0; count--) {
Node node = dequeue();
if (node.getData() % 2 == 0) {
enqueue(node.getData());
}
}
}
Try the following function to delete odd number in queue.
public void deleteOdd() { // delete odd number in the queue
if (size == 0) { // make sure if it is empty or not
System.out.print("Empty\n");
return;
}
Node ptr = front;
while (ptr != rear.getNext()) {
if (ptr.getData() % 2 != 0) {
Node tmp = ptr.getNext();
ptr.data = tmp.getData();
ptr.next = tmp.next;
size--;
}
else
ptr = ptr.getNext();
}
System.out.println();
}
QueueLinked queue = new QueueLinked();
for (int i=1; i<=20; i++) {
queue.enqueue(i);
}
queue.display();
queue.deleteOdd();

Swap linkedlist nodes

I am trying to solve a question asked in a interview to swap two nodes in a linkedlist. I happened to find the solution for the answer posted online.
public static void searchNode(int dataX, int dataY, Node head) {
Node currentDataX = head, prevDataX = null;
while (currentDataX != null && currentDataX.data != dataX) {
prevDataX = currentDataX;
currentDataX = currentDataX.next;
}
Node currentDataY = head, prevDataY = null;
while (currentDataY != null && currentDataY.data != dataY) {
prevDataY = currentDataY;
currentDataY = currentDataY.next;
}
if (prevDataX == null) {
head = currentDataX;
}else {
prevDataX.next = currentDataY;
}
if (prevDataY == null) {
head = currentDataY;
}else {
prevDataY.next = currentDataX;
}
// Swap next pointers
Node temp = currentDataY.next;
currentDataY.next = currentDataX.next;
currentDataX.next = temp;
}
The solution is very clear to me except I don't understand the else cases where prevDataX and prevDataY are null. Why are we doing prevDataX.next = currentDataY, and prevDataX.next = currentDataY when we are executing a swap in the end anyway.

I'm having trouble collecting 5 coins and successfully going to next world

So we recently started coding in college and I'm having trouble with my game in Greenfoot. I should normally be able to collect 5 coins on level 1, go to the door, and progress to level 2 and so on... This is my piece of code so far:
private void collect () {
Actor coin = getOneIntersectingObject(Coin.class);
if (coin != null) {
getWorld().removeObject(coin);
coinsCollected++;
}
if (coinsCollected == 5 && fiveCoinsLevel1 == false) {
if (this.getWorld().getClass() == Level_1.class) {
getWorld().addObject(new door_temp(), 157, 162);
fiveCoinsLevel1 = true;
secondLevel();
coinsCollected = 0;
}
}
if (coinsCollected == 5 && fiveCoinsLevel2 == false && fiveCoinsLevel1 == true) {
if (this.getWorld().getClass() == Level_2.class) {
getWorld().addObject(new door_temp(), 157, 162);
fiveCoinsLevel2 = true;
thirdLevel();
}
}
}
After that I have two methods that set the world to either level 2 or 3:
public void secondLevel () {
Actor secondlvl = getOneIntersectingObject(door_temp.class);
if (secondlvl != null) {
Greenfoot.setWorld(new Level_2());
}
}
public void thirdLevel () {
Actor thirdlvl = getOneIntersectingObject(door_temp.class);
if (thirdlvl != null) {
Greenfoot.setWorld(new Level_3());
}
}
Now for some reason, once I collect all 5 coins on level 1 and reach the door to go to level 2, it sends me straight to level 3.
Thanks to anyone who can help me :)

java.util.ConcurrentModificationException in recursion

i know after debugging that sons list is changed
i don't know why it is changed
and this modification causes me problems in my algorithm
public class IDS extends Algo {
public State found = null;
public IDS(char[][] input, int size) {
super(input, size);
}
public String solve() {
State root = new State(0, 0, 0, 0, "", 0, 0);
for (int i = 0; i < size * size; i++) {
found = DLS(root, i);
if (found != null) {
return found.path + " " + found.dist;
}
}
return "no path";
}
private State DLS(State node, int depth) {
if (depth == 0 && super.inp[node.row][node.col] == 'G') {
return node;
}
if (depth > 0) {
// List<State> sons = super.find_neighbors(node.row, node.col, node.prod_time);
// for (int j = 0; j < sons.size(); j++) {
//State cur = sons.get(j);
for(State cur : super.find_neighbors(node.row, node.col, node.prod_time)){
cur.addCost(node.dist);
cur.path = cur.addpath(node.path);
found = DLS(cur, depth - 1);
if (found != null) {
return found;
}
}
}
return null;
}
}
here is the abstract class:
abstract class Algo {
public static Map<Integer,String> ways = new TreeMap<>();
protected char[][]inp;
protected int size;
private Map<Character,Integer>costs = new HashMap<>();
public List<State>sons = new ArrayList<>();
public Algo(){}
public Algo(char[][] input,int size){
inp = input;
this.size = size;
ways.put(1,"R");
ways.put(2,"RD");
ways.put(3,"D");
ways.put(4,"LD");
ways.put(5,"L");
ways.put(6,"LU");
ways.put(7,"U");
ways.put(8,"RU");
costs.put('R',1);
costs.put('D',3);
costs.put('H',10);
costs.put('G',0);
costs.put('S',0);
}
private void addDirection(int row,int col,int prod, int loc){
int cos = costs.get(inp[row][col]);
State s = new State(row,col,0,prod,"",loc,cos);
sons.add(s);
}
public abstract String solve();
//gets the parent i,j and the prod_t of the sons
public List<State> find_neighbors(int i, int j,int prod_t){
List<String>openD = new ArrayList<>();
sons.clear();
if(j+1 < size) {//right
if (inp[i][j + 1] != 'W') {
addDirection(i, j + 1, prod_t, 1);
openD.add("R");
}
}
if(i-1 >= 0) {
if (inp[i - 1][j] != 'W') {//up
addDirection(i - 1, j, prod_t, 7);
openD.add("U");
}
}
if(i+1 < size) {
if (inp[i + 1][j] != 'W') {//down
addDirection(i + 1, j, prod_t, 3);
openD.add("D");
}
}
if(j-1 >= 0){
if(inp[i][j-1]!='W'){//left
addDirection(i,j-1,prod_t,5);
openD.add("L");
}
}
if(openD.contains("L")){
if(openD.contains("U")){
if(inp[i-1][j-1]!='W'){
addDirection(i-1,j-1,prod_t,6);
}
}
if(openD.contains("D")){
if(inp[i+1][j-1]!='W'){
addDirection(i+1,j-1,prod_t,4);
}
}
}
if(openD.contains("R")){
if(openD.contains("U")) {
if (inp[i - 1][j + 1] != 'W') {
addDirection(i - 1, j + 1, prod_t, 8);
}
}
if(openD.contains("D")){
if(inp[i+1][j+1]!='W'){
addDirection(i+1,j+1,prod_t,2);
}
}
}
return sons;
}
}
the exception just helped me know the list has modified however still don't know why :
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859)
at java.util.ArrayList$Itr.next(ArrayList.java:831)
at IDS.DLS(IDS.java:33)
at IDS.solve(IDS.java:17)
at ex1.main(ex1.java:34)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
super.find_neighbors modifies and returns the sons list. Inside your loop the method DLS is recursively called which calls super.find_neighbors again (modifying the same list that is currently iterated one recursion above). Because the list is changed during you iterate over it the exception is thrown.
You are doings a sons.clear() inside Algo.find_neighbours() That will cause the ConcurrentModification in the loop. Moreover, since find_neighbours() always return an empty List, what's the poingt in trying to iterate over it?

Categories