Problem:
I have 3 machines, each machine have a limit of 30 ms time, each machine have 3 zones that a task can't be executed there.
The tasks have a P (priority) and W (weight, which is the time to complete the task in this setup), tasks must be first ordered by a priority, from lower to higher like this:
Task 01 {6, 2} // P/W = 3 this task executed last (3)
Task 02 {7, 7} // P/W = 1 this task executed first (1)
Task 03 {4, 2} // P/W = 2 this task executed second (2)
Now, in order to execute a tasks(I have 6), I must check all 3 machines to find the first fit to the task, to chose a fit for task, it must be the optimal in the 3 machines, example:
Machine 01; |-----5----9-------16-17--19-20|
Machine 02: |----4-5--7-8---------17-18--|
Machine 03: |-----5---8--10---13--15---18--|
(1)Task 02 executed in machine 02 (We look for P ms to execute task, and the minimum time to start a task, since both machine 01 (starting from 9 ms) and 02 (starting from 8 ms) have a 7 ms free time, machine 02 can start a task first then the machine 01).
(2)Task 03 executed in machine 02 (We look for P ms to execute task).
(3)Task 01 executed in machine 01 (We look for P ms to execute task).
Certain periods of time are defined as critical, and cannot be used to schedule a job. These periods (for instance 5-9, 7-8), are stored in the dedicated struct z_indispo.
The bfeet struct is used to store in witch the task start and in witch machine.
I implemented mostly the entire algorithm in C, but my results are different than expected:
#include <stdio.h>
typedef struct _z_indispo {
int t1;
int t2;
} z_indispo;
typedef struct _machines {
int t[20]; // array represent time
z_indispo zone[2];
} machines;
typedef struct _tache {
int p;
int w;
int c; // p/w
int i; // Task number
} tache;
typedef struct _bfeet {
int t; // Store the time to of ending execution by a task
int m; // The machine responsible for executing a task.
} bfeet;
int main(int argc, char **argv)
{
machines m[4];
tache j[6];
tache j_tmp;
bfeet b[4];
int i = 0;
int n = 0;
int u = 0;
int k = 0;
int count = 0;
int trouver = 0;
int f_totale = 0;
int f[3] = {0};
m[0].zone[0].t1 = 7;
m[0].zone[0].t2 = 9;
m[0].zone[1].t1 = 14;
m[0].zone[1].t2 = 15;
m[1].zone[0].t1 = 8;
m[1].zone[0].t2 = 9;
m[1].zone[1].t1 = 16;
m[1].zone[1].t2 = 17;
m[2].zone[0].t1 = 7;
m[2].zone[0].t2 = 8;
m[2].zone[1].t1 = 18;
m[2].zone[1].t2 = 19;
/*
* Initialise all machines
* 0: Represent free time.
* -1: Represent critical zone range.
* -2: Represent a task already executed.
*/
for(i = 0; i< 3; ++i)
{
for(count = 0; count < 20; ++count)
{
if((count >= m[i].zone[0].t1 - 1 && count <= m[i].zone[0].t2 - 1) ||
(count >= m[i].zone[1].t1 - 1 && count <= m[i].zone[1].t2 - 1))
{
m[i].t[count] = -1;
}
else
{
m[i].t[count] = 0;
}
}
}
for(i = 0; i< 3; ++i)
{
if(i == 0)
printf(" D(1,1) t1 s1 D(1,2) t2 s2 D(1,3)\n");
else if(i == 1)
printf(" D(2,1) t1 s1 D(2,2) t2 s2 D(2,3)\n");
else if(i == 2)
printf(" D(3,1) t1 s1 D(3,2) t2 s2 D(3,3)\n");
printf("|");
for(count = 0; count < 20; ++count)
{
printf("%3d", m[i].t[count]);
}
printf(" |\n\n");
}
j[0].p = 5;
j[0].w = 2;
j[0].i = 1;
j[1].p = 9;
j[1].w = 3;
j[1].i = 2;
j[2].p = 6;
j[2].w = 3;
j[2].i = 3;
j[3].p = 6;
j[3].w = 4;
j[3].i = 4;
j[4].p = 7;
j[4].w = 7;
j[4].i = 5;
/*
* Calc C = P/W .
*/
for(count = 0; count < 5; ++count)
{
j[count].c = j[count].p / j[count].w;
}
/*
* Sort tasks from low to hight
*/
for(count = 0; count < 5; ++count)
{
for(k = 0; k < 5 - count; ++k)
{
if(j[k].c > j[k + 1].c)
{
j_tmp = j[k + 1];
j[k + 1] = j[k];
j[k] = j_tmp;
}
}
}
/*printf("|%2J |%2 P |%2 W | C |\n");
printf("_____________________\n");
for(count = 0; count < 5; ++count)
{
printf("|%-4d|%-4d|%-4d|%-4d|\n", j[count].i, j[count].p, j[count].w, j[count].c);
}
printf("\n");*/
/*
* Execute tasks
*/
while(n < 5)
{
for(count = 0; count < 3; ++count)
{
i = 0;
trouver = 0;
while(i <= 20 && trouver != 1)
{
if(m[count].t[i] == 0) // We have a free time to start with it.
{
u = 0; // num of available indexs.
while(m[count].t[i] != -1 && m[count].t[i] != -2)
{
if(u == j[n].p)
break;
++u;
++i;
}
if(u < j[n].p)
{
while(m[count].t[i] == -1 && m[count].t[i] == -2) // bypass unfree unites
++i;
}
else if(u == j[n].p)
{
b[count].t = i - u;
b[count].m = count; //
trouver = 1; // we find the Necessary unites to start a task
}
}
else
++i;
}
}
if(u < j[n].p)
printf("There is no free time to execute task %d", j[n].i);
else
{
// Find the minimum time in all machines to start a task
b[3].t = b[0].t;
b[3].m = b[0].m;
for(count = 0; count < 3; ++count)
{
if(b[3].t > b[count + 1].t)
{
b[3].t = b[count + 1].t;
b[3].m = b[count + 1].m;
}
}
// Put -2 to indicate that index is unfree
u = b[3].t + j[n].p;
for(count = b[3].t; count < u; ++count)
{
m[b[3].m].t[count] = -2;
}
if(b[3].m == 0)
f[0] = (b[3].t + j[n].p);
else if(b[3].m == 1)
f[1] = (b[3].t + j[n].p);
else if(b[3].m == 2)
f[2] = (b[3].t + j[n].p);
printf("Task %d end at %-2d, machine %d.\n", j[n].i, b[3].t + j[n].p, b[3].m + 1);
}
++n;
}
printf("\n");
f_totale = f[0] + f[1] + f[2];
printf("F of machine 01: %d.\n", f[0]);
printf("F of machine 02: %d.\n", f[1]);
printf("F of machine 03: %d.\n", f[2]);
printf("Total F: %d.\n", f_totale);
printf("\n");
/*printf("\n");
for(i = 0; i< 3; ++i)
{
if(i == 0)
printf(" D(1,1) t1 s1 D(1,2) t2 s2 D(1,3)\n");
else if(i == 1)
printf(" D(2,1) t1 s1 D(2,2) t2 s2 D(2,3)\n");
else if(i == 2)
printf(" D(3,1) t1 s1 D(3,2) t2 s2 D(3,3)\n");
printf("|");
for(count = 0; count < 20; ++count)
{
printf("%3d", m[i].t[count]);
}
printf(" |\n\n");
}*/
return 0;
}
UPDATE:
I have now only two unavailability zones in each machine. I also updated the code to fix some errors, but I still get a different output then this example:
I have this unavailability zones:
m[0].zone[0].t1 = 7;
m[0].zone[0].t2 = 9;
m[0].zone[1].t1 = 14;
m[0].zone[1].t2 = 15;
m[1].zone[0].t1 = 8;
m[1].zone[0].t2 = 9;
m[1].zone[1].t1 = 16;
m[1].zone[1].t2 = 17;
m[2].zone[0].t1 = 7;
m[2].zone[0].t2 = 8;
m[2].zone[1].t1 = 18;
m[2].zone[1].t2 = 19;
5 tasks:
p | 6 9 5 7 6
w | 3 3 2 7 4
_______________
c | 2 3 2 1 1
After ordering by c:
p | 7 6 5 6 9
w | 7 4 2 3 3
_______________
c | 1 1 2 2 3
The execution of tasks should be like this:
J4
|_______7__9_____14_15__________| ms
Task 04 should end at 7, P represent the time necessary to execute a task.
J5
|________8_9__________16_17_____| ms
Task 05 should end at 7.
J1 J3
|_______7_8_______________18_19_| ms
Task 01 should end at 6, task 03 should end at 14.
UPDATE 02: (This problem fixed)
I noticed a strange behavior in my program, after I initializing m[i].t[count] array, I found that variables responsible for storing unavailability zones changed:
NOTE: This problem fixed.
UPDATE03: (This problem fixed but with new issue)
I have situation when a task can't find the necessary unites to start, I never get this message "There is no free time to execute task ", witch I should receive it for task 2, since it has 9 unites, and all machines have no such of free time like that. The code responsible for this test:
for(count = 0; count < 3; ++count) // search on all machines
{
i = 0;
trouver = 0;
while(i < 20 && trouver != 1)
{
if(m[count].t[i] == 0) // We have a free time to start with it.
{
u = 0; // num of available indexs.
while(m[count].t[i] != -1 && m[count].t[i] != -2)
{
if(u == j[n].p)
break;
++u;
++i;
}
if(u < j[n].p)
{
while(m[count].t[i] == -1 && m[count].t[i] == -2) // bypass unfree unites
++i;
}
else if(u == j[n].p)
{
b[count].t = i - u;
b[count].m = count; //
trouver = 1; // we find the Necessary unites to start a task
}
}
else
++i;
}
}
/* u represent the number of continuous free time,
j[n].p represent the necessary time to execute the current task, n is the current task
if(u < j[n].p)
printf("There is no free time to execute task %d", j[n].i);
else
{
// Find the minimum time in all machines to start a task
b[3].t = b[0].t;
b[3].m = b[0].m;
UPDATE04:
Now I can see excluded task when there is no free time to execute a task, however, the output is not right, because I see a task override the period time on another task:
while(n < 5)
{
k = 0;
for(count = 0; count < 3; ++count)
{
i = 0;
u = 0;
trouver = 0;
while(i < 20 && trouver != 1)
{
if(m[count].t[i] == 0) // We have a free time to start with it.
{
//u = 0; // num of available indexs.
if(u == j[n].p)
break;
else
{
++u;
++i;
}
}
if(u != j[n].p)
{
if((m[count].t[i] == -1 || m[count].t[i] == -2))// bypass unfree unites
{
u = 0;
++i;
}
}
if(u == j[n].p)
{
++k;
b[count].t = i - u;
b[count].m = count; //
trouver = 1; // we find the Necessary unites to start a task
}
}
}
if(u != j[n].p)
{
printf("There is no free time to execute task %d.\n", j[n].i);
}
else
{
// Find the minimum time in all machines to start a task
b[3] = b[0];
for(count = 0; count < 3; ++count)
{
if(b[count].t != 0)
if(b[3].t > b[count + 1].t)
{
b[3] = b[count + 1];
}
}
// Put -2 to indicate that index is unfree
u = b[3].t + j[n].p;
for(count = b[3].t; count < u; ++count)
{
m[b[3].m].t[count] = -2;
}
if(b[3].m == 0)
f[0] = (b[3].t + j[n].p);
else if(b[3].m == 1)
f[1] = (b[3].t + j[n].p);
else if(b[3].m == 2)
f[2] = (b[3].t + j[n].p);
printf("Task %d end at %-2d, machine %d.\n", j[n].i, b[3].t + j[n].p, b[3].m + 1);
}
++n;
}
Output:
D(1,1) t1 s1 D(1,2) t2 s2 D(1,3)
| 0 0 0 0 0 0 -1 -1 -1 0 0 0 0 -1 -1 0 0 0 0 0 |
D(2,1) t1 s1 D(2,2) t2 s2 D(2,3)
| 0 0 0 0 0 0 0 -1 -1 0 0 0 0 0 0 -1 -1 0 0 0 |
D(3,1) t1 s1 D(3,2) t2 s2 D(3,3)
| 0 0 0 0 0 0 -1 -1 0 0 0 0 0 0 0 0 0 -1 -1 0 |
| J | P | W | C |
_____________________
|1 |5 |2 |2 |
|2 |7 |3 |2 |
|3 |8 |3 |2 |
|5 |17 |7 |2 |
|4 |16 |4 |4 |
Task 1 end at 5 , machine 1.
Task 2 end at 7 , machine 1.
Task 3 end at 8 , machine 1.
There is no free time to execute task 5.
There is no free time to execute task 4.
F of machine 01: 8.
F of machine 02: 0.
F of machine 03: 0.
Total F: 8.
D(1,1) t1 s1 D(1,2) t2 s2 D(1,3)
| -2 -2 -2 -2 -2 -2 -2 -2 -1 0 0 0 0 -1 -1 0 0 0 0 0 |
D(2,1) t1 s1 D(2,2) t2 s2 D(2,3)
| 0 0 0 0 0 0 0 -1 -1 0 0 0 0 0 0 -1 -1 0 0 0 |
D(3,1) t1 s1 D(3,2) t2 s2 D(3,3)
| 0 0 0 0 0 0 -1 -1 0 0 0 0 0 0 0 0 0 -1 -1 0 |
I found that the problem was in how I search for the minimum starting time in the machines to start task:
....
// Find the minimum time in all machines to start a task
b[3] = b[0]; // this cause the problem
for(count = 0; count < 3; ++count)
{
if(b[count].t != 0)
if(b[3].t > b[count + 1].t)
{
b[3] = b[count + 1];
}
}
b[3] as start could refer to a machine that can't start the current task, so I made a little change:
// Find the minimum time in all machines to start a task
for(count = 0; count < 3; ++count) // search only in the machines that can execute the current task
{
if(b[count].m != -1)
{
b[3] = b[count];
break;
}
}
for(count = 0; count < 3; ++count) // search for the first machines that can execute the current task
{
if(b[count].m != -1)
{
if((b[3].t > b[count + 1].t) && (b[count + 1].m != -1)) // make sure the next machine can start the current task
{
b[3] = b[count + 1];
}
}
}
The complete algorithm:
#include <stdio.h>
typedef struct _z_indispo {
int t1;
int t2;
} z_indispo;
typedef struct _machines {
int t[20]; // array represent time
z_indispo zone[2];
} machines;
typedef struct _tache {
int p;
int w;
int c; // p/w
int i; // Task number
} tache;
typedef struct _bfeet {
int t; // Store the time to of ending execution by a task
int m; // The machine responsible for executing a task.
} bfeet;
int main(int argc, char **argv)
{
machines m[4] = {0};
tache j[6];
tache j_tmp;
bfeet b[4] = {0};
int i = 0;
int n = 0;
int u = 0;
int k = 0;
int count = 0;
int trouver = 0;
int f_totale = 0;
int f[3] = {0};
m[0].zone[0].t1 = 7;
m[0].zone[0].t2 = 9;
m[0].zone[1].t1 = 14;
m[0].zone[1].t2 = 15;
m[1].zone[0].t1 = 8;
m[1].zone[0].t2 = 9;
m[1].zone[1].t1 = 16;
m[1].zone[1].t2 = 17;
m[2].zone[0].t1 = 7;
m[2].zone[0].t2 = 8;
m[2].zone[1].t1 = 18;
m[2].zone[1].t2 = 19;
/*
* Initialise all machines
* 0: Represent free time.
* -1: Represent critical zone range.
* -2: Represent a task already executed.
*/
for(i = 0; i< 3; ++i)
{
for(count = 0; count < 20; ++count)
{
if((count >= m[i].zone[0].t1 - 1 && count <= m[i].zone[0].t2 - 1) ||
(count >= m[i].zone[1].t1 - 1 && count <= m[i].zone[1].t2 - 1))
{
m[i].t[count] = -1;
}
else
{
m[i].t[count] = 0;
}
}
}
for(i = 0; i< 3; ++i)
{
if(i == 0)
printf(" D(1,1) t1 s1 D(1,2) t2 s2 D(1,3)\n");
else if(i == 1)
printf(" D(2,1) t1 s1 D(2,2) t2 s2 D(2,3)\n");
else if(i == 2)
printf(" D(3,1) t1 s1 D(3,2) t2 s2 D(3,3)\n");
printf("|");
for(count = 0; count < 20; ++count)
{
printf("%3d", m[i].t[count]);
}
printf(" |\n\n");
}
j[0].p = 5;
j[0].w = 2;
j[0].i = 1;
j[1].p = 7;
j[1].w = 3;
j[1].i = 2;
j[2].p = 4;
j[2].w = 1;
j[2].i = 3;
j[3].p = 6;
j[3].w = 4;
j[3].i = 4;
j[4].p = 7;
j[4].w = 7;
j[4].i = 5;
/*
* Calc C = P/W .
*/
for(count = 0; count < 5; ++count)
{
j[count].c = j[count].p / j[count].w;
}
/*
* Sort tasks from low to hight
*/
for(count = 0; count < 5; ++count)
{
for(k = 0; k < 5 - count; ++k)
{
if(j[k].c > j[k + 1].c)
{
j_tmp = j[k + 1];
j[k + 1] = j[k];
j[k] = j_tmp;
}
}
}
printf("|%2J |%2 P |%2 W | C |\n");
printf("_____________________\n");
for(count = 0; count < 5; ++count)
{
printf("|%-4d|%-4d|%-4d|%-4d|\n", j[count].i, j[count].p, j[count].w, j[count].c);
}
printf("\n");
/*
* Execute tasks
*/
while(n < 5)
{
k = 0;
for(count = 0; count < 3; ++count)
{
i = 0;
u = 0;
trouver = 0;
while(i < 20 && trouver != 1)
{
if(m[count].t[i] == 0) // we find a free unite
{
while(m[count].t[i] == 0 && u != j[n].p && i < 20) // count a continues free time, quit when u equal the necessary time to execute the current task
{
++u;
++i;
}
if(u == j[n].p) // we found a free continues time
{
b[count].t = i - u; // save the starting index
b[count].m = count; // save the machine responsible for executing the current task
++k;
trouver = 1;
}
else if(u != j[n].p) // if we encounter zone unavailability or index reserved by another task
{
u = 0; // restart u counter
while((m[count].t[i] == -1 || m[count].t[i] == -2) && (i < 20)) // bypass reserved/unavailability index's
++i;
}
}
else
++i; // bypass reserved/unavailability index's
}
if(trouver != 1) // we mark this machine as it can't execute the current task
{
b[count].m = -1;
}
}
if(k == 0)
printf("There is no free time to execute task %d.\n", j[n].i);
else
{
// Find the minimum time in all machines to start a task
for(count = 0; count < 3; ++count) // search only in the machines that can execute the current task
{
if(b[count].m != -1)
{
b[3] = b[count];
break;
}
}
for(count = 0; count < 3; ++count) // search only in the machines that can execute the current task
{
if(b[count].m != -1)
{
if((b[3].t > b[count + 1].t) && (b[count + 1].m != -1))
{
b[3] = b[count + 1];
}
}
}
// Put -2 to indicate that index as unfree
u = b[3].t + j[n].p;
for(count = b[3].t; count < u; ++count)
{
m[b[3].m].t[count] = -2;
}
if(b[3].m == 0)
f[0] = f[0] + (b[3].t + j[n].p) * j[n].w;
else if(b[3].m == 1)
f[1] = f[1] + (b[3].t + j[n].p) * j[n].w;
else if(b[3].m == 2)
f[2] = f[2] + (b[3].t + j[n].p) * j[n].w;
printf("Task %d end at %-3dms, machine %d.\n", j[n].i, b[3].t + j[n].p, b[3].m + 1);
}
++n;
}
printf("\n");
f_totale = f[0] + f[1] + f[2];
printf("F of machine 01: %d.\n", f[0]);
printf("F of machine 02: %d.\n", f[1]);
printf("F of machine 03: %d.\n", f[2]);
printf("Total F: %d.\n", f_totale);
printf("\n");
printf("\n");
for(i = 0; i< 3; ++i)
{
if(i == 0)
printf(" D(1,1) t1 s1 D(1,2) t2 s2 D(1,3)\n");
else if(i == 1)
printf(" D(2,1) t1 s1 D(2,2) t2 s2 D(2,3)\n");
else if(i == 2)
printf(" D(3,1) t1 s1 D(3,2) t2 s2 D(3,3)\n");
printf("|");
for(count = 0; count < 20; ++count)
{
printf("%3d", m[i].t[count]);
}
printf(" |\n\n");
}
return 0;
}
You have persistent short-by-one errors in your array definitions. Basically, C arrays are zero-indexed, so if you want to access array[n], array has to have been defined with size at least n+1. For instance your machine struct should be
typedef struct _machines {
int t[20];
z_indispo zone[2];
} machines;
since you access machine.t[20] and machine.zone[1].
This fixes the issue in your second update (memory getting stomped on like that is a pretty good indicator that you're indexing beyond the end of the array). The first one will likely get fixed (or at least you'll be a lot further along the road to a solution) once you fix the array initializations in main() similarly (e.g. you're accessing b[3].t, but since you defined it via bfeet b[3] it only has indices b[0], b[1] and b[2]).
Related
To preface what I'm trying to do - I'm trying to make a Shortest Job First (SJF), the OS algo in C.
And to handle the sort-by-burst-time, I'm pushing all the ready processes in a stack, and then sorting that stack in a descending order. So for example - if the stack looks like 3,5,1,2 with "2" on top, I'm trying to sort it as: 5,3,2,1 with "1" on top. So when I start using pop, I'll get elements in the order I require.
But the problem with the code I'm going to show is, it orders 1,1,5,3 as 5,1,1,3. The last process "3" is never sorted.
Code for Sorting:
void sortByBurst() {
int size = top;
struct fcfs temp;
for (int i = 0; i < size - 1; i++) {
for (int j = 0; j < (size - 1 - i); j++) {
if (stack[j].burst < stack[j + 1].burst) {
temp = stack[j];
stack[j] = stack[j + 1];
stack[j + 1] = temp;
}
}
}
}
And in case you want to see where I'm handling the rest of the logic i.e making decisions on what to push - this is the for loop for that:
for (i = 0; i < numOfProc; i++) {
if (first_process == 1 && p[i].arrival <= current_time && p[i].completed == 0) {
min_index = i;
} else if (first_process == 0 && last_index != -1) {
for (int k = 0; k < numOfProc; k++) {
if (p[k].completed == 0 && p[k].arrival <= p[last_index].max_slot && p[k].inQ != 1) {
push(p[k]);
p[k].inQ = 1;
critical_case = 1;
} else if (p[k].completed == 0 && p[k].arrival > finalp[last_index].max_slot && p[k].inQ != 1) {
min_index = k;
}
}
if (critical_case == 1) {
sortByBurst();
struct fcfs compare = pop();
for (int l = 0; l < numOfProc; l++) {
if (compare.pid == p[l].pid) {
min_index = l;
break;
}
}
}
break;
}
}
The input I'm testing my code with is:
1. Process 1 | 2 (Arrival) | 1 (Burst)
2. Process 2 | 1 (Arrival) | 5 (Burst)
3. Process 3 | 4 (Arrival) | 1 (Burst)
4. Process 4 | 0 (Arrival) | 6 (Burst)
5. Process 5 | 2 (Arrival) | 3 (Burst)
Required Output:
1. Process 4 | 0 (Arrival) | 6 (Burst)
2. Process 1 | 2 (Arrival) | 1 (Burst)
3. Process 3 | 4 (Arrival) | 1 (Burst)
4. Process 5 | 2 (Arrival) | 3 (Burst)
5. Process 2 | 1 (Arrival) | 5 (Burst)
Output I'm Getting:
1. Process 4 | 0 (Arrival) | 6 (Burst)
2. Process 5 | 2 (Arrival) | 3 (Burst)
3. Process 3 | 4 (Arrival) | 1 (Burst)
4. Process 1 | 2 (Arrival) | 1 (Burst)
5. Process 2 | 1 (Arrival) | 5 (Burst)
As you can see, the Process 5 should be at 4th place in the list. But because in Stack - it's still on Top even after sorting, the algo is not working as it should. Kindly look into what I'm doing wrong here.
Complete Code:
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
struct fcfs {
int pid, arrival, burst, min_slot, max_slot, wait_time, completed, inQ;
};
struct fcfs stack[10];
int top = -1;
void push(struct fcfs process);
struct fcfs pop();
void sortByBurst();
void pline(int x);
void main() {
int i, numOfProc, j;
int counter = 0;
int current_time = 0;
int completed = 0;
struct fcfs p[10], finalp[10];
int first_process = 1;
int prevMaxSlot = 0;
int last_index = -1;
int critical_case = 0;
printf("Enter total number of Processes \n");
scanf("%d", &numOfProc);
for (i = 0; i < numOfProc; i++) {
printf("Enter Arrival Time & Burst Time for Process %d: \n", i + 1);
scanf("%d %d", &p[i].arrival, &p[i].burst);
p[i].pid = i + 1;
p[i].wait_time = 0;
p[i].completed = 0;
p[i].inQ = 0;
}
int prev = 0;
while (completed != numOfProc) {
int min_index = -1;
for (i = 0; i < numOfProc; i++) {
if (first_process == 1 && p[i].arrival <= current_time && p[i].completed == 0) {
min_index = i;
} else if (first_process == 0 && last_index != -1) {
for (int k = 0; k < numOfProc; k++) {
if (p[k].completed == 0 && p[k].arrival <= p[last_index].max_slot && p[k].inQ != 1) {
push(p[k]);
p[k].inQ = 1;
critical_case = 1;
} else if (p[k].completed == 0 && p[k].arrival > finalp[last_index].max_slot && p[k].inQ != 1) {
min_index = k;
}
}
if (critical_case == 1) {
sortByBurst();
struct fcfs compare = pop();
for (int l = 0; l < numOfProc; l++) {
if (compare.pid == p[l].pid) {
min_index = l;
break;
}
}
}
break;
}
}
if (min_index == -1) {
current_time++;
} else {
if (p[min_index].arrival == prevMaxSlot) {
p[min_index].min_slot = prevMaxSlot;
p[min_index].max_slot = p[min_index].arrival + p[min_index].burst;
} else if (p[min_index].arrival < prevMaxSlot || p[min_index].arrival == prevMaxSlot) {
p[min_index].min_slot = prevMaxSlot;
p[min_index].max_slot = p[min_index].min_slot + p[min_index].burst;
} else if (p[min_index].arrival > prevMaxSlot) {
p[min_index].min_slot = p[min_index].arrival;
p[min_index].max_slot = p[min_index].arrival + p[min_index].burst;
}
p[min_index].wait_time = (first_process == 1) ? 0 : abs(p[i].min_slot - prev);
p[min_index].completed = 1;
prev = current_time;
prevMaxSlot = p[min_index].max_slot;
finalp[counter++] = p[min_index];
first_process = 0;
last_index = min_index;
completed++;
}
}
pline(44);
printf("Slot\tPID\tArrival\t\tBurst\n");
pline(44);
for (i = 0; i < numOfProc; i++) {
if ((finalp[i].min_slot - finalp[i - 1].max_slot) > 0 && i > 0) {
printf("%d - %d\tNONE\tNONE\t\tNONE\n", finalp[i - 1].max_slot, finalp[i].min_slot);
} else if ((abs(0 - finalp[i].min_slot) > 0 && i == 0)) {
printf("0 - %d\tNONE\tNONE\t\tNONE\n", finalp[i].min_slot);
}
printf("%d - %d\t%d\t%d\t\t%d\n", finalp[i].min_slot, finalp[i].max_slot, finalp[i].pid, finalp[i].arrival,
finalp[i].burst);
}
pline(44);
}
void pline(int x) {
for (int i = 0; i < x; i++) {
printf("-");
}
printf("\n");
}
void push(struct fcfs process) {
if (top == 10)
printf("\n Overflow");
else {
top = top + 1;
stack[top] = process;
}
}
struct fcfs pop() {
struct fcfs process;
if (top == -1)
printf("Underflow");
else {
process = stack[top];
top = top - 1;
}
return process;
}
void sortByBurst() {
int size = top + 1;
struct fcfs temp;
for (int i = 1; i < size - 1; i++) {
for (int j = 0; j < (size - 1 - i); j++) {
if (stack[j].burst < stack[j + 1].burst) {
temp = stack[j];
stack[j] = stack[j + 1];
stack[j + 1] = temp;
}
}
}
}
The issue was with top & i = 1;
In the sorting function, int size = top + 1 and initializing the for loop with i = 0 fixed it.
Thanks a lot to all who contributed.
we are trying to achieve round robin algorithm using linked list.
But My logic has some errors.
When I try to run it for 3 process then the first process values are wrong and sometimes right for the other below processes.
Please Help me.
I tried Searching for logics
Code Link: https://pastebin.com/FkbtUEaQ
#include<stdio.h>
struct process
{
char na[20];
int at, bt, ft, tat, rem;
//float ntat;
} Q[5], temp;
void roundRobin()
{
int rr[20], q, x, k;
int f, r, n, i, j, tt = 0, qt, t, flag, wt = 0;
float awt = 0, antat = 0, atat = 0;
printf("Enter the no. of jobs:");
scanf("%d", &n);
for (r = 0; r < n; r++)// aceppting arrival; and burst time
{
printf("Enter process name,arrival time and burst time:\n");
scanf("%s%d%d", Q[r].na, &Q[r].at, &Q[r].bt);
}
printf("Enter quantum:\n");
scanf("%d", &qt);
for (i = 0; i < n; i++)
{
for (j = i + 1; j < n; j++)
{
if (Q[i].at < Q[j].at) {
temp = Q[i];
Q[i] = Q[j];
Q[j] = temp;
}
}
}
for (i = 0; i < n; i++)
{
Q[i].rem = Q[i].bt;
Q[i].ft = 0;
}
tt = 0;
q = 0;
rr[q] = 0;
do
{
for (j = 0; j < n; j++)
if (tt >= Q[j].at)
{
x = 0;
for (k = 0; k <= q; k++)
if (rr[k] == j)
x++;
if (x == 0)
{
q++;
rr[q] = j;
}
}
if (q == 0)
i = 0;
if (Q[i].rem == 0)
i++;
if (i > q)
i = (i - 1) % q;
if (i <= q)
{
if (Q[i].rem > 0)
{
if (Q[i].rem < qt)
{
tt += Q[i].rem;
Q[i].rem = 0;
} else
{
tt += qt;
Q[i].rem -= qt;
}
Q[i].ft = tt;
}
i++;
}
flag = 0;
for (j = 0; j < n; j++)
if (Q[j].rem > 0)
flag++;
} while (flag != 0);
printf("\n\n\t\tROUND ROBIN ALGORITHM");
printf("\n***************************");
printf("\nprocesses Arrival time burst time finish time tat wt ntat");
for (f = 0; f < n; f++) {
wt = Q[f].ft - Q[f].bt - Q[f].at;
Q[f].tat = Q[f].ft - Q[f].at;
Q[f].ntat = (float) Q[f].tat / Q[f].bt;
antat += Q[f].ntat;
atat += Q[f].tat;
awt += wt;
printf("\n\t%s\t%d\t%d\t%d\t%d\t%d %f", Q[f].na, Q[f].at, Q[f].bt,
Q[f].ft, Q[f].tat, wt, Q[f].ntat);
}
antat /= n;
atat /= n;
awt /= n;
printf("\nAverage tat is %f", atat);
printf("\nAverage normalised tat is %f", antat);
printf("\n average waiting time is %f", awt);
}
void main()
{
roundRobin();
getch();
clrscr();
}
The First Process Gives Wrong Values
processes | ArrivalTime | BurstTime | FinishTime | Tat | WaitTime
a 0 10 60 60 50
b 0 20 30 30 10
c 0 30 50 50 20
In the do while loop you use i to index the rr array with valid indexes 0 to q as well as the Q array with valid indexes 0 to n − 1, of which only the former is correct. So, you have to change every occurrence of Q[i] in this loop to Q[rr[i]].
After that, still the order of the statements
if (Q[rr[i]].rem == 0)
i++;
if (i > q)
i = (i - 1) % q;
is wrong - the test for Q[rr[i]].rem == 0 is to be done each time a new i is chosen, e. g.:
while (Q[rr[i %= q+1]].rem == 0) i++;
I am aware this is a brute force and non optimal approach to solving the 3Sum problem. It does the job of detecting the triplets which sum up to zero. But I am looking for ways to detect duplicate triplets. I am not able to come up with the logic to look for similar triplet combinations which have already been considered. Thanks!
int** threeSum(int* nums, int numsSize, int *returnSize)
{
int count = 0;
int **res = NULL;
for (int i=0; i<(numsSize-2) ; i++)
{
for (int j=i+1; j<(numsSize-1) ; j++)
{
for(int k=j+1; k<numsSize ; k++)
{
if (0==(nums[i]+nums[j]+nums[k]))
{
if (count > 0)
{
res = (int **)realloc(res,sizeof(int *)*(count+1));
res[count] = (int *) malloc(sizeof(int)*3);
res[count][0] = nums[i];
res[count][1] = nums[j];
res[count][2] = nums[k];
count++;
}
else if (0==count)
{
res = (int **) malloc(sizeof(int *)*1);
res[0] = (int *) malloc(sizeof(int)*3);
res[0][0] = nums[i];
res[0][1] = nums[j];
res[0][2] = nums[k];
count++;
}
}
}
}
}
*returnSize=count;
if (count > 0)
return res;
else
return NULL;``
}
You can simplify your code as there are redundant blocks:
realloc can be called with NULL and acts like malloc.
returning res is OK when count is 0 as it was initialized to NULL.
You can check for duplicates, you can sort the triplet and search it in the list of matches before insertion, with brute force too:
int **threeSum(int *nums, int numsSize, int *returnSize) {
int count = 0;
int **res = NULL;
for (int i = 0; i < numsSize - 2; i++) {
for (int j = i + 1; j < numsSize - 1; j++) {
for (int k = j + 1; k < numsSize; k++) {
if (nums[i] + nums[j] + nums[k] == 0) {
int a = nums[i], b = nums[j], c = nums[k], n;
if (a > b) { int t = a; a = b; b = t; }
if (b > c) { int t = b; b = c; c = t; }
if (a > b) { int t = a; a = b; b = t; }
for (n = 0; n < count; n++) {
if (a == res[n][0] && b == res[n][1])
break;
}
if (n == count) {
int **p = realloc(res, sizeof(*p) * (count + 1));
int *p1 = malloc(sizeof(*p1) * 3);
if (p == NULL || p1 == NULL) {
for (n = 0; n < count; n++)
free(res[n]);
free(res);
free(p);
free(p1);
*returnSize = -1;
return NULL;
}
res = p;
p1[0] = a;
p1[1] = b;
p1[2] = c;
res[count] = p1;
count++;
}
break; // any other match would be a duplicate.
}
}
}
}
*returnSize = count;
return res;
}
Notes:
no need to test if c == res[n][2] because res only contains matches
no need to test further elements for the same i and j after a match is found.
Edit I deleted this incorrect answer, but now enabled it (although not updated from various comments, because it is still wrong).
For what it's worth I changed the duplicate removal to this:
int terms = 2;
// . . .
// remove duplicates
for(int i = 2; i < TERMS; i++) {
if(nums[i] != nums[terms - 1] || nums[i] != nums[terms - 2]) {
nums[terms++] = nums[i];
}
}
First I sort the array, and then remove duplicates.
Optionally, I make early loop terminations when the 0 sum is impossible.
I have not created an array of solutions, only printed – I leave that to you.
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#define TERMS 30 // length of array
#define MAXVAL 9 // value range + - MAXVAL
#define CHECK // compiler option quit when 0 sum is impossible
int cmp(const void *a, const void *b) {
return (*(int*)a) - (*(int*)b);
}
void show(char *legend, int *nums, int size)
{
printf("%s\n", legend);
for(int i = 0; i < size; i++) {
printf("%d ", nums[i]);
}
printf("\n\n");
}
int main(void) {
int nums[TERMS];
int terms = 1;
int sum;
int results = 0;
// build array
//srand((unsigned)time(NULL)); // comment out for repeatable values
for(int i = 0; i < TERMS; i++) {
nums[i] = rand() % (MAXVAL * 2 + 1) - MAXVAL;
}
show("input", nums, TERMS);
// sort array
qsort(nums, TERMS, sizeof nums[0], cmp);
show("sorted", nums, TERMS);
// remove duplicates
for(int i = 1; i < TERMS; i++) {
if(nums[i] != nums[terms - 1]) {
nums[terms++] = nums[i];
}
}
show("removed dups", nums, terms);
// find triplets with 0 sum
printf("zero sum triplets\n");
for(int i = 0; i < terms; i++) {
#ifdef CHECK
if(nums[i] > 0) {
// early termination if impossible
break;
}
#endif
for(int j = i + 1; j < terms; j++) {
for(int k = terms-1; k > j; k--) {
#ifdef CHECK
if(nums[k] < 0) {
// early termination if impossible
break;
}
#endif
sum = nums[i] + nums[j] + nums[k];
if(sum == 0) {
printf("%4d %4d %4d\n", nums[i], nums[j], nums[k]);
results++;
}
}
}
}
printf("\n%d results\n", results);
return 0;
}
Program output
input
-6 9 -2 5 8 2 -7 -6 -8 2 -4 -3 -3 3 -4 7 3 1 -8 -7 6 3 -2 -8 -2 4 8 -8 6 -7
sorted
-8 -8 -8 -8 -7 -7 -7 -6 -6 -4 -4 -3 -3 -2 -2 -2 1 2 2 3 3 3 4 5 6 6 7 8 8 9
removed dups
-8 -7 -6 -4 -3 -2 1 2 3 4 5 6 7 8 9
zero sum triplets
-8 1 7
-8 2 6
-8 3 5
-7 -2 9
-7 1 6
-7 2 5
-7 3 4
-6 -3 9
-6 -2 8
-6 1 5
-6 2 4
-4 -3 7
-4 -2 6
-4 1 3
-3 -2 5
-3 1 2
16 results
Since you want to stay with brute force, I am responding with that context. You can do an increasing sort your detected triplet into a temp array of 3 ints, before storing it in the res. When a new triplet is detected, sort it and insert that into the temp array, compare the temp array with the arrays stored in your res array to detect a duplicate set and if duplicate continue.
ie. compare res[0][0], res[0][1], res[0][2] with the temp[0], temp[1], temp[2]and detect the duplicates for every triplet that exists in res. And since every res row is sorted, it should be easy to detect duplicates by comparing position to position.
let us say res after a few rounds looks as follows:
-2 1 1
-3 1 2
-7 3 4
and if a new triplet detected is say [4, 3, -7], in temp it will be [-7, 3, 4] and when we loop through res and compare, duplicate will be detected.
To sort num[i], num[j], num[k] you could do the following (again staying in your brute force context):
if ((num[i] > num[j]))
{
/* Compare the first two numbers in num triplet */
temp[0] = num[j];
temp[1] = num[i];
}
else
{
temp[0] = num[i];
temp[1] = num[j];
}
//now compare the third number num[k]
if (num[k] < temp[0])
{
/* num[k] is the smallest number, shift the temp array to the right */
temp[2] = temp[1];
temp[1] = temp[0];
temp[0] = num[k]; /* Add the third number in the beginning of temp array */
}
else
if (num[k] >= temp[1])
{
/* num[k] is the shortest number, no shifting needed */
temp[2] = num[k]; /* Add the number num[k] to the end of temp array */
}
else
{
/* num[k] is in the middle, shift temp[1] to the right and insert num[k] */
temp[2] = temp [1]; /* Shift the last number in temp[k] */
temp[1] = num[k]; /* Overwrite temp[1] with the new number in num[k] which will put num[k] in the middle */
}
I haven't tested this code yet.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I try to write a sudoku solver
I always get a segmentation fault after calling getPossibleElements in solveSudoku.
If I delete this line the error doesnt appear.
My Code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SUDOKU_X 8
#define SUDOKU_Y 8
#define MAX_FILENAME 50
#define MAX_POSSIBILITIES 8
typedef enum bool {false, true} bool;
void printPossibilities (bool numbers[], const int pos_x, const int pos_y) {
int i = 0;
for (i = 0; i <= MAX_POSSIBILITIES; i++) {
if (numbers[i]) {
printf("%d ", (i+1));
}
}
}
void getPossibleElements (bool numbers[],int a[][SUDOKU_Y], const int pos_x, const int pos_y) {
int x = 0;
int y = 0;
int i = 0;
int j = 0;
int tmp = 0;
for (x = 0; x <= MAX_POSSIBILITIES; x++) {
numbers[x] = true;
}
/* row */
for (x = 0; x <= SUDOKU_X; x++) {
if (a[pos_y][x] > 0) {
printf("ROW->a[%d][%d]\n",pos_y,x);
printf("ROW->%d\n",a[pos_y][x]-1);
numbers[a[pos_y][x]-1] = false;
}
}
/* coloumn */
for (y = 0; y <= SUDOKU_Y; y++) {
if (a[y][pos_x] > 0) {
printf("coloumn->a[%d][%d]\n",y,pos_x);
printf("coloumn->%d\n",a[y][pos_x]-1);
numbers[a[y][pos_x]-1] = false;
}
}
/* field */
if (pos_x <= 2 && pos_y <= 2) {
x = 0;
y = 0;
}
else if (pos_x <= 5 && pos_y <= 2) {
x = 3;
y = 0;
}
else if (pos_x <= 8 && pos_y <= 2) {
x = 6;
y = 0;
}
else if (pos_x <= 2 && pos_y <= 5) {
x = 0;
y = 3;
}
else if (pos_x <= 5 && pos_y <= 5) {
x = 3;
y = 3;
}
else if (pos_x <= 8 && pos_y <= 5) {
x = 6;
y = 3;
}
else if (pos_x <= 2) {
x = 0;
y = 6;
}
else if (pos_x <= 5) {
x = 3;
y = 6;
}
else if (pos_x <= 8) {
x = 6;
y = 6;
}
printf("DB!!! x=%d y=%d\n", x,y);
for (j = y; j < (y+3); j++) {
for (i = x; i < (x+3); i++) {
if (a[j][i] > 0) {
printf("FIELD->a[%d][%d]\n",j,i);
printf("FIELD->%d\n",(a[j][i])-1);
numbers[(a[j][i])-1] = false;
}
}
}
printf("db");
}
void printSudoku (int a[][SUDOKU_Y]) {
int i = 0;
int j = 0;
printf("-------------------------------\n");
for (j = 0; j <= SUDOKU_X; j++)
{
for (i = 0; i <= SUDOKU_Y; i++) {
if (i == 0) {
printf("|");
}
printf(" %d ",a[j][i]);
if (i == 2 || i == 5 || i == 8) {
printf("|");
}
}
printf("\n");
if (j == 2 || j == 5) {
printf("|-----------------------------|\n");
}
}
printf("-------------------------------\n");
}/* printSudoku */
bool solveSudoku (int a [][SUDOKU_Y]) {
bool numbers[MAX_POSSIBILITIES];
int x = 0;
int y = 0;
printSudoku(a);
getPossibleElements(numbers,a,x,y);
printPossibilities(numbers,x,y);
return true;
}
void readFiletoArray (const char * fileName, int a[][SUDOKU_Y])
{
FILE *fp = fopen(fileName,"r");
int i = 0;
int j = 0;
int val0 = 0;
int val1 = 0;
int val2 = 0;
if( fp == NULL ) {
perror("Error while opening the file.\n");
exit(EXIT_FAILURE);
}
while(fscanf(fp, "%d %d %d", &val0, &val1, &val2) > 0) {
a[j][i++] = val0;
a[j][i++] = val1;
a[j][i++] = val2;
if (i >= 8) {
i = 0;
j++;
}
}
fclose(fp);
} /* readFiletoArray */
int main (int argc, char * argv []) {
int a[SUDOKU_X][SUDOKU_Y];
char fileName[MAX_FILENAME];
bool numbers[MAX_POSSIBILITIES];
bool success = false;
if(argc == 2) {
strncpy(fileName, argv[1], MAX_FILENAME-1);
fileName[MAX_FILENAME] = '\0';
}
else {
printf("ERROR: Invalid Parameter\n");
exit(EXIT_FAILURE);
}
readFiletoArray(fileName, a);
success = solveSudoku(a);
printf("DB");
exit(EXIT_SUCCESS);
} /* Main */
sudoku.txt (Program Parameter)
0 5 9 0 4 0 2 0 0
0 1 0 0 5 0 0 0 7
4 0 0 3 2 9 0 1 5
3 2 0 1 0 0 9 0 0
0 0 7 4 0 6 5 0 0
0 0 4 0 0 5 0 7 8
6 9 0 5 0 3 0 0 4
5 0 0 0 6 0 0 3 0
0 0 8 0 1 0 6 5 0
Thx
At a glance, this is because you are running off the end of the array in various places.
for (x = 0; x <= MAX_POSSIBILITIES; x++) { // 0,1,2...8
See that <= you have there? That's your problem.
numbers is declared as bool numbers[MAX_POSSIBILITIES];, and array indices in C start at 0 and go to length - 1. Zero through seven in this case, but you are trying to access numbers[8].
You have the same issue elsewhere. a is declared as
int a[SUDOKU_X][SUDOKU_Y]; // int a[8][8];
and in getPossibleElements you are iterating from 0 to 8 inclusive, like so:
for (x = 0; x <= SUDOKU_X; x++) {
...
for (y = 0; y <= SUDOKU_Y; y++) {
...thus running off the end of your array again.
Same deal in printPossibilities.
Change MAX_POSSIBILITIES, SUDOKU_X and SUDOKU_Y to be 9 in your #defines and iterate from 0 to 8 by doing
for (x = 0; x < SUDOKU_X; x++) { // 0,1,2...8
One more thing. You should fix your fileName stuff too. Same deal. The last index in an array is length - 1, not length. If you had warnings cranked up when you compiled, it probably would have mentioned this one.
if (argc == 2) {
strncpy(fileName, argv[1], MAX_FILENAME - 2); // was MAX_FILENAME - 1
fileName[MAX_FILENAME - 1] = '\0'; // was [MAX_FILENAME]
}
I have a program and i tried to use Open MP.
The output is still correct (i tested it after multiple runs), but the times i get are quite odd.
So the time for the single threaded version is 0.1 seconds.
With 2 treads i get 0.05, but with 4 i obtain 0.15 seconds.
How is this possible?
I am just using simple parallel for's.
#pragma omp parallel for private(i, j)
for(i = 1; i <= total_height; i++){
for(j = 1; j <= total_width; j++){
int current_neighbours = neighbours[i][j];
// if(i == 2 && j == 1)
// printf("%d%d\n", current_neighbours, neighbours[2][1]);
if(current_neighbours == 0 || current_neighbours == 1 || current_neighbours > 3){
if(map[i][j] == 1){
update_maps(i, j, 0);
}
}
else if(current_neighbours == 3){
if(map[i][j] == 0){
update_maps(i, j, 1);
}
}
}
}
The update_maps functions looks like this
void update_maps(int i, int j, int value){
map[i][j] = value;
int k, neighbouri, neighbourj;
int num_of_thread = omp_get_thread_num();
if(value == 0)
value = -1;
for(k = 0; k < 8 ; k++){
neighbouri = i + di[k];
neighbourj = j + dj[k];
if(in_map(neighbouri, neighbourj)){
neighbouri--;
neighbourj--;
modify[neighbouri * total_height + neighbourj + (total_height * total_width * num_of_thread)] += value;
}
}
}