LCOV - code coverage report
Current view: top level - intopt - intopt.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 90.2 % 399 360
Test Date: 2024-11-23 13:35:59 Functions: 85.7 % 21 18

            Line data    Source code
       1              : #include <math.h>
       2              : #include <stdio.h>
       3              : #include <stdlib.h>
       4              : #include <string.h>
       5              : 
       6              : typedef struct simplex {
       7              :   int m;
       8              :   int n;
       9              :   int *var;
      10              :   double **a;
      11              :   double *b;
      12              :   double *x;
      13              :   double *c;
      14              :   double y;
      15              : } simplex_t;
      16              : 
      17              : typedef struct node {
      18              :   int m;
      19              :   int n;
      20              :   int k;
      21              :   int h;
      22              :   double xh;
      23              :   double ak;
      24              :   double bk;
      25              :   double *min;
      26              :   double *max;
      27              :   double **a;
      28              :   double *b;
      29              :   double *x;
      30              :   double *c;
      31              :   double z;
      32              : } node_t;
      33              : 
      34              : typedef struct link {
      35              :   node_t *data;
      36              :   struct link *next;
      37              : } link_t;
      38              : 
      39      1437803 : void free_node(node_t **p) {
      40      1437803 :   if (*p == NULL)
      41        18960 :     return;
      42      1418843 :   if ((*p)->a != NULL) {
      43     14403332 :     for (int i = 0; i < (*p)->m + 1; i++) {
      44     13741808 :       free((*p)->a[i]);
      45     13741808 :       (*p)->a[i] = NULL;
      46              :     }
      47       661524 :     free((*p)->a);
      48       661524 :     (*p)->a = NULL;
      49              :   }
      50      1418843 :   if ((*p)->b != NULL) {
      51       661524 :     free((*p)->b);
      52       661524 :     (*p)->b = NULL;
      53              :   }
      54      1418843 :   if ((*p)->c != NULL) {
      55       661524 :     free((*p)->c);
      56       661524 :     (*p)->c = NULL;
      57              :   }
      58      1418843 :   if ((*p)->x != NULL) {
      59       661524 :     free((*p)->x);
      60       661524 :     (*p)->x = NULL;
      61              :   }
      62      1418843 :   if ((*p)->min != NULL) {
      63      1418843 :     free((*p)->min);
      64      1418843 :     (*p)->min = NULL;
      65              :   }
      66      1418843 :   if ((*p)->max != NULL) {
      67      1418843 :     free((*p)->max);
      68      1418843 :     (*p)->max = NULL;
      69              :   }
      70      1418843 :   free(*p);
      71      1418843 :   *p = NULL;
      72              : }
      73              : 
      74              : double intopt(int m, int n, double **a, double *b, double *c, double *x);
      75              : 
      76              : double simplex(int m, int n, double **a, double *b, double *c, double *x,
      77              :                double y);
      78              : 
      79              : double xsimplex(int m, int n, double **a, double *b, double *c, double *x,
      80              :                 double y, int *var, int h);
      81              : 
      82              : void pivot(simplex_t *s, int row, int col);
      83              : 
      84              : void prepare(simplex_t *s, int k);
      85              : 
      86              : int initial(simplex_t *s, int m, int n, double **a, double *b, double *c,
      87              :             double *x, double y, int *var);
      88              : 
      89              : int select_nonbasic(simplex_t *s);
      90              : 
      91              : int init(simplex_t *s, int m, int n, double **a, double *b, double *c,
      92              :          double *x, double y, int *var);
      93              : 
      94              : const double epsilon = 1e-9;
      95              : 
      96              : double **make_matrix(int m, int n);
      97              : 
      98              : node_t *initial_node(int m, int n, double **a, double *b, double *c);
      99              : node_t *extend(node_t *p, int m, int n, double **a, double *b, double *c, int k,
     100              :                double ak, double bk);
     101              : int is_integer(double *xp);
     102              : int integer(node_t *p);
     103              : void bound(node_t *p, link_t **h, double *zp, double *x);
     104              : int branch(node_t *q, double z);
     105              : void succ(node_t *p, link_t **h, int m, int n, double **a, double *b, double *c,
     106              :           int k, double ak, double bk, double *zp, double *x);
     107              : 
     108              : // Lab 4
     109              : 
     110         2612 : node_t *initial_node(int m, int n, double **a, double *b, double *c) {
     111              : 
     112         2612 :   node_t *p = calloc(1, sizeof(node_t));
     113         2612 :   p->a = make_matrix(m + 1, n + 1);
     114         2612 :   p->b = calloc(m + 1, sizeof(double));
     115         2612 :   p->c = calloc(n + 1, sizeof(double));
     116         2612 :   p->x = calloc(n + 1, sizeof(double));
     117         2612 :   p->min = calloc(n, sizeof(double));
     118         2612 :   p->max = calloc(n, sizeof(double));
     119         2612 :   p->m = m;
     120         2612 :   p->n = n;
     121              : 
     122              :   // Copy a, b, and c to p
     123              :   // so iterate through each element of the matrix and copy it over
     124              :   // hopefully the compiler can unroll this loop or SIMD it.
     125              :   // check assembly to optimize it
     126        18388 :   for (size_t i = 0; i < m; i++) {
     127       138880 :     for (size_t j = 0; j < n; j++) {
     128       123104 :       p->a[i][j] = a[i][j];
     129              :     }
     130        15776 :     p->b[i] = b[i];
     131              :   }
     132        18388 :   for (size_t k = 0; k < n; k++) {
     133        15776 :     p->c[k] = c[k];
     134              :   }
     135        18388 :   for (size_t i = 0; i < n; i++) {
     136        15776 :     p->min[i] = -INFINITY;
     137        15776 :     p->max[i] = INFINITY;
     138              :   }
     139         2612 :   return p;
     140              : }
     141              : 
     142      1513618 : node_t *extend(node_t *p, int m, int n, double **a, double *b, double *c, int k,
     143              :                double ak, double bk) {
     144              : 
     145      1513618 :   node_t *q = malloc(sizeof(*q));
     146              : 
     147      1513618 :   q->k = k;
     148      1513618 :   q->ak = ak;
     149      1513618 :   q->bk = bk;
     150              : 
     151      1513618 :   if (ak > 0 && isfinite(p->max[k])) {
     152       267510 :     q->m = p->m;
     153      1246108 :   } else if (ak < 0 && p->min[k] > 0) {
     154       273296 :     q->m = p->m;
     155              :   } else {
     156       972812 :     q->m = p->m + 1;
     157              :   }
     158              : 
     159      1513618 :   q->n = p->n;
     160      1513618 :   q->h = -1;
     161      1513618 :   q->a = make_matrix(q->m + 1, q->n + 1);
     162      1513618 :   q->b = calloc(q->m + 1, sizeof(double));
     163      1513618 :   q->c = calloc(q->n + 1, sizeof(double));
     164      1513618 :   q->x = calloc(q->n + 1, sizeof(double));
     165      1513618 :   q->min = calloc(n, sizeof(double));
     166      1513618 :   q->max = calloc(n, sizeof(double));
     167              : 
     168              :   // copy values to q
     169     18538964 :   for (size_t i = 0; i < n; i++) {
     170     17025346 :     q->min[i] = p->min[i];
     171     17025346 :     q->max[i] = p->max[i];
     172     17025346 :     q->c[i] = c[i];
     173              :   }
     174     18538964 :   for (size_t i = 0; i < m; i++) {
     175    216730748 :     for (size_t j = 0; j < n; j++)
     176    199705402 :       q->a[i][j] = a[i][j];
     177              : 
     178     17025346 :     q->b[i] = b[i];
     179              :   }
     180              : 
     181      1513618 :   if (ak > 0) {
     182       756809 :     if (q->max[k] == INFINITY || bk < q->max[k])
     183       756809 :       q->max[k] = bk;
     184              : 
     185       756809 :   } else if (q->min[k] == -INFINITY || -bk > q->min[k])
     186       659484 :     q->min[k] = -bk;
     187              : 
     188     18538964 :   for (size_t i = m, j = 0; j < n; j++) {
     189     17025346 :     if (q->min[j] > -INFINITY) {
     190      5672017 :       q->a[i][j] = -1;
     191      5672017 :       q->b[i] = -q->min[j];
     192      5672017 :       i++;
     193              :     }
     194     17025346 :     if (q->max[j] < INFINITY) {
     195      7730721 :       q->a[i][j] = 1;
     196      7730721 :       q->b[i] = q->max[j];
     197      7730721 :       i++;
     198              :     }
     199              :   }
     200              : 
     201      1513618 :   return q;
     202              : }
     203              : 
     204     11240364 : int is_integer(double *xp) {
     205     11240364 :   double x = *xp;
     206     11240364 :   double r = lround(x); // round or lround
     207     11240364 :   if (fabs(r - x) < epsilon) {
     208      9345797 :     *xp = r;
     209      9345797 :     return 1;
     210              :   }
     211      1894567 :   return 0;
     212              : }
     213              : 
     214      1059894 : int integer(node_t *p) {
     215      6184663 :   for (size_t i = 0; i < p->n; i++) {
     216      6164631 :     if (!is_integer(&(p->x[i]))) {
     217      1039862 :       return 0;
     218              :     }
     219              :   }
     220        20032 :   return 1;
     221              : }
     222              : 
     223              : 
     224        18960 : void bound(node_t *p, link_t **h, double *zp, double *x)
     225              : {
     226        18960 :     if (p == NULL || h == NULL)
     227            0 :         return;
     228              : 
     229        18960 :     if (p->z > *zp)
     230              :     {
     231        13245 :         *zp = p->z;
     232        13245 :         memcpy(x, p->x, sizeof(double) * p->n);
     233              : 
     234        13245 :         if ((*h) == NULL)
     235              :         {
     236          838 :             return;
     237              :         }
     238              :         link_t *q, *prev, *next;
     239        12407 :         q = *h;
     240        15735 :         while (q->data->z < p->z)
     241              :         {
     242         3601 :             q = q->next;
     243         3601 :             if (q == NULL)
     244              :             {
     245          273 :                 return;
     246              :             }
     247         3328 :             if (q->data == NULL)
     248              :             {
     249            0 :                 return;
     250              :             }
     251              :         }
     252              : 
     253        12134 :         prev = q;
     254        12134 :         q = q->next;
     255       299940 :         while (q != NULL)
     256              :         {
     257       287806 :             next = q->next;
     258       287806 :             if (q->data->z < p->z)
     259              :             {
     260          511 :                 prev->next = q->next;
     261          511 :                 free_node(&q->data);
     262          511 :                 free(q);
     263              :             }
     264              :             else
     265              :             {
     266       287295 :                 prev = q;
     267              :             }
     268       287806 :             q = next;
     269              :         }
     270              :     }
     271              : }
     272              : 
     273      1039862 : int branch(node_t *q, double z) {
     274              :   double min, max;
     275              : 
     276      1039862 :   if (q->z < z) {
     277       185157 :     return 0;
     278              :   }
     279              : 
     280      5075733 :   for (size_t h = 0; h < q->n; h++) {
     281      5075733 :     if (!is_integer(&q->x[h])) {
     282       854705 :       if (q->min[h] == -INFINITY) {
     283       581312 :         min = 0;
     284              :       } else {
     285       273393 :         min = q->min[h];
     286              :       }
     287       854705 :       max = q->max[h];
     288              : 
     289       854705 :       if (floorf(q->x[h] < min || ceilf(q->x[h]) > max)) {
     290            0 :         continue;
     291              :       }
     292       854705 :       q->h = h;
     293       854705 :       q->xh = q->x[h];
     294              : 
     295              :       // delete each of a,b,c,x
     296       854705 :       if (q->a != NULL) { // delete matrix
     297     19072960 :         for (size_t i = 0; i < q->m + 1; i++) {
     298     18218255 :           free(q->a[i]);
     299     18218255 :           q->a[i] = NULL;
     300              :         }
     301       854705 :         free(q->a);
     302       854705 :         q->a = NULL;
     303              :       }
     304       854705 :       if (q->b != NULL) { // etc..
     305       854705 :         free(q->b);
     306       854705 :         q->b = NULL;
     307              :       }
     308       854705 :       if (q->c != NULL) {
     309       854705 :         free(q->c);
     310       854705 :         q->c = NULL;
     311              :       }
     312       854705 :       if (q->x != NULL) {
     313       854705 :         free(q->x);
     314       854705 :         q->x = NULL;
     315              :       }
     316       854705 :       return 1;
     317              :     }
     318              :   }
     319            0 :   return 0;
     320              : }
     321              : 
     322      1513618 : void succ(node_t *p, link_t **h, int m, int n, double **a, double *b, double *c,
     323              :           int k, double ak, double bk, double *zp, double *x) {
     324              : 
     325      1513618 :   node_t *q = extend(p, m, n, a, b, c, k, ak, bk);
     326              : 
     327      1513618 :   if (q == NULL) {
     328       852629 :     return;
     329              :   }
     330              : 
     331      1513618 :   q->z = simplex(q->m, q->n, q->a, q->b, q->c, q->x, 0);
     332              : 
     333      1513617 :   if (isfinite(q->z)) {
     334      1056746 :     if (integer(q)) {
     335        18960 :       bound(q, h, zp, x);
     336        18960 :             free_node(&q);
     337      1037786 :     } else if (branch(q, *zp)) {
     338              :       // add q to the linked list h
     339       852629 :       link_t *node = malloc(sizeof(link_t)); // free this
     340       852629 :       node->data = q;
     341       852629 :       node->next = NULL;
     342              : 
     343              :       // insert the new node
     344       852629 :       if (h != NULL) {
     345       852629 :         node->next = *h;
     346       852629 :         *h = node;
     347              :       } else {
     348            0 :         *h = node;
     349              :       }
     350       852629 :     return;
     351              :     }
     352              :   }
     353       660988 :   free_node(&q);
     354              : }
     355              : 
     356              : // Prev labs
     357            0 : void print(simplex_t *s) {
     358            0 :   printf("%14s = %10d\n%14s = %10d\n", "m", s->m, "n", s->n);
     359            0 :   printf("%14s = ", "max z");
     360            0 :   for (size_t i = 0; i < s->m; i++) {
     361            0 :     printf("%10.3lf*x_%zu", s->c[i], i);
     362            0 :     if (i != s->m - 1) {
     363            0 :       printf(" + ");
     364              :     }
     365              :   }
     366            0 :   printf("\n");
     367            0 :   for (size_t i = 0; i < s->m; i++) {
     368            0 :     for (size_t j = 0; j < s->n; ++j) {
     369            0 :       printf("%10.3lf*x_%zu", s->a[i][j], j);
     370            0 :       if (j != s->n - 1) {
     371            0 :         printf(" + ");
     372              :       } else {
     373            0 :         printf(" \u2264 %10.3lf", s->b[i]);
     374              :       }
     375              :     }
     376            0 :     printf("\n");
     377              :   }
     378            0 : }
     379              : 
     380      1516230 : double **make_matrix(int m, int n) {
     381              :   double **a;
     382              : 
     383      1516230 :   a = calloc(m, sizeof(double *));
     384     33476320 :   for (int i = 0; i < m; i += 1) {
     385     31960090 :     a[i] = calloc(n, sizeof(double));
     386              :   }
     387      1516230 :   return a;
     388              : }
     389              : 
     390            0 : void fill_matrix(double **a, int m, int n) {
     391              :   int i, j;
     392            0 :   for (i = 0; i < m; i++)
     393            0 :     for (j = 0; j < n; j++)
     394            0 :       scanf("%lf", &a[i][j]);
     395            0 : }
     396              : 
     397            0 : void free_matrix(double **a, int m) {
     398              :   int i;
     399            0 :   for (i = 0; i < m; i++)
     400            0 :     free(a[i]);
     401            0 :   free(a);
     402            0 : }
     403              : 
     404      1514307 : void prepare(simplex_t *s, int k) {
     405      1514307 :   int m = s->m;
     406      1514307 :   int n = s->n;
     407              :   int i;
     408              : 
     409     31948057 :   for (i = m + n; i > n; i--)
     410     30433750 :     s->var[i] = s->var[i - 1];
     411              : 
     412      1514307 :   s->var[n] = m + n;
     413      1514307 :   n += 1;
     414              : 
     415     31948057 :   for (i = 0; i < m; i++)
     416     30433750 :     s->a[i][n - 1] = -1;
     417              : 
     418      1514307 :   s->x = calloc(m + n, sizeof(double)); // doesn't free the old?
     419      1514307 :   s->c = calloc(n, sizeof(double));
     420      1514307 :   s->c[n - 1] = -1;
     421      1514307 :   s->n = n;
     422      1514307 :   pivot(s, k, n - 1);
     423      1514307 : }
     424              : 
     425      1516230 : double simplex(int m, int n, double **a, double *b, double *c, double *x,
     426              :                double y) {
     427      1516230 :   return xsimplex(m, n, a, b, c, x, y, NULL, 0);
     428              : }
     429              : 
     430      3030537 : double xsimplex(int m, int n, double **a, double *b, double *c, double *x,
     431              :                 double y, int *var, int h) {
     432              :   simplex_t s;
     433              :   int i, row, col;
     434              : 
     435      3030537 :   if (!initial(&s, m, n, a, b, c, x, y, var)) {
     436       456871 :     free(s.var);
     437       456871 :     s.var = NULL;
     438       456871 :     return NAN;
     439              :   }
     440              : 
     441     47576106 :   while ((col = select_nonbasic(&s)) >= 0) {
     442     45002442 :     row = -1;
     443   1026991910 :     for (i = 0; i < m; i++) {
     444    981989468 :       if (a[i][col] > epsilon &&
     445    506521762 :           (row < 0 || b[i] / a[i][col] < b[row] / a[row][col])) {
     446    139501126 :         row = i;
     447              :       }
     448              :     }
     449     45002442 :     if (row < 0) {
     450            0 :       free(s.var);
     451            0 :       s.var = NULL;
     452            0 :       return NAN;
     453              :     }
     454     45002442 :     pivot(&s, row, col);
     455              :   }
     456              : 
     457      2573664 :   if (h == 0) {
     458     13117379 :     for (i = 0; i < n; i++) {
     459     12058021 :       if (s.var[i] < n) {
     460      2493444 :         x[s.var[i]] = 0;
     461              :       }
     462              :     }
     463     22314424 :     for (i = 0; i < m; i++) {
     464     21255066 :       if (s.var[n + i] < n) {
     465      9564577 :         x[s.var[n + i]] = s.b[i];
     466              :       }
     467              :     }
     468      1059358 :     free(s.var);
     469      1059358 :     s.var = NULL;
     470              :   } else {
     471     20062038 :     for (i = 0; i < n; i++) {
     472     18547732 :       x[i] = 0;
     473              :     }
     474     31948030 :     for (i = n; i < n + m; i++) {
     475     30433724 :       x[i] = s.b[i - n];
     476              :     }
     477              :   }
     478      2573664 :   return s.y;
     479              : }
     480              : 
     481     47265334 : void pivot(simplex_t *s, int row, int col) {
     482     47265334 :   double **a = s->a;
     483     47265334 :   double *b = s->b;
     484     47265334 :   double *c = s->c;
     485     47265334 :   int m = s->m;
     486     47265334 :   int n = s->n;
     487              :   int i, j, t;
     488              : 
     489     47265334 :   t = s->var[col];
     490     47265334 :   s->var[col] = s->var[n + row];
     491     47265334 :   s->var[n + row] = t;
     492     47265334 :   s->y = s->y + c[col] * b[row] / a[row][col];
     493              : 
     494    652710353 :   for (i = 0; i < n; ++i) {
     495    605445019 :     if (i != col) {
     496    558179685 :       c[i] = c[i] - c[col] * a[row][i] / a[row][col];
     497              :     }
     498              :   }
     499     47265334 :   c[col] = -c[col] / a[row][col];
     500              : 
     501   1075911068 :   for (i = 0; i < m; ++i) {
     502   1028645734 :     if (i != row) {
     503    981380400 :       b[i] = b[i] - a[i][col] * b[row] / a[row][col];
     504              :     }
     505              :   }
     506              : 
     507   1075911066 :   for (i = 0; i < m; ++i) {
     508   1028645732 :     if (i != row) {
     509  13885327997 :       for (j = 0; j < n; ++j) {
     510  12903947598 :         if (j != col) {
     511  11922567199 :           a[i][j] = a[i][j] - a[i][col] * a[row][j] / a[row][col];
     512              :         }
     513              :       }
     514              :     }
     515              :   }
     516              : 
     517   1075911042 :   for (i = 0; i < m; ++i) {
     518   1028645708 :     if (i != row) {
     519    981380375 :       a[i][col] = -a[i][col] / a[row][col];
     520              :     }
     521              :   }
     522              : 
     523    652710338 :   for (i = 0; i < n; ++i) {
     524    605445004 :     if (i != col) {
     525    558179671 :       a[row][i] = a[row][i] / a[row][col];
     526              :     }
     527              :   }
     528              : 
     529     47265334 :   b[row] = b[row] / a[row][col];
     530     47265334 :   a[row][col] = 1 / a[row][col];
     531              : 
     532     47265334 :   return;
     533              : }
     534              : 
     535      3030537 : int initial(simplex_t *s, int m, int n, double **a, double *b, double *c,
     536              :             double *x, double y, int *var) {
     537      3030537 :   int i, j, k = 0;
     538              :   double w;
     539      3030537 :   k = init(s, m, n, a, b, c, x, y, var);
     540              : 
     541      3030537 :   if (b[k] >= 0) {
     542      1516230 :     return 1; // lab 2
     543              :   }
     544      1514307 :   prepare(s, k);
     545      1514307 :   n = s->n;
     546      1514307 :   s->y = xsimplex(m, n, s->a, s->b, s->c, s->x, 0, s->var, 1);
     547              : 
     548     31133833 :   for (i = 0; i < m + n; i++) {
     549     31133833 :     if (s->var[i] == m + n - 1) {
     550      1514306 :       if (fabs(s->x[i]) > epsilon) {
     551       456871 :         free(s->x);
     552       456871 :         free(s->c);
     553       456871 :         s->x = NULL;
     554       456871 :         s->c = NULL;
     555       456871 :         return 0;
     556              :       } else
     557      1057435 :         break;
     558              :     }
     559              :   }
     560              : 
     561      1057435 :   if (i >= n) {
     562     10437855 :     for (j = 0, k = 0; k < n; k++) {
     563      9689270 :       if (fabs(s->a[i - n][k]) > fabs(s->a[i - n][j]))
     564      1667692 :         j = k;
     565              :     }
     566       748585 :     pivot(s, i - n, j);
     567       748585 :     i = j;
     568              :   }
     569              : 
     570      1057435 :   if (i < n - 1) {
     571       994507 :     k = s->var[i];
     572       994507 :     s->var[i] = s->var[n - 1];
     573       994507 :     s->var[n - 1] = k;
     574     21092283 :     for (k = 0; k < m; k++) {
     575     20097776 :       w = s->a[k][n - 1];
     576     20097776 :       s->a[k][n - 1] = s->a[k][i];
     577     20097776 :       s->a[k][i] = s->a[k][i];
     578     20097776 :       s->a[k][i] = w;
     579              :     }
     580              :   }
     581      1057435 :   free(s->c);
     582      1057435 :   s->c = c;
     583      1057435 :   s->y = y;
     584     22302391 :   for (k = n - 1; k < n + m - 1; k++)
     585     21244956 :     s->var[k] = s->var[k + 1];
     586      1057435 :   n = s->n = s->n - 1;
     587      1057435 :   double *t = calloc(n, sizeof(double *));
     588              : 
     589     13107774 :   for (k = 0; k < n; k++) {
     590    138298244 :     for (j = 0; j < n; j++) {
     591    129652032 :       if (k == s->var[j]) {
     592      3404127 :         t[j] = t[j] + s->c[k];
     593      3404127 :         goto next_k;
     594              :       }
     595              :     }
     596     90619678 :     for (j = 0; j < m; j++) {
     597     90619678 :       if (s->var[n + j] == k)
     598      8646212 :         break;
     599              :     }
     600      8646212 :     s->y = s->y + s->c[k] * s->b[j];
     601    111733296 :     for (i = 0; i < n; i++)
     602    103087084 :       t[i] = t[i] - s->c[k] * s->a[j][i];
     603              : 
     604     12050339 :   next_k:;
     605              :   }
     606     13107774 :   for (i = 0; i < n; i++)
     607     12050339 :     s->c[i] = t[i];
     608      1057435 :   free(t);
     609      1057435 :   free(s->x);
     610      1057435 :   t = NULL;
     611      1057435 :   s->x = NULL;
     612      1057435 :   return 1;
     613              : }
     614              : 
     615     47576106 : int select_nonbasic(simplex_t *s) {
     616              :   int i;
     617    258416668 :   for (i = 0; i < s->n; i++) {
     618    255843004 :     if (s->c[i] > epsilon) {
     619     45002442 :       return i;
     620              :     }
     621              :   }
     622      2573664 :   return -1;
     623              : }
     624              : 
     625      3030537 : int init(simplex_t *s, int m, int n, double **a, double *b, double *c,
     626              :          double *x, double y, int *var) {
     627              :   int i, k;
     628      3030537 :   s->m = m;
     629      3030537 :   s->n = n;
     630      3030537 :   s->a = a;
     631      3030537 :   s->b = b;
     632      3030537 :   s->c = c;
     633      3030537 :   s->x = x;
     634      3030537 :   s->y = y;
     635      3030537 :   s->var = var;
     636              : 
     637      3030537 :   if (s->var == NULL) {
     638      1516230 :     s->var = calloc(m + n + 1, sizeof(int));
     639     49001212 :     for (i = 0; i < m + n; i++) {
     640     47484982 :       s->var[i] = i;
     641              :     }
     642              :   }
     643     60877610 :   for (k = 0, i = 1; i < m; i++) {
     644     57847073 :     if (b[i] < b[k]) {
     645      5631720 :       k = i;
     646              :     }
     647              :   }
     648      3030537 :   return k;
     649              : }
     650              : 
     651              : // körs free på p och h?
     652         2075 : void free_list(link_t **head) {
     653         2075 :     link_t *current = *head;
     654              :     link_t *next;
     655              :     
     656         2075 :     while (current != NULL) {
     657            0 :         next = current->next;       // Save next pointer before we free current
     658            0 :         free_node(&current->data);  // Free the node_t data using your existing free_node
     659            0 :         free(current);              // Free the link_t structure itself
     660            0 :         current = next;
     661              :     }
     662         2075 :     *head = NULL;  // Set the head pointer to NULL after freeing
     663         2075 : }
     664              : 
     665         2612 : double intopt(int m, int n, double **a, double *b, double *c, double *x) {
     666         2612 :   node_t *p = initial_node(m, n, a, b, c);
     667         2612 :   double z = -INFINITY;
     668         2612 :   link_t *h = calloc(m, sizeof(link_t));
     669         2612 :   h->data = p;
     670         2612 :   h->next = NULL;
     671              : 
     672         2612 :   p->z = simplex(p->m, p->n, p->a, p->b, p->c, p->x, 0);
     673              : 
     674         2612 :   if (integer(p) || !isfinite(p->z)) {
     675          536 :     z = p->z;
     676          536 :     if (integer(p)) {
     677              :       // copy px to x
     678          536 :       memcpy(x, p->x, sizeof(double) * p->n);
     679              :     }
     680          536 :     free_node(&p);
     681          536 :     free(h);
     682              :     //free_list(&h); // this doesn't free the entire list?
     683          536 :     return z;
     684              :   }
     685              : 
     686         2076 :   branch(p, z);
     687              : 
     688       758884 :   while (h != NULL) {
     689       756809 :     link_t *pop = h;
     690       756809 :     h = pop->next;
     691       756809 :     node_t *p = pop->data;
     692       756809 :     free(pop);
     693              :     
     694       756809 :     succ(p, &h, m, n, a, b, c, p->h, 1, floorf(p->xh), &z, x);
     695       756809 :     succ(p, &h, m, n, a, b, c, p->h, -1, -ceilf(p->xh), &z, x);
     696       756808 :     free_node(&p);
     697              :   }
     698              :   //free(h);
     699         2075 :   free_list(&h);
     700         2075 :   h = NULL;
     701         2075 :   if (z == -INFINITY)
     702            0 :     return NAN;
     703              :   else
     704         2075 :     return z;
     705              : }
        

Generated by: LCOV version 2.0-1