how can I make my boxblur code work faster? - c

I have written a box blur code for gray image blur, but it turned out to work much slower than I expected. How can I improve its performance?
void boxfilter(int* const srcImg, int* const desImg, const int mask, const int nrows, const int ncols)
{
LL *buffer, *rowImg, *rowPtr;
int *srcPtr, *desPtr;
LL pre, sum;
int row, col, i, len, r;
const int MAX_ROW_COL = nrows > ncols ? nrows : ncols;
const int MASK_SIZE = mask*mask;
LL *headL, *tailL;
int *head, *tail;
r = mask / 2;
rowImg = (LL *)malloc(sizeof(LL)*nrows*ncols);
buffer = (LL *)malloc(sizeof(LL)*(MAX_ROW_COL + mask));
len = nrows + 2 * r;
srcPtr = srcImg;
rowPtr = rowImg;
for (col = 0; col < ncols; ++col)
{
srcPtr = srcImg + col;
head = srcPtr + r*ncols;
tail = srcPtr + (nrows - 2 - r)*ncols;
for (i = 0; i < r; ++i)
{
buffer[i] = *head;
buffer[len - 1 - i] = *tail;
head += ncols;
tail -= ncols;
}
for (i = r; i < len - r; ++i)
{
buffer[i] = *srcPtr;
srcPtr += ncols;
}
sum = buffer[0];
for (i = 1; i < mask; ++i)
{
sum += buffer[i];
}
rowPtr = rowImg + col;
*rowPtr = sum;
pre = sum;
headL = buffer;
tailL = buffer + mask;
for (i = mask; i < len; ++i, ++headL, ++tailL)
{
*rowPtr = pre;
rowPtr += ncols;
pre = pre - *headL + *tailL;
}
}
len = ncols + 2 * r;
rowPtr = rowImg;
desPtr = desImg;
for (row = 0; row < nrows; ++row)
{
headL = rowPtr + r;
tailL = rowPtr + (ncols - 2 - r);
for (i = 0; i < r; ++i)
{
buffer[i] = *headL;
buffer[len - 1 - i] = *tailL;
++headL;
--tailL;
}
for (i = r; i < len - r; ++i)
{
buffer[i] = *rowPtr;
++rowPtr;
}
sum = buffer[0];
for (i = 1; i < mask; ++i)
{
sum += buffer[i];
}
*desPtr = sum/MASK_SIZE;
++desPtr;
pre = sum;
headL = buffer;
tailL = buffer + mask;
for (i = mask; i < len; ++i, ++headL, ++tailL)
{
*desPtr = pre/MASK_SIZE;
++desPtr;
pre = pre - *headL + *tailL;
}
}
free(rowImg);
free(buffer);
return;
}

Related

fprintf in a while loop will only print my data 10 times to a file

ran into a problem regarding fprintf, we want to write a double array into our file for every loop in our main's while loop, however when this loop goes higher than 10 it simply stops fprintf'ing.
The function in question is "store_trash_file". Also the program is controlled by a few defines at top.
Day_max = controls the amount of loops in our while loop
SIZE = with higher SIZE it seems it will fprintf less, and with a smaller it will fprintf more lines.
Ill be putting up the entire code, so u can run it, perhaps keep an eye on the create directories function, as it will make folders and some txts
Any help is much appreciated
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <conio.h>
#include <io.h>
#include <process.h>
#define MARGIN 70
#define MARGIN2 30
#define NAREA 4
#define NSUBAREA 4
#define SIZE 20
#define DAY_MAX 20
#define AREAS_PER_TRUCK 4
#define LOWER1 6
#define LOWER2 8
#define LOWER3 10
#define UPPER1 8
#define UPPER2 10
#define UPPER3 12
typedef struct subarea
{
int co2_cost, time, emptied_subarea_counter, lower_random, upper_random, activity_level;
double average, total_trash_subarea_avg, sensorData[SIZE], sensorDataTotal[SIZE];
} subarea;
typedef struct area
{
subarea *subarea_array[NAREA + 1];
double average, total_trash_area_avg;
int emptied_area_counter;
} area;
void simulated_days(area *area_dynamic, area *area_static);
void average_trash(area *area);
void sensor_data_start(area *area, double start_var);
void compare_trash_to_empty(area *area_array[NAREA + 1], int *area_number_p);
void empty_trash(area *area, int *co2_counter_p, int *time_counter_p);
void store_trash_file(area *area_array[NAREA + 1]);
void create_areas(area *area_array[NAREA + 1]);
void empty_trash_static(area *area, int *co2_counter_static_p, int *time_counter_static_p);
void create_directories();
void make_txt_file(char file_name[30], char file_name2[30]);
int main(void)
{
int co2_counter = 0, time_counter = 0;
int co2_counter_static = 0, time_counter_static = 0;
int day_counter = 0;
int area_number;
int garbage_truck_amount = 0;
double *area_array_avg[DAY_MAX][NAREA];
double *subarea_array_avg[DAY_MAX][NAREA * NSUBAREA];
double *trashcan_array_avg[DAY_MAX][NAREA * NSUBAREA * SIZE];
area *area_array[NAREA + 1];
area *area_array_static[NAREA + 1];
srand(time(NULL));
for (int i = NAREA; i > 0; i -= AREAS_PER_TRUCK)
{
garbage_truck_amount++;
}
printf("Garbage trucks: %d\n", garbage_truck_amount);
create_areas(area_array);
create_areas(area_array_static);
create_directories();
int running = 1;
while (running)
{
for (int i = 1; i < NAREA + 1; i++)
{
simulated_days(area_array[i], area_array_static[i]);
average_trash(area_array[i]);
average_trash(area_array_static[i]);
}
for (int i = 1; i < NAREA + 1; i++)
{
for (int j = 0; j < NSUBAREA; j++)
{
printf("area array: %lf\n", area_array[i]->subarea_array[j]->average);
printf("area array static: %lf\n", area_array_static[i]->subarea_array[j]->average);
}
}
for (int i = 0; i < garbage_truck_amount; i++)
{
compare_trash_to_empty(area_array, &area_number);
empty_trash(area_array[area_number], &co2_counter, &time_counter);
for (int j = 1; j < NAREA + 1; j++)
{
average_trash(area_array[j]);
}
}
if (day_counter > 1 && day_counter % 14 == 0)
{
for (int i = 1; i < NAREA + 1; i++)
{
empty_trash_static(area_array_static[i], &co2_counter_static, &time_counter_static);
average_trash(area_array_static[i]);
}
}
store_trash_file(area_array);
printf("Day: %d\n", day_counter + 1);
for (int i = 0; i < NSUBAREA; i++)
{
for (int j = 1; j < NAREA + 1; j++)
{
printf("%lf\t", area_array[j]->subarea_array[i]->average);
printf("%lf\t", area_array_static[j]->subarea_array[i]->average);
}
printf("\n");
}
printf("\n");
day_counter++;
if(day_counter == DAY_MAX)
{
running = 0;
}
}
}
void simulated_days(area *area_dynamic, area *area_static)
{
for (int i = 0; i < NSUBAREA; i++)
{
for (int j = 0; j < SIZE; j++)
{
int x = ((rand() % (area_dynamic->subarea_array[i]->upper_random - area_dynamic->subarea_array[i]->lower_random + 1)) + area_dynamic->subarea_array[i]->lower_random);
area_dynamic->subarea_array[i]->sensorData[j] += x;
area_dynamic->subarea_array[i]->sensorDataTotal[j] += x;
area_static->subarea_array[i]->sensorData[j] += x;
area_static->subarea_array[i]->sensorDataTotal[j] += x;
}
}
}
void average_trash(area *area)
{
double sum[NSUBAREA];
double sum_total[NSUBAREA];
double area_trash_sum = 0;
double area_trash_sum_total = 0;
for (int i = 0; i < NSUBAREA; i++)
{
sum[i] = 0;
sum_total[i] = 0;
}
for (int i = 0; i < NSUBAREA; i++)
{
for (int j = 0; j < SIZE; j++)
{
sum[i] += area->subarea_array[i]->sensorData[j];
sum_total[i] += area->subarea_array[i]->sensorDataTotal[j];
}
area->subarea_array[i]->average = sum[i] / SIZE;
area->subarea_array[i]->total_trash_subarea_avg = sum_total[i] / SIZE;
}
for (int i = 0; i < NSUBAREA; i++)
{
area_trash_sum += area->subarea_array[i]->average;
area_trash_sum_total += area->subarea_array[i]->total_trash_subarea_avg;
}
area->average = area_trash_sum / NSUBAREA;
area->total_trash_area_avg = area_trash_sum_total / NSUBAREA;
}
void sensor_data_start(area *area, double start_var)
{
for (int i = 0; i < NSUBAREA; i++)
{
for (int j = 0; j < SIZE; j++)
{
area->subarea_array[i]->sensorData[j] = start_var;
area->subarea_array[i]->sensorDataTotal[j] = start_var;
}
}
}
void compare_trash_to_empty(area *area_array[NAREA + 1], int *area_number_p)
{
int highBlock = 0;
for (int i = 1; i < NAREA + 1; i++)
{
if (area_array[i]->average >= MARGIN)
{
if (area_array[i]->average > area_array[highBlock]->average)
{
highBlock = i;
}
}
}
*area_number_p = highBlock;
printf("\nhighblock %d\n", highBlock);
}
void empty_trash(area *area, int *co2_counter_p, int *time_counter_p)
{
for (int i = 0; i < NSUBAREA; i++)
{
if (area->subarea_array[i]->average > MARGIN2)
{
*co2_counter_p += area->subarea_array[i]->co2_cost;
*time_counter_p += area->subarea_array[i]->time;
area->subarea_array[i]->average = 0;
area->subarea_array[i]->emptied_subarea_counter++;
for (int j = 0; j < SIZE; j++)
{
if (area->subarea_array[i]->sensorData[j] <= 100)
{
area->subarea_array[i]->sensorData[j] = 0;
}
else if (area->subarea_array[i]->sensorData[j] > 100)
{
area->subarea_array[i]->sensorData[j] -= 100;
}
}
}
}
area->emptied_area_counter++;
}
void store_trash_file(area *area_array[NAREA + 1])
{
// int xcount = 0;
// int ycount = 0;
// double area_array_avg[NAREA];
// double subarea_array_avg[NAREA * NSUBAREA];
// double trashcan_array_avg[NAREA * NSUBAREA * SIZE];
FILE *output_filepointer;
char *dirname2 = "C:\\Users\\jacob\\Documents\\software\\projekter\\p1\\kode\\intelligenttrash\\data\\area";
char newdirname[150];
char newdirname2[150];
char newdirname3[150];
for (int i = 1; i < NAREA + 1; i++)
{
// area_array_avg[i - 1] = (area_array[i]->total_trash_area_avg);
snprintf(newdirname, 150, "%s%d\\area_average_total.txt", dirname2, i);
output_filepointer = fopen(newdirname, "a");
fprintf(output_filepointer, "%lf ", area_array[i]->total_trash_area_avg);
for (int j = 0; j < NSUBAREA; j++)
{
// subarea_array_avg[j + (ycount * NSUBAREA)] = (area_array[i]->subarea_array[j]->total_trash_subarea_avg);
snprintf(newdirname2, 150, "%s%d%s%d\\subarea_average_total.txt", dirname2, i, "\\subarea", j);
output_filepointer = fopen(newdirname2, "a");
fprintf(output_filepointer, "%lf ", area_array[i]->subarea_array[j]->total_trash_subarea_avg);
for (int z = 0; z < SIZE; z++)
{
// trashcan_array_avg[z + (xcount * SIZE)] = (area_array[i]->subarea_array[j]->sensorDataTotal[z]);
snprintf(newdirname3, 150, "%s%d%s%d\\trashcan_trash.txt", dirname2, i, "\\subarea", j);
output_filepointer = fopen(newdirname3, "a");
fprintf(output_filepointer, "%lf ", area_array[i]->subarea_array[j]->sensorDataTotal[z]);
}
// xcount++;
fprintf(output_filepointer, "\n");
output_filepointer = fopen(newdirname2, "a");
fprintf(output_filepointer, "\n");
}
// ycount++;
output_filepointer = fopen(newdirname, "a");
fprintf(output_filepointer, "\n");
}
fclose(output_filepointer);
}
void create_areas(area *area_array[NAREA + 1])
{
int percentage_added[3][2] = {{LOWER1, UPPER1}, {LOWER2, UPPER2}, {LOWER3, UPPER3}};
int activity_level;
for (int i = 0; i < NAREA + 1; i++)
{
area_array[i] = malloc(sizeof(area));
for (int j = 0; j < NSUBAREA; j++)
{
activity_level = (rand() % 3);
area_array[i]->subarea_array[j] = malloc(sizeof(subarea));
area_array[i]->subarea_array[j]->co2_cost = 50;
area_array[i]->subarea_array[j]->time = 50;
area_array[i]->subarea_array[j]->average = 0;
area_array[i]->subarea_array[j]->emptied_subarea_counter = 0;
area_array[i]->subarea_array[j]->total_trash_subarea_avg = 0;
area_array[i]->subarea_array[j]->lower_random = percentage_added[activity_level][0];
area_array[i]->subarea_array[j]->upper_random = percentage_added[activity_level][1];
area_array[i]->subarea_array[j]->activity_level = activity_level;
}
sensor_data_start(area_array[i], 0);
area_array[i]->average = 0;
area_array[i]->total_trash_area_avg = 0;
area_array[i]->emptied_area_counter = 0;
}
}
void empty_trash_static(area *area, int *co2_counter_static_p, int *time_counter_static_p)
{
for (int i = 0; i < NSUBAREA; i++)
{
*co2_counter_static_p += area->subarea_array[i]->co2_cost;
*time_counter_static_p += area->subarea_array[i]->time;
area->subarea_array[i]->average = 0;
area->subarea_array[i]->emptied_subarea_counter++;
for (int j = 0; j < SIZE; j++)
{
if (area->subarea_array[i]->sensorData[j] <= 100)
{
area->subarea_array[i]->sensorData[j] = 0;
}
else if (area->subarea_array[i]->sensorData[j] > 100)
{
area->subarea_array[i]->sensorData[j] -= 100;
}
}
}
area->emptied_area_counter++;
}
void create_directories()
{
int check;
char *dirname1 = "C:\\Users\\jacob\\Documents\\software\\projekter\\p1\\kode\\intelligenttrash\\data";
char *dirname2 = "C:\\Users\\jacob\\Documents\\software\\projekter\\p1\\kode\\intelligenttrash\\data\\area";
mkdir(dirname1);
for (int i = 1; i < NAREA + 1; i++)
{
char newdirname[100];
char newdirname2[100];
snprintf(newdirname, 100, "%s%d", dirname2, i);
mkdir(newdirname);
for (int j = 1; j < NSUBAREA + 1; j++)
{
snprintf(newdirname2, 100, "%s%d%s%d", dirname2, i, "\\subarea", j);
mkdir(newdirname2);
}
}
}
void make_txt_file(char file_name[30], char file_name2[30])
{
FILE *output_filepointer;
char *dirname2 = "C:\\Users\\jacob\\Documents\\software\\projekter\\p1\\kode\\intelligenttrash\\data\\area";
char newdirname[100];
char newdirname2[100];
for (int i = 1; i < NAREA + 1; i++)
{
if (file_name != "none")
{
snprintf(newdirname, 100, "%s%d\\%s.txt", dirname2, i, file_name);
output_filepointer = fopen(newdirname, "a");
}
for (int j = 1; j < NSUBAREA + 1; j++)
{
if (file_name2 != "none")
{
snprintf(newdirname2, 100, "%s%d%s%d\\%s.txt", dirname2, i, "\\subarea", j, file_name2);
output_filepointer = fopen(newdirname2, "a");
}
}
}
fclose(output_filepointer);
}

Getting a segmentation fault on cs50's filter

I'm currently stuck on cs50's pset4 filter (less comfortable). The program compiles perfectly. I have tried out the first three parts of the code (grayscale, sepia & reflection) and their output has been as desired; however, whenever I try out blur, I keep getting hit with a seg fault. Could someone please help me identify where the error(s) lies?
void blur(int height, int width, RGBTRIPLE image[height][width])
{
for (int i = 0; i <height; i++)
{
for (int j = 0; j < width; j++)
{
int c = i + 1;
int d = j + 1;
int e = i + 2;
int f = j + 2;
float blurred_blue = 0;
float blurred_green = 0;
float blurred_red = 0;
int z = 0;
if (height - i == 1 && width - j >= 2)
{
for (int a = i - 1; a < c; a++)
{
for (int b = j - 1; b < f; b++)
{
blurred_blue = blurred_blue + image[a][b].rgbtBlue;
blurred_green = blurred_green + image[a][b].rgbtGreen;
blurred_red = blurred_red + image[a][b].rgbtRed;
z++;
}
}
}
else if (width - j == 1 && height - i >= 2)
{
for(int a = i - 1; a < e; a++)
{
for(int b = j - 1; b < d; b++)
{
blurred_blue = blurred_blue + image[a][b].rgbtBlue;
blurred_green = blurred_green + image[a][b].rgbtGreen;
blurred_red = blurred_red + image[a][b].rgbtRed;
z++;
}
}
}
else
{
for(int a = i - 1; a < e; a++)
{
for(int b = j - 1; b < f; b++)
{
blurred_blue = blurred_blue + image[a][b].rgbtBlue;
blurred_green = blurred_green + image[a][b].rgbtGreen;
blurred_red = blurred_red + image[a][b].rgbtRed;
z++;
}
}
}
image[i][j].rgbtBlue = round (blurred_blue / z);
image[i][j].rgbtGreen = round (blurred_green / z);
image[i][j].rgbtRed = round (blurred_red / z);
}
}
return;
}

Array function use on strict mode

i have trouble for using these array function to be able to use it on MQL4 strict mode.
Could anyone hint me where i should start? The purpose is so it could work on strict mode.
int Trigger;
void function6(int &arrays[50])
{
int vals = ArraySize(arrays);
int trailingstop = TimeCurrent() - (arrays[function5(arrays) - 1]);
while(trailingstop > Trigger)
{
arrays[function5(arrays) - 1] = 0;
trailingstop = TimeCurrent() - (arrays[function5(arrays) - 1]);
if(function5(arrays) < 2)
break;
}
}
int function5(int &arrays[50])
{
int vals = ArraySize(arrays);
for(int k = 0; k < vals; k++)
if(!(arrays[k] > 0))
return (k);
return (vals - 1);
}
void function4(double &val[50])
{
int vald = ArraySize(val);
for(int l = vald; l > 0; l--)
val[l] = val[l - 1];
val[0] = 0;
}
void function3(int &arrays[50])
{
int vald = ArraySize(arrays);
for(int l = vald; l > 0; l--)
arrays[l] = arrays[l - 1];
arrays[0] = 0;
}
Arrays start at 0, not 1. When using ArraySize to define counting of arrays, you should always minus 1 to account for starting at 0.
void function6(int &arrays[50])
{
int vals = ArraySize(arrays)-1;
int trailingstop = TimeCurrent() - (arrays[function5(arrays) - 1]);
while(trailingstop > Trigger)
{
arrays[function5(arrays) - 1] = 0;
trailingstop = TimeCurrent() - (arrays[function5(arrays) - 1]);
if(function5(arrays) < 2) break;
}
}
int function5(int &arrays[50])
{
int vals = ArraySize(arrays)-1;
for(int k = 0; k < vals; k++)
if(!(arrays[k] > 0)) return (k);
return (vals - 1);
}
void function4(double &val[50])
{
int vald = ArraySize(val)-1;
for(int l = vald; l > 0; l--)
val[l] = val[l - 1];
val[0] = 0;
}
void function3(int &arrays[50])
{
int vald = ArraySize(arrays)-1;
for(int l = vald; l > 0; l--) arrays[l] = arrays[l - 1];
arrays[0] = 0;
}

Dijkstra’s shortest path algorithm in C - changing paramateres problem

this program is made to calculate shortest path between two vertexs. FUnction add_edge is adding edges and also their distance in format add_edge(g, 1, 2, 7);where first parameter is linked list, second and third paramater are edges and last one is distance between them.
Problem is that my program was made to insert it in this format add_edge(g, 'a', 'b', 7);but sending it as integer and in function making it to number with this action int a = a - 'a';.
and after i transformed my code to sending numbers instead of characters it stopped to work. showing no error but returning tash numbers.
Here's old code(working):
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
typedef struct {
int vertex;
int weight;
} edge_t;
typedef struct {
edge_t **edges;
int edges_len;
int edges_size;
int dist;
int prev;
int visited;
} vertex_t;
typedef struct {
vertex_t **vertices;
int vertices_len;
int vertices_size;
} graph_t;
typedef struct {
int *data;
int *prio;
int *index;
int len;
int size;
} heap_t;
void add_vertex (graph_t *g, int i) {
int j;
if (g->vertices_size < i + 1) {
int size = g->vertices_size * 2 > i ? g->vertices_size * 2 : i + 4;
g->vertices = realloc(g->vertices, size * sizeof (vertex_t *));
for (j = g->vertices_size; j < size; j++)
g->vertices[j] = NULL;
g->vertices_size = size;
}
if (!g->vertices[i]) {
g->vertices[i] = calloc(1, sizeof (vertex_t));
g->vertices_len++;
}
}
void add_edge (graph_t *g, int a, int b, int w) {
a = a - 'a';
b = b - 'a';
add_vertex(g, a);
add_vertex(g, b);
vertex_t *v = g->vertices[a];
if (v->edges_len >= v->edges_size) {
v->edges_size = v->edges_size ? v->edges_size * 2 : 4;
v->edges = realloc(v->edges, v->edges_size * sizeof (edge_t *));
}
edge_t *e = calloc(1, sizeof (edge_t));
e->vertex = b;
e->weight = w;
v->edges[v->edges_len++] = e;
}
heap_t *create_heap (int n) {
heap_t *h = calloc(1, sizeof (heap_t));
h->data = calloc(n + 1, sizeof (int));
h->prio = calloc(n + 1, sizeof (int));
h->index = calloc(n, sizeof (int));
return h;
}
void push_heap (heap_t *h, int v, int p) {
int i = h->index[v] == 0 ? ++h->len : h->index[v];
int j = i / 2;
while (i > 1) {
if (h->prio[j] < p)
break;
h->data[i] = h->data[j];
h->prio[i] = h->prio[j];
h->index[h->data[i]] = i;
i = j;
j = j / 2;
}
h->data[i] = v;
h->prio[i] = p;
h->index[v] = i;
}
int min (heap_t *h, int i, int j, int k) {
int m = i;
if (j <= h->len && h->prio[j] < h->prio[m])
m = j;
if (k <= h->len && h->prio[k] < h->prio[m])
m = k;
return m;
}
int pop_heap (heap_t *h) {
int v = h->data[1];
int i = 1;
while (1) {
int j = min(h, h->len, 2 * i, 2 * i + 1);
if (j == h->len)
break;
h->data[i] = h->data[j];
h->prio[i] = h->prio[j];
h->index[h->data[i]] = i;
i = j;
}
h->data[i] = h->data[h->len];
h->prio[i] = h->prio[h->len];
h->index[h->data[i]] = i;
h->len--;
return v;
}
void dijkstra (graph_t *g, int a, int b) {
int i, j;
a = a - 'a';
b = b - 'a';
for (i = 0; i < g->vertices_len; i++) {
vertex_t *v = g->vertices[i];
v->dist = INT_MAX;
v->prev = 0;
v->visited = 0;
}
vertex_t *v = g->vertices[a];
v->dist = 0;
heap_t *h = create_heap(g->vertices_len);
push_heap(h, a, v->dist);
while (h->len) {
i = pop_heap(h);
if (i == b)
break;
v = g->vertices[i];
v->visited = 1;
for (j = 0; j < v->edges_len; j++) {
edge_t *e = v->edges[j];
vertex_t *u = g->vertices[e->vertex];
if (!u->visited && v->dist + e->weight <= u->dist) {
u->prev = i;
u->dist = v->dist + e->weight;
push_heap(h, e->vertex, u->dist);
}
}
}
v = g->vertices[i];
printf("%d\n", v->dist);
}
int main () {
graph_t *g = calloc(1, sizeof (graph_t));
add_edge(g, 'a', 'b', 7);
add_edge(g, 'a', 'c' ,9);
dijkstra(g, 'a', 'c');
return 0;
}
and here is my new code(that i want to make work):
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
typedef struct {
int vertex;
int weight;
} edge_t;
typedef struct {
edge_t **edges;
int edges_len;
int edges_size;
int dist;
int prev;
int visited;
} vertex_t;
typedef struct {
vertex_t **vertices;
int vertices_len;
int vertices_size;
} graph_t;
typedef struct {
int *data;
int *prio;
int *index;
int len;
int size;
} heap_t;
void add_vertex (graph_t *g, int i) {
int j;
if (g->vertices_size < i + 1) {
int size = g->vertices_size * 2 > i ? g->vertices_size * 2 : i + 4;
g->vertices = realloc(g->vertices, size * sizeof (vertex_t *));
for (j = g->vertices_size; j < size; j++)
g->vertices[j] = NULL;
g->vertices_size = size;
}
if (!g->vertices[i]) {
g->vertices[i] = calloc(1, sizeof (vertex_t));
g->vertices_len++;
}
}
void add_edge (graph_t *g, int a, int b, int w) {
add_vertex(g, a);
add_vertex(g, b);
vertex_t *v = g->vertices[a];
if (v->edges_len >= v->edges_size) {
v->edges_size = v->edges_size ? v->edges_size * 2 : 4;
v->edges = realloc(v->edges, v->edges_size * sizeof (edge_t *));
}
edge_t *e = calloc(1, sizeof (edge_t));
e->vertex = b;
e->weight = w;
v->edges[v->edges_len++] = e;
}
heap_t *create_heap (int n) {
heap_t *h = calloc(1, sizeof (heap_t));
h->data = calloc(n + 1, sizeof (int));
h->prio = calloc(n + 1, sizeof (int));
h->index = calloc(n, sizeof (int));
return h;
}
void push_heap (heap_t *h, int v, int p) {
int i = h->index[v] == 0 ? ++h->len : h->index[v];
int j = i / 2;
while (i > 1) {
if (h->prio[j] < p)
break;
h->data[i] = h->data[j];
h->prio[i] = h->prio[j];
h->index[h->data[i]] = i;
i = j;
j = j / 2;
}
h->data[i] = v;
h->prio[i] = p;
h->index[v] = i;
}
int min (heap_t *h, int i, int j, int k) {
int m = i;
if (j <= h->len && h->prio[j] < h->prio[m])
m = j;
if (k <= h->len && h->prio[k] < h->prio[m])
m = k;
return m;
}
int pop_heap (heap_t *h) {
int v = h->data[1];
int i = 1;
while (1) {
int j = min(h, h->len, 2 * i, 2 * i + 1);
if (j == h->len)
break;
h->data[i] = h->data[j];
h->prio[i] = h->prio[j];
h->index[h->data[i]] = i;
i = j;
}
h->data[i] = h->data[h->len];
h->prio[i] = h->prio[h->len];
h->index[h->data[i]] = i;
h->len--;
return v;
}
void dijkstra (graph_t *g, int a, int b) {
int i, j;
for (i = 0; i < g->vertices_len; i++) {
vertex_t *v = g->vertices[i];
v->dist = INT_MAX;
v->prev = 0;
v->visited = 0;
}
vertex_t *v = g->vertices[a];
v->dist = 0;
heap_t *h = create_heap(g->vertices_len);
push_heap(h, a, v->dist);
while (h->len) {
i = pop_heap(h);
if (i == b)
break;
v = g->vertices[i];
v->visited = 1;
for (j = 0; j < v->edges_len; j++) {
edge_t *e = v->edges[j];
vertex_t *u = g->vertices[e->vertex];
if (!u->visited && v->dist + e->weight <= u->dist) {
u->prev = i;
u->dist = v->dist + e->weight;
push_heap(h, e->vertex, u->dist);
}
}
}
v = g->vertices[i];
printf("%d\n", v->dist);
}
int main () {
graph_t *g = calloc(1, sizeof (graph_t));
add_edge(g, 1, 2, 7);
add_edge(g, 1, 3 9);
dijkstra(g, 1, 3);
return 0;
}
I would be happy for any suggestion how to make it work even the old one to transform to accept numbers as paramateres and not 'characters'. thanks guys
John Bollinger's comment is right; you are testing different indices. Inside your dijkstra, you are assuming that the graph is fully populated, when it is really very sparse. If I have it correctly, you can ignore the nil nodes:
## -1,3 +1,4 ##
+#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
## -116,11 +117,17 ##
int i, j;
for (i = 0; i < g->vertices_len; i++) {
vertex_t *v = g->vertices[i];
- v->dist = INT_MAX;
- v->prev = 0;
- v->visited = 0;
+ if (v) {
+ v->dist = INT_MAX;
+ v->prev = 0;
+ v->visited = 0;
+ }
}
vertex_t *v = g->vertices[a];
+ if (v == 0) {
+ printf("-1\n");
+ return;
+ }
v->dist = 0;
heap_t *h = create_heap(g->vertices_len);
push_heap(h, a, v->dist);
## -129,10 +136,12 ##
if (i == b)
break;
v = g->vertices[i];
+ assert(v);
v->visited = 1;
for (j = 0; j < v->edges_len; j++) {
edge_t *e = v->edges[j];
vertex_t *u = g->vertices[e->vertex];
+ assert(u);
if (!u->visited && v->dist + e->weight <= u->dist) {
u->prev = i;
u->dist = v->dist + e->weight;
## -140,8 +149,11 ##
}
}
}
- v = g->vertices[i];
- printf("%d\n", v->dist);
+ if (v = g->vertices[i]) {
+ printf("%d\n", v->dist);
+ } else {
+ printf("-2\n");
+ }
}
At the very least, it doesn't fault with your config.

Trying to find number of possible paths going through all points exactly once starting at the center of a 5x5 array. Diagonal movement is also allowed

#include <iostream>
using namespace std;
long long int acc = 0;
bool isValid(int x, int y, int m[5][5])
{
if(x > -1 && x < 5 && y > -1 && y < 5 && m[x][y] == 0)
{
return true;
}
else
{
return false;
}
}
void start(int x, int y, int m[5][5],int count)
{
if(isValid(x,y,m))
{
count++;
if(count == 25)
{
acc++;
}
else
{
m[x][y] = 1;
start(x+1,y,m,count);
start(x-1,y,m,count);
start(x,y+1,m,count);
start(x,y-1,m,count);
start(x+1,y+1,m,count);
start(x-1,y-1,m,count);
start(x+1,y-1,m,count);
start(x-1,y+1,m,count);
}
}
}
int main()
{
int map[5][5];
for(int i = 0; i < 5; i++)
{
for(int j = 0;j < 5; j++)
{
map[i][j] = 0;
}
}
start(2,2,map,0);
cout<<acc;
}
or another code which i tried
#include <iostream>
#include <vector>
using namespace std;
long long int acc = 0;
class Point
{
public:
int row;
int column;
int count;
int map[5][5];
};
vector<Point> pts;
bool isValid(Point *b)
{
if(b->column > -1 && b->column <5 && b->row > -1 && b->row < 5 && b->map[b->column][b->row] != 1)
{
return true;
}
else
{
return false;
}
}
void start(vector<Point> A)
{
if(A.size() == 0)
{
cout<<acc;
}
Point *temp = &A.back();
A.pop_back();
if(isValid(temp))
{
temp->map[temp->column][temp->row] = 1;
temp->count = temp->count + 1;
if(temp->count == 25)
{
acc++;
}
else
{
Point *p = new Point;
for(int i = 0; i < 5; i++)
{
for(int j = 0;j < 5; j++)
{
p->map[i][j] = temp->map[i][j];
}
}
p->column = temp->column + 1;
p->row = temp->row;
p->count = temp->count;
A.push_back(*p);
Point *q = new Point;
for(int i = 0; i < 5; i++)
{
for(int j = 0;j < 5; j++)
{
q->map[i][j] = temp->map[i][j];
}
}
q->column = temp->column - 1;
q->row = temp->row;
q->count = temp->count;
A.push_back(*q);
Point *r = new Point;
for(int i = 0; i < 5; i++)
{
for(int j = 0;j < 5; j++)
{
r->map[i][j] = temp->map[i][j];
}
}
r->column = temp->column;
r->row = temp->row + 1;
r->count = temp->count;
A.push_back(*r);
Point *s = new Point;
for(int i = 0; i < 5; i++)
{
for(int j = 0;j < 5; j++)
{
s->map[i][j] = temp->map[i][j];
}
}
s->column = temp->column;
s->row = temp->row - 1;
s->count = temp->count;
A.push_back(*s);
Point *t = new Point;
for(int i = 0; i < 5; i++)
{
for(int j = 0;j < 5; j++)
{
t->map[i][j] = temp->map[i][j];
}
}
t->column = temp->column + 1;
t->row = temp->row + 1;
t->count = temp->count;
A.push_back(*t);
Point *u = new Point;
for(int i = 0; i < 5; i++)
{
for(int j = 0;j < 5; j++)
{
u->map[i][j] = temp->map[i][j];
}
}
u->column = temp->column - 1;
u->row = temp->row - 1;
u->count = temp->count;
A.push_back(*u);
Point *v = new Point;
for(int i = 0; i < 5; i++)
{
for(int j = 0;j < 5; j++)
{
v->map[i][j] = temp->map[i][j];
}
}
v->column = temp->column + 1;
v->row = temp->row - 1;
v->count = temp->count;
A.push_back(*v);
Point *w = new Point;
for(int i = 0; i < 5; i++)
{
for(int j = 0;j < 5; j++)
{
w->map[i][j] = temp->map[i][j];
}
}
w->column = temp->column - 1;
w->row = temp->row + 1;
w->count = temp->count;
A.push_back(*w);
}
}
cout<<A.size();
start(A);
}
int main()
{
pts.clear();
Point *p = new Point;
p->map[2][2] = 0;
p->column = 2;
p->row = 2;
p->count = 0;
cout<<p<<endl;
pts.push_back(*p);
start(pts);
}
the first runs for about 150 iterations and then outputs 0, to indicate no completepaths, which is definitely wrong.
the second seems an error in pointers and addresses, which i still cannot get my head around.

Resources