Trying to sort a struct array in Descending Order - c

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.

Related

How I can consider number as a value 1 in C language?

I have a problem in my C program. I need to write a histogram of numbers. If the number on the input will be outside the interval [1, 9], consider such a number as the value 1. I don't understand why it doesn't work.
#include <stdio.h>
#include <stdlib.h>
void printHistogram_vertical(int *hist, int n);
int main()
{
int i, j;
int inputValue;
scanf("%d", &inputValue);
int hist[inputValue];
for (i = 0; i < inputValue; ++i)
{
scanf("%d", &hist[i]);
}
int results[10] = {0};
for (i = 0; i < 10; ++i)
{
for (j = 0; j < inputValue; ++j)
{
if (hist[j] >= 10 && hist[j] < 1)
{
results[j] == 1;
}
if (hist[j] == i)
{
results[i]++;
}
}
}
return 0;
}
void printHistogram_vertical(int *hist, int n)
{
int i, j;
for (i = 1; i < n; i++)
{
printf(" %d ", i);
for (j = 0; j < hist[i]; ++j)
{
printf("#");
}
printf("\n");
}
}
Input:
9
3 3 2 3 7 1 1 4 10
My Output:
1 ##
2 #
3 ###
4 #
5
6
7 #
8
9
The correct output:
1 ###
2 #
3 ###
4 #
5
6
7 #
8
9
If the number is bigger than 10 and smaller than 1 it should count this number as 1. I write this function:
for (i = 0; i < 10; ++i)
{
for (j = 0; j < inputValue; ++j)
{
if (hist[j] >= 10 && hist[j] < 1)
{
results[j] == 1;
}
if (hist[j] == i)
{
results[i]++;
}
}
}
There are 2 problems with following condition:
if (hist[j] >= 10 && hist[j] < 1)
{
results[j] == 1;
}
The comparison is broken. Value cannot be above 9 AND below 1 at the same time. It should be OR instead.
What should be increment of index 1, is actually comparison == of wrong index.
Replacement:
if (hist[j] >= 10 || hist[j] < 1)
{
results[1]++;
}
But double for loop construction is more complicated than it needs to be. It could be replaced with single for loop:
for (j = 0; j < inputValue; ++j) {
int value = hist[j];
if(value >= 1 && value <= 9) {
results[value]++;
}
else {
results[1]++;
}
}

How to find and save parallel shortest path in undirected graph by Dijkstra’s algorithm in C

I have the follow graph:
A-B,11
A-C,10
B-D,5
C-D,6
C-E,15
D-E,4
The task is to find shortest path, print route and distance to all pairs like this:
Path: A -> D
Route: A -> C -> D
Distance: 10 + 6 = 16
In that example of graph, we have few path that repeating, but have a various route, like this:
Route: A -> B -> D
Route: A -> C -> D
I need to save all of this various path and print at the end. Now program find and print all path exept these cases. I tried many options, but for some reason I can’t understand how to solve this problem.
I store weights in 2 dimentional array like this:
A B C D E
A 0 11 10 0 0
B 11 0 0 5 0
C 10 0 0 6 15
D 0 5 6 0 4
E 0 0 15 4 0
My code below:
...
typedef struct s_way_dijkstra {
int isld_nm;
bool is_chk;
int parent;
struct s_way_dijkstra *next;
}t_way_dijkstra;
void printDistance(t_way_dijkstra *djk_var, int j) {
if (djk_var[j].parent == -1 )
return;
printDistance(djk_var, djk_var[j].parent);
if (djk_var[j].parent != 0 )
printstr("+ ");
printint(djk_var[j].isld_nm - djk_var[djk_var[j].parent].isld_nm);
printstr(" ");
// for (;i > 0 && djk_var->parent[i] != -1; i--)
// printf("%d ", j);
}
void printRoute(t_way_dijkstra *djk_var, int j, char **isld) {
if (djk_var[j].parent == -1)
return;
printRoute(djk_var, djk_var[j].parent, isld);
printstr(" -> ");
printstr(isld[j]);
}
static void printSolution(t_way_dijkstra *djk_var, int n, char **isld, int src) {
for (int i = 0; i < n; i++)
printf("%d ", djk_var[i].isld_nm);
printf("\n");
printf("\nparent\n");
for (int i = 0; i < n; i++)
printf("%d ", djk_var[i].parent);
printf("\n");
for (int i = src; i < n; i++) {
if (djk_var[i].isld_nm != 0) {
// Path
printstr("Path: ");
printstr(isld[src]);
printstr(" -> ");
printstr(isld[i]);
// Route
printstr("\nRoute: ");
printstr(isld[src]);
printRoute(djk_var, i, isld);
printstr("\n");
// Distance
if (djk_var[i].parent >= 1) {
printstr("Distance: ");
printDistance(djk_var, i);
printstr("= ");
printint(djk_var[i].isld_nm);
printstr("\n");
}
else {
printstr("Distance: ");
printint(djk_var[i].isld_nm);
printstr("\n");
}
}
}
}
static int get_min_distance(t_way_dijkstra *djk_var , t_main *vars) {
int min_val = INT_MAX;
int min_ind = 0;
for (int i = 0; i < vars->nmb_isld; i++) {
if (djk_var[i].is_chk == false && djk_var[i].isld_nm <= min_val) {
min_val = djk_var[i].isld_nm;
min_ind = i;
}
}
return min_ind;
}
static void dijkstra(int src, t_main *vars, t_graph *graph, t_way_dijkstra *djk_var) {
int min_ind = 0;
for (int i = 0; i < vars->nmb_isld; i++) {
djk_var[i].parent = -1;
djk_var[i].isld_nm = INT_MAX;
djk_var[i].is_chk = false;
}
djk_var[src].isld_nm = 0;
for (int i = 0; i < vars->nmb_isld; i++) {
min_ind = get_min_distance(djk_var, vars);
djk_var[min_ind].is_chk = true;
for (int j = src; j < vars->nmb_isld; j++) {
if (!djk_var[j].is_chk && graph->array[min_ind][j]
&& djk_var[min_ind].isld_nm != INT_MAX
&& djk_var[min_ind].isld_nm + graph->array[min_ind][j] < djk_var[j].isld_nm) {
djk_var[j].parent = min_ind;
djk_var[j].isld_nm = djk_var[min_ind].isld_nm + graph->array[min_ind][j];
}
}
}
printSolution(djk_var, vars->nmb_isld, graph->isld, src);
}
...

Unclear Segmentation Fault returning 139 [closed]

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]
}

how to build spiral square matrix using recursion?

I wanted to build a spiral square matrix using recursion. I am able to build spiral square matrix using iterative method as below:
void main()
{
int initial_direction = UP , n = MAX , p = 1 ; /* intial_direction
is set to UP because we need to start moving right */
int r ,c , a[MAX][MAX];
int row_right = 0 , column_down = n-1 , row_left = n-1 , column_up = 0 ;
clrscr ();
//Set all elements of the matrix to 0
for(r = 0 ; r < MAX ; r++)
{
for(c = 0 ; c < MAX ; c++)
a[r][c] = 0 ;
}
//Generate elements of the spiral matrix
while(p != n*n+1)
{
if(initial_direction == UP)
{
//Move RIGHT
r = row_right++ ;
for(c = 0 ; c < n ; c++)
{
if(a[r][c] == 0)
a[r][c] = p++;
}
initial_direction = RIGHT ;
}
else if(initial_direction == RIGHT)
{
//Move down
c = column_down-- ;
for(r = 0 ; r < n ; r++)
{
if(a[r][c] == 0)
a[r][c] = p++;
}
initial_direction = DOWN ;
}
else if(initial_direction == DOWN)
{
//Move left
r = row_left-- ;
for(c = n-1 ; c >= 0 ; c--)
{
if(a[r][c] == 0)
a[r][c] = p++;
}
initial_direction = LEFT ;
}
else if(initial_direction == LEFT)
{
//Move up
c = column_up++;
for(r = n-1 ; r >= 0 ; r--)
{
if(a[r][c] == 0)
a[r][c] = p++;
}
initial_direction = UP ;
}
}
//Print the matrix
printf("\n\n");
for(r = 0 ; r < MAX ; r++)
{
for(c = 0 ; c < MAX ; c++)
printf("%4d ",a[r][c]);
printf("\n");
}
}
I wanted to create the same matrix using recursion:
Here is the code i used:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
bool s[5][5] = {0};
int counter;
typedef enum {
right = 0,
down,
left,
up
}c_flag;
c_flag flag;
int last;
int build_matrix(int a[5][5],int i,int j, c_flag flag)
{
int ret;
if (i < 0 || i>=5 || j < 0 || j >= 5)
{
if (last == right)
{
flag = down;
last = flag;
}
if (last == down)
{
flag = left;
last = flag;
}
if (last == left)
{
flag = up;
last = flag;
}
if (last == up)
{
flag = left;
last = flag;
}
return false;
}
if (s[i][j] == true)
{
if (last == right)
{
flag = down;
last = flag;
}
if (last == down)
{
flag = left;
last = flag;
}
if (last == left)
{
flag = up;
last = flag;
}
if (last == up)
{
flag = left;
last = flag;
}
return false;
}
if(s[i][j] == false)
{
s[i][j] = true;
a[i][j] = ++ counter;
}
if (flag == right)
{
ret = build_matrix(a,i,j+1,right);
//if (!ret)
// return false;
}
flag = down;
last = flag;
if (flag == down)
{
ret =build_matrix(a,i+1,j,down);
//if (!ret)
// return false;
}
flag = left;
last = flag;
if (flag == left)
{
ret = build_matrix(a,i,j-1,left);
//if (!ret)
// return false;
}
flag = up;
last = flag;
if (flag == up)
{
ret = build_matrix (a,i-1,j,up);
//if (!ret)
// return false;
}
flag = right;
last = flag;
return false;
}
int main()
{
int i, j, n = 5;
int k, ret;
//printf("Enter N to construct square matrix \n");
//scanf("%d",&n);
int a[5][5] = {0};
k = n/2 + n%2;
for (i = 0; i < k; i++)
{
ret = build_matrix(a,i,i,right);
}
for(i = 0; i < n; i++)
{
for(j = 0; j < n; j++)
printf("%d",a[i][j]);
printf("\n");
}
return 0;
}
I am getting out put for above as :
1 2 3 4 5
16 19 22 25 6
15 18 21 24 7
14 17 20 23 8
13 12 11 10 9
instead of
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
Problem is Flag is not setting proper, i dunno inside which recursion call flag is getting disturbed.
Please some one help implement using recursion.
#include <stdio.h>
void build_matrix(int msize, int a[msize][msize], int size, int value){
int i, row, col;
if(size < 1)
return;
row = col = (msize - size) / 2;
if(size==1){
a[row][col] = value;
return;
}
for(i=0;i<size-1;++i)
a[row][col++] = value++;//RIGHT
for(i=0;i<size-1;++i)
a[row++][col] = value++;//DOWN
for(i=0;i<size-1;++i)
a[row][col--] = value++;//LEFT
for(i=0;i<size-1;++i)
a[row--][col] = value++;//UP
build_matrix(msize, a, size-2, value);
}
int main(){
int size;
printf("input size : ");
scanf("%d", &size);
int a[size][size];
build_matrix(size, a, size, 1);
for(int r=0;r<size;++r){
for(int c=0;c<size;++c)
printf("%3d ", a[r][c]);
printf("\n");
}
return 0;
}
Working Code, without divide and Just recurse:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define N 20
bool s[N][N] = {0};
int counter;
typedef enum {
right = 0,
down,
left,
up
}c_flag;
c_flag flag;
int build_matrix(int a[N][N],int i,int j, c_flag flag)
{
int ret;
if (i < 0 || i>=N || j < 0 || j >= N || s[i][j] == true)
return false;
if(s[i][j] == false && a[i][j] == 0)
{
s[i][j] = true;
a[i][j] = ++ counter;
}
if (flag == right)
ret = build_matrix(a,i,j+1,right);
flag = down;
if (flag == down)
ret =build_matrix(a,i+1,j,down);
flag = left;
if (flag == left)
ret = build_matrix(a,i,j-1,left);
flag = up;
if (flag == up)
ret = build_matrix (a,i-1,j,up);
flag = right;
if (flag == right)
ret = build_matrix(a,i,j+1,right);
return false;
}
int main()
{
int i, j;
int k, ret;
//printf("Enter N to construct square matrix \n");
//scanf("%d",&n);
int a[N][N] = {0};
k = N/2 + N%2;
build_matrix(a,i,i,right);
for(i = 0; i < N; i++)
{
for(j = 0; j < N; j++)
{
if (!(a[i][j] < 100))
printf("%3d ",a[i][j]);
else if(a[i][j] < 10)
printf("00%d ",a[i][j]);
else
printf("0%d ",a[i][j]);
}
printf("\n");
}
return 0;
}

Implementing first fit like algorithm

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]).

Resources