I am attempting to code a deadlock detection algorithm. I must use a 7x7 array filled with w's, x's, and n's. w = waiting for resource, x = exclusively holding a resource, and n = no need for the resource. The rows represent jobs or processes and the columns represent resources. I will give a test case array:
String [][] grid = {{"w","n","x","x","x","n","n"},
{"x","w","n","n","n","x","n"},
{"n","x","w","n","n","n","n"},
{"n","n","n","n","n","n","x"},
{"n","n","n","n","n","n","n"},
{"n","n","w","n","n","n","w"},
{"w","w","w","w","w","w","w"}};
As you can see the deadlock is among Row 0, 1 and 2. R0 is waiting forC0 (resource 1), but R1 is holding it. R1 is waiting for C1 (resource 2) but R2 is holding it. R2 is waiting for C2 (resource 3), but R0 is holding it. Visually, it is a cycle.
My algorithm searches the rows for w's and the columns for x's and places them in a single dimensional array. That part works. The array should read w x w x w x...until the end.
To check if we have completed a cycle I keep track of the index of the rows where w's and x's are found and place them into another single dimensional array. So in this example, the first array would read w x w x w x... and the the second array would read 0 1 1 2 2 0...
Once the single dimensional arrays reach a size of 4 (determined by count variable) I would check the first index (array[0]) and the last index (array[count-1]). If array[0] is 'w' and array[count-1] is 'x' and if the row indexes are equal then a deadlock is detected.
My algorithm works on paper, but somehow my math is wrong with my second array (WHI) The indexes print out correctly the first time ( 0 1 1 2 2 0...) but if I print out WHI[0] (which should always be 0) it gives me 1 2 5 5 6 6 6 6 ...
public void printSingleArrays()
{
String [] WH = new String[14];
int [] WHI = new int[14];
int count = 0;
for (int a = 0; a < WH.length && a < WHI.length; a += 2)
for (int i = 0; i < array.length ; i++)
for (int j = 0; j < array[i].length ; j++)
{
if (array[i][j].equals("w"))
{
WH[a] = array[i][j];
WHI[a] = i;
count++;
System.out.print(WH[a] + " ");
System.out.println(WHI[a] + " ");
for (int k = 0; k < array.length; k++)
{
if (array[k][j].equals("x"))
{
WH[a+1] = array[k][j];
WHI[a+1] = k;
System.out.print(WH[a+1] + " ");
System.out.print(WHI[a+1] + " ");
count++;
if (count >= 4)
{
System.out.print("Count is: " + count); // used for debugging
System.out.print(", First letter is: " + WH[0]);
System.out.println(", Index is: " + WHI[0]);
}
else
System.out.println();
}
}
}
}
for (int m = 0; m < WH.length; m++)
{
System.out.print(WH[m] + " ");
}
System.out.println();
for (int n = 0; n < WH.length; n++)
{
System.out.print(WHI[n] + " ");
}
}
Obviously, constructors and a client class are needed. I would just like to know how my array WHI changes when I print out WHI[0]?? Let me know if you need more resources or instruction the the problem!
Here is example of solving problem using graph.
First construct graph by iterating through grid
First iterating through all rows(j) for each column(i), it will find acquirer node who has "x" and waiting nodes who has "w".
Then add acquirer node into list of acquires of each waiting nodes.
Now we have graph ready, just find cycle by iterating over graph by dfs and see if node has been visited, if any of node was visited previously then it's a cycle, it means it is a deadlock.
Now in this case, graph can be disconnected graph means all node may not reach one or more node. In that case we may need to keep track of which nodes have been visited while detecting cycle and look for cycle for the node which was not visited.
Here is the code:
package example;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class DeadlockDetection {
static String [][] grid = {{"w","n","x","x","x","n","n"},
{"x","w","n","n","n","x","n"},
{"n","x","w","n","n","n","n"},
{"n","n","n","n","n","n","x"},
{"n","n","n","n","n","n","n"},
{"n","n","w","n","n","n","w"},
{"w","w","w","w","w","w","w"}};
public static void main(String[] args) {
System.out.println(isDeadlock());
}
public static class Node{
int id;
List<Node> acquirerNodes = new ArrayList<Node>();
public Node(int id){
this.id=id;
}
}
public static boolean isDeadlock(){
List<Node> nodes = new ArrayList<Node>();
//Construct Graph
for(int i=0; i< grid.length; i++){
nodes.add(new Node(i));
}
for(int i=0; i<grid.length; i++){
List<Node> waitingNodes = new ArrayList<Node>();
Node acquirer = null;
for(int j=0; j<grid.length; j++){
if(grid[j][i].equals("w") ){
waitingNodes.add(nodes.get(i));
} else if(grid[j][i].equals("x") ){
acquirer = nodes.get(i);
}
if(acquirer != null)
for(Node n: waitingNodes)
n.acquirerNodes.add(acquirer);
}
}
//In case of non-strongly disconnected graph, we may need to traverse through all nodes.
HashSet<Node> nodesFoundInGraph = new HashSet<Node>();
for(int i=0; i< grid.length; i++){
if(!nodesFoundInGraph.contains(nodes.get(i))){
HashSet<Node> visited = new HashSet<Node>();
if(isCycle(nodes.get(i), visited))
return true;
nodesFoundInGraph.addAll(visited);
}
}
return false;
}
public static boolean isCycle(Node node, Set<Node> visited){
if(visited.contains(node)){
return true;
}
visited.add(node);
for(Node n: node.acquirerNodes){
if(isCycle(n, visited)){
return true;
}
}
return false;
}
}
Related
I need to check if the numbers I stored in my LinkedList are in sequence.
Example sets are: 123, 124, 125, 1900, 1901.
If the code encounters the 123, it checks for the next which is 124 until 125 then stops since 1900 is not the next number after 125 when you are naturally counting. So I need to get the indexes of the first(123) and last sequence(125). Then on to the next sequence, 1900 and 1901.
for(int o = 0; o < zeroIndex.size(); o++)
{
if(-1 == (zeroIndex.get(o) - zeroIndex.get(o+1)))
{
System.out.println(zeroIndex.get(o) + "trailing");
}
}
String serialIndex = "";
for(int o = 1; o < zeroIndex.size(); o++)
{serialIndex += "("+Integer.toString(o-1);
while(i<zeroIndex.size() && zeroIndex.get(o-1)+1 == zeroIndex.get(o))
{ i++;
//System.out.println(zeroIndex.get(o) + "trailing");
}
serialIndex = serialIndex+Integer.toString(i-1)+"),";
}
System.out.println(serialIndex);
We will loop to the linked list and check if the previous is one less than current value.If this condition is true we will increment i else we will break will loop and add that i to ans
for example
123, 124, 125, 1900, 1901.
we will start from
124 ----- our serialIndex string will be (0 and 124 is one greater than 123 so we increment i. when we reach 1900 we will break the while loop as 1900 is not 1 greater than 125 and now our serialIndex string will b (0,2).
In the end we will have serialIndex string as (0,2),(3,4)
I do not have your full code to test so this is best i can do.If you encounter any error please let me know.
This works with O(n)
import java.util.LinkedList;
public class TestLinkedList {
public static void main(String[] args) {
LinkedList<Integer> a = new LinkedList<Integer>();
a.add(124);
a.add(125);
a.add(126);
a.add(1900);
a.add(1901);
int index = 0;
int index1 = 0;
for (int i = 0; i < a.size(); i++) {
if (i+1 < a.size() && a.get(i) + 1 == a.get(i + 1)) {
index1 = i + 1;
} else {
if (index != index1) {
System.out.println(index + " " + index1);
}
index = i+1;
index1 = i+1;
}
}
}
}
output
0 2
3 4
Here is a quick example on how to do it. First, create our list.
List<Integer> a = new LinkedList<Integer>();
a.add(124);
a.add(125);
a.add(126);
a.add(1900);
a.add(1901);
So, now that we have a list, let start. First, declaring our variables
int current; //will hold the current value during the iteration
int indexStart = 0; //the index of the beginning of the current sequence
int previous = a.get(0); //the previous value
int length = a.size(); //the length (optionnal, but this will be used later)
Then, here come the funny par (fully commented)
//Iterate from 1 to the end (0 is already in `previous`
for(int i = 1 ; i < length; ++i){
//get the current value
current = a.get(i);
//if the sequence is broken, print the index and print also the sublist using `List.subList`.
if(current != previous + 1){
System.out.format("Sequence from %d to %d%n", indexStart, i - 1);
System.out.println(a.subList(indexStart, i));
//reset the start of the current sequence
indexStart = i;
}
//update the previous value with the current for the next iteration.
previous = current;
}
//Print the last sequence.
System.out.format("Sequence from %d to %d%n", indexStart, length - 1);
System.out.println(a.subList(indexStart, length));
This will print :
Sequence from 0 to 2
[124, 125, 126]
Sequence from 3 to 4
[1900, 1901]
This is quite simple, just iterate the loop and keep the previous and current value to be able check if the sequence is correct or not.
Note that with a LinkedList, I would have used an Iterator but I need an int index so this would have give a longer solution, so to keep this simple, I used List.get.
I started with a 2D array matrix program that works entirely ok. I converted most of it to implement a linked list version of the same thing. Currently (using .printStackTrace) I find my null pointer exception is from this line -> matrix.setValue(matrixRow, matrixColumn, value);
which calls setValue and the error is thrown at this -> a[x][y] = value; //error in this line
I hope to have included enough code, let me know if more info is helpful. In need of a coding break for the moment. Many thanks.
else { //matrix creation
matrix = new Node();
int matrixRow = 1;
int matrixColumn = 1;
for (int i = 1; i <= matrixSize; i++) {
//scanner one line at a time
scanner = new Scanner(fileIO.getNextLine());
if (scanner.hasNextDouble()) {
while (scanner.hasNextDouble()) {
value = scanner.nextDouble();
matrix.construct(matrixRow, matrixColumn);
matrix.setValue(matrixRow, matrixColumn, value);
matrixColumn++;
}//while
matrixRow++;
matrixColumn = 1;
}//if
}//for
if (matrix.isSquare()) {
determinant = matrixMaths.determinate(matrix);
fileIO.writeToOutput(matrix.toString());
fileIO.writeToOutput("The determinant is: " + String.valueOf(determinant));
fileIO.writeToOutput("\n\n");
} else {
errorMsg = "\n\nMatrix is not square.\n\n";
fileIO.writeToOutput(errorMsg);
}//else
}//else matrix creation
Node construct(int n, int m) {
Node[][] a = new Node[n][m];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
Node ptr = new Node();
ptr.data = a[i][j];
ptr.right = null;
ptr.down = null;
a[i][j] = ptr;
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (j != n - 1)
a[i][j].right = a[i][j + 1];
if (i != n - 1)
a[i][j].down = a[i + 1][j];
}
}
return a[0][0];
}
public void setValue(int x, int y, double value) {
a[x][y] = value; //error in this line
if (x > sizeX) {
sizeX = x;
}
if (y > sizeY) {
sizeY = y;
}
}
* Edit *
I had put in system.out statements right before I called setValue to see that I was passing the values of 1 to the array. The method only gets this far until I get the error.
So, setValue(matrixRow, matrixColumn, value) -> setValue(1,1,value); on the first go through the while loop. I changed to this
int matrixRow = 0;
int matrixColumn = 0;
but then get the new error here (last return in the construct method):
return a[0][0];
another arrayOutOfBounds...
I'm going to try to follow the logic again but not sure yet where to make the fix. Help please!
And changing the row/column = 2 also gets the NUllPtr again.
So, made a few changes and am getting further...
} else { //matrix creation
matrix = new Node();
int matrixRow = 0;
int matrixColumn = 0;
System.out.println("\n" + "matrixSize " + matrixSize);
for (int i = 1; i <= matrixSize; i++) {
//scanner one line at a time
scanner = new Scanner(fileIO.getNextLine());
if (scanner.hasNextDouble()) {
while (scanner.hasNextDouble()) {
value = scanner.nextDouble();
System.out.println(matrixRow + " row number");
System.out.println(matrixColumn + " column number");
System.out.println(value + " value");
matrix.construct(matrixRow, matrixColumn, value);
matrixColumn++;
}//while
matrixRow++;
matrixColumn = 1;
}
My input is this...
3
3 -2 4
-1 5 2
-3 6 4
Output gets through matrices size 1 and 2. It gets as far as the third matrix row 3, column 0. At row 3, col 0, I get the ArrayIndexOutOfBounds error again.
I had it working but then ran into trouble setting the values but.... the project is to be a "matrix as a linked list" which is different than the previous assignment "matrix as a 2D array". So perhaps my structures are incorrect to begin with? Also, My Node class is separate (as an ADT implementing an interface). There is a whole 'nother class for finding the determinant. Not worried about that at right now. Also, we are given the "matrix size" the line before the matrix data in the input. And thank you again!
**Can't sleep edit...
This construct works through the entire input file. So now I just need to figure out where to set the values. (Value is not being assigned here so I'll likely delete it unless I can figure out a way around that).
void construct(int n, int m, double value) {
System.out.println("construct " + n + " n " + m + " m " + value + " value");
Node[][] a = new Node[n + 1][m + 1];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
Node ptr = new Node();
ptr.data = a[i][j];
ptr.right = null;
ptr.down = null;
a[i][j] = ptr;
a[i][j].right = a[i][j + 1];
a[i][j].down = a[i + 1][j];
}
}
}
It seems to be an off by one error. If we replace the values:
int matrixRow = 1;
int matrixColumn = 1;
into what is being declared, we see that you are accessing the array at the place a[1][1], but your declaration for the array size is Node[][] a = new Node[1][1]; (when replacing n and m by the value above). This means that the only element accessible for setValue is a[0][0] (because arrays have a length of size - 1.
I suggest you do an array bounds-checking if-statement on the setValue function, you'll be able to catch errors like this with greater ease. Another way to check my theory is to set matrixRow and matrixColumn as 2 and insert a debug print statement for the array at the beginning of the setValue function, and see what is the first element populated.
Edit:
The reason you get an error in your construct function is because you are creating a zero length array, and then trying to access its first element (see Why does Java allow arrays of size 0? for more info on zero length arrays in java)
I don't know the nature of your project, but I suggest you separate the logic of your code. It seems that you are representing your matrix as an array of "Node"s, and that you know the size of the matrix beforehand.
If so, I would suggest representing your matrix as a class, and making the construct method return and instance of that class.
At the very least, I see no reason as to why you should need to create the matrix inside the while loop. Create it beforehand, and populate it with values later.
I want to print put the elements in an array that only occur twice. So if, for example, number 2 occurs 3 or 4 times, it should not be printed. The code I've written so far is below.
The issue in my code is with the loop. For example, for the number 2, since j=i+1 is the initialization condition, the inner loop won't read the elements before the jth location- since there is a 2 at index 6, it won't count the 2s before it, making the required condition true and displaying the 2. Is there a way to fix this?
public class Problem2 {
public static void exactlytwice(int[] x) {
int count, j;
for (int i = 0; i < x.length; i++) {
count = 0;
for (j = i + 1; j < x.length; j++) {
if (x[i] == x[j])
count++;
}
if (count == 1) System.out.print(x[i] + " ");
}
}
public static void main(String[] args) {
int[] x = new int[15];
x[0] = 2;
x[1] = 2;
x[2] = 2;
x[3] = 13;
x[4] = 44;
x[5] = 44;
x[6] = 2;
x[7] = 63;
x[8] = 63;
x[9] = 90;
x[10] = 1;
x[11] = 2;
x[12] = 150;
x[13] = 150;
x[14] = 180;
exactlytwice(x);
}
}
aside from the issue you wrote, the bigger problem I see with your code is that its inefficient. You are doing a loop inside a loop here, which is very slow (o(n^2)).
My suggestion is to keep a map of numbers->count, and then only take the ones that appear only twice in the map:
public static void exactlytwice(int[] x) {
Map<Integer, Integer> counter = new HashMap<>();
for (int i = 0; i < x.length; i++) {
if (counter.contains(i)) {
counter.put(i,1);
} else {
counter.put(i,counter.get(i)+1);
}
}
for (Integer i : counter.keyset()) {
if (counter.get(i) == 2) {
System.out.println(i);
}
}
}
Think about maintaining a seperate array/list which keeps track of all the elements that has been counted/printed by which you could just skip the same number that shows again down the array.
Or you could sort the array and then perform the whole logic to check for duplicates.
Just for completeness, there is a solution without extra-map. It's still O(n^2), but uses no extra memory. And It uses kind of fun idea.
First, we only need to output first occurence of a number, every other one is not relevant, because we either have more than 2 of them, or we've already output the first one.
Second, we can then indeed continue, from i+1 element, because at this point, there are no elements equal to ith, that are earlier in array.
public static void exactlytwice(int[] x) {
int count, j;
TOP:
for (int i = 0; i < x.length; i++) {
count = 0;
for (j = 0; j < i; j++) {
if (x[j] == x[i])
// had this number earlier, so go to the next one.
continue TOP;
}
for (j = i+1; j < x.length; j++) {
if (i != j && x[i] == x[j])
count++;
}
if (count == 1) System.out.print(x[i] + " ");
}
}
In addition to the answers provided, there are two more ways you could go about this:
If array modification is permitted, change elements already encountered to a dummy value, and skip the value if encountered. This reduces the time complexity to O(n) from O(n^2), but destroys the original array. Of course, this assumes that the acceptable integers are restricted to a certain set (thanks to #Dzmitry Paulenka for reminding me that I hadn't stated this explicitly). To keep the array, you could make a copy (although then the space complexity becomes O(n) ).
If any integer is acceptable, then create an encountered boolean array, all intialized to false. Change the locations of elements encountered in the original array to true in the encountered boolean array, and if the value is already true, it can be skipped. Again, time complexity O(n), but O(n) space complexity, and unlike in the second method of 1., does not require the permissible range of numbers (ints) to be restricted.
Alternately, simply make the initialization of j as j=0, and then ensure that only those numbers which don't have that number appearing before them are printed, i.e., that the number is printed only if it occurs at j>=i (thanks to #Nir Levy for pointing the j>=i requirement out). This is (slightly) more inefficient than the code already written, but the time complexity remains the same O(n^2).
With Java 8 you can achieve this using streams like this :
public static void main(String[] args)
{
List<Integer> list = Stream.of(12,1,3,4,2,3,7,6,7,3,1,8,4,12,33,45,78,36,8)
.collect(Collectors.groupingBy(x->x, Collectors.summingInt(x->1)))
.entrySet().stream().filter(x->x.getValue()==2)
.collect(ArrayList<Integer>::new,(x,y)->x.add(y.getKey()),ArrayList<Integer>::addAll);
System.out.println(list);
}
The result is :
[1, 4, 7, 8, 12]
Code:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
public class Writer {
private int counter;
private Random generator = new Random();
private List<Integer> data = new ArrayList<Integer>();
private Map<Integer,Integer> map = new HashMap<Integer,Integer>();
public Writer(int n){
populate(n);
}
private final void populate(int n){
for(int i = 0; i != n; i++){
data.add(generator.nextInt(10));
}
}
private final void reset(){
this.counter = 0;
}
public final void occurence(){
for(int dp : data){
for(int i = 0; i < data.size(); i++){
if(dp == data.get(i)){
counter += 1;
}
}
map.put(dp, counter);
reset();
}
}
public final void filter(int d){
for(int key : map.keySet()){
if(map.get(key) == d){
System.out.println("Key: " + key + " Value: " + map.get(key));
}
}
}
public void rawData(){
System.out.println(data.toString());
}
public void output(){
System.out.println(map.toString());
}
Initiate:
// Create instance of Writer class and generate '100' random numbers
Writer writer = new Writer(100);
// Output raw data
writer.rawData();
// Process data
writer.occurence();
// Filter numbers with occurence '10'
writer.filter(10);
// Output processed data
writer.output();
Output (from from calling filter(10)):
Key: 3 Value: 10
Key: 8 Value: 10
So I have been trying to fix this by myself but I didn't find enough info on the subject.
In the next code, there is a function that receives an array of a
linked list (Integer), the array is a representation of a square that
has black and white squares inside (1 = white, 0 = black), the format
is the next one: The first node of the linked list is white, every
next node is the opposite color of the last node. For example if the
square is: white -> white -> white -> black - > white - > black ->
black the linked list would be 3 -> 1 -> 1 -> 2 -> null (if there are
consecutive colors they sum up in the linked list as seen before). So
my code is the next:
public static int[][] restorePicture (LinkedList[] linked_list)
{
boolean black = false;
int[][] Input = new int [(linked_list.length)][];
for(int k = 0; k < linked_list.length; k++)
Input[k] = new int[linked_list[k].size()];
for(int i = 0;i < linked_list.length; i++)
{
black = false;
int j = 0;
while(linked_list[i].get(j) != linked_list[i].getLast())
{
if(black == false)
{
for(int z = (int) linked_list[i].get(j); z > 0 ;z--)
Input[j++][i] = 1;
black = true;
}
if(black == true)
{
for(int x = (int) linked_list[i].get(j); x > 0 ;x--)
Input[j++][i] = 0;
black = false;
}
}
}
for(int i = 0; i < Input.length; i++)
for(int j = 0; j < Input[j].length; j++)
System.out.println(Input[i][j]);
return Input;
}
i assume that you call the method 'restorePicture' with a simple LinkedList instead an Array of LinkedList.
Thats why you get the error.
Check the method call at line 10 in your code. Compile error statements in Eclipse are quiet good.
The warning you get because you do not specify the type of LinkedList, so you have to change the parameter definition to.
public static int[][] restorePicture (LinkedList<Integer>[] linked_list)
To create a new Array of LinkedLIst you have to code
LinkedList<Integer>[] linked_list = new LinkedList[input.length];
I having a really hard time finding a plateau within an array. What I'm looking for is length and location of the longest sequence of equal values where the numbers on both sides are smaller. Now I know there could be two or more valid plateaus with same length ideally I would like to print the plateau with a higher value.
I have created an array[40] and a Random obj. To fill the array, once I have filled it I know I will need a loop to check the indexes. But thats where the confusion comes in. I have tried using a for loop to find the plateau but my results would just increase the value stored within the index.
Any points in the right direction I would greatly appreciate it.
import java.util.Random;
public class Plateau {
public static void main(String[]args)
{
int[] array1 = new int[40];
Random genrator = new Random();
for (int i = 0; i < array1.length; i++)
{
array1[i] = genrator.nextInt(21 - 1);
}
for(int i = 0; i < array1.length; i++)
{
System.out.print(array1[i] + " ");
}
System.out.println("\n");
for (int i = 0; i < array1.length; i++)
{
if (array1[i] < array1[i] + 1)
{
System.out.println(array1[i] + " ");
}
}
}
}
In pseudo-code:
V value=first value
P position=1
L length=0
Scan the values from position Q=2
Compare current value C to V
If C is less than V
if this sequence Q-P is longer than L
save length as L
save P as location R
update V and P to current value
If C is greater than V
update V and P to current value
I don't have a compiler for pseudo-code so it might not be exactly right, but it should be a start.