mirror of
https://github.com/Interlisp/maiko.git
synced 2026-01-17 08:33:48 +00:00
* Remove static char *id = from all source files. The same information is included in a comment in each source file. * Remove unused template file 'id'
280 lines
7.0 KiB
C
280 lines
7.0 KiB
C
/* $Id: lpmain.c,v 1.2 1999/01/03 02:07:19 sybalsky Exp $ (C) Copyright Venue, All Rights Reserved
|
|
*/
|
|
|
|
/************************************************************************/
|
|
/* */
|
|
/* (C) Copyright 1989, 1990, 1990, 1991, 1992, 1993, 1994, 1995 Venue. */
|
|
/* All Rights Reserved. */
|
|
/* Manufactured in the United States of America. */
|
|
/* */
|
|
/************************************************************************/
|
|
|
|
#include "version.h"
|
|
|
|
#include <setjmp.h>
|
|
#include <signal.h>
|
|
#include <stdlib.h>
|
|
|
|
#ifdef OS4
|
|
#include <sys/types.h>
|
|
#endif /* OS4 */
|
|
|
|
#include "lpkit.h"
|
|
#include "lpglob.h"
|
|
#include "lppatch.h"
|
|
|
|
#include "lispemul.h"
|
|
#include "lspglob.h"
|
|
#include "lispmap.h"
|
|
#include "adr68k.h"
|
|
#include "arith.h"
|
|
|
|
#define CFREE(x) \
|
|
if (x) { \
|
|
free(x); \
|
|
(x) = (void *)0; \
|
|
}
|
|
|
|
lprec *Medley_lp = NULL; /* The lp description for us */
|
|
int SolveCount = 0; /* Counter for interrupting periodically */
|
|
jmp_buf LP_jmpbuf;
|
|
|
|
static lprec *initmilp(lprec *lp) {
|
|
int i, j, rownr;
|
|
int *num, *rownum;
|
|
sstate *st; /* for saving state at timeouts */
|
|
|
|
if (!lp) CALLOC(lp, 1, lprec);
|
|
|
|
/* Done already in lisp. Rows--; */
|
|
Sum = Rows + Columns;
|
|
|
|
strcpy(lp->lp_name, "LOTS-TP integer program");
|
|
|
|
lp->active = FALSE;
|
|
lp->verbose = FALSE;
|
|
lp->print_duals = FALSE;
|
|
lp->print_sol = FALSE;
|
|
lp->debug = FALSE;
|
|
lp->print_at_invert = FALSE;
|
|
lp->trace = FALSE;
|
|
|
|
lp->rows = Rows;
|
|
lp->columns = Columns;
|
|
lp->sum = Rows + Columns;
|
|
lp->rows_alloc = Rows;
|
|
lp->columns_alloc = Columns;
|
|
lp->sum_alloc = lp->sum;
|
|
|
|
lp->names_used = FALSE;
|
|
|
|
lp->obj_bound = DEF_INFINITE;
|
|
lp->bb_rule = FIRST_NI;
|
|
lp->break_at_int = FALSE;
|
|
lp->infinite = DEF_INFINITE;
|
|
lp->epsilon = DEF_EPSILON;
|
|
lp->epsb = DEF_EPSB;
|
|
lp->epsd = DEF_EPSD;
|
|
lp->epsel = DEF_EPSEL;
|
|
lp->non_zeros = Non_zeros;
|
|
lp->mat_alloc = Non_zeros;
|
|
lp->row_end_valid = FALSE;
|
|
|
|
CFREE(lp->mat);
|
|
MALLOC(lp->mat, Non_zeros, matrec);
|
|
|
|
CFREE(lp->col_no);
|
|
CALLOC(lp->col_no, Non_zeros, int);
|
|
|
|
CFREE(lp->col_end);
|
|
CALLOC(lp->col_end, Columns + 1, int);
|
|
|
|
CFREE(lp->row_end);
|
|
CALLOC(lp->row_end, Rows + 1, int);
|
|
|
|
CFREE(lp->orig_rh);
|
|
CALLOC(lp->orig_rh, Rows + 1, REAL);
|
|
|
|
CFREE(lp->rh);
|
|
CALLOC(lp->rh, Rows + 1, REAL);
|
|
|
|
CFREE(lp->rhs);
|
|
CALLOC(lp->rhs, Rows + 1, REAL);
|
|
|
|
CFREE(lp->must_be_int);
|
|
CALLOC(lp->must_be_int, Sum + 1, short);
|
|
|
|
CFREE(lp->orig_upbo);
|
|
MALLOC(lp->orig_upbo, Sum + 1, REAL);
|
|
|
|
CFREE(lp->upbo);
|
|
CALLOC(lp->upbo, Sum + 1, REAL);
|
|
|
|
CFREE(lp->orig_lowbo);
|
|
CALLOC(lp->orig_lowbo, Sum + 1, REAL);
|
|
|
|
CFREE(lp->lowbo);
|
|
CALLOC(lp->lowbo, Sum + 1, REAL);
|
|
|
|
for (i = 0; i <= Sum; i++) {
|
|
lp->orig_upbo[i] = lp->infinite;
|
|
lp->orig_lowbo[i] = 0;
|
|
}
|
|
lp->basis_valid = TRUE;
|
|
|
|
CFREE(lp->bas);
|
|
CALLOC(lp->bas, Rows + 1, int);
|
|
|
|
CFREE(lp->basis);
|
|
CALLOC(lp->basis, Sum + 1, short);
|
|
|
|
CFREE(lp->lower);
|
|
CALLOC(lp->lower, Sum + 1, short);
|
|
|
|
for (i = 0; i <= Rows; i++) {
|
|
lp->bas[i] = i;
|
|
lp->basis[i] = TRUE;
|
|
}
|
|
for (i = Rows + 1; i <= Sum; i++) lp->basis[i] = FALSE;
|
|
for (i = 0; i <= Sum; i++) lp->lower[i] = TRUE;
|
|
|
|
lp->eta_valid = TRUE;
|
|
lp->eta_size = 0;
|
|
lp->eta_alloc = 10000;
|
|
lp->max_num_inv = DEFNUMINV;
|
|
|
|
CFREE(lp->eta_value);
|
|
CALLOC(lp->eta_value, 10000, REAL);
|
|
|
|
CFREE(lp->eta_row_nr);
|
|
CALLOC(lp->eta_row_nr, 10000, int);
|
|
|
|
CFREE(lp->eta_col_end);
|
|
CALLOC(lp->eta_col_end, Rows + lp->max_num_inv + 1, int);
|
|
|
|
lp->iter = 0;
|
|
lp->total_iter = 0;
|
|
|
|
CFREE(lp->solution);
|
|
CALLOC(lp->solution, Sum + 1, REAL);
|
|
|
|
CFREE(lp->best_solution);
|
|
CALLOC(lp->best_solution, Sum + 1, REAL);
|
|
|
|
CFREE(lp->duals);
|
|
CALLOC(lp->duals, Rows + 1, REAL);
|
|
|
|
lp->maximise = FALSE;
|
|
lp->floor_first = TRUE;
|
|
|
|
lp->scaling_used = FALSE;
|
|
|
|
CALLOC(lp->ch_sign, Rows + 1, short);
|
|
|
|
for (i = 0; i <= Rows; i++) lp->ch_sign[i] = FALSE;
|
|
|
|
st = lp->solve_states = NULL;
|
|
for (i = 0; i < Sum + 2; i++) {
|
|
if (st) /* There's an old state-saver to use; re-use it. */
|
|
{
|
|
st->saved = 0; /* clear the in-use field */
|
|
st->notint = 0; /* And the not-integer field */
|
|
st = st->next;
|
|
} else {
|
|
st = (sstate *)malloc(sizeof(sstate));
|
|
if (!st) ERROR(ERR_NOMEM); /* Tell the guy there's no memory */
|
|
st->next = lp->solve_states;
|
|
st->saved = 0;
|
|
st->notint = 0; /* And the not-integer field */
|
|
lp->solve_states = st;
|
|
st = (sstate *)NULL;
|
|
}
|
|
}
|
|
|
|
lp->valid = FALSE;
|
|
|
|
return (lp);
|
|
}
|
|
|
|
int lpmain(LispPTR lispresults) {
|
|
int i, failure;
|
|
float *results = (float *)Addr68k_from_LADDR(lispresults);
|
|
|
|
/* solve it */
|
|
|
|
SolveCount = 0; /* reset the "timer", to limit length of a run */
|
|
|
|
if (failure = setjmp(LP_jmpbuf)) return (S_POSITIVE | failure);
|
|
|
|
/* solve it */
|
|
|
|
Level = 0;
|
|
|
|
failure = milpsolve(Medley_lp->solve_states, Orig_upbo, Orig_lowbo, Basis, Lower, Bas);
|
|
|
|
Medley_lp->eta_size = Eta_size;
|
|
Medley_lp->eta_alloc = Eta_alloc;
|
|
Medley_lp->num_inv = Num_inv;
|
|
|
|
if ((failure == INT_SOLN) || (failure == OPTIMAL))
|
|
for (i = 0; i < Sum + 1; i++) results[i] = Best_solution[i];
|
|
|
|
return (S_POSITIVE | failure); /* Tell him what happened so far. */
|
|
|
|
} /* main */
|
|
|
|
int lpsetup(int rows, int cols, int nonnuls, int rhs, int relns, int cend, int mat, int ints,
|
|
int lowbo, int upbo, int objbound)
|
|
{
|
|
double obj_bound = -Infinite;
|
|
int failure, i, autoscale;
|
|
|
|
if (failure = setjmp(LP_jmpbuf)) return (S_POSITIVE | failure);
|
|
|
|
/* mallopt(M_DEBUG, 1);*/ /*debugging!!!!*/
|
|
|
|
Rows = rows & 0xFFFF;
|
|
Columns = cols & 0xFFFF;
|
|
Non_zeros = nonnuls & 0xFFFF;
|
|
|
|
printf("Rows = %d. Cols = %d. Non-zeros = %d.\n", Rows, Columns, Non_zeros);
|
|
|
|
Medley_lp = initmilp(Medley_lp);
|
|
readlispinput(Medley_lp, Addr68k_from_LADDR(rhs), Addr68k_from_LADDR(relns),
|
|
Addr68k_from_LADDR(cend), Addr68k_from_LADDR(mat), Addr68k_from_LADDR(ints),
|
|
Addr68k_from_LADDR(lowbo), Addr68k_from_LADDR(upbo));
|
|
|
|
auto_scale(Medley_lp); /* Scale values */
|
|
|
|
Medley_lp->total_iter = 0;
|
|
Medley_lp->max_level = 1;
|
|
Medley_lp->total_nodes = 0;
|
|
|
|
set_globals(Medley_lp); /* Set global vars for the run */
|
|
if (Isvalid(Medley_lp)) {
|
|
if (objbound) {
|
|
Medley_lp->obj_bound = Best_solution[0] = *((float *)Addr68k_from_LADDR(objbound));
|
|
} else if (Maximise && Medley_lp->obj_bound == Infinite)
|
|
Best_solution[0] = -Infinite;
|
|
else if (!Maximise && Medley_lp->obj_bound == -Infinite)
|
|
Best_solution[0] = Infinite;
|
|
else
|
|
Best_solution[0] = Medley_lp->obj_bound;
|
|
|
|
Level = 0;
|
|
|
|
if (!Medley_lp->basis_valid) {
|
|
for (i = 0; i <= Medley_lp->rows; i++) {
|
|
Medley_lp->basis[i] = TRUE;
|
|
Medley_lp->bas[i] = i;
|
|
}
|
|
for (i = Medley_lp->rows + 1; i <= Medley_lp->sum; i++) Medley_lp->basis[i] = FALSE;
|
|
for (i = 0; i <= Medley_lp->sum; i++) Medley_lp->lower[i] = TRUE;
|
|
Medley_lp->basis_valid = TRUE;
|
|
}
|
|
|
|
Medley_lp->eta_valid = FALSE;
|
|
}
|
|
return (0);
|
|
} /* lpsetup */
|