⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 read.c

📁 matlab整数规划工具箱
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
   ============================================================================
   NAME : read.c

   PURPOSE : translation of lp-problem and storage in sparse matrix

   SHORT : Subroutines for yacc program to store the input in an intermediate
   data-structure. The yacc and lex programs translate the input.  First the
   problemsize is determined and the date is read into an intermediate
   structure, then readinput fills the sparse matrix.

   USAGE : call yyparse(); to start reading the input.  call readinput(); to
   fill the sparse matrix.
   ============================================================================
   Rows : contains the amount of rows + 1. Rows-1 is the amount of constraints
   (no bounds) Rows also contains the rownr 0 which is the objective function

   Columns : contains the amount of columns (different variable names found in
   the constraints)

   Nonnuls : contains the amount of nonnuls = sum of different entries of all
   columns in the constraints and in the objectfunction

   Hash_tab : contains all columnnames on the first level of the structure the
   row information is kept under each column structure in a linked list (also
   the objective funtion is in this structure) Bound information is also
   stored under under the column name

   First_rside : points to a linked list containing all relational operators
   and the righthandside values of the constraints the linked list is in
   reversed order with respect to the rownumbers
   ============================================================================ */
#include "lpkit.h"
#include "lpglob.h"
#include <string.h>
#include <limits.h>

short            *relat;
int              Verbose;
constraint_name  *First_constraint_name;
rside            *First_rside;
tmp_store_struct tmp_store;
short            Ignore_decl;
hashtable        *Hash_tab;

#define HASHSIZE  10007 /* prime number is better, MB */

/*
 * errorhandeling routine for yyparse()
 */
void yyerror(char *string)
{
  fprintf(stderr, "PARSING ERROR: %s on line %d, quiting\n", string, yylineno);
  exit(EXIT_FAILURE);
}

void check_decl(int within_int_decl)
{
  if(within_int_decl) {
    Ignore_decl = FALSE;
  }
  else {
    fprintf(stderr, "Unknown declaration specifier on line %d, ignored\n",
	    yylineno);
    Ignore_decl = TRUE;
  }
}

void add_int_var(char *name)
{
  hashelem *hp;
  
  if(Verbose)
    fprintf(stderr, "int: %s\n", name);
  if(!(hp = findhash(name, Hash_tab)))
    fprintf(stderr,
	    "Unknown variable %s declared integer on line %d, ignored\n",
	    name, yylineno);
  else if(hp->must_be_int)
    fprintf(stderr, "Variable %s declared integer more than once on line %d\n",
	    name, yylineno);
  else
    hp->must_be_int = TRUE;
}

/*
 * initialisation of hashtable and globals.
 */
void init_read(void)
{
  Rows = 0;
  Non_zeros = 0;
  Columns = 0;
  CALLOC(First_rside, 1);
  First_rside->value = 0;
  /* first row (nr 0) is always the objective function */
  First_rside->relat = OF;
  Hash_tab = create_hash_table(HASHSIZE);
} /* init */


/*
 * searchs in column-list (p is pointer to first element of column-list)
 * for column->row = row.
 * getrow() returns a pointer to this column structure.
 * If not found a NULL-pointer is returned
 */
static column *getrow(column *p,
		      int row)
{
  for(; p != NULL; p = p->next)
    if(p->row == row)
      return(p);
  return(p) ;
} /* getrow */

/*
 * Creates a bound record.
 * Set lowbo = 0 and upbo = Infinite
 *
 */
static bound *create_bound_rec(void)
{
  bound *bp;
  CALLOC(bp, 1);
  bp->upbo = DEF_INFINITE;
  bp->lowbo = 0;
  return(bp);
} /* create_bound_rec */

/*
 * clears the tmp_store variable after all information has been copied
 */
void null_tmp_store(void)
{
  tmp_store.value = 0;
  tmp_store.rhs_value = 0;
}

/*
 * variable : pointer to text array with name of variable
 * row      : the rownumber of the constraint
 * value    : value of matrixelement
 *            A(row, variable).
 * Sign     : (global)  determines the sign of value.
 * store()  : stores value in matrix
 *	      A(row, variable). If A(row, variable) already contains data,
 *	      value is added to the existing value.
 */
static void store(char *variable,
		  int row,
		  REAL value) 
{ 
  hashelem *h_tab_p;
  column *col_p;
  
  if(value == 0) {
    fprintf(stderr,
	    "(store) Warning, variable %s has an effective coefficient of 0 on line %d. Ignored.\n",
	    variable, yylineno);
    return;
  }
  
  if((h_tab_p = findhash(variable, Hash_tab)) == NULL) {
    h_tab_p = puthash(variable, Hash_tab);
    Columns++; /* counter for calloc of final array */
    CALLOC(h_tab_p->col, 1);
    Non_zeros++; /* for calloc of final arrays */
    h_tab_p->col->row = row;
    h_tab_p->col->value = value;
  }
  else if((col_p = getrow(h_tab_p->col, row)) == NULL) {
    CALLOC(col_p, 1);
    Non_zeros++; /* for calloc of final arrays */
    col_p->value = value;
    col_p->row = row;
    col_p->next = h_tab_p->col;
    h_tab_p->col = col_p;
  }
  else
    col_p->value += value;
} /* store */

/*
 * store relational operator given in yylex[0] in the rightside list.
 * Also checks if it constaint was a bound and if so stores it in the
 * boundslist
 */
void store_re_op(void)
{
  short tmp_relat;

  switch(yytext[0]) {
    
  case '=':
    tmp_relat = EQ;
    break;
    
  case '>':
    tmp_relat=GE;
    break;
    
  case '<':
    tmp_relat=LE;
    break;
    
  default:
    fprintf(stderr, "Error: unknown relational operator %s on line %d\n",
	    yytext, yylineno);
    exit(EXIT_FAILURE);
    break;
  }

  if(Lin_term_count > 1) /* it is not a bound */
    First_rside->relat = tmp_relat;
  else /* could be a bound */
    tmp_store.relat = tmp_relat;
} /* save_re_op */

/*
 * store RHS value in the rightside structure
 * if type = true then
 */
void rhs_store(REAL value)
{
  if(Lin_term_count > 1) /* not a bound */
    First_rside->value += value;
  else /* a bound */
    tmp_store.rhs_value += value;
} /* RHS_store */

/*
 * store all data in the right place
 * count the amount of lineair terms in a constraint
 * only store in data-structure if the constraint is not a bound
 */
void var_store(char *var, int row, REAL value)
{
  if(strlen(var) > MAXSTRL) {
    fprintf(stderr,
	    "Variable name '%s' too long, at most %d characters allowed\n",
	    var, MAXSTRL);
    exit(EXIT_FAILURE);
  }
  /* also in a bound the same var name can occur more than once. Check for
     this. Don't increment Lin_term_count */
  
  if(Lin_term_count != 1 || strcmp(tmp_store.name, var) != 0)
    Lin_term_count++;

  /* always store objective function with rownr == 0. */
  if(row == 0) {
    store(var,  row,  value);
    return;
  }
  
  if(Lin_term_count == 1) { /* don't store yet. could be a bound */
    strcpy(tmp_store.name, var);
    tmp_store.row = row;
    tmp_store.value += value;
    return;
  }
  
  if(Lin_term_count == 2) { /* now you can also store the first variable */
    rside *rp;
    
    /* make space for the rhs information */
    CALLOC(rp, 1);
    rp->next = First_rside;
    First_rside = rp;
    First_rside->value = tmp_store.rhs_value;
    First_rside->relat = tmp_store.relat;
    
    if(tmp_store.value != 0)
      store(tmp_store.name, tmp_store.row, tmp_store.value);
    else
      fprintf(stderr,
	      "Warning, variable %s has an effective coefficient of 0 on line %d. Ignored.\n",
	      tmp_store.name, yylineno);
    
    null_tmp_store();
  }
  
  store(var, row, value);
} /* var_store */



/*
 * store the information in tmp_store because it is a bound
 */
void store_bounds(void)
{
  if(tmp_store.value != 0) {
    hashelem *h_tab_p;
    REAL boundvalue;
      
    if((h_tab_p = findhash(tmp_store.name, Hash_tab)) == NULL) {
      /* a new columnname is found, create an entry in the hashlist */
      h_tab_p = puthash(tmp_store.name, Hash_tab);
      Columns++; /* counter for calloc of final array */
      /* create a place to store bounds information */
      h_tab_p->bnd = create_bound_rec();
    }
    else if(h_tab_p->bnd == NULL)
      /* create a place to store bounds information */
      h_tab_p->bnd = create_bound_rec();

    /* else bound_rec already exists */
      
    if(tmp_store.value < 0) { /* divide by negative number, */
      /* relational operator may change */
      if(tmp_store.relat == GE)
	tmp_store.relat = LE;
      else if(tmp_store.relat == LE)
	tmp_store.relat = GE;
    }
    /* Check sanity of bound; all variables should be positive */
    boundvalue = tmp_store.rhs_value / tmp_store.value;
    if(   ((tmp_store.relat == EQ) && (boundvalue < 0))
       || ((tmp_store.relat == LE) && (boundvalue < 0))) { /* Error */
      fprintf(stderr,
	      "Error on line %d: variables must always be non-negative\n",
	      yylineno);
      exit(EXIT_FAILURE);
    }
      
    if((tmp_store.relat == GE) && (boundvalue <= 0)) /* Warning */
      fprintf(stderr,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -