Compare commits
3
Commits
displayfix
...
goblin
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7d4af06584 | ||
|
|
80bd79bec1 | ||
|
|
e046814557 |
@@ -3860,6 +3860,7 @@ AM_CONDITIONAL(BUILD_REGEX, [test "x$build_brlcad_regex" = "xyes"])
|
||||
AM_CONDITIONAL(BUILD_ZLIB, [test "x$build_brlcad_zlib" = "xyes"])
|
||||
AM_CONDITIONAL(BUILD_URT, [test "x$build_brlcad_urt" = "xyes"])
|
||||
AM_CONDITIONAL(BUILD_OPENNURBS, [test "x$build_brlcad_opennurbs" = "xyes"])
|
||||
AM_CONDITIONAL(BUILD_GOBLIN, [test "x$build_brlcad_goblin" = "xyes"])
|
||||
AM_CONDITIONAL(BUILD_BOOST, [test "x$ac_cv_header_limit" = "xyes" && test "x$ac_cv_header_istream" = "xyes"])
|
||||
AM_CONDITIONAL(BUILD_STEP, [test "x$build_brlcad_step" = "xyes"])
|
||||
AM_CONDITIONAL(BUILD_TERMLIB, [test "x$build_brlcad_termlib" = "xyes"])
|
||||
@@ -4310,6 +4311,9 @@ AC_CONFIG_FILES([
|
||||
src/other/libutahrle/Makefile
|
||||
src/other/libutahrle/include/Makefile
|
||||
src/other/libz/Makefile
|
||||
src/other/goblin/Makefile
|
||||
src/other/goblin/goblin/Makefile
|
||||
src/other/goblin/glpk/Makefile
|
||||
src/other/openNURBS/Makefile
|
||||
src/other/tcl/Makefile
|
||||
src/other/tk/Makefile
|
||||
|
||||
@@ -95,6 +95,12 @@ else !BUILD_TKPNG
|
||||
TKPNGDIR=
|
||||
endif
|
||||
|
||||
if BUILD_GOBLIN
|
||||
GOBLINDIR=goblin
|
||||
else !BUILD_GOBLIN
|
||||
GOBLINDIR=
|
||||
endif
|
||||
|
||||
if BUILD_OPENNURBS
|
||||
OPENNURBSDIR=openNURBS
|
||||
else !BUILD_OPENNURBS
|
||||
@@ -154,6 +160,7 @@ SUBDIRS = \
|
||||
${TOGLDIR} \
|
||||
${OPENNURBSDIR} \
|
||||
${TNTDIR} \
|
||||
${GOBLINDIR} \
|
||||
awf
|
||||
|
||||
endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,20 @@
|
||||
|
||||
SUBDIRS = \
|
||||
goblin \
|
||||
glpk
|
||||
|
||||
EXTRA_DIST = \
|
||||
README \
|
||||
LICENSE
|
||||
|
||||
include $(top_srcdir)/misc/Makefile.defs
|
||||
|
||||
SUBDIRS = \
|
||||
goblin \
|
||||
glpk
|
||||
|
||||
EXTRA_DIST = \
|
||||
README \
|
||||
LICENSE
|
||||
|
||||
include $(top_srcdir)/misc/Makefile.defs
|
||||
@@ -0,0 +1,142 @@
|
||||
Goblin is a full-featured tool chain for handling graphs. The project provides code
|
||||
from the following areas:
|
||||
|
||||
Optimization: Nearly all algorithms described in textbooks on graph optimization are
|
||||
implemented.
|
||||
|
||||
Layout: The most common models (orthogonal, layered, force directed) are supported.
|
||||
|
||||
Composition: Especially for planar graphs, a lot of rules are implemented to derive
|
||||
one graph from another.
|
||||
|
||||
File import and export: Graphs can be read from Dimacs, Tsplib and Steinlib formats.
|
||||
Layouts can be exported to nearly arbitrary bitmap and vectorial formats
|
||||
by implicit use of the fig2dev and the netpbm packages.
|
||||
|
||||
Manipulation: Graph incidence structures can be edited and attributes can be assigned to
|
||||
nodes and edges in the graphical front end.
|
||||
|
||||
While all algorithms are implemented in a C++ class library (libgoblin.a), the editor
|
||||
code and partially the file I/O code are written in the Tcl/Tk scripting language and use
|
||||
a Tcl wrapper of the C++ library.
|
||||
|
||||
Users can choose from the following interfaces:
|
||||
|
||||
* A C++ programming interface (API) described here
|
||||
* A Tcl/Tk programming interface which is less efficient, but sometimes more convenient
|
||||
* A graphical user interface (GUI) to manipulate graphs, but also to run problem solvers
|
||||
and to visualize the (intermediate) results
|
||||
* Solver executables for several optmization problems
|
||||
|
||||
Intended audience
|
||||
|
||||
Any general software on graph optimization can be considered a loose collection of solvers
|
||||
for more or less related combinatorial problems. Other than for LP solvers, the interface
|
||||
is ample and often requires to choose a particular optimization method which is adequate for
|
||||
a certain class of graph instances. Many applications require a programming interface instead
|
||||
of a graphical user interface. In that sense, Goblin is expert software.
|
||||
|
||||
Originally, the library has been designed to visualize graph algorithms. While it takes special
|
||||
efforts to produce good running examples and snap shots, the final output can be interpreted
|
||||
by every undergraduate student who has been instructed with the algorithm's key features.
|
||||
The GUI has been prepared to fiddle about with algorithms.
|
||||
|
||||
Of course, the library is also suited for practical computations. A general statement on the
|
||||
performance is difficult: Some solvers have been added only for sake of completeness (like max-cut),
|
||||
others can solve large-scale instances (like min-cost flow).
|
||||
|
||||
|
||||
Licence
|
||||
|
||||
GOBLIN is open source software and licenced by the GNU Lesser Public License (LGPL). That is,
|
||||
GOBLIN may be downloaded, compiled and used for scientific, educational and other purposes free of
|
||||
charge. For details, in particular the statements about redistribution and changes of the source
|
||||
code, observe the LGPL document which is attached to the package.
|
||||
|
||||
Project state
|
||||
|
||||
The project state permanently toggles between stable and beta: There are frequent functional
|
||||
extensions, and these sometimes require revisions of the internal data structures and even the
|
||||
C++ programming interface.
|
||||
|
||||
Here are some more detailed remarks on the development state:
|
||||
|
||||
The optimization stuff is very comprehensive and, in general, stable. Future releases will come
|
||||
up with alternative methods and performance improvements rather than solvers for additional problems.
|
||||
The drawing codes are mostly stable, but several general features are missing (3D support, infinite
|
||||
nodes and edges, free-style display features). The orthogonal methods lack strong compaction rules.
|
||||
|
||||
The internal graph representations still do not allow for node hierarchies and arbitrary tags on nodes
|
||||
and edges. Tracing is supported for many but not for all methods. This functionality is still difficult
|
||||
to control.
|
||||
Goblin is a full-featured tool chain for handling graphs. The project provides code
|
||||
from the following areas:
|
||||
|
||||
Optimization: Nearly all algorithms described in textbooks on graph optimization are
|
||||
implemented.
|
||||
|
||||
Layout: The most common models (orthogonal, layered, force directed) are supported.
|
||||
|
||||
Composition: Especially for planar graphs, a lot of rules are implemented to derive
|
||||
one graph from another.
|
||||
|
||||
File import and export: Graphs can be read from Dimacs, Tsplib and Steinlib formats.
|
||||
Layouts can be exported to nearly arbitrary bitmap and vectorial formats
|
||||
by implicit use of the fig2dev and the netpbm packages.
|
||||
|
||||
Manipulation: Graph incidence structures can be edited and attributes can be assigned to
|
||||
nodes and edges in the graphical front end.
|
||||
|
||||
While all algorithms are implemented in a C++ class library (libgoblin.a), the editor
|
||||
code and partially the file I/O code are written in the Tcl/Tk scripting language and use
|
||||
a Tcl wrapper of the C++ library.
|
||||
|
||||
Users can choose from the following interfaces:
|
||||
|
||||
* A C++ programming interface (API) described here
|
||||
* A Tcl/Tk programming interface which is less efficient, but sometimes more convenient
|
||||
* A graphical user interface (GUI) to manipulate graphs, but also to run problem solvers
|
||||
and to visualize the (intermediate) results
|
||||
* Solver executables for several optmization problems
|
||||
|
||||
Intended audience
|
||||
|
||||
Any general software on graph optimization can be considered a loose collection of solvers
|
||||
for more or less related combinatorial problems. Other than for LP solvers, the interface
|
||||
is ample and often requires to choose a particular optimization method which is adequate for
|
||||
a certain class of graph instances. Many applications require a programming interface instead
|
||||
of a graphical user interface. In that sense, Goblin is expert software.
|
||||
|
||||
Originally, the library has been designed to visualize graph algorithms. While it takes special
|
||||
efforts to produce good running examples and snap shots, the final output can be interpreted
|
||||
by every undergraduate student who has been instructed with the algorithm's key features.
|
||||
The GUI has been prepared to fiddle about with algorithms.
|
||||
|
||||
Of course, the library is also suited for practical computations. A general statement on the
|
||||
performance is difficult: Some solvers have been added only for sake of completeness (like max-cut),
|
||||
others can solve large-scale instances (like min-cost flow).
|
||||
|
||||
|
||||
Licence
|
||||
|
||||
GOBLIN is open source software and licenced by the GNU Lesser Public License (LGPL). That is,
|
||||
GOBLIN may be downloaded, compiled and used for scientific, educational and other purposes free of
|
||||
charge. For details, in particular the statements about redistribution and changes of the source
|
||||
code, observe the LGPL document which is attached to the package.
|
||||
|
||||
Project state
|
||||
|
||||
The project state permanently toggles between stable and beta: There are frequent functional
|
||||
extensions, and these sometimes require revisions of the internal data structures and even the
|
||||
C++ programming interface.
|
||||
|
||||
Here are some more detailed remarks on the development state:
|
||||
|
||||
The optimization stuff is very comprehensive and, in general, stable. Future releases will come
|
||||
up with alternative methods and performance improvements rather than solvers for additional problems.
|
||||
The drawing codes are mostly stable, but several general features are missing (3D support, infinite
|
||||
nodes and edges, free-style display features). The orthogonal methods lack strong compaction rules.
|
||||
|
||||
The internal graph representations still do not allow for node hierarchies and arbitrary tags on nodes
|
||||
and edges. Tracing is supported for many but not for all methods. This functionality is still difficult
|
||||
to control.
|
||||
@@ -0,0 +1,150 @@
|
||||
set(GLPK_SOURCES
|
||||
glpavl.c
|
||||
glpbcs1.c
|
||||
glpbcs2.c
|
||||
glpchol.c
|
||||
glpdmp.c
|
||||
glphbsm.c
|
||||
glpies1.c
|
||||
glpies2.c
|
||||
glpies3.c
|
||||
glpinv.c
|
||||
glpipm.c
|
||||
glplib1.c
|
||||
glplib2.c
|
||||
glplib3.c
|
||||
glplpp1.c
|
||||
glplpp2.c
|
||||
glplpt.c
|
||||
glplpx1.c
|
||||
glplpx2.c
|
||||
glplpx3.c
|
||||
glplpx4.c
|
||||
glplpx5.c
|
||||
glplpx6a.c
|
||||
glplpx6b.c
|
||||
glplpx6c.c
|
||||
glplpx7.c
|
||||
glplpx8a.c
|
||||
glplpx8c.c
|
||||
glplpx8d.c
|
||||
glpluf.c
|
||||
glpmat.c
|
||||
glpmip1.c
|
||||
glpmpl1.c
|
||||
glpmpl2.c
|
||||
glpmpl3.c
|
||||
glpmpl4.c
|
||||
glpmps.c
|
||||
glpqmd.c
|
||||
glpspm.c
|
||||
glpspx1.c
|
||||
glpspx2.c
|
||||
glpstr.c
|
||||
glptsp.c
|
||||
)
|
||||
|
||||
file(GLOB GLPK_HEADERS *.h)
|
||||
|
||||
include_directories(
|
||||
../../../include
|
||||
)
|
||||
|
||||
add_definitions(
|
||||
-DON_DLL_EXPORTS
|
||||
)
|
||||
|
||||
if(MSVC)
|
||||
add_definitions(
|
||||
-DUNICODE
|
||||
)
|
||||
|
||||
endif(MSVC)
|
||||
|
||||
add_library(glpk SHARED ${GLPK_SOURCES})
|
||||
|
||||
target_link_libraries(glpk ${GLPK_LINKLIBRARIES})
|
||||
|
||||
set_property(TARGET glpk PROPERTY LINK_INTERFACE_LIBRARIES "")
|
||||
|
||||
install(TARGETS glpk
|
||||
RUNTIME DESTINATION bin
|
||||
LIBRARY DESTINATION lib
|
||||
)
|
||||
|
||||
install(FILES ${GLPK_HEADERS} DESTINATION include)
|
||||
set(GLPK_SOURCES
|
||||
glpavl.c
|
||||
glpbcs1.c
|
||||
glpbcs2.c
|
||||
glpchol.c
|
||||
glpdmp.c
|
||||
glphbsm.c
|
||||
glpies1.c
|
||||
glpies2.c
|
||||
glpies3.c
|
||||
glpinv.c
|
||||
glpipm.c
|
||||
glplib1.c
|
||||
glplib2.c
|
||||
glplib3.c
|
||||
glplpp1.c
|
||||
glplpp2.c
|
||||
glplpt.c
|
||||
glplpx1.c
|
||||
glplpx2.c
|
||||
glplpx3.c
|
||||
glplpx4.c
|
||||
glplpx5.c
|
||||
glplpx6a.c
|
||||
glplpx6b.c
|
||||
glplpx6c.c
|
||||
glplpx7.c
|
||||
glplpx8a.c
|
||||
glplpx8c.c
|
||||
glplpx8d.c
|
||||
glpluf.c
|
||||
glpmat.c
|
||||
glpmip1.c
|
||||
glpmpl1.c
|
||||
glpmpl2.c
|
||||
glpmpl3.c
|
||||
glpmpl4.c
|
||||
glpmps.c
|
||||
glpqmd.c
|
||||
glpspm.c
|
||||
glpspx1.c
|
||||
glpspx2.c
|
||||
glpstr.c
|
||||
glptsp.c
|
||||
)
|
||||
|
||||
file(GLOB GLPK_HEADERS *.h)
|
||||
|
||||
include_directories(
|
||||
../../../include
|
||||
)
|
||||
|
||||
add_definitions(
|
||||
-DON_DLL_EXPORTS
|
||||
)
|
||||
|
||||
if(MSVC)
|
||||
add_definitions(
|
||||
-DUNICODE
|
||||
)
|
||||
|
||||
endif(MSVC)
|
||||
|
||||
add_library(glpk SHARED ${GLPK_SOURCES})
|
||||
|
||||
target_link_libraries(glpk ${GLPK_LINKLIBRARIES})
|
||||
|
||||
set_property(TARGET glpk PROPERTY LINK_INTERFACE_LIBRARIES "")
|
||||
|
||||
install(TARGETS glpk
|
||||
RUNTIME DESTINATION bin
|
||||
LIBRARY DESTINATION lib
|
||||
)
|
||||
|
||||
install(FILES ${GLPK_HEADERS} DESTINATION include)
|
||||
@@ -0,0 +1,176 @@
|
||||
|
||||
lib_LTLIBRARIES = libglpk.la
|
||||
noinst_LTLIBRARIES = libglpk_nil.la
|
||||
|
||||
GLPK_INC = \
|
||||
glpavl.h \
|
||||
glpbcs.h \
|
||||
glpchol.h \
|
||||
glpdmp.h \
|
||||
glphbsm.h \
|
||||
glpies.h \
|
||||
glpinv.h \
|
||||
glpipm.h \
|
||||
glpk.h \
|
||||
glplib.h \
|
||||
glplpp.h \
|
||||
glplpt.h \
|
||||
glplpx.h \
|
||||
glpluf.h \
|
||||
glpmat.h \
|
||||
glpmip.h \
|
||||
glpmpl.h \
|
||||
glpmps.h \
|
||||
glpqmd.h \
|
||||
glpspm.h \
|
||||
glpspx.h \
|
||||
glpstr.h \
|
||||
glptsp.h
|
||||
|
||||
GLPK_SRC = \
|
||||
glpavl.c \
|
||||
glpbcs1.c \
|
||||
glpbcs2.c \
|
||||
glpchol.c \
|
||||
glpdmp.c \
|
||||
glphbsm.c \
|
||||
glpies1.c \
|
||||
glpies2.c \
|
||||
glpies3.c \
|
||||
glpinv.c \
|
||||
glpipm.c \
|
||||
glplib1.c \
|
||||
glplib2.c \
|
||||
glplib3.c \
|
||||
glplpp1.c \
|
||||
glplpp2.c \
|
||||
glplpt.c \
|
||||
glplpx1.c \
|
||||
glplpx2.c \
|
||||
glplpx3.c \
|
||||
glplpx4.c \
|
||||
glplpx5.c \
|
||||
glplpx6a.c \
|
||||
glplpx6b.c \
|
||||
glplpx6c.c \
|
||||
glplpx7.c \
|
||||
glplpx8a.c \
|
||||
glplpx8c.c \
|
||||
glplpx8d.c \
|
||||
glpluf.c \
|
||||
glpmat.c \
|
||||
glpmip1.c \
|
||||
glpmpl1.c \
|
||||
glpmpl2.c \
|
||||
glpmpl3.c \
|
||||
glpmpl4.c \
|
||||
glpmps.c \
|
||||
glpqmd.c \
|
||||
glpspm.c \
|
||||
glpspx1.c \
|
||||
glpspx2.c \
|
||||
glpstr.c \
|
||||
glptsp.c
|
||||
|
||||
|
||||
glpkincludedir = $(includedir)/glpk
|
||||
glpkinclude_HEADERS = $(GLPK_INC)
|
||||
|
||||
libglpk_nil_la_SOURCES = $(GLPK_SRC)
|
||||
|
||||
libglpk_la_SOURCES =
|
||||
libglpk_la_LIBADD = libglpk_nil.la
|
||||
|
||||
EXTRA_DIST = \
|
||||
CMakeLists.txt
|
||||
|
||||
include $(top_srcdir)/misc/Makefile.defs
|
||||
|
||||
|
||||
lib_LTLIBRARIES = libglpk.la
|
||||
noinst_LTLIBRARIES = libglpk_nil.la
|
||||
|
||||
GLPK_INC = \
|
||||
glpavl.h \
|
||||
glpbcs.h \
|
||||
glpchol.h \
|
||||
glpdmp.h \
|
||||
glphbsm.h \
|
||||
glpies.h \
|
||||
glpinv.h \
|
||||
glpipm.h \
|
||||
glpk.h \
|
||||
glplib.h \
|
||||
glplpp.h \
|
||||
glplpt.h \
|
||||
glplpx.h \
|
||||
glpluf.h \
|
||||
glpmat.h \
|
||||
glpmip.h \
|
||||
glpmpl.h \
|
||||
glpmps.h \
|
||||
glpqmd.h \
|
||||
glpspm.h \
|
||||
glpspx.h \
|
||||
glpstr.h \
|
||||
glptsp.h
|
||||
|
||||
GLPK_SRC = \
|
||||
glpavl.c \
|
||||
glpbcs1.c \
|
||||
glpbcs2.c \
|
||||
glpchol.c \
|
||||
glpdmp.c \
|
||||
glphbsm.c \
|
||||
glpies1.c \
|
||||
glpies2.c \
|
||||
glpies3.c \
|
||||
glpinv.c \
|
||||
glpipm.c \
|
||||
glplib1.c \
|
||||
glplib2.c \
|
||||
glplib3.c \
|
||||
glplpp1.c \
|
||||
glplpp2.c \
|
||||
glplpt.c \
|
||||
glplpx1.c \
|
||||
glplpx2.c \
|
||||
glplpx3.c \
|
||||
glplpx4.c \
|
||||
glplpx5.c \
|
||||
glplpx6a.c \
|
||||
glplpx6b.c \
|
||||
glplpx6c.c \
|
||||
glplpx7.c \
|
||||
glplpx8a.c \
|
||||
glplpx8c.c \
|
||||
glplpx8d.c \
|
||||
glpluf.c \
|
||||
glpmat.c \
|
||||
glpmip1.c \
|
||||
glpmpl1.c \
|
||||
glpmpl2.c \
|
||||
glpmpl3.c \
|
||||
glpmpl4.c \
|
||||
glpmps.c \
|
||||
glpqmd.c \
|
||||
glpspm.c \
|
||||
glpspx1.c \
|
||||
glpspx2.c \
|
||||
glpstr.c \
|
||||
glptsp.c
|
||||
|
||||
|
||||
glpkincludedir = $(includedir)/glpk
|
||||
glpkinclude_HEADERS = $(GLPK_INC)
|
||||
|
||||
libglpk_nil_la_SOURCES = $(GLPK_SRC)
|
||||
|
||||
libglpk_la_SOURCES =
|
||||
libglpk_la_LIBADD = libglpk_nil.la
|
||||
|
||||
EXTRA_DIST = \
|
||||
CMakeLists.txt
|
||||
|
||||
include $(top_srcdir)/misc/Makefile.defs
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,268 @@
|
||||
/* glpavl.h */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _GLPAVL_H
|
||||
#define _GLPAVL_H
|
||||
|
||||
#include "glpdmp.h"
|
||||
|
||||
#define avl_create_tree glp_avl_create_tree
|
||||
#define avl_strcmp glp_avl_strcmp
|
||||
#define avl_insert_by_key glp_avl_insert_by_key
|
||||
#define avl_find_next_node glp_avl_find_next_node
|
||||
#define avl_find_prev_node glp_avl_find_prev_node
|
||||
#define avl_find_by_key glp_avl_find_by_key
|
||||
#define avl_next_by_key glp_avl_next_by_key
|
||||
#define avl_insert_by_pos glp_avl_insert_by_pos
|
||||
#define avl_find_by_pos glp_avl_find_by_pos
|
||||
#define avl_delete_node glp_avl_delete_node
|
||||
#define avl_rotate_subtree glp_avl_rotate_subtree
|
||||
#define avl_delete_tree glp_avl_delete_tree
|
||||
|
||||
typedef struct AVLTREE AVLTREE;
|
||||
typedef struct AVLNODE AVLNODE;
|
||||
|
||||
struct AVLTREE
|
||||
{ /* AVL tree (Adelson-Velsky & Landis binary search tree) */
|
||||
DMP *pool;
|
||||
/* memory pool for allocating nodes */
|
||||
void *info;
|
||||
/* transit pointer passed to the routine fcmp */
|
||||
int (*fcmp)(void *info, void *key1, void *key2);
|
||||
/* user-defined key comparison routine; if this field is NULL,
|
||||
ordering by keys is not used */
|
||||
int size;
|
||||
/* size of the tree = total number of nodes */
|
||||
AVLNODE *root;
|
||||
/* pointer to the root node */
|
||||
int height;
|
||||
/* height of the tree */
|
||||
};
|
||||
|
||||
struct AVLNODE
|
||||
{ /* node of AVL tree */
|
||||
void *key;
|
||||
/* pointer to node key (data structure for representing keys is
|
||||
supplied by the user) */
|
||||
int rank;
|
||||
/* node rank = relative position of the node in its own subtree =
|
||||
number of nodes in the left subtree plus one */
|
||||
int type;
|
||||
/* reserved for application specific information */
|
||||
void *link;
|
||||
/* reserved for application specific information */
|
||||
AVLNODE *up;
|
||||
/* pointer to the parent node */
|
||||
short int flag;
|
||||
/* node flag:
|
||||
0 - this node is the left child of its parent (or this node is
|
||||
the root of the tree and has no parent)
|
||||
1 - this node is the right child of its parent */
|
||||
short int bal;
|
||||
/* node balance = the difference between heights of the right and
|
||||
left subtrees:
|
||||
-1 - the left subtree is higher than the right one;
|
||||
0 - the left and right subtrees have the same height;
|
||||
+1 - the left subtree is lower than the right one */
|
||||
AVLNODE *left;
|
||||
/* pointer to the root of the left subtree */
|
||||
AVLNODE *right;
|
||||
/* pointer to the root of the right subtree */
|
||||
};
|
||||
|
||||
AVLTREE *avl_create_tree(void *info, int (*fcmp)(void *info,
|
||||
void *key1, void *key2));
|
||||
/* create AVL tree */
|
||||
|
||||
int avl_strcmp(void *info, void *key1, void *key2);
|
||||
/* compare keys of character string type */
|
||||
|
||||
AVLNODE *avl_insert_by_key(AVLTREE *tree, void *key);
|
||||
/* insert new node with given key into AVL tree */
|
||||
|
||||
AVLNODE *avl_find_next_node(AVLTREE *tree, AVLNODE *node);
|
||||
/* find next node in AVL tree */
|
||||
|
||||
AVLNODE *avl_find_prev_node(AVLTREE *tree, AVLNODE *node);
|
||||
/* find previous node in AVL tree */
|
||||
|
||||
AVLNODE *avl_find_by_key(AVLTREE *tree, void *key);
|
||||
/* find first node with given key in AVL tree */
|
||||
|
||||
AVLNODE *avl_next_by_key(AVLTREE *tree, AVLNODE *node);
|
||||
/* find next node with same key in AVL tree */
|
||||
|
||||
AVLNODE *avl_insert_by_pos(AVLTREE *tree, int pos);
|
||||
/* insert new node into given position of AVL tree */
|
||||
|
||||
AVLNODE *avl_find_by_pos(AVLTREE *tree, int pos);
|
||||
/* find node placed in given position of AVL tree */
|
||||
|
||||
void avl_delete_node(AVLTREE *tree, AVLNODE *node);
|
||||
/* delete specified node from AVL tree */
|
||||
|
||||
AVLNODE *avl_rotate_subtree(AVLTREE *tree, AVLNODE *node);
|
||||
/* restore balance of AVL subtree */
|
||||
|
||||
void avl_delete_tree(AVLTREE *tree);
|
||||
/* delete AVL tree */
|
||||
|
||||
#endif
|
||||
|
||||
/* eof */
|
||||
/* glpavl.h */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _GLPAVL_H
|
||||
#define _GLPAVL_H
|
||||
|
||||
#include "glpdmp.h"
|
||||
|
||||
#define avl_create_tree glp_avl_create_tree
|
||||
#define avl_strcmp glp_avl_strcmp
|
||||
#define avl_insert_by_key glp_avl_insert_by_key
|
||||
#define avl_find_next_node glp_avl_find_next_node
|
||||
#define avl_find_prev_node glp_avl_find_prev_node
|
||||
#define avl_find_by_key glp_avl_find_by_key
|
||||
#define avl_next_by_key glp_avl_next_by_key
|
||||
#define avl_insert_by_pos glp_avl_insert_by_pos
|
||||
#define avl_find_by_pos glp_avl_find_by_pos
|
||||
#define avl_delete_node glp_avl_delete_node
|
||||
#define avl_rotate_subtree glp_avl_rotate_subtree
|
||||
#define avl_delete_tree glp_avl_delete_tree
|
||||
|
||||
typedef struct AVLTREE AVLTREE;
|
||||
typedef struct AVLNODE AVLNODE;
|
||||
|
||||
struct AVLTREE
|
||||
{ /* AVL tree (Adelson-Velsky & Landis binary search tree) */
|
||||
DMP *pool;
|
||||
/* memory pool for allocating nodes */
|
||||
void *info;
|
||||
/* transit pointer passed to the routine fcmp */
|
||||
int (*fcmp)(void *info, void *key1, void *key2);
|
||||
/* user-defined key comparison routine; if this field is NULL,
|
||||
ordering by keys is not used */
|
||||
int size;
|
||||
/* size of the tree = total number of nodes */
|
||||
AVLNODE *root;
|
||||
/* pointer to the root node */
|
||||
int height;
|
||||
/* height of the tree */
|
||||
};
|
||||
|
||||
struct AVLNODE
|
||||
{ /* node of AVL tree */
|
||||
void *key;
|
||||
/* pointer to node key (data structure for representing keys is
|
||||
supplied by the user) */
|
||||
int rank;
|
||||
/* node rank = relative position of the node in its own subtree =
|
||||
number of nodes in the left subtree plus one */
|
||||
int type;
|
||||
/* reserved for application specific information */
|
||||
void *link;
|
||||
/* reserved for application specific information */
|
||||
AVLNODE *up;
|
||||
/* pointer to the parent node */
|
||||
short int flag;
|
||||
/* node flag:
|
||||
0 - this node is the left child of its parent (or this node is
|
||||
the root of the tree and has no parent)
|
||||
1 - this node is the right child of its parent */
|
||||
short int bal;
|
||||
/* node balance = the difference between heights of the right and
|
||||
left subtrees:
|
||||
-1 - the left subtree is higher than the right one;
|
||||
0 - the left and right subtrees have the same height;
|
||||
+1 - the left subtree is lower than the right one */
|
||||
AVLNODE *left;
|
||||
/* pointer to the root of the left subtree */
|
||||
AVLNODE *right;
|
||||
/* pointer to the root of the right subtree */
|
||||
};
|
||||
|
||||
AVLTREE *avl_create_tree(void *info, int (*fcmp)(void *info,
|
||||
void *key1, void *key2));
|
||||
/* create AVL tree */
|
||||
|
||||
int avl_strcmp(void *info, void *key1, void *key2);
|
||||
/* compare keys of character string type */
|
||||
|
||||
AVLNODE *avl_insert_by_key(AVLTREE *tree, void *key);
|
||||
/* insert new node with given key into AVL tree */
|
||||
|
||||
AVLNODE *avl_find_next_node(AVLTREE *tree, AVLNODE *node);
|
||||
/* find next node in AVL tree */
|
||||
|
||||
AVLNODE *avl_find_prev_node(AVLTREE *tree, AVLNODE *node);
|
||||
/* find previous node in AVL tree */
|
||||
|
||||
AVLNODE *avl_find_by_key(AVLTREE *tree, void *key);
|
||||
/* find first node with given key in AVL tree */
|
||||
|
||||
AVLNODE *avl_next_by_key(AVLTREE *tree, AVLNODE *node);
|
||||
/* find next node with same key in AVL tree */
|
||||
|
||||
AVLNODE *avl_insert_by_pos(AVLTREE *tree, int pos);
|
||||
/* insert new node into given position of AVL tree */
|
||||
|
||||
AVLNODE *avl_find_by_pos(AVLTREE *tree, int pos);
|
||||
/* find node placed in given position of AVL tree */
|
||||
|
||||
void avl_delete_node(AVLTREE *tree, AVLNODE *node);
|
||||
/* delete specified node from AVL tree */
|
||||
|
||||
AVLNODE *avl_rotate_subtree(AVLTREE *tree, AVLNODE *node);
|
||||
/* restore balance of AVL subtree */
|
||||
|
||||
void avl_delete_tree(AVLTREE *tree);
|
||||
/* delete AVL tree */
|
||||
|
||||
#endif
|
||||
|
||||
/* eof */
|
||||
@@ -0,0 +1,426 @@
|
||||
/* glpbcs.h (branch-and-cut framework) */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _GLPBCS_H
|
||||
#define _GLPBCS_H
|
||||
|
||||
#include "glpies.h"
|
||||
|
||||
#define bcs_driver glp_bcs_driver
|
||||
#define bcs_get_event glp_bcs_get_event
|
||||
#define bcs_add_var glp_bcs_add_var
|
||||
#define bcs_add_con glp_bcs_add_con
|
||||
#define bcs_get_next_var glp_bcs_get_next_var
|
||||
#define bcs_get_next_con glp_bcs_get_next_con
|
||||
#define bcs_set_var_appl glp_bcs_set_var_appl
|
||||
#define bcs_set_con_appl glp_bcs_set_con_appl
|
||||
#define bcs_get_var_appl glp_bcs_get_var_appl
|
||||
#define bcs_get_con_appl glp_bcs_get_con_appl
|
||||
#define bcs_get_num_rows glp_bcs_get_num_rows
|
||||
#define bcs_get_num_cols glp_bcs_get_num_cols
|
||||
#define bcs_get_ith_con glp_bcs_get_ith_con
|
||||
#define bcs_get_jth_var glp_bcs_get_jth_var
|
||||
#define bcs_get_var_info glp_bcs_get_var_info
|
||||
#define bcs_get_con_info glp_bcs_get_con_info
|
||||
#define bcs_which_var glp_bcs_which_var
|
||||
#define bcs_which_con glp_bcs_which_con
|
||||
#define bcs_get_lp_object glp_bcs_get_lp_object
|
||||
|
||||
typedef struct BCS BCS;
|
||||
typedef struct BCSVAR BCSVAR;
|
||||
typedef struct BCSCON BCSCON;
|
||||
typedef struct BCSJOB BCSJOB;
|
||||
|
||||
struct BCS
|
||||
{ /* branch-and-cut workspace */
|
||||
IESTREE *tree;
|
||||
/* implicit enumeration tree */
|
||||
DMP *var_pool;
|
||||
/* memory pool for variables */
|
||||
DMP *con_pool;
|
||||
/* memory pool for constraints */
|
||||
DMP *job_pool;
|
||||
/* memory pool for subproblems */
|
||||
void *info;
|
||||
/* transit pointer passed to the application procedure */
|
||||
void (*appl)(void *info, BCS *bcs);
|
||||
/* event-driven application procedure */
|
||||
int event;
|
||||
/* current event code: */
|
||||
#define BCS_V_UNDEF 1000 /* undefined event (never raised) */
|
||||
#define BCS_V_INIT 1001 /* initializing */
|
||||
#define BCS_V_GENCON 1002 /* constraints generation required */
|
||||
#define BCS_V_GENCUT 1003 /* cutting planes generation required */
|
||||
#define BCS_V_BRANCH 1004 /* branch selection required */
|
||||
#define BCS_V_BINGO 1005 /* better solution found */
|
||||
#define BCS_V_DELVAR 1006 /* some variable is being deleted */
|
||||
#define BCS_V_DELCON 1007 /* some constraint is being deleted */
|
||||
#define BCS_V_TERM 1008 /* terminating */
|
||||
BCSVAR *br_var;
|
||||
/* pointer to a variable chosen by the application procedure to
|
||||
branch on; NULL means no variable has been chosen */
|
||||
BCSVAR *this_var;
|
||||
/* pointer returned by the routine bcs_which_var */
|
||||
BCSCON *this_con;
|
||||
/* pointer returned by the routine bcs_which_con */
|
||||
int found;
|
||||
/* this flag is set if the solver has found at least one integer
|
||||
feasible solution */
|
||||
double best;
|
||||
/* value of the objective function for the best integer feasible
|
||||
solution found by the solver (if the flag found is clear, this
|
||||
value is undefined) */
|
||||
double t_last;
|
||||
/* most recent time when the visual information was displayed */
|
||||
};
|
||||
|
||||
struct BCSVAR
|
||||
{ /* variable */
|
||||
int flag;
|
||||
/* flag used to check pointers: */
|
||||
#define BCS_VAR_FLAG 0x2A564152
|
||||
IESITEM *col;
|
||||
/* pointer to the corresponding master column; the field link in
|
||||
the master column structure points to this structure */
|
||||
int attr;
|
||||
/* variable attributes: */
|
||||
#define BCS_CONTIN 0x01 /* continuous */
|
||||
#define BCS_INTEGER 0x02 /* integer */
|
||||
#define BCS_STATIC 0x04 /* static */
|
||||
#define BCS_DYNAMIC 0x08 /* dynamic */
|
||||
#define BCS_MARKED 0x10 /* marked (for internal purposes) */
|
||||
#define BCS_NONINT 0x20 /* integer infeasibility */
|
||||
int disc;
|
||||
/* reserved for application specific information */
|
||||
void *link;
|
||||
/* reserved for application specific information */
|
||||
};
|
||||
|
||||
struct BCSCON
|
||||
{ /* constraint */
|
||||
int flag;
|
||||
/* flag used to check pointers: */
|
||||
#define BCS_CON_FLAG 0x2A434F4E
|
||||
IESITEM *row;
|
||||
/* pointer to the corresponding master row; the field link in the
|
||||
master row structure points to this structure */
|
||||
int attr;
|
||||
/* constraint attributes: */
|
||||
#define BCS_MARKED 0x10 /* marked (for internal purposes) */
|
||||
int disc;
|
||||
/* reserved for application specific information */
|
||||
void *link;
|
||||
/* reserved for application specific information */
|
||||
};
|
||||
|
||||
struct BCSJOB
|
||||
{ /* subproblem */
|
||||
int flag;
|
||||
/* flag used to check pointers: */
|
||||
#define BCS_JOB_FLAG 0x2A4A4F42
|
||||
IESNODE *node;
|
||||
/* pointer to the corresponding node problem; the field link in
|
||||
the node problem structure refers to this structure */
|
||||
};
|
||||
|
||||
int bcs_driver(char *name, int dir,
|
||||
void *info, void (*appl)(void *info, BCS *bcs));
|
||||
/* branch-and-cut driver */
|
||||
|
||||
int bcs_get_event(BCS *bcs);
|
||||
/* determine current event code */
|
||||
|
||||
BCSVAR *bcs_add_var(BCS *bcs, char *name, int attr, int typx,
|
||||
double lb, double ub, double coef, int len, BCSCON *con[],
|
||||
double val[]);
|
||||
/* add variable to the branch-and-cut workspace */
|
||||
|
||||
BCSCON *bcs_add_con(BCS *bcs, char *name, int attr, int typx,
|
||||
double lb, double ub, int len, BCSVAR *var[], double val[]);
|
||||
/* add constraint to the branch-and-cut workspace */
|
||||
|
||||
BCSVAR *bcs_get_next_var(BCS *bcs, BCSVAR *var);
|
||||
/* get pointer to the next variable */
|
||||
|
||||
BCSCON *bcs_get_next_con(BCS *bcs, BCSCON *con);
|
||||
/* get pointer to the next constraint */
|
||||
|
||||
void bcs_set_var_appl(BCS *bcs, BCSVAR *var, int disc, void *link);
|
||||
/* store application information to variable */
|
||||
|
||||
void bcs_set_con_appl(BCS *bcs, BCSCON *con, int disc, void *link);
|
||||
/* store application information to constraint */
|
||||
|
||||
void bcs_get_var_appl(BCS *bcs, BCSVAR *var, int *disc, void **link);
|
||||
/* retrieve application information from variable */
|
||||
|
||||
void bcs_get_con_appl(BCS *bcs, BCSCON *con, int *disc, void **link);
|
||||
/* retrieve application information from constraint */
|
||||
|
||||
int bcs_get_num_rows(BCS *bcs);
|
||||
/* determine number of rows */
|
||||
|
||||
int bcs_get_num_cols(BCS *bcs);
|
||||
/* determine number of columns */
|
||||
|
||||
BCSCON *bcs_get_ith_con(BCS *bcs, int i);
|
||||
/* determine pointer to i-th constraint */
|
||||
|
||||
BCSVAR *bcs_get_jth_var(BCS *bcs, int j);
|
||||
/* determine pointer to j-th variable */
|
||||
|
||||
void bcs_get_var_info(BCS *bcs, BCSVAR *var, int *tagx, double *vx,
|
||||
double *dx);
|
||||
/* obtain solution information for variable */
|
||||
|
||||
void bcs_get_con_info(BCS *bcs, BCSCON *con, int *tagx, double *vx,
|
||||
double *dx);
|
||||
/* obtain solution information for constraint */
|
||||
|
||||
BCSVAR *bcs_which_var(BCS *bcs);
|
||||
/* determine which variable is meant */
|
||||
|
||||
BCSCON *bcs_which_con(BCS *bcs);
|
||||
/* determine which constraint is meant */
|
||||
|
||||
LPX *bcs_get_lp_object(BCS *bcs);
|
||||
/* get pointer to internal LP object */
|
||||
|
||||
#endif
|
||||
|
||||
/* eof */
|
||||
/* glpbcs.h (branch-and-cut framework) */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _GLPBCS_H
|
||||
#define _GLPBCS_H
|
||||
|
||||
#include "glpies.h"
|
||||
|
||||
#define bcs_driver glp_bcs_driver
|
||||
#define bcs_get_event glp_bcs_get_event
|
||||
#define bcs_add_var glp_bcs_add_var
|
||||
#define bcs_add_con glp_bcs_add_con
|
||||
#define bcs_get_next_var glp_bcs_get_next_var
|
||||
#define bcs_get_next_con glp_bcs_get_next_con
|
||||
#define bcs_set_var_appl glp_bcs_set_var_appl
|
||||
#define bcs_set_con_appl glp_bcs_set_con_appl
|
||||
#define bcs_get_var_appl glp_bcs_get_var_appl
|
||||
#define bcs_get_con_appl glp_bcs_get_con_appl
|
||||
#define bcs_get_num_rows glp_bcs_get_num_rows
|
||||
#define bcs_get_num_cols glp_bcs_get_num_cols
|
||||
#define bcs_get_ith_con glp_bcs_get_ith_con
|
||||
#define bcs_get_jth_var glp_bcs_get_jth_var
|
||||
#define bcs_get_var_info glp_bcs_get_var_info
|
||||
#define bcs_get_con_info glp_bcs_get_con_info
|
||||
#define bcs_which_var glp_bcs_which_var
|
||||
#define bcs_which_con glp_bcs_which_con
|
||||
#define bcs_get_lp_object glp_bcs_get_lp_object
|
||||
|
||||
typedef struct BCS BCS;
|
||||
typedef struct BCSVAR BCSVAR;
|
||||
typedef struct BCSCON BCSCON;
|
||||
typedef struct BCSJOB BCSJOB;
|
||||
|
||||
struct BCS
|
||||
{ /* branch-and-cut workspace */
|
||||
IESTREE *tree;
|
||||
/* implicit enumeration tree */
|
||||
DMP *var_pool;
|
||||
/* memory pool for variables */
|
||||
DMP *con_pool;
|
||||
/* memory pool for constraints */
|
||||
DMP *job_pool;
|
||||
/* memory pool for subproblems */
|
||||
void *info;
|
||||
/* transit pointer passed to the application procedure */
|
||||
void (*appl)(void *info, BCS *bcs);
|
||||
/* event-driven application procedure */
|
||||
int event;
|
||||
/* current event code: */
|
||||
#define BCS_V_UNDEF 1000 /* undefined event (never raised) */
|
||||
#define BCS_V_INIT 1001 /* initializing */
|
||||
#define BCS_V_GENCON 1002 /* constraints generation required */
|
||||
#define BCS_V_GENCUT 1003 /* cutting planes generation required */
|
||||
#define BCS_V_BRANCH 1004 /* branch selection required */
|
||||
#define BCS_V_BINGO 1005 /* better solution found */
|
||||
#define BCS_V_DELVAR 1006 /* some variable is being deleted */
|
||||
#define BCS_V_DELCON 1007 /* some constraint is being deleted */
|
||||
#define BCS_V_TERM 1008 /* terminating */
|
||||
BCSVAR *br_var;
|
||||
/* pointer to a variable chosen by the application procedure to
|
||||
branch on; NULL means no variable has been chosen */
|
||||
BCSVAR *this_var;
|
||||
/* pointer returned by the routine bcs_which_var */
|
||||
BCSCON *this_con;
|
||||
/* pointer returned by the routine bcs_which_con */
|
||||
int found;
|
||||
/* this flag is set if the solver has found at least one integer
|
||||
feasible solution */
|
||||
double best;
|
||||
/* value of the objective function for the best integer feasible
|
||||
solution found by the solver (if the flag found is clear, this
|
||||
value is undefined) */
|
||||
double t_last;
|
||||
/* most recent time when the visual information was displayed */
|
||||
};
|
||||
|
||||
struct BCSVAR
|
||||
{ /* variable */
|
||||
int flag;
|
||||
/* flag used to check pointers: */
|
||||
#define BCS_VAR_FLAG 0x2A564152
|
||||
IESITEM *col;
|
||||
/* pointer to the corresponding master column; the field link in
|
||||
the master column structure points to this structure */
|
||||
int attr;
|
||||
/* variable attributes: */
|
||||
#define BCS_CONTIN 0x01 /* continuous */
|
||||
#define BCS_INTEGER 0x02 /* integer */
|
||||
#define BCS_STATIC 0x04 /* static */
|
||||
#define BCS_DYNAMIC 0x08 /* dynamic */
|
||||
#define BCS_MARKED 0x10 /* marked (for internal purposes) */
|
||||
#define BCS_NONINT 0x20 /* integer infeasibility */
|
||||
int disc;
|
||||
/* reserved for application specific information */
|
||||
void *link;
|
||||
/* reserved for application specific information */
|
||||
};
|
||||
|
||||
struct BCSCON
|
||||
{ /* constraint */
|
||||
int flag;
|
||||
/* flag used to check pointers: */
|
||||
#define BCS_CON_FLAG 0x2A434F4E
|
||||
IESITEM *row;
|
||||
/* pointer to the corresponding master row; the field link in the
|
||||
master row structure points to this structure */
|
||||
int attr;
|
||||
/* constraint attributes: */
|
||||
#define BCS_MARKED 0x10 /* marked (for internal purposes) */
|
||||
int disc;
|
||||
/* reserved for application specific information */
|
||||
void *link;
|
||||
/* reserved for application specific information */
|
||||
};
|
||||
|
||||
struct BCSJOB
|
||||
{ /* subproblem */
|
||||
int flag;
|
||||
/* flag used to check pointers: */
|
||||
#define BCS_JOB_FLAG 0x2A4A4F42
|
||||
IESNODE *node;
|
||||
/* pointer to the corresponding node problem; the field link in
|
||||
the node problem structure refers to this structure */
|
||||
};
|
||||
|
||||
int bcs_driver(char *name, int dir,
|
||||
void *info, void (*appl)(void *info, BCS *bcs));
|
||||
/* branch-and-cut driver */
|
||||
|
||||
int bcs_get_event(BCS *bcs);
|
||||
/* determine current event code */
|
||||
|
||||
BCSVAR *bcs_add_var(BCS *bcs, char *name, int attr, int typx,
|
||||
double lb, double ub, double coef, int len, BCSCON *con[],
|
||||
double val[]);
|
||||
/* add variable to the branch-and-cut workspace */
|
||||
|
||||
BCSCON *bcs_add_con(BCS *bcs, char *name, int attr, int typx,
|
||||
double lb, double ub, int len, BCSVAR *var[], double val[]);
|
||||
/* add constraint to the branch-and-cut workspace */
|
||||
|
||||
BCSVAR *bcs_get_next_var(BCS *bcs, BCSVAR *var);
|
||||
/* get pointer to the next variable */
|
||||
|
||||
BCSCON *bcs_get_next_con(BCS *bcs, BCSCON *con);
|
||||
/* get pointer to the next constraint */
|
||||
|
||||
void bcs_set_var_appl(BCS *bcs, BCSVAR *var, int disc, void *link);
|
||||
/* store application information to variable */
|
||||
|
||||
void bcs_set_con_appl(BCS *bcs, BCSCON *con, int disc, void *link);
|
||||
/* store application information to constraint */
|
||||
|
||||
void bcs_get_var_appl(BCS *bcs, BCSVAR *var, int *disc, void **link);
|
||||
/* retrieve application information from variable */
|
||||
|
||||
void bcs_get_con_appl(BCS *bcs, BCSCON *con, int *disc, void **link);
|
||||
/* retrieve application information from constraint */
|
||||
|
||||
int bcs_get_num_rows(BCS *bcs);
|
||||
/* determine number of rows */
|
||||
|
||||
int bcs_get_num_cols(BCS *bcs);
|
||||
/* determine number of columns */
|
||||
|
||||
BCSCON *bcs_get_ith_con(BCS *bcs, int i);
|
||||
/* determine pointer to i-th constraint */
|
||||
|
||||
BCSVAR *bcs_get_jth_var(BCS *bcs, int j);
|
||||
/* determine pointer to j-th variable */
|
||||
|
||||
void bcs_get_var_info(BCS *bcs, BCSVAR *var, int *tagx, double *vx,
|
||||
double *dx);
|
||||
/* obtain solution information for variable */
|
||||
|
||||
void bcs_get_con_info(BCS *bcs, BCSCON *con, int *tagx, double *vx,
|
||||
double *dx);
|
||||
/* obtain solution information for constraint */
|
||||
|
||||
BCSVAR *bcs_which_var(BCS *bcs);
|
||||
/* determine which variable is meant */
|
||||
|
||||
BCSCON *bcs_which_con(BCS *bcs);
|
||||
/* determine which constraint is meant */
|
||||
|
||||
LPX *bcs_get_lp_object(BCS *bcs);
|
||||
/* get pointer to internal LP object */
|
||||
|
||||
#endif
|
||||
|
||||
/* eof */
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,226 @@
|
||||
/* glpchol.h */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _GLPCHOL_H
|
||||
#define _GLPCHOL_H
|
||||
|
||||
#include "glpmat.h"
|
||||
|
||||
#define chol_numb glp_chol_numb
|
||||
#define chol_symb glp_chol_symb
|
||||
#define create_adat glp_create_adat
|
||||
#define create_chol glp_create_chol
|
||||
#define decomp_adat glp_decomp_adat
|
||||
#define decomp_chol glp_decomp_chol
|
||||
#define delete_adat glp_delete_adat
|
||||
#define delete_chol glp_delete_chol
|
||||
#define min_deg glp_min_deg
|
||||
#define solve_adat glp_solve_adat
|
||||
#define solve_chol glp_solve_chol
|
||||
|
||||
extern void chol_symb(MAT *A, MAT *U, int head[], int next[],
|
||||
char work[]);
|
||||
/* compute Cholesky decomposition A = U'*U; symbolic phase */
|
||||
|
||||
extern int chol_numb(MAT *A, MAT *U, void *head[], double work[]);
|
||||
/* compute Cholesky decomposition A = U'*U; numeric phase */
|
||||
|
||||
extern void min_deg(MAT *A, PER *P);
|
||||
/* minimum degree ordering */
|
||||
|
||||
typedef struct CHOL CHOL;
|
||||
|
||||
struct CHOL
|
||||
{ /* Cholesky factorization of symmetric positive definite matrix
|
||||
in the form A = P'*U'*U*P */
|
||||
int n;
|
||||
/* order of matrices */
|
||||
PER *P;
|
||||
/* permutation matrix (that determines A~ = P*A*P' for which the
|
||||
factorization is actually computed) */
|
||||
MAT *U;
|
||||
/* upper triangular matrix (U'*U = A~ = P*A*P') */
|
||||
int sing;
|
||||
/* number of processed non-positive or very small diagonal
|
||||
elements of the matrix U during numeric factorization (for
|
||||
details see comments to the chol_numb routine) */
|
||||
};
|
||||
|
||||
extern CHOL *create_chol(MAT *A);
|
||||
/* create Cholesky factorization */
|
||||
|
||||
extern void decomp_chol(CHOL *chol, MAT *A);
|
||||
/* compute Cholesky factorization */
|
||||
|
||||
extern void solve_chol(CHOL *chol, double x[], double work[]);
|
||||
/* solving linear system using Cholesky factorization */
|
||||
|
||||
extern void delete_chol(CHOL *chol);
|
||||
/* delete Cholesky factorization */
|
||||
|
||||
typedef struct ADAT ADAT;
|
||||
|
||||
struct ADAT
|
||||
{ /* Cholesky factorization of symmetric positive definite matrix
|
||||
S = A*D*A', where A is rectangular matrix (of full rank), D is
|
||||
diagonal matrix; no dense columns processing */
|
||||
int m;
|
||||
/* number of rows of A */
|
||||
int n;
|
||||
/* number of columns of A, order of D */
|
||||
MAT *S;
|
||||
/* S = A*D*A' (only upper triangular part) */
|
||||
CHOL *chol;
|
||||
/* Cholesky factorization of S */
|
||||
};
|
||||
|
||||
extern ADAT *create_adat(MAT *A);
|
||||
/* create Cholesky factorization for S = A*D*A' */
|
||||
|
||||
extern void decomp_adat(ADAT *adat, MAT *A, double D[]);
|
||||
/* compute Cholesky factorization for S = A*D*A' */
|
||||
|
||||
extern void solve_adat(ADAT *adat, double x[], double work[]);
|
||||
/* solve system A*D*A'*x = b using Cholesky factorization */
|
||||
|
||||
extern void delete_adat(ADAT *adat);
|
||||
/* delete Cholesky factorization for S = A*D*A' */
|
||||
|
||||
#endif
|
||||
|
||||
/* eof */
|
||||
/* glpchol.h */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _GLPCHOL_H
|
||||
#define _GLPCHOL_H
|
||||
|
||||
#include "glpmat.h"
|
||||
|
||||
#define chol_numb glp_chol_numb
|
||||
#define chol_symb glp_chol_symb
|
||||
#define create_adat glp_create_adat
|
||||
#define create_chol glp_create_chol
|
||||
#define decomp_adat glp_decomp_adat
|
||||
#define decomp_chol glp_decomp_chol
|
||||
#define delete_adat glp_delete_adat
|
||||
#define delete_chol glp_delete_chol
|
||||
#define min_deg glp_min_deg
|
||||
#define solve_adat glp_solve_adat
|
||||
#define solve_chol glp_solve_chol
|
||||
|
||||
extern void chol_symb(MAT *A, MAT *U, int head[], int next[],
|
||||
char work[]);
|
||||
/* compute Cholesky decomposition A = U'*U; symbolic phase */
|
||||
|
||||
extern int chol_numb(MAT *A, MAT *U, void *head[], double work[]);
|
||||
/* compute Cholesky decomposition A = U'*U; numeric phase */
|
||||
|
||||
extern void min_deg(MAT *A, PER *P);
|
||||
/* minimum degree ordering */
|
||||
|
||||
typedef struct CHOL CHOL;
|
||||
|
||||
struct CHOL
|
||||
{ /* Cholesky factorization of symmetric positive definite matrix
|
||||
in the form A = P'*U'*U*P */
|
||||
int n;
|
||||
/* order of matrices */
|
||||
PER *P;
|
||||
/* permutation matrix (that determines A~ = P*A*P' for which the
|
||||
factorization is actually computed) */
|
||||
MAT *U;
|
||||
/* upper triangular matrix (U'*U = A~ = P*A*P') */
|
||||
int sing;
|
||||
/* number of processed non-positive or very small diagonal
|
||||
elements of the matrix U during numeric factorization (for
|
||||
details see comments to the chol_numb routine) */
|
||||
};
|
||||
|
||||
extern CHOL *create_chol(MAT *A);
|
||||
/* create Cholesky factorization */
|
||||
|
||||
extern void decomp_chol(CHOL *chol, MAT *A);
|
||||
/* compute Cholesky factorization */
|
||||
|
||||
extern void solve_chol(CHOL *chol, double x[], double work[]);
|
||||
/* solving linear system using Cholesky factorization */
|
||||
|
||||
extern void delete_chol(CHOL *chol);
|
||||
/* delete Cholesky factorization */
|
||||
|
||||
typedef struct ADAT ADAT;
|
||||
|
||||
struct ADAT
|
||||
{ /* Cholesky factorization of symmetric positive definite matrix
|
||||
S = A*D*A', where A is rectangular matrix (of full rank), D is
|
||||
diagonal matrix; no dense columns processing */
|
||||
int m;
|
||||
/* number of rows of A */
|
||||
int n;
|
||||
/* number of columns of A, order of D */
|
||||
MAT *S;
|
||||
/* S = A*D*A' (only upper triangular part) */
|
||||
CHOL *chol;
|
||||
/* Cholesky factorization of S */
|
||||
};
|
||||
|
||||
extern ADAT *create_adat(MAT *A);
|
||||
/* create Cholesky factorization for S = A*D*A' */
|
||||
|
||||
extern void decomp_adat(ADAT *adat, MAT *A, double D[]);
|
||||
/* compute Cholesky factorization for S = A*D*A' */
|
||||
|
||||
extern void solve_adat(ADAT *adat, double x[], double work[]);
|
||||
/* solve system A*D*A'*x = b using Cholesky factorization */
|
||||
|
||||
extern void delete_adat(ADAT *adat);
|
||||
/* delete Cholesky factorization for S = A*D*A' */
|
||||
|
||||
#endif
|
||||
|
||||
/* eof */
|
||||
@@ -0,0 +1,568 @@
|
||||
/* glpdmp.c */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#include <string.h>
|
||||
#include "glpdmp.h"
|
||||
#include "glplib.h"
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- dmp_create_pool - create dynamic memory pool.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glpdmp.h"
|
||||
-- DMP *dmp_create_pool(int size);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The routine dmp_create_pool creates a dynamic memory pool.
|
||||
--
|
||||
-- If the parameter size is positive, the fixed-sized memory pool is
|
||||
-- created. This means that all atoms in the memory pool have the same
|
||||
-- size (in bytes). The size should be in the range 1 to 256 bytes.
|
||||
--
|
||||
-- If the parameter size is zero, the variable-sized memory pool is
|
||||
-- created. This means that atoms in the memory pool may have different
|
||||
-- sizes.
|
||||
--
|
||||
-- *Returns*
|
||||
--
|
||||
-- The routine returns a pointer to the created dynamic memory pool. */
|
||||
|
||||
DMP *dmp_create_pool(int size)
|
||||
{ DMP *pool;
|
||||
if (!(0 <= size && size <= 256))
|
||||
fault("dmp_create_pool: size = %d; invalid atom size", size);
|
||||
pool = umalloc(sizeof(DMP));
|
||||
pool->size = size;
|
||||
pool->avail = NULL;
|
||||
pool->link = NULL;
|
||||
pool->used = 0;
|
||||
pool->stock = NULL;
|
||||
pool->count = 0;
|
||||
return pool;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- dmp_get_atom - obtain free atom from fixed-sized memory pool.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glpdmp.h"
|
||||
-- void *dmp_get_atom(DMP *pool);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The routine dmp_get_atom obtains a free atom (which is continuous
|
||||
-- space of memory) from the specified fixed-sized dynamic memory pool.
|
||||
--
|
||||
-- The atom size, in bytes, should be specified on creating the pool by
|
||||
-- the routine dmp_create_pool.
|
||||
--
|
||||
-- Note that the free atom returned by the routine initially contains
|
||||
-- arbitrary data (not binary zeros).
|
||||
--
|
||||
-- *Returns*
|
||||
--
|
||||
-- The routine returns a pointer to the free atom. */
|
||||
|
||||
void *dmp_get_atom(DMP *pool)
|
||||
{ int size = pool->size;
|
||||
void *atom, *blk;
|
||||
if (size == 0)
|
||||
fault("dmp_get_atom: pool = %p; attempt to obtain atom from va"
|
||||
"riable-sized pool", pool);
|
||||
/* if there is a free atom, just pull it from the list */
|
||||
atom = pool->avail;
|
||||
if (atom != NULL)
|
||||
{ pool->avail = *(void **)atom;
|
||||
goto skip;
|
||||
}
|
||||
/* free atom list is empty; if the most recently allocated block
|
||||
doesn't exist or hasn't enough space, a new block is needed */
|
||||
if (pool->link == NULL || pool->used + size > DMP_BLK_SIZE)
|
||||
{ /* pull a new block from the list of free blocks, or if this
|
||||
list is empty, ask the control program for the block */
|
||||
blk = pool->stock;
|
||||
if (blk != NULL)
|
||||
pool->stock = *(void **)blk;
|
||||
else
|
||||
blk = umalloc(DMP_BLK_SIZE);
|
||||
/* the new block becomes the most recently allocated block */
|
||||
*(void **)blk = pool->link;
|
||||
pool->link = blk;
|
||||
/* now only a few bytes in the beginning of the new block are
|
||||
used to keep a pointer to the previously allocated block */
|
||||
pool->used = align_datasize(sizeof(void *));
|
||||
}
|
||||
/* the most recently allocated block exists and has enough space
|
||||
to allocate an atom */
|
||||
atom = (void *)((char *)pool->link + pool->used);
|
||||
pool->used += (size >= sizeof(void *) ? size : sizeof(void *));
|
||||
skip: pool->count++;
|
||||
#if 1
|
||||
memset(atom, '?', size);
|
||||
#endif
|
||||
return atom;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- dmp_free_atom - return specified atom to fixed-sized memory pool.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glpdmp.h"
|
||||
-- void dmp_free_atom(DMP *pool, void *atom);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The routine dmp_free_atom frees the atom, which the parameter atom
|
||||
-- points to, returning it to the specified fixed-sized dynamic memory
|
||||
-- pool.
|
||||
--
|
||||
-- Note that the atom should be returned only to the pool, from which
|
||||
-- it was obtained by the routine dmp_get_atom. */
|
||||
|
||||
void dmp_free_atom(DMP *pool, void *atom)
|
||||
{ if (pool->size == 0)
|
||||
fault("dmp_free_atom: pool = %p; attempt to return atom to var"
|
||||
"iable-sized pool", pool);
|
||||
if (pool->count == 0)
|
||||
fault("dmp_free_atom: pool = %p; pool allocation error", pool);
|
||||
/* just push the atom to the list of free atoms */
|
||||
*(void **)atom = pool->avail;
|
||||
pool->avail = atom;
|
||||
pool->count--;
|
||||
return;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- dmp_get_atomv - obtain free atom from variable-sized memory pool.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glpdmp.h"
|
||||
-- void *dmp_get_atomv(DMP *pool, int size);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The routine dmp_get_atomv obtains a free atom (which is continuous
|
||||
-- space of memory) from the specified variable-sized memory pool.
|
||||
--
|
||||
-- The atom size, in bytes, should be specified by the parameter size.
|
||||
-- The size should be in the range 1 to 256 bytes.
|
||||
--
|
||||
-- Note that the free atom returned by the routine initially contains
|
||||
-- arbitrary data (not binary zeros).
|
||||
--
|
||||
-- *Returns*
|
||||
--
|
||||
-- The routine returns a pointer to the free atom. */
|
||||
|
||||
void *dmp_get_atomv(DMP *pool, int size)
|
||||
{ void *atom, *blk;
|
||||
if (pool->size != 0)
|
||||
fault("dmp_get_atomv: pool = %p; attempt to obtain atom from f"
|
||||
"ixed-sized pool", pool);
|
||||
if (!(1 <= size && size <= 256))
|
||||
fault("dmp_get_atomv: size = %d; invalid atom size", size);
|
||||
/* the actual atom size should be not shorter than sizeof(void *)
|
||||
and should be properly aligned */
|
||||
if (size < sizeof(void *)) size = sizeof(void *);
|
||||
size = align_datasize(size);
|
||||
/* if the most recently allocated block doesn't exist or hasn't
|
||||
enough space, a new block is needed */
|
||||
if (pool->link == NULL || pool->used + size > DMP_BLK_SIZE)
|
||||
{ /* pull a new block from the list of free blocks, or if this
|
||||
list is empty, ask the control program for the block */
|
||||
blk = pool->stock;
|
||||
if (blk != NULL)
|
||||
pool->stock = *(void **)blk;
|
||||
else
|
||||
blk = umalloc(DMP_BLK_SIZE);
|
||||
/* the new block becomes the most recently allocated block */
|
||||
*(void **)blk = pool->link;
|
||||
pool->link = blk;
|
||||
/* now only a few bytes in the beginning of the new block are
|
||||
used to keep a pointer to the previously allocated block */
|
||||
pool->used = align_datasize(sizeof(void *));
|
||||
}
|
||||
/* the most recently allocated block exists and has enough space
|
||||
to allocate an atom */
|
||||
atom = (void *)((char *)pool->link + pool->used);
|
||||
pool->used += size;
|
||||
pool->count++;
|
||||
#if 1
|
||||
memset(atom, '?', size);
|
||||
#endif
|
||||
return atom;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- dmp_free_all - return all atoms to dynamic memory pool.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glpdmp.h"
|
||||
-- void dmp_free_all(DMP *pool);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The routine dmp_free_all frees all the atoms, which were obtained
|
||||
-- from the specified memory pool and which are still in use, returning
|
||||
-- them to the pool.
|
||||
--
|
||||
-- Note that no memory allocated to the pool is returned to the control
|
||||
-- program. */
|
||||
|
||||
void dmp_free_all(DMP *pool)
|
||||
{ void *blk;
|
||||
/* move all allocated blocks to the list of free blocks */
|
||||
while (pool->link != NULL)
|
||||
{ blk = pool->link;
|
||||
pool->link = *(void **)blk;
|
||||
*(void **)blk = pool->stock;
|
||||
pool->stock = blk;
|
||||
}
|
||||
pool->avail = NULL;
|
||||
pool->used = 0;
|
||||
pool->count = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- dmp_delete_pool - delete dynamic memory pool.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glpdmp.h"
|
||||
-- void dmp_delete_pool(DMP *pool);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The routine dmp_delete_pool deletes the specified dynamic memory
|
||||
-- pool and frees all the memory allocated to this object. */
|
||||
|
||||
void dmp_delete_pool(DMP *pool)
|
||||
{ void *blk;
|
||||
while (pool->link != NULL)
|
||||
{ blk = pool->link;
|
||||
pool->link = *(void **)blk;
|
||||
ufree(blk);
|
||||
}
|
||||
while (pool->stock != NULL)
|
||||
{ blk = pool->stock;
|
||||
pool->stock = *(void **)blk;
|
||||
ufree(blk);
|
||||
}
|
||||
ufree(pool);
|
||||
return;
|
||||
}
|
||||
|
||||
/* eof */
|
||||
/* glpdmp.c */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#include <string.h>
|
||||
#include "glpdmp.h"
|
||||
#include "glplib.h"
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- dmp_create_pool - create dynamic memory pool.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glpdmp.h"
|
||||
-- DMP *dmp_create_pool(int size);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The routine dmp_create_pool creates a dynamic memory pool.
|
||||
--
|
||||
-- If the parameter size is positive, the fixed-sized memory pool is
|
||||
-- created. This means that all atoms in the memory pool have the same
|
||||
-- size (in bytes). The size should be in the range 1 to 256 bytes.
|
||||
--
|
||||
-- If the parameter size is zero, the variable-sized memory pool is
|
||||
-- created. This means that atoms in the memory pool may have different
|
||||
-- sizes.
|
||||
--
|
||||
-- *Returns*
|
||||
--
|
||||
-- The routine returns a pointer to the created dynamic memory pool. */
|
||||
|
||||
DMP *dmp_create_pool(int size)
|
||||
{ DMP *pool;
|
||||
if (!(0 <= size && size <= 256))
|
||||
fault("dmp_create_pool: size = %d; invalid atom size", size);
|
||||
pool = umalloc(sizeof(DMP));
|
||||
pool->size = size;
|
||||
pool->avail = NULL;
|
||||
pool->link = NULL;
|
||||
pool->used = 0;
|
||||
pool->stock = NULL;
|
||||
pool->count = 0;
|
||||
return pool;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- dmp_get_atom - obtain free atom from fixed-sized memory pool.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glpdmp.h"
|
||||
-- void *dmp_get_atom(DMP *pool);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The routine dmp_get_atom obtains a free atom (which is continuous
|
||||
-- space of memory) from the specified fixed-sized dynamic memory pool.
|
||||
--
|
||||
-- The atom size, in bytes, should be specified on creating the pool by
|
||||
-- the routine dmp_create_pool.
|
||||
--
|
||||
-- Note that the free atom returned by the routine initially contains
|
||||
-- arbitrary data (not binary zeros).
|
||||
--
|
||||
-- *Returns*
|
||||
--
|
||||
-- The routine returns a pointer to the free atom. */
|
||||
|
||||
void *dmp_get_atom(DMP *pool)
|
||||
{ int size = pool->size;
|
||||
void *atom, *blk;
|
||||
if (size == 0)
|
||||
fault("dmp_get_atom: pool = %p; attempt to obtain atom from va"
|
||||
"riable-sized pool", pool);
|
||||
/* if there is a free atom, just pull it from the list */
|
||||
atom = pool->avail;
|
||||
if (atom != NULL)
|
||||
{ pool->avail = *(void **)atom;
|
||||
goto skip;
|
||||
}
|
||||
/* free atom list is empty; if the most recently allocated block
|
||||
doesn't exist or hasn't enough space, a new block is needed */
|
||||
if (pool->link == NULL || pool->used + size > DMP_BLK_SIZE)
|
||||
{ /* pull a new block from the list of free blocks, or if this
|
||||
list is empty, ask the control program for the block */
|
||||
blk = pool->stock;
|
||||
if (blk != NULL)
|
||||
pool->stock = *(void **)blk;
|
||||
else
|
||||
blk = umalloc(DMP_BLK_SIZE);
|
||||
/* the new block becomes the most recently allocated block */
|
||||
*(void **)blk = pool->link;
|
||||
pool->link = blk;
|
||||
/* now only a few bytes in the beginning of the new block are
|
||||
used to keep a pointer to the previously allocated block */
|
||||
pool->used = align_datasize(sizeof(void *));
|
||||
}
|
||||
/* the most recently allocated block exists and has enough space
|
||||
to allocate an atom */
|
||||
atom = (void *)((char *)pool->link + pool->used);
|
||||
pool->used += (size >= sizeof(void *) ? size : sizeof(void *));
|
||||
skip: pool->count++;
|
||||
#if 1
|
||||
memset(atom, '?', size);
|
||||
#endif
|
||||
return atom;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- dmp_free_atom - return specified atom to fixed-sized memory pool.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glpdmp.h"
|
||||
-- void dmp_free_atom(DMP *pool, void *atom);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The routine dmp_free_atom frees the atom, which the parameter atom
|
||||
-- points to, returning it to the specified fixed-sized dynamic memory
|
||||
-- pool.
|
||||
--
|
||||
-- Note that the atom should be returned only to the pool, from which
|
||||
-- it was obtained by the routine dmp_get_atom. */
|
||||
|
||||
void dmp_free_atom(DMP *pool, void *atom)
|
||||
{ if (pool->size == 0)
|
||||
fault("dmp_free_atom: pool = %p; attempt to return atom to var"
|
||||
"iable-sized pool", pool);
|
||||
if (pool->count == 0)
|
||||
fault("dmp_free_atom: pool = %p; pool allocation error", pool);
|
||||
/* just push the atom to the list of free atoms */
|
||||
*(void **)atom = pool->avail;
|
||||
pool->avail = atom;
|
||||
pool->count--;
|
||||
return;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- dmp_get_atomv - obtain free atom from variable-sized memory pool.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glpdmp.h"
|
||||
-- void *dmp_get_atomv(DMP *pool, int size);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The routine dmp_get_atomv obtains a free atom (which is continuous
|
||||
-- space of memory) from the specified variable-sized memory pool.
|
||||
--
|
||||
-- The atom size, in bytes, should be specified by the parameter size.
|
||||
-- The size should be in the range 1 to 256 bytes.
|
||||
--
|
||||
-- Note that the free atom returned by the routine initially contains
|
||||
-- arbitrary data (not binary zeros).
|
||||
--
|
||||
-- *Returns*
|
||||
--
|
||||
-- The routine returns a pointer to the free atom. */
|
||||
|
||||
void *dmp_get_atomv(DMP *pool, int size)
|
||||
{ void *atom, *blk;
|
||||
if (pool->size != 0)
|
||||
fault("dmp_get_atomv: pool = %p; attempt to obtain atom from f"
|
||||
"ixed-sized pool", pool);
|
||||
if (!(1 <= size && size <= 256))
|
||||
fault("dmp_get_atomv: size = %d; invalid atom size", size);
|
||||
/* the actual atom size should be not shorter than sizeof(void *)
|
||||
and should be properly aligned */
|
||||
if (size < sizeof(void *)) size = sizeof(void *);
|
||||
size = align_datasize(size);
|
||||
/* if the most recently allocated block doesn't exist or hasn't
|
||||
enough space, a new block is needed */
|
||||
if (pool->link == NULL || pool->used + size > DMP_BLK_SIZE)
|
||||
{ /* pull a new block from the list of free blocks, or if this
|
||||
list is empty, ask the control program for the block */
|
||||
blk = pool->stock;
|
||||
if (blk != NULL)
|
||||
pool->stock = *(void **)blk;
|
||||
else
|
||||
blk = umalloc(DMP_BLK_SIZE);
|
||||
/* the new block becomes the most recently allocated block */
|
||||
*(void **)blk = pool->link;
|
||||
pool->link = blk;
|
||||
/* now only a few bytes in the beginning of the new block are
|
||||
used to keep a pointer to the previously allocated block */
|
||||
pool->used = align_datasize(sizeof(void *));
|
||||
}
|
||||
/* the most recently allocated block exists and has enough space
|
||||
to allocate an atom */
|
||||
atom = (void *)((char *)pool->link + pool->used);
|
||||
pool->used += size;
|
||||
pool->count++;
|
||||
#if 1
|
||||
memset(atom, '?', size);
|
||||
#endif
|
||||
return atom;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- dmp_free_all - return all atoms to dynamic memory pool.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glpdmp.h"
|
||||
-- void dmp_free_all(DMP *pool);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The routine dmp_free_all frees all the atoms, which were obtained
|
||||
-- from the specified memory pool and which are still in use, returning
|
||||
-- them to the pool.
|
||||
--
|
||||
-- Note that no memory allocated to the pool is returned to the control
|
||||
-- program. */
|
||||
|
||||
void dmp_free_all(DMP *pool)
|
||||
{ void *blk;
|
||||
/* move all allocated blocks to the list of free blocks */
|
||||
while (pool->link != NULL)
|
||||
{ blk = pool->link;
|
||||
pool->link = *(void **)blk;
|
||||
*(void **)blk = pool->stock;
|
||||
pool->stock = blk;
|
||||
}
|
||||
pool->avail = NULL;
|
||||
pool->used = 0;
|
||||
pool->count = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- dmp_delete_pool - delete dynamic memory pool.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glpdmp.h"
|
||||
-- void dmp_delete_pool(DMP *pool);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The routine dmp_delete_pool deletes the specified dynamic memory
|
||||
-- pool and frees all the memory allocated to this object. */
|
||||
|
||||
void dmp_delete_pool(DMP *pool)
|
||||
{ void *blk;
|
||||
while (pool->link != NULL)
|
||||
{ blk = pool->link;
|
||||
pool->link = *(void **)blk;
|
||||
ufree(blk);
|
||||
}
|
||||
while (pool->stock != NULL)
|
||||
{ blk = pool->stock;
|
||||
pool->stock = *(void **)blk;
|
||||
ufree(blk);
|
||||
}
|
||||
ufree(pool);
|
||||
return;
|
||||
}
|
||||
|
||||
/* eof */
|
||||
@@ -0,0 +1,162 @@
|
||||
/* glpdmp.h */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _GLPDMP_H
|
||||
#define _GLPDMP_H
|
||||
|
||||
#define dmp_create_pool glp_dmp_create_pool
|
||||
#define dmp_get_atom glp_dmp_get_atom
|
||||
#define dmp_free_atom glp_dmp_free_atom
|
||||
#define dmp_get_atomv glp_dmp_get_atomv
|
||||
#define dmp_free_all glp_dmp_free_all
|
||||
#define dmp_delete_pool glp_dmp_delete_pool
|
||||
|
||||
typedef struct DMP DMP;
|
||||
|
||||
struct DMP
|
||||
{ /* dynamic memory pool (set of atoms) */
|
||||
int size;
|
||||
/* size of each atom, in bytes (1 <= size <= 256); if size is 0,
|
||||
atoms may have different sizes */
|
||||
void *avail;
|
||||
/* pointer to the linked list of free atoms (not used in the case
|
||||
of variable-sized pools) */
|
||||
void *link;
|
||||
/* pointer to the linked list of allocated blocks (it points to
|
||||
the most recently allocated block) */
|
||||
int used;
|
||||
/* number of bytes used in the most recently allocated block */
|
||||
void *stock;
|
||||
/* pointer to the linked list of free blocks */
|
||||
int count;
|
||||
/* total number of allocated atoms */
|
||||
};
|
||||
|
||||
#define DMP_BLK_SIZE 8000
|
||||
/* the size of memory blocks, in bytes, allocated for dynamic memory
|
||||
pools (all pools use memory blocks of the same size) */
|
||||
|
||||
DMP *dmp_create_pool(int size);
|
||||
/* create dynamic memory pool */
|
||||
|
||||
void *dmp_get_atom(DMP *pool);
|
||||
/* obtain free atom from fixed-sized memory pool */
|
||||
|
||||
void dmp_free_atom(DMP *pool, void *atom);
|
||||
/* return specified atom to fixed-sized memory pool */
|
||||
|
||||
void *dmp_get_atomv(DMP *pool, int size);
|
||||
/* obtain free atom from variable-sized memory pool */
|
||||
|
||||
void dmp_free_all(DMP *pool);
|
||||
/* return all atoms to dynamic memory pool */
|
||||
|
||||
void dmp_delete_pool(DMP *pool);
|
||||
/* delete dynamic memory pool */
|
||||
|
||||
#endif
|
||||
|
||||
/* eof */
|
||||
/* glpdmp.h */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _GLPDMP_H
|
||||
#define _GLPDMP_H
|
||||
|
||||
#define dmp_create_pool glp_dmp_create_pool
|
||||
#define dmp_get_atom glp_dmp_get_atom
|
||||
#define dmp_free_atom glp_dmp_free_atom
|
||||
#define dmp_get_atomv glp_dmp_get_atomv
|
||||
#define dmp_free_all glp_dmp_free_all
|
||||
#define dmp_delete_pool glp_dmp_delete_pool
|
||||
|
||||
typedef struct DMP DMP;
|
||||
|
||||
struct DMP
|
||||
{ /* dynamic memory pool (set of atoms) */
|
||||
int size;
|
||||
/* size of each atom, in bytes (1 <= size <= 256); if size is 0,
|
||||
atoms may have different sizes */
|
||||
void *avail;
|
||||
/* pointer to the linked list of free atoms (not used in the case
|
||||
of variable-sized pools) */
|
||||
void *link;
|
||||
/* pointer to the linked list of allocated blocks (it points to
|
||||
the most recently allocated block) */
|
||||
int used;
|
||||
/* number of bytes used in the most recently allocated block */
|
||||
void *stock;
|
||||
/* pointer to the linked list of free blocks */
|
||||
int count;
|
||||
/* total number of allocated atoms */
|
||||
};
|
||||
|
||||
#define DMP_BLK_SIZE 8000
|
||||
/* the size of memory blocks, in bytes, allocated for dynamic memory
|
||||
pools (all pools use memory blocks of the same size) */
|
||||
|
||||
DMP *dmp_create_pool(int size);
|
||||
/* create dynamic memory pool */
|
||||
|
||||
void *dmp_get_atom(DMP *pool);
|
||||
/* obtain free atom from fixed-sized memory pool */
|
||||
|
||||
void dmp_free_atom(DMP *pool, void *atom);
|
||||
/* return specified atom to fixed-sized memory pool */
|
||||
|
||||
void *dmp_get_atomv(DMP *pool, int size);
|
||||
/* obtain free atom from variable-sized memory pool */
|
||||
|
||||
void dmp_free_all(DMP *pool);
|
||||
/* return all atoms to dynamic memory pool */
|
||||
|
||||
void dmp_delete_pool(DMP *pool);
|
||||
/* delete dynamic memory pool */
|
||||
|
||||
#endif
|
||||
|
||||
/* eof */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,270 @@
|
||||
/* glphbsm.h */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _GLPHBSM_H
|
||||
#define _GLPHBSM_H
|
||||
|
||||
#include "glpmat.h"
|
||||
|
||||
#define load_hbsm glp_load_hbsm
|
||||
#define free_hbsm glp_free_hbsm
|
||||
#define hbsm_to_mat glp_hbsm_to_mat
|
||||
|
||||
typedef struct HBSM HBSM;
|
||||
|
||||
struct HBSM
|
||||
{ /* sparse matrix in Harwell-Boeing format; for details see the
|
||||
report: I.S.Duff, R.G.Grimes, J.G.Lewis. User's Guide for the
|
||||
Harwell-Boeing Sparse Matrix Collection (Release I), 1992 */
|
||||
char title[72+1];
|
||||
/* matrix title (informative) */
|
||||
char key[8+1];
|
||||
/* matrix key (informative) */
|
||||
char mxtype[3+1];
|
||||
/* matrix type:
|
||||
R.. real matrix
|
||||
C.. complex matrix
|
||||
P.. pattern only (no numerical values supplied)
|
||||
.S. symmetric (lower triangle + main diagonal)
|
||||
.U. unsymmetric
|
||||
.H. hermitian (lower triangle + main diagonal)
|
||||
.Z. skew symmetric (lower triangle only)
|
||||
.R. rectangular
|
||||
..A assembled
|
||||
..E elemental (unassembled) */
|
||||
char rhstyp[3+1];
|
||||
/* optional types:
|
||||
F.. right-hand sides in dense format
|
||||
M.. right-hand sides in same format as matrix
|
||||
.G. starting vector(s) (guess) is supplied
|
||||
..X exact solution vector(s) is supplied */
|
||||
char ptrfmt[16+1];
|
||||
/* format for pointers */
|
||||
char indfmt[16+1];
|
||||
/* format for row (or variable) indices */
|
||||
char valfmt[20+1];
|
||||
/* format for numerical values of coefficient matrix */
|
||||
char rhsfmt[20+1];
|
||||
/* format for numerical values of right-hand sides */
|
||||
int totcrd;
|
||||
/* total number of cards excluding header */
|
||||
int ptrcrd;
|
||||
/* number of cards for ponters */
|
||||
int indcrd;
|
||||
/* number of cards for row (or variable) indices */
|
||||
int valcrd;
|
||||
/* number of cards for numerical values */
|
||||
int rhscrd;
|
||||
/* number of lines for right-hand sides
|
||||
(including starting guesses and solution vectors if present)
|
||||
(zero indicates no right-hand side data is present) */
|
||||
int nrow;
|
||||
/* number of rows (or variables) */
|
||||
int ncol;
|
||||
/* number of columns (or elements) */
|
||||
int nnzero;
|
||||
/* number of row (or variable) indices
|
||||
(equal to number of entries for assembled matrix) */
|
||||
int neltvl;
|
||||
/* number of elemental matrix entries
|
||||
(zero in case of assembled matrix) */
|
||||
int nrhs;
|
||||
/* number of right-hand sides */
|
||||
int nrhsix;
|
||||
/* number of row indices
|
||||
(ignored in case of unassembled matrix) */
|
||||
int nrhsvl;
|
||||
/* total number of entries in all right-hand sides */
|
||||
int nguess;
|
||||
/* total number of entries in all starting guesses */
|
||||
int nexact;
|
||||
/* total number of entries in all solution vectors */
|
||||
int *colptr; /* alias = eltptr */
|
||||
/* column pointers (in case of assembled matrix)
|
||||
elemental matrix pointers (in case of unassembled matrix) */
|
||||
int *rowind; /* alias = varind */
|
||||
/* row indices (in case of assembled matrix);
|
||||
variable indices (in case of unassembled matrix) */
|
||||
int *rhsptr;
|
||||
/* right-hand side pointers */
|
||||
int *rhsind;
|
||||
/* right-hand side indices */
|
||||
double *values;
|
||||
/* matrix values */
|
||||
double *rhsval;
|
||||
/* right-hand side values */
|
||||
double *sguess;
|
||||
/* starting guess values */
|
||||
double *xexact;
|
||||
/* solution vector values */
|
||||
};
|
||||
|
||||
extern HBSM *load_hbsm(char *fname);
|
||||
/* load sparse matrix in Harwell-Boeing format */
|
||||
|
||||
extern void free_hbsm(HBSM *hbsm);
|
||||
/* free sparse matrix in Harwell-Boeing format */
|
||||
|
||||
extern MAT *hbsm_to_mat(HBSM *hbsm);
|
||||
/* convert sparse matrix from HBSM to MAT */
|
||||
|
||||
#endif
|
||||
|
||||
/* eof */
|
||||
/* glphbsm.h */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _GLPHBSM_H
|
||||
#define _GLPHBSM_H
|
||||
|
||||
#include "glpmat.h"
|
||||
|
||||
#define load_hbsm glp_load_hbsm
|
||||
#define free_hbsm glp_free_hbsm
|
||||
#define hbsm_to_mat glp_hbsm_to_mat
|
||||
|
||||
typedef struct HBSM HBSM;
|
||||
|
||||
struct HBSM
|
||||
{ /* sparse matrix in Harwell-Boeing format; for details see the
|
||||
report: I.S.Duff, R.G.Grimes, J.G.Lewis. User's Guide for the
|
||||
Harwell-Boeing Sparse Matrix Collection (Release I), 1992 */
|
||||
char title[72+1];
|
||||
/* matrix title (informative) */
|
||||
char key[8+1];
|
||||
/* matrix key (informative) */
|
||||
char mxtype[3+1];
|
||||
/* matrix type:
|
||||
R.. real matrix
|
||||
C.. complex matrix
|
||||
P.. pattern only (no numerical values supplied)
|
||||
.S. symmetric (lower triangle + main diagonal)
|
||||
.U. unsymmetric
|
||||
.H. hermitian (lower triangle + main diagonal)
|
||||
.Z. skew symmetric (lower triangle only)
|
||||
.R. rectangular
|
||||
..A assembled
|
||||
..E elemental (unassembled) */
|
||||
char rhstyp[3+1];
|
||||
/* optional types:
|
||||
F.. right-hand sides in dense format
|
||||
M.. right-hand sides in same format as matrix
|
||||
.G. starting vector(s) (guess) is supplied
|
||||
..X exact solution vector(s) is supplied */
|
||||
char ptrfmt[16+1];
|
||||
/* format for pointers */
|
||||
char indfmt[16+1];
|
||||
/* format for row (or variable) indices */
|
||||
char valfmt[20+1];
|
||||
/* format for numerical values of coefficient matrix */
|
||||
char rhsfmt[20+1];
|
||||
/* format for numerical values of right-hand sides */
|
||||
int totcrd;
|
||||
/* total number of cards excluding header */
|
||||
int ptrcrd;
|
||||
/* number of cards for ponters */
|
||||
int indcrd;
|
||||
/* number of cards for row (or variable) indices */
|
||||
int valcrd;
|
||||
/* number of cards for numerical values */
|
||||
int rhscrd;
|
||||
/* number of lines for right-hand sides
|
||||
(including starting guesses and solution vectors if present)
|
||||
(zero indicates no right-hand side data is present) */
|
||||
int nrow;
|
||||
/* number of rows (or variables) */
|
||||
int ncol;
|
||||
/* number of columns (or elements) */
|
||||
int nnzero;
|
||||
/* number of row (or variable) indices
|
||||
(equal to number of entries for assembled matrix) */
|
||||
int neltvl;
|
||||
/* number of elemental matrix entries
|
||||
(zero in case of assembled matrix) */
|
||||
int nrhs;
|
||||
/* number of right-hand sides */
|
||||
int nrhsix;
|
||||
/* number of row indices
|
||||
(ignored in case of unassembled matrix) */
|
||||
int nrhsvl;
|
||||
/* total number of entries in all right-hand sides */
|
||||
int nguess;
|
||||
/* total number of entries in all starting guesses */
|
||||
int nexact;
|
||||
/* total number of entries in all solution vectors */
|
||||
int *colptr; /* alias = eltptr */
|
||||
/* column pointers (in case of assembled matrix)
|
||||
elemental matrix pointers (in case of unassembled matrix) */
|
||||
int *rowind; /* alias = varind */
|
||||
/* row indices (in case of assembled matrix);
|
||||
variable indices (in case of unassembled matrix) */
|
||||
int *rhsptr;
|
||||
/* right-hand side pointers */
|
||||
int *rhsind;
|
||||
/* right-hand side indices */
|
||||
double *values;
|
||||
/* matrix values */
|
||||
double *rhsval;
|
||||
/* right-hand side values */
|
||||
double *sguess;
|
||||
/* starting guess values */
|
||||
double *xexact;
|
||||
/* solution vector values */
|
||||
};
|
||||
|
||||
extern HBSM *load_hbsm(char *fname);
|
||||
/* load sparse matrix in Harwell-Boeing format */
|
||||
|
||||
extern void free_hbsm(HBSM *hbsm);
|
||||
/* free sparse matrix in Harwell-Boeing format */
|
||||
|
||||
extern MAT *hbsm_to_mat(HBSM *hbsm);
|
||||
/* convert sparse matrix from HBSM to MAT */
|
||||
|
||||
#endif
|
||||
|
||||
/* eof */
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,346 @@
|
||||
/* glpinv.h */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _GLPINV_H
|
||||
#define _GLPINV_H
|
||||
|
||||
#include "glpluf.h"
|
||||
|
||||
#define inv_create glp_inv_create
|
||||
#define inv_decomp glp_inv_decomp
|
||||
#define inv_h_solve glp_inv_h_solve
|
||||
#define inv_ftran glp_inv_ftran
|
||||
#define inv_btran glp_inv_btran
|
||||
#define inv_update glp_inv_update
|
||||
#define inv_delete glp_inv_delete
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- The structure INV defines an invertable form of the basis matrix B,
|
||||
-- which is based on LU-factorization and is the following sextet:
|
||||
--
|
||||
-- [B] = (F, H, V, P0, P, Q), (1)
|
||||
--
|
||||
-- where F, H, and V are such matrices that
|
||||
--
|
||||
-- B = F * H * V, (2)
|
||||
--
|
||||
-- and P0, P, and Q are such permutation matrices that the matrix
|
||||
--
|
||||
-- L = P0 * F * inv(P0) (3)
|
||||
--
|
||||
-- is lower triangular with unity diagonal, and the matrix
|
||||
--
|
||||
-- U = P * V * Q (4)
|
||||
--
|
||||
-- is upper triangular. All the matrices have the same order m, which
|
||||
-- is the order of the basis matrix B.
|
||||
--
|
||||
-- The matrices F, V, P, and Q are stored in the structure LUF (see the
|
||||
-- section GLPLUF), which is a member of the structure INV.
|
||||
--
|
||||
-- The matrix H is stored in the form of eta file using row-like format
|
||||
-- as follows:
|
||||
--
|
||||
-- H = H[1] * H[2] * ... * H[nfs], (5)
|
||||
--
|
||||
-- where H[k], k = 1, 2, ..., nfs, is a row-like factor, which differs
|
||||
-- from the unity matrix only by one row, nfs is current number of row-
|
||||
-- like factors. After the factorization has been built for some given
|
||||
-- basis matrix B the matrix H has no factors and thus it is the unity
|
||||
-- matrix. Then each time when the factorization is recomputed for an
|
||||
-- adjacent basis matrix, the next factor H[k], k = 1, 2, ... is built
|
||||
-- and added to the end of the eta file H.
|
||||
--
|
||||
-- Being sparse vectors non-trivial rows of the factors H[k] are stored
|
||||
-- in the right part of the sparse vector area (SVA) in the same manner
|
||||
-- as rows and columns of the matrix F.
|
||||
--
|
||||
-- For more details see the program documentation. */
|
||||
|
||||
typedef struct INV INV;
|
||||
|
||||
struct INV
|
||||
{ /* invertable (factorized) form of the basis matrix */
|
||||
int m;
|
||||
/* order of the matrices B, F, H, V, P0, P, Q */
|
||||
int valid;
|
||||
/* if this flag is not set, the invertable form is invalid and
|
||||
can't be updated nor used in ftran and btran operations */
|
||||
LUF *luf;
|
||||
/* LU-factorization (holds the matrices F, V, P, Q) */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* matrix H in the form of eta file */
|
||||
int hh_max;
|
||||
/* maximal number of row-like factors (that limits maximal number
|
||||
of updates of the factorization) */
|
||||
int hh_nfs;
|
||||
/* current number of row-like factors (0 <= hh_nfs <= hh_max) */
|
||||
int *hh_ndx; /* int hh_ndx[1+hh_max]; */
|
||||
/* hh_ndx[0] is not used;
|
||||
hh_ndx[k], k = 1, ..., nfs, is number of a non-trivial row of
|
||||
the factor H[k] */
|
||||
int *hh_ptr; /* int hh_ptr[1+hh_max]; */
|
||||
/* hh_ptr[0] is not used;
|
||||
hh_ptr[k], k = 1, ..., nfs, is a pointer to the first element
|
||||
of the non-trivial row of the factor H[k] in the sparse vector
|
||||
area */
|
||||
int *hh_len; /* int hh_len[1+hh_max]; */
|
||||
/* hh_len[0] is not used;
|
||||
hh_len[k], k = 1, ..., nfs, is total number of elements in the
|
||||
non-trivial row of the factor H[k] */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* matrix P0 */
|
||||
int *p0_row; /* int p0_row[1+n]; */
|
||||
/* p0_row[0] is not used; p0_row[i] = j means that p0[i,j] = 1 */
|
||||
int *p0_col; /* int p0_col[1+n]; */
|
||||
/* p0_col[0] is not used; p0_col[j] = i means that p0[i,j] = 1 */
|
||||
/* if i-th row or column of the matrix F corresponds to i'-th row
|
||||
or column of the matrix L = P0*F*inv(P0), then p0_row[i'] = i
|
||||
and p0_col[i] = i' */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* partially transformed column is inv(F*H)*B[j], where B[j] is a
|
||||
new column, which will replace the existing j-th column of the
|
||||
basis matrix */
|
||||
int cc_len;
|
||||
/* number of (non-zero) elements in the partially transformed
|
||||
column; if cc_len < 0, the column has been not prepared yet */
|
||||
int *cc_ndx; /* int cc_ndx[1+m]; */
|
||||
/* cc_ndx[0] is not used;
|
||||
cc_ndx[k], k = 1, ..., cc_len, is a row index of the partially
|
||||
transformed column element */
|
||||
double *cc_val; /* double cc_val[1+m]; */
|
||||
/* cc_val[0] is not used;
|
||||
cc_val[k], k = 1, ..., cc_len, is a numerical (non-zero) value
|
||||
of the column element */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* control parameters */
|
||||
double upd_tol;
|
||||
/* update tolerance; if on updating the factorization absolute
|
||||
value of some diagonal element of the matrix U = P*V*Q is less
|
||||
than upd_tol, the factorization is considered as inaccurate */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* some statistics */
|
||||
int nnz_h;
|
||||
/* current number of non-zeros in all factors of the matrix H */
|
||||
};
|
||||
|
||||
INV *inv_create(int m, int max_upd);
|
||||
/* create factorization of the basis matrix */
|
||||
|
||||
int inv_decomp(INV *inv,
|
||||
void *info, int (*col)(void *info, int j, int rn[], double bj[]));
|
||||
/* compute factorization of the basis matrix */
|
||||
|
||||
void inv_h_solve(INV *inv, int tr, double x[]);
|
||||
/* solve system H*x = b or H'*x = b */
|
||||
|
||||
void inv_ftran(INV *inv, double x[], int save);
|
||||
/* perform forward transformation (FTRAN) */
|
||||
|
||||
void inv_btran(INV *inv, double x[]);
|
||||
/* perform backward transformation (BTRAN) */
|
||||
|
||||
int inv_update(INV *inv, int j);
|
||||
/* update factorization for adjacent basis matrix */
|
||||
|
||||
void inv_delete(INV *inv);
|
||||
/* delete factorization of the basis matrix */
|
||||
|
||||
#endif
|
||||
|
||||
/* eof */
|
||||
/* glpinv.h */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _GLPINV_H
|
||||
#define _GLPINV_H
|
||||
|
||||
#include "glpluf.h"
|
||||
|
||||
#define inv_create glp_inv_create
|
||||
#define inv_decomp glp_inv_decomp
|
||||
#define inv_h_solve glp_inv_h_solve
|
||||
#define inv_ftran glp_inv_ftran
|
||||
#define inv_btran glp_inv_btran
|
||||
#define inv_update glp_inv_update
|
||||
#define inv_delete glp_inv_delete
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- The structure INV defines an invertable form of the basis matrix B,
|
||||
-- which is based on LU-factorization and is the following sextet:
|
||||
--
|
||||
-- [B] = (F, H, V, P0, P, Q), (1)
|
||||
--
|
||||
-- where F, H, and V are such matrices that
|
||||
--
|
||||
-- B = F * H * V, (2)
|
||||
--
|
||||
-- and P0, P, and Q are such permutation matrices that the matrix
|
||||
--
|
||||
-- L = P0 * F * inv(P0) (3)
|
||||
--
|
||||
-- is lower triangular with unity diagonal, and the matrix
|
||||
--
|
||||
-- U = P * V * Q (4)
|
||||
--
|
||||
-- is upper triangular. All the matrices have the same order m, which
|
||||
-- is the order of the basis matrix B.
|
||||
--
|
||||
-- The matrices F, V, P, and Q are stored in the structure LUF (see the
|
||||
-- section GLPLUF), which is a member of the structure INV.
|
||||
--
|
||||
-- The matrix H is stored in the form of eta file using row-like format
|
||||
-- as follows:
|
||||
--
|
||||
-- H = H[1] * H[2] * ... * H[nfs], (5)
|
||||
--
|
||||
-- where H[k], k = 1, 2, ..., nfs, is a row-like factor, which differs
|
||||
-- from the unity matrix only by one row, nfs is current number of row-
|
||||
-- like factors. After the factorization has been built for some given
|
||||
-- basis matrix B the matrix H has no factors and thus it is the unity
|
||||
-- matrix. Then each time when the factorization is recomputed for an
|
||||
-- adjacent basis matrix, the next factor H[k], k = 1, 2, ... is built
|
||||
-- and added to the end of the eta file H.
|
||||
--
|
||||
-- Being sparse vectors non-trivial rows of the factors H[k] are stored
|
||||
-- in the right part of the sparse vector area (SVA) in the same manner
|
||||
-- as rows and columns of the matrix F.
|
||||
--
|
||||
-- For more details see the program documentation. */
|
||||
|
||||
typedef struct INV INV;
|
||||
|
||||
struct INV
|
||||
{ /* invertable (factorized) form of the basis matrix */
|
||||
int m;
|
||||
/* order of the matrices B, F, H, V, P0, P, Q */
|
||||
int valid;
|
||||
/* if this flag is not set, the invertable form is invalid and
|
||||
can't be updated nor used in ftran and btran operations */
|
||||
LUF *luf;
|
||||
/* LU-factorization (holds the matrices F, V, P, Q) */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* matrix H in the form of eta file */
|
||||
int hh_max;
|
||||
/* maximal number of row-like factors (that limits maximal number
|
||||
of updates of the factorization) */
|
||||
int hh_nfs;
|
||||
/* current number of row-like factors (0 <= hh_nfs <= hh_max) */
|
||||
int *hh_ndx; /* int hh_ndx[1+hh_max]; */
|
||||
/* hh_ndx[0] is not used;
|
||||
hh_ndx[k], k = 1, ..., nfs, is number of a non-trivial row of
|
||||
the factor H[k] */
|
||||
int *hh_ptr; /* int hh_ptr[1+hh_max]; */
|
||||
/* hh_ptr[0] is not used;
|
||||
hh_ptr[k], k = 1, ..., nfs, is a pointer to the first element
|
||||
of the non-trivial row of the factor H[k] in the sparse vector
|
||||
area */
|
||||
int *hh_len; /* int hh_len[1+hh_max]; */
|
||||
/* hh_len[0] is not used;
|
||||
hh_len[k], k = 1, ..., nfs, is total number of elements in the
|
||||
non-trivial row of the factor H[k] */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* matrix P0 */
|
||||
int *p0_row; /* int p0_row[1+n]; */
|
||||
/* p0_row[0] is not used; p0_row[i] = j means that p0[i,j] = 1 */
|
||||
int *p0_col; /* int p0_col[1+n]; */
|
||||
/* p0_col[0] is not used; p0_col[j] = i means that p0[i,j] = 1 */
|
||||
/* if i-th row or column of the matrix F corresponds to i'-th row
|
||||
or column of the matrix L = P0*F*inv(P0), then p0_row[i'] = i
|
||||
and p0_col[i] = i' */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* partially transformed column is inv(F*H)*B[j], where B[j] is a
|
||||
new column, which will replace the existing j-th column of the
|
||||
basis matrix */
|
||||
int cc_len;
|
||||
/* number of (non-zero) elements in the partially transformed
|
||||
column; if cc_len < 0, the column has been not prepared yet */
|
||||
int *cc_ndx; /* int cc_ndx[1+m]; */
|
||||
/* cc_ndx[0] is not used;
|
||||
cc_ndx[k], k = 1, ..., cc_len, is a row index of the partially
|
||||
transformed column element */
|
||||
double *cc_val; /* double cc_val[1+m]; */
|
||||
/* cc_val[0] is not used;
|
||||
cc_val[k], k = 1, ..., cc_len, is a numerical (non-zero) value
|
||||
of the column element */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* control parameters */
|
||||
double upd_tol;
|
||||
/* update tolerance; if on updating the factorization absolute
|
||||
value of some diagonal element of the matrix U = P*V*Q is less
|
||||
than upd_tol, the factorization is considered as inaccurate */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* some statistics */
|
||||
int nnz_h;
|
||||
/* current number of non-zeros in all factors of the matrix H */
|
||||
};
|
||||
|
||||
INV *inv_create(int m, int max_upd);
|
||||
/* create factorization of the basis matrix */
|
||||
|
||||
int inv_decomp(INV *inv,
|
||||
void *info, int (*col)(void *info, int j, int rn[], double bj[]));
|
||||
/* compute factorization of the basis matrix */
|
||||
|
||||
void inv_h_solve(INV *inv, int tr, double x[]);
|
||||
/* solve system H*x = b or H'*x = b */
|
||||
|
||||
void inv_ftran(INV *inv, double x[], int save);
|
||||
/* perform forward transformation (FTRAN) */
|
||||
|
||||
void inv_btran(INV *inv, double x[]);
|
||||
/* perform backward transformation (BTRAN) */
|
||||
|
||||
int inv_update(INV *inv, int j);
|
||||
/* update factorization for adjacent basis matrix */
|
||||
|
||||
void inv_delete(INV *inv);
|
||||
/* delete factorization of the basis matrix */
|
||||
|
||||
#endif
|
||||
|
||||
/* eof */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,80 @@
|
||||
/* glpipm.h */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _GLPIPM_H
|
||||
#define _GLPIPM_H
|
||||
|
||||
#include "glpmat.h"
|
||||
|
||||
#define ipm1 glp_ipm1
|
||||
#define ipm1_driver glp_ipm1_driver
|
||||
|
||||
extern int ipm1(MAT *A, double b[], double c[], double x[], double y[],
|
||||
double z[]);
|
||||
/* primal-dual interior point method for linear programming */
|
||||
|
||||
#endif
|
||||
|
||||
/* eof */
|
||||
/* glpipm.h */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _GLPIPM_H
|
||||
#define _GLPIPM_H
|
||||
|
||||
#include "glpmat.h"
|
||||
|
||||
#define ipm1 glp_ipm1
|
||||
#define ipm1_driver glp_ipm1_driver
|
||||
|
||||
extern int ipm1(MAT *A, double b[], double c[], double x[], double y[],
|
||||
double z[]);
|
||||
/* primal-dual interior point method for linear programming */
|
||||
|
||||
#endif
|
||||
|
||||
/* eof */
|
||||
@@ -0,0 +1,76 @@
|
||||
/* glpk.h */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
extern "C" {
|
||||
|
||||
#ifndef _GLPK_H
|
||||
#define _GLPK_H
|
||||
|
||||
#include "glpbcs.h"
|
||||
#include "glplib.h"
|
||||
#include "glplpx.h"
|
||||
|
||||
#endif
|
||||
|
||||
/* eof */
|
||||
}
|
||||
/* glpk.h */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
extern "C" {
|
||||
|
||||
#ifndef _GLPK_H
|
||||
#define _GLPK_H
|
||||
|
||||
#include "glpbcs.h"
|
||||
#include "glplib.h"
|
||||
#include "glplpx.h"
|
||||
|
||||
#endif
|
||||
|
||||
/* eof */
|
||||
}
|
||||
@@ -0,0 +1,366 @@
|
||||
/* glplib.h */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _GLPLIB_H
|
||||
#define _GLPLIB_H
|
||||
|
||||
#define lib_set_ptr glp_lib_set_ptr
|
||||
#define lib_get_ptr glp_lib_get_ptr
|
||||
#define lib_init_env glp_lib_init_env
|
||||
#define lib_env_ptr glp_lib_env_ptr
|
||||
#define lib_free_env glp_lib_free_env
|
||||
#define print glp_lib_print
|
||||
#define lib_set_print_hook glp_lib_set_print_hook
|
||||
#define fault glp_lib_fault
|
||||
#define lib_set_fault_hook glp_lib_set_fault_hook
|
||||
#define _insist glp_lib_insist
|
||||
#define umalloc glp_lib_umalloc
|
||||
#define ucalloc glp_lib_ucalloc
|
||||
#define ufree glp_lib_ufree
|
||||
#define ufopen glp_lib_ufopen
|
||||
#define ufclose glp_lib_ufclose
|
||||
#define utime glp_lib_utime
|
||||
#define str2int glp_lib_str2int
|
||||
#define str2dbl glp_lib_str2dbl
|
||||
#define strspx glp_lib_strspx
|
||||
#define strtrim glp_lib_strtrim
|
||||
|
||||
typedef struct LIBENV LIBENV;
|
||||
typedef struct LIBMEM LIBMEM;
|
||||
|
||||
#define LIB_MAX_OPEN 20
|
||||
/* maximal number of simultaneously open i/o streams */
|
||||
|
||||
struct LIBENV
|
||||
{ /* library environmental block */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* user-defined hook routines */
|
||||
void *print_info;
|
||||
/* transit pointer passed to the routine print_hook */
|
||||
int (*print_hook)(void *info, char *msg);
|
||||
/* user-defined print hook routine */
|
||||
void *fault_info;
|
||||
/* transit pointer passed to the routine fault_hook */
|
||||
int (*fault_hook)(void *info, char *msg);
|
||||
/* user-defined fault hook routine */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* dynamic memory registration */
|
||||
LIBMEM *mem_ptr;
|
||||
/* pointer to the linked list of allocated memory blocks */
|
||||
int mem_limit;
|
||||
/* maximal amount of memory (in bytes) available for dynamic
|
||||
allocation */
|
||||
int mem_total;
|
||||
/* total amount of currently allocated memory (in bytes; is the
|
||||
sum of the size fields over all memory block descriptors) */
|
||||
int mem_tpeak;
|
||||
/* peak value of mem_total */
|
||||
int mem_count;
|
||||
/* total number of currently allocated memory blocks */
|
||||
int mem_cpeak;
|
||||
/* peak value of mem_count */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* input/output streams registration */
|
||||
void *file_slot[LIB_MAX_OPEN]; /* FILE *file_slot[]; */
|
||||
/* file_slot[k], 0 <= k <= LIB_MAX_OPEN-1, is a pointer to k-th
|
||||
i/o stream; if k-th slot is free, file_slot[k] is NULL */
|
||||
};
|
||||
|
||||
struct LIBMEM
|
||||
{ /* memory block descriptor */
|
||||
int size;
|
||||
/* size of block (in bytes, including descriptor) */
|
||||
int flag;
|
||||
/* descriptor flag */
|
||||
LIBMEM *prev;
|
||||
/* pointer to the previous memory block descriptor */
|
||||
LIBMEM *next;
|
||||
/* pointer to the next memory block descriptor */
|
||||
/* actual data start here (there may be a "hole" between the next
|
||||
field and actual data due to data alignment) */
|
||||
};
|
||||
|
||||
#define LIB_MEM_FLAG 0x20101960
|
||||
/* value used as memory block descriptor flag */
|
||||
|
||||
void lib_set_ptr(void *ptr);
|
||||
/* store a pointer */
|
||||
|
||||
void *lib_get_ptr(void);
|
||||
/* retrieve a pointer */
|
||||
|
||||
int lib_init_env(void);
|
||||
/* initialize library environment */
|
||||
|
||||
LIBENV *lib_env_ptr(void);
|
||||
/* retrieve a pointer to the environmental block */
|
||||
|
||||
int lib_free_env(void);
|
||||
/* free library environment */
|
||||
|
||||
void print(char *fmt, ...);
|
||||
/* print informative message */
|
||||
|
||||
void lib_set_print_hook(void *info, int (*hook)(void *info, char *msg));
|
||||
/* install print hook routine */
|
||||
|
||||
void fault(char *fmt, ...);
|
||||
/* print error message and terminate program execution */
|
||||
|
||||
void lib_set_fault_hook(void *info, int (*hook)(void *info, char *msg));
|
||||
/* install fault hook routine */
|
||||
|
||||
#define insist(expr) \
|
||||
((void)((expr) || (_insist(#expr, __FILE__, __LINE__), 1)))
|
||||
|
||||
void _insist(char *expr, char *file, int line);
|
||||
/* check for logical condition */
|
||||
|
||||
/* some processors need data to be properly aligned; the align_boundary
|
||||
macro defines the boundary, which should fit for all data types; the
|
||||
align_datasize macro allows enlarging size of data item in order the
|
||||
immediately following data of any type should be properly aligned */
|
||||
|
||||
#define align_boundary sizeof(double)
|
||||
|
||||
#define align_datasize(size) \
|
||||
((((size) + (align_boundary - 1)) / align_boundary) * align_boundary)
|
||||
|
||||
void *umalloc(int size);
|
||||
/* allocate memory block */
|
||||
|
||||
void *ucalloc(int nmemb, int size);
|
||||
/* allocate memory block */
|
||||
|
||||
void ufree(void *ptr);
|
||||
/* free memory block */
|
||||
|
||||
void *ufopen(char *fname, char *mode);
|
||||
/* open file */
|
||||
|
||||
void ufclose(void *fp);
|
||||
/* close file */
|
||||
|
||||
double utime(void);
|
||||
/* determine the current universal time */
|
||||
|
||||
int str2int(char *str, int *val);
|
||||
/* convert character string to value of integer type */
|
||||
|
||||
int str2dbl(char *str, double *val);
|
||||
/* convert character string to value of double type */
|
||||
|
||||
char *strspx(char *str);
|
||||
/* remove all spaces from character string */
|
||||
|
||||
char *strtrim(char *str);
|
||||
/* remove trailing spaces from character string */
|
||||
|
||||
#endif
|
||||
|
||||
/* eof */
|
||||
/* glplib.h */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _GLPLIB_H
|
||||
#define _GLPLIB_H
|
||||
|
||||
#define lib_set_ptr glp_lib_set_ptr
|
||||
#define lib_get_ptr glp_lib_get_ptr
|
||||
#define lib_init_env glp_lib_init_env
|
||||
#define lib_env_ptr glp_lib_env_ptr
|
||||
#define lib_free_env glp_lib_free_env
|
||||
#define print glp_lib_print
|
||||
#define lib_set_print_hook glp_lib_set_print_hook
|
||||
#define fault glp_lib_fault
|
||||
#define lib_set_fault_hook glp_lib_set_fault_hook
|
||||
#define _insist glp_lib_insist
|
||||
#define umalloc glp_lib_umalloc
|
||||
#define ucalloc glp_lib_ucalloc
|
||||
#define ufree glp_lib_ufree
|
||||
#define ufopen glp_lib_ufopen
|
||||
#define ufclose glp_lib_ufclose
|
||||
#define utime glp_lib_utime
|
||||
#define str2int glp_lib_str2int
|
||||
#define str2dbl glp_lib_str2dbl
|
||||
#define strspx glp_lib_strspx
|
||||
#define strtrim glp_lib_strtrim
|
||||
|
||||
typedef struct LIBENV LIBENV;
|
||||
typedef struct LIBMEM LIBMEM;
|
||||
|
||||
#define LIB_MAX_OPEN 20
|
||||
/* maximal number of simultaneously open i/o streams */
|
||||
|
||||
struct LIBENV
|
||||
{ /* library environmental block */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* user-defined hook routines */
|
||||
void *print_info;
|
||||
/* transit pointer passed to the routine print_hook */
|
||||
int (*print_hook)(void *info, char *msg);
|
||||
/* user-defined print hook routine */
|
||||
void *fault_info;
|
||||
/* transit pointer passed to the routine fault_hook */
|
||||
int (*fault_hook)(void *info, char *msg);
|
||||
/* user-defined fault hook routine */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* dynamic memory registration */
|
||||
LIBMEM *mem_ptr;
|
||||
/* pointer to the linked list of allocated memory blocks */
|
||||
int mem_limit;
|
||||
/* maximal amount of memory (in bytes) available for dynamic
|
||||
allocation */
|
||||
int mem_total;
|
||||
/* total amount of currently allocated memory (in bytes; is the
|
||||
sum of the size fields over all memory block descriptors) */
|
||||
int mem_tpeak;
|
||||
/* peak value of mem_total */
|
||||
int mem_count;
|
||||
/* total number of currently allocated memory blocks */
|
||||
int mem_cpeak;
|
||||
/* peak value of mem_count */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* input/output streams registration */
|
||||
void *file_slot[LIB_MAX_OPEN]; /* FILE *file_slot[]; */
|
||||
/* file_slot[k], 0 <= k <= LIB_MAX_OPEN-1, is a pointer to k-th
|
||||
i/o stream; if k-th slot is free, file_slot[k] is NULL */
|
||||
};
|
||||
|
||||
struct LIBMEM
|
||||
{ /* memory block descriptor */
|
||||
int size;
|
||||
/* size of block (in bytes, including descriptor) */
|
||||
int flag;
|
||||
/* descriptor flag */
|
||||
LIBMEM *prev;
|
||||
/* pointer to the previous memory block descriptor */
|
||||
LIBMEM *next;
|
||||
/* pointer to the next memory block descriptor */
|
||||
/* actual data start here (there may be a "hole" between the next
|
||||
field and actual data due to data alignment) */
|
||||
};
|
||||
|
||||
#define LIB_MEM_FLAG 0x20101960
|
||||
/* value used as memory block descriptor flag */
|
||||
|
||||
void lib_set_ptr(void *ptr);
|
||||
/* store a pointer */
|
||||
|
||||
void *lib_get_ptr(void);
|
||||
/* retrieve a pointer */
|
||||
|
||||
int lib_init_env(void);
|
||||
/* initialize library environment */
|
||||
|
||||
LIBENV *lib_env_ptr(void);
|
||||
/* retrieve a pointer to the environmental block */
|
||||
|
||||
int lib_free_env(void);
|
||||
/* free library environment */
|
||||
|
||||
void print(char *fmt, ...);
|
||||
/* print informative message */
|
||||
|
||||
void lib_set_print_hook(void *info, int (*hook)(void *info, char *msg));
|
||||
/* install print hook routine */
|
||||
|
||||
void fault(char *fmt, ...);
|
||||
/* print error message and terminate program execution */
|
||||
|
||||
void lib_set_fault_hook(void *info, int (*hook)(void *info, char *msg));
|
||||
/* install fault hook routine */
|
||||
|
||||
#define insist(expr) \
|
||||
((void)((expr) || (_insist(#expr, __FILE__, __LINE__), 1)))
|
||||
|
||||
void _insist(char *expr, char *file, int line);
|
||||
/* check for logical condition */
|
||||
|
||||
/* some processors need data to be properly aligned; the align_boundary
|
||||
macro defines the boundary, which should fit for all data types; the
|
||||
align_datasize macro allows enlarging size of data item in order the
|
||||
immediately following data of any type should be properly aligned */
|
||||
|
||||
#define align_boundary sizeof(double)
|
||||
|
||||
#define align_datasize(size) \
|
||||
((((size) + (align_boundary - 1)) / align_boundary) * align_boundary)
|
||||
|
||||
void *umalloc(int size);
|
||||
/* allocate memory block */
|
||||
|
||||
void *ucalloc(int nmemb, int size);
|
||||
/* allocate memory block */
|
||||
|
||||
void ufree(void *ptr);
|
||||
/* free memory block */
|
||||
|
||||
void *ufopen(char *fname, char *mode);
|
||||
/* open file */
|
||||
|
||||
void ufclose(void *fp);
|
||||
/* close file */
|
||||
|
||||
double utime(void);
|
||||
/* determine the current universal time */
|
||||
|
||||
int str2int(char *str, int *val);
|
||||
/* convert character string to value of integer type */
|
||||
|
||||
int str2dbl(char *str, double *val);
|
||||
/* convert character string to value of double type */
|
||||
|
||||
char *strspx(char *str);
|
||||
/* remove all spaces from character string */
|
||||
|
||||
char *strtrim(char *str);
|
||||
/* remove trailing spaces from character string */
|
||||
|
||||
#endif
|
||||
|
||||
/* eof */
|
||||
@@ -0,0 +1,140 @@
|
||||
/* glplib1.c */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include "glplib.h"
|
||||
|
||||
static void *pointer = NULL;
|
||||
/* some "secret" place to store a pointer */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- lib_set_ptr - store a pointer.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glplib.h"
|
||||
-- void lib_set_ptr(void *ptr);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The routine lib_set_ptr stores a pointer specified by the parameter
|
||||
-- ptr in some "secret" place. */
|
||||
|
||||
void lib_set_ptr(void *ptr)
|
||||
{ pointer = ptr;
|
||||
return;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- lib_get_ptr - retrieve a pointer.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glplib.h"
|
||||
-- void *lib_get_ptr(void);
|
||||
--
|
||||
-- *Returns*
|
||||
--
|
||||
-- The routine lib_get_ptr returns a pointer previously stored by the
|
||||
-- routine lib_set_ptr. If the latter has not been called yet, NULL is
|
||||
-- returned. */
|
||||
|
||||
void *lib_get_ptr(void)
|
||||
{ void *ptr;
|
||||
ptr = pointer;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/* eof */
|
||||
/* glplib1.c */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include "glplib.h"
|
||||
|
||||
static void *pointer = NULL;
|
||||
/* some "secret" place to store a pointer */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- lib_set_ptr - store a pointer.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glplib.h"
|
||||
-- void lib_set_ptr(void *ptr);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The routine lib_set_ptr stores a pointer specified by the parameter
|
||||
-- ptr in some "secret" place. */
|
||||
|
||||
void lib_set_ptr(void *ptr)
|
||||
{ pointer = ptr;
|
||||
return;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- lib_get_ptr - retrieve a pointer.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glplib.h"
|
||||
-- void *lib_get_ptr(void);
|
||||
--
|
||||
-- *Returns*
|
||||
--
|
||||
-- The routine lib_get_ptr returns a pointer previously stored by the
|
||||
-- routine lib_set_ptr. If the latter has not been called yet, NULL is
|
||||
-- returned. */
|
||||
|
||||
void *lib_get_ptr(void)
|
||||
{ void *ptr;
|
||||
ptr = pointer;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/* eof */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,442 @@
|
||||
/* glplib3.c */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <float.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "glplib.h"
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- str2int - convert character string to value of integer type.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glplib.h"
|
||||
-- int str2int(char *str, int *val);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The routine str2int converts the character string str to a value of
|
||||
-- integer type and stores the value into location, which the parameter
|
||||
-- val points to (in the case of error content of this location is not
|
||||
-- changed).
|
||||
--
|
||||
-- *Returns*
|
||||
--
|
||||
-- The routine returns one of the following error codes:
|
||||
--
|
||||
-- 0 - no error;
|
||||
-- 1 - value out of range;
|
||||
-- 2 - character string is syntactically incorrect. */
|
||||
|
||||
int str2int(char *str, int *_val)
|
||||
{ int d, k, s, val = 0;
|
||||
/* scan optional sign */
|
||||
if (str[0] == '+')
|
||||
s = +1, k = 1;
|
||||
else if (str[0] == '-')
|
||||
s = -1, k = 1;
|
||||
else
|
||||
s = +1, k = 0;
|
||||
/* check for the first digit */
|
||||
if (!isdigit((unsigned char)str[k])) return 2;
|
||||
/* scan digits */
|
||||
while (isdigit((unsigned char)str[k]))
|
||||
{ d = str[k++] - '0';
|
||||
if (s > 0)
|
||||
{ if (val > INT_MAX / 10) return 1;
|
||||
val *= 10;
|
||||
if (val > INT_MAX - d) return 1;
|
||||
val += d;
|
||||
}
|
||||
else
|
||||
{ if (val < INT_MIN / 10) return 1;
|
||||
val *= 10;
|
||||
if (val < INT_MIN + d) return 1;
|
||||
val -= d;
|
||||
}
|
||||
}
|
||||
/* check for terminator */
|
||||
if (str[k] != '\0') return 2;
|
||||
/* conversion is completed */
|
||||
*_val = val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- str2dbl - convert character string to value of double type.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glplib.h"
|
||||
-- int str2dbl(char *str, double *val);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The routine str2dbl converts the character string str to a value of
|
||||
-- double type and stores the value into location, which the parameter
|
||||
-- val points to (in the case of error content of this location is not
|
||||
-- changed).
|
||||
--
|
||||
-- *Returns*
|
||||
--
|
||||
-- The routine returns one of the following error codes:
|
||||
--
|
||||
-- 0 - no error;
|
||||
-- 1 - value out of range;
|
||||
-- 2 - character string is syntactically incorrect. */
|
||||
|
||||
int str2dbl(char *str, double *_val)
|
||||
{ int k;
|
||||
double val;
|
||||
/* scan optional sign */
|
||||
k = (str[0] == '+' || str[0] == '-' ? 1 : 0);
|
||||
/* check for decimal point */
|
||||
if (str[k] == '.')
|
||||
{ k++;
|
||||
/* a digit should follow it */
|
||||
if (!isdigit((unsigned char)str[k])) return 2;
|
||||
k++;
|
||||
goto frac;
|
||||
}
|
||||
/* integer part should start with a digit */
|
||||
if (!isdigit((unsigned char)str[k])) return 2;
|
||||
/* scan integer part */
|
||||
while (isdigit((unsigned char)str[k])) k++;
|
||||
/* check for decimal point */
|
||||
if (str[k] == '.') k++;
|
||||
frac: /* scan optional fraction part */
|
||||
while (isdigit((unsigned char)str[k])) k++;
|
||||
/* check for decimal exponent */
|
||||
if (str[k] == 'E' || str[k] == 'e')
|
||||
{ k++;
|
||||
/* scan optional sign */
|
||||
if (str[k] == '+' || str[k] == '-') k++;
|
||||
/* a digit should follow E, E+ or E- */
|
||||
if (!isdigit((unsigned char)str[k])) return 2;
|
||||
}
|
||||
/* scan optional exponent part */
|
||||
while (isdigit((unsigned char)str[k])) k++;
|
||||
/* check for terminator */
|
||||
if (str[k] != '\0') return 2;
|
||||
/* perform conversion */
|
||||
{ char *endptr;
|
||||
val = strtod(str, &endptr);
|
||||
if (*endptr != '\0') return 2;
|
||||
}
|
||||
/* check for overflow */
|
||||
if (!(-DBL_MAX <= val && val <= +DBL_MAX)) return 1;
|
||||
/* check for underflow */
|
||||
if (-DBL_MIN < val && val < +DBL_MIN) val = 0.0;
|
||||
/* conversion is completed */
|
||||
*_val = val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- strspx - remove all spaces from character string.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glplib.h"
|
||||
-- char *strspx(char *str);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The routine strspx removes all spaces from the character string str.
|
||||
--
|
||||
-- *Examples*
|
||||
--
|
||||
-- strspx(" Errare humanum est ") => "Errarehumanumest"
|
||||
--
|
||||
-- strspx(" ") => ""
|
||||
--
|
||||
-- *Returns*
|
||||
--
|
||||
-- The routine returns a pointer to the character string. */
|
||||
|
||||
char *strspx(char *str)
|
||||
{ char *s, *t;
|
||||
for (s = t = str; *s; s++) if (*s != ' ') *t++ = *s;
|
||||
*t = '\0';
|
||||
return str;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- strtrim - remove trailing spaces from character string.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glplib.h"
|
||||
-- char *strtrim(char *str);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The routine strtrim removes trailing spaces from the character
|
||||
-- string str.
|
||||
--
|
||||
-- *Examples*
|
||||
--
|
||||
-- strtrim("Errare humanum est ") => "Errare humanum est"
|
||||
--
|
||||
-- strtrim(" ") => ""
|
||||
--
|
||||
-- *Returns*
|
||||
--
|
||||
-- The routine returns a pointer to the character string. */
|
||||
|
||||
char *strtrim(char *str)
|
||||
{ char *t;
|
||||
for (t = strrchr(str, '\0') - 1; t >= str; t--)
|
||||
{ if (*t != ' ') break;
|
||||
*t = '\0';
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
/* eof */
|
||||
/* glplib3.c */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <float.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "glplib.h"
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- str2int - convert character string to value of integer type.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glplib.h"
|
||||
-- int str2int(char *str, int *val);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The routine str2int converts the character string str to a value of
|
||||
-- integer type and stores the value into location, which the parameter
|
||||
-- val points to (in the case of error content of this location is not
|
||||
-- changed).
|
||||
--
|
||||
-- *Returns*
|
||||
--
|
||||
-- The routine returns one of the following error codes:
|
||||
--
|
||||
-- 0 - no error;
|
||||
-- 1 - value out of range;
|
||||
-- 2 - character string is syntactically incorrect. */
|
||||
|
||||
int str2int(char *str, int *_val)
|
||||
{ int d, k, s, val = 0;
|
||||
/* scan optional sign */
|
||||
if (str[0] == '+')
|
||||
s = +1, k = 1;
|
||||
else if (str[0] == '-')
|
||||
s = -1, k = 1;
|
||||
else
|
||||
s = +1, k = 0;
|
||||
/* check for the first digit */
|
||||
if (!isdigit((unsigned char)str[k])) return 2;
|
||||
/* scan digits */
|
||||
while (isdigit((unsigned char)str[k]))
|
||||
{ d = str[k++] - '0';
|
||||
if (s > 0)
|
||||
{ if (val > INT_MAX / 10) return 1;
|
||||
val *= 10;
|
||||
if (val > INT_MAX - d) return 1;
|
||||
val += d;
|
||||
}
|
||||
else
|
||||
{ if (val < INT_MIN / 10) return 1;
|
||||
val *= 10;
|
||||
if (val < INT_MIN + d) return 1;
|
||||
val -= d;
|
||||
}
|
||||
}
|
||||
/* check for terminator */
|
||||
if (str[k] != '\0') return 2;
|
||||
/* conversion is completed */
|
||||
*_val = val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- str2dbl - convert character string to value of double type.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glplib.h"
|
||||
-- int str2dbl(char *str, double *val);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The routine str2dbl converts the character string str to a value of
|
||||
-- double type and stores the value into location, which the parameter
|
||||
-- val points to (in the case of error content of this location is not
|
||||
-- changed).
|
||||
--
|
||||
-- *Returns*
|
||||
--
|
||||
-- The routine returns one of the following error codes:
|
||||
--
|
||||
-- 0 - no error;
|
||||
-- 1 - value out of range;
|
||||
-- 2 - character string is syntactically incorrect. */
|
||||
|
||||
int str2dbl(char *str, double *_val)
|
||||
{ int k;
|
||||
double val;
|
||||
/* scan optional sign */
|
||||
k = (str[0] == '+' || str[0] == '-' ? 1 : 0);
|
||||
/* check for decimal point */
|
||||
if (str[k] == '.')
|
||||
{ k++;
|
||||
/* a digit should follow it */
|
||||
if (!isdigit((unsigned char)str[k])) return 2;
|
||||
k++;
|
||||
goto frac;
|
||||
}
|
||||
/* integer part should start with a digit */
|
||||
if (!isdigit((unsigned char)str[k])) return 2;
|
||||
/* scan integer part */
|
||||
while (isdigit((unsigned char)str[k])) k++;
|
||||
/* check for decimal point */
|
||||
if (str[k] == '.') k++;
|
||||
frac: /* scan optional fraction part */
|
||||
while (isdigit((unsigned char)str[k])) k++;
|
||||
/* check for decimal exponent */
|
||||
if (str[k] == 'E' || str[k] == 'e')
|
||||
{ k++;
|
||||
/* scan optional sign */
|
||||
if (str[k] == '+' || str[k] == '-') k++;
|
||||
/* a digit should follow E, E+ or E- */
|
||||
if (!isdigit((unsigned char)str[k])) return 2;
|
||||
}
|
||||
/* scan optional exponent part */
|
||||
while (isdigit((unsigned char)str[k])) k++;
|
||||
/* check for terminator */
|
||||
if (str[k] != '\0') return 2;
|
||||
/* perform conversion */
|
||||
{ char *endptr;
|
||||
val = strtod(str, &endptr);
|
||||
if (*endptr != '\0') return 2;
|
||||
}
|
||||
/* check for overflow */
|
||||
if (!(-DBL_MAX <= val && val <= +DBL_MAX)) return 1;
|
||||
/* check for underflow */
|
||||
if (-DBL_MIN < val && val < +DBL_MIN) val = 0.0;
|
||||
/* conversion is completed */
|
||||
*_val = val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- strspx - remove all spaces from character string.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glplib.h"
|
||||
-- char *strspx(char *str);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The routine strspx removes all spaces from the character string str.
|
||||
--
|
||||
-- *Examples*
|
||||
--
|
||||
-- strspx(" Errare humanum est ") => "Errarehumanumest"
|
||||
--
|
||||
-- strspx(" ") => ""
|
||||
--
|
||||
-- *Returns*
|
||||
--
|
||||
-- The routine returns a pointer to the character string. */
|
||||
|
||||
char *strspx(char *str)
|
||||
{ char *s, *t;
|
||||
for (s = t = str; *s; s++) if (*s != ' ') *t++ = *s;
|
||||
*t = '\0';
|
||||
return str;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- strtrim - remove trailing spaces from character string.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glplib.h"
|
||||
-- char *strtrim(char *str);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The routine strtrim removes trailing spaces from the character
|
||||
-- string str.
|
||||
--
|
||||
-- *Examples*
|
||||
--
|
||||
-- strtrim("Errare humanum est ") => "Errare humanum est"
|
||||
--
|
||||
-- strtrim(" ") => ""
|
||||
--
|
||||
-- *Returns*
|
||||
--
|
||||
-- The routine returns a pointer to the character string. */
|
||||
|
||||
char *strtrim(char *str)
|
||||
{ char *t;
|
||||
for (t = strrchr(str, '\0') - 1; t >= str; t--)
|
||||
{ if (*t != ' ') break;
|
||||
*t = '\0';
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
/* eof */
|
||||
@@ -0,0 +1,672 @@
|
||||
/* glplpp.h */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _GLPLPP_H
|
||||
#define _GLPLPP_H
|
||||
|
||||
#include "glplpx.h"
|
||||
|
||||
#define lpp_create_wksp glp_lpp_create_wksp
|
||||
#define lpp_add_row glp_lpp_add_row
|
||||
#define lpp_add_col glp_lpp_add_col
|
||||
#define lpp_add_aij glp_lpp_add_aij
|
||||
#define lpp_remove_row glp_lpp_remove_row
|
||||
#define lpp_remove_col glp_lpp_remove_col
|
||||
#define lpp_enque_row glp_lpp_enque_row
|
||||
#define lpp_deque_row glp_lpp_deque_row
|
||||
#define lpp_enque_col glp_lpp_enque_col
|
||||
#define lpp_deque_col glp_lpp_deque_col
|
||||
#define lpp_load_orig glp_lpp_load_orig
|
||||
#define lpp_append_tqe glp_lpp_append_tqe
|
||||
#define lpp_build_prob glp_lpp_build_prob
|
||||
#define lpp_alloc_sol glp_lpp_alloc_sol
|
||||
#define lpp_load_sol glp_lpp_load_sol
|
||||
#define lpp_unload_sol glp_lpp_unload_sol
|
||||
#define lpp_delete_wksp glp_lpp_delete_wksp
|
||||
|
||||
#define lpp_presolve glp_lpp_presolve
|
||||
#define lpp_postsolve glp_lpp_postsolve
|
||||
|
||||
typedef struct LPP LPP;
|
||||
typedef struct LPPROW LPPROW;
|
||||
typedef struct LPPCOL LPPCOL;
|
||||
typedef struct LPPAIJ LPPAIJ;
|
||||
typedef struct LPPTQE LPPTQE;
|
||||
typedef struct LPPLFE LPPLFE;
|
||||
typedef struct LPPLFX LPPLFX;
|
||||
|
||||
struct LPP
|
||||
{ /* LP presolver workspace */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* original problem segment */
|
||||
int orig_m;
|
||||
/* number of rows in the original problem */
|
||||
int orig_n;
|
||||
/* number of columns in the original problem */
|
||||
int orig_nnz;
|
||||
/* number of non-zeros in the original problem */
|
||||
int orig_dir;
|
||||
/* optimization direction for the original problem:
|
||||
LPX_MIN - minimization
|
||||
LPX_MAX - maximization */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* transformed problem segment (always minimization) */
|
||||
int nrows;
|
||||
/* number of rows introduced into the transformed problem;
|
||||
this count increases by one each time when a new row is added
|
||||
to the transformed problem and never decreases; thus, actual
|
||||
number of rows may be less than nrows due to row deletions */
|
||||
int ncols;
|
||||
/* number of columns introduced into the transformed problem;
|
||||
this count increases by one each time when a new column is
|
||||
added to the transformed problem and never decreases; thus,
|
||||
actual number of columns may be less than ncols due to column
|
||||
deletions */
|
||||
DMP *row_pool;
|
||||
/* memory pool to hold LPPROW instances */
|
||||
DMP *col_pool;
|
||||
/* memory pool to hold LPPCOL instances */
|
||||
DMP *aij_pool;
|
||||
/* memory pool to hold LPPAIJ instances */
|
||||
LPPROW *row_ptr;
|
||||
/* initial pointer to the doubly linked list of rows */
|
||||
LPPCOL *col_ptr;
|
||||
/* initial pointer to the doubly linked list of columns */
|
||||
LPPROW *row_que;
|
||||
/* initial pointer to the queue of active rows */
|
||||
LPPCOL *col_que;
|
||||
/* initial pointer to the queue of active columns */
|
||||
double c0;
|
||||
/* constant term of the objective function */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* transformation history segment */
|
||||
DMP *tqe_pool;
|
||||
/* memory pool to hold instances of data structures that describe
|
||||
transformations performed by the presolver routines */
|
||||
LPPTQE *tqe_list;
|
||||
/* pointer to the first transformation queue entry; each time
|
||||
when the presolver applies some transformation to the problem,
|
||||
the corresponding entry is built and added to the beginning of
|
||||
this linked list */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* resultant problem segment */
|
||||
int m;
|
||||
/* number of rows in the resultant problem */
|
||||
int n;
|
||||
/* number of columns in the resultant problem */
|
||||
int nnz;
|
||||
/* number of non-zeros in the resultant problem */
|
||||
int *row_ref; /* int row_ref[1+m]; */
|
||||
/* row_ref[0] is not used;
|
||||
row_ref[i], i = 1, ..., m, is the reference number assigned to
|
||||
a row, which is i-th row of the resultant problem */
|
||||
int *col_ref; /* int col_ref[1+n]; */
|
||||
/* col_ref[0] is not used;
|
||||
col_ref[j], j = 1, ..., n, is the reference number assigned to
|
||||
a column, which is j-th column of the resultant problem */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* recovered solution segment */
|
||||
int *row_stat; /* int row_stat[1+nrows]; */
|
||||
/* row_stat[0] is not used;
|
||||
row_stat[i], i = 1, ..., nrows, is the status of i-th row:
|
||||
0 - row is not recovered yet
|
||||
LPX_BS - inactive constraint
|
||||
LPX_NL - active constraint on lower bound
|
||||
LPX_NU - active constraint on upper bound
|
||||
LPX_NF - (can never be)
|
||||
LPX_NS - active equality constraint */
|
||||
double *row_prim; /* double row_prim[1+nrows]; */
|
||||
/* row_prim[0] is not used;
|
||||
row_prim[i] is a primal value of i-th auxiliary variable */
|
||||
double *row_dual; /* double row_dual[1+nrows]; */
|
||||
/* row_dual[0] is not used;
|
||||
row_dual[i] is a dual value of i-th auxiliary variable */
|
||||
int *col_stat; /* int col_stat[1+ncols]; */
|
||||
/* col_stat[0] is not used;
|
||||
col_stat[j], j = 1, ..., ncols, is the status of j-th column:
|
||||
0 - column is not recovered yet
|
||||
LPX_BS - basic variable
|
||||
LPX_NL - non-basic variable on lower bound
|
||||
LPX_NU - non-basic variable on upper bound
|
||||
LPX_NF - non-basic free variable
|
||||
LPX_NS - non-basic fixed variable */
|
||||
double *col_prim; /* double col_prim[1+ncols]; */
|
||||
/* col_prim[0] is not used;
|
||||
col_prim[j] is a primal value of j-th structural variable */
|
||||
double *col_dual; /* double col_dual[1+ncols]; */
|
||||
/* col_dual[0] is not used;
|
||||
col_dual[j] is a dual value of j-th structural variable */
|
||||
};
|
||||
|
||||
struct LPPROW
|
||||
{ /* row (constraint) */
|
||||
int i;
|
||||
/* reference number assigned to this row, 1 <= i <= nrows;
|
||||
rows of the original problem are assigned the numbers from 1
|
||||
to orig_m */
|
||||
double lb;
|
||||
/* lower bound or -DBL_MAX, if this row has no lower bound */
|
||||
double ub;
|
||||
/* upper bound or +DBL_MAX, if this row has no upper bound */
|
||||
LPPAIJ *ptr;
|
||||
/* initial pointer to the linked list of constraint coefficients
|
||||
for the row */
|
||||
int temp;
|
||||
/* auxiliary attribute used by some presolver routines */
|
||||
LPPROW *prev;
|
||||
/* pointer to the previous row in the linked list */
|
||||
LPPROW *next;
|
||||
/* pointer to the next row in the linked list */
|
||||
int q_flag;
|
||||
/* if this flag is set, the row is in the active queue */
|
||||
LPPROW *q_prev;
|
||||
/* pointer to the previous row in the active queue */
|
||||
LPPROW *q_next;
|
||||
/* pointer to the next row in the active queue */
|
||||
};
|
||||
|
||||
struct LPPCOL
|
||||
{ /* column (variable) */
|
||||
int j;
|
||||
/* reference number assigned to the column, 1 <= j <= ncols;
|
||||
columns of the original problem are assigned the numbers from
|
||||
1 to orig_n */
|
||||
double lb;
|
||||
/* lower bound or -DBL_MAX, if the column has no lower bound */
|
||||
double ub;
|
||||
/* upper bound or +DBL_MAX, if the column has no upper bound */
|
||||
double c;
|
||||
/* objective coefficient at the column */
|
||||
LPPAIJ *ptr;
|
||||
/* initial pointer to the linked list of constraint coefficients
|
||||
for the column */
|
||||
LPPCOL *prev;
|
||||
/* pointer to the previous column in the linked list */
|
||||
LPPCOL *next;
|
||||
/* pointer to the next column in the linked list */
|
||||
int q_flag;
|
||||
/* if this flag is set, the column is in the active queue */
|
||||
LPPCOL *q_prev;
|
||||
/* pointer to the previous column in the active queue */
|
||||
LPPCOL *q_next;
|
||||
/* pointer to the next column in the active queue */
|
||||
};
|
||||
|
||||
struct LPPAIJ
|
||||
{ /* element of the constraint matrix */
|
||||
LPPROW *row;
|
||||
/* pointer to the corresponding row */
|
||||
LPPCOL *col;
|
||||
/* pointer to the corresponding column */
|
||||
double val;
|
||||
/* numerical value of this element */
|
||||
LPPAIJ *r_prev;
|
||||
/* pointer to the previous element in the same row */
|
||||
LPPAIJ *r_next;
|
||||
/* pointer to the next element in the same row */
|
||||
LPPAIJ *c_prev;
|
||||
/* pointer to the previous element in the same column */
|
||||
LPPAIJ *c_next;
|
||||
/* pointer to the next element in the same column */
|
||||
};
|
||||
|
||||
struct LPPTQE
|
||||
{ /* transformation queue entry */
|
||||
int type;
|
||||
/* entry type: */
|
||||
#define LPP_EMPTY_ROW 0x01
|
||||
#define LPP_EMPTY_COL 0x02
|
||||
#define LPP_FREE_ROW 0x03
|
||||
#define LPP_FIXED_COL 0x04
|
||||
#define LPP_ROW_SNGTON1 0x05
|
||||
#define LPP_ROW_SNGTON2 0x06
|
||||
#define LPP_COL_SNGTON1 0x07
|
||||
#define LPP_COL_SNGTON2 0x08
|
||||
#define LPP_FORCING_ROW 0x09
|
||||
void *info;
|
||||
/* pointer to specific part of this entry (depends on the entry
|
||||
type) */
|
||||
LPPTQE *next;
|
||||
/* pointer to an entry, which was created *before* this entry */
|
||||
};
|
||||
|
||||
struct LPPLFE
|
||||
{ /* linear form element */
|
||||
int ref;
|
||||
/* row/column reference number */
|
||||
double val;
|
||||
/* numerical value */
|
||||
LPPLFE *next;
|
||||
/* pointer to the next element */
|
||||
};
|
||||
|
||||
struct LPPLFX
|
||||
{ /* extended linear form element */
|
||||
int ref;
|
||||
/* row/column reference number */
|
||||
int flag;
|
||||
/* row/column flag */
|
||||
double val;
|
||||
/* numerical value */
|
||||
LPPLFX *next;
|
||||
/* pointer to the next element */
|
||||
};
|
||||
|
||||
LPP *lpp_create_wksp(void);
|
||||
/* create LP presolver workspace */
|
||||
|
||||
LPPROW *lpp_add_row(LPP *lpp, double lb, double ub);
|
||||
/* add new row to the transformed problem */
|
||||
|
||||
LPPCOL *lpp_add_col(LPP *lpp, double lb, double ub, double c);
|
||||
/* add new column to the transformed problem */
|
||||
|
||||
LPPAIJ *lpp_add_aij(LPP *lpp, LPPROW *row, LPPCOL *col, double val);
|
||||
/* add new element to the constraint matrix */
|
||||
|
||||
void lpp_remove_row(LPP *lpp, LPPROW *row);
|
||||
/* remove row from the transformed problem */
|
||||
|
||||
void lpp_remove_col(LPP *lpp, LPPCOL *col);
|
||||
/* remove column from the transformed problem */
|
||||
|
||||
void lpp_enque_row(LPP *lpp, LPPROW *row);
|
||||
/* place row in the active queue */
|
||||
|
||||
void lpp_deque_row(LPP *lpp, LPPROW *row);
|
||||
/* remove row from the active queue */
|
||||
|
||||
void lpp_enque_col(LPP *lpp, LPPCOL *col);
|
||||
/* place column in the active queue */
|
||||
|
||||
void lpp_deque_col(LPP *lpp, LPPCOL *col);
|
||||
/* remove column from the active queue */
|
||||
|
||||
void lpp_load_orig(LPP *lpp, LPX *orig);
|
||||
/* load original problem into LP presolver workspace */
|
||||
|
||||
void *lpp_append_tqe(LPP *lpp, int type, int size);
|
||||
/* append new transformation queue entry */
|
||||
|
||||
LPX *lpp_build_prob(LPP *lpp);
|
||||
/* build resultant problem */
|
||||
|
||||
void lpp_alloc_sol(LPP *lpp);
|
||||
/* allocate recovered solution segment */
|
||||
|
||||
void lpp_load_sol(LPP *lpp, LPX *prob);
|
||||
/* load basic solution into LP presolver workspace */
|
||||
|
||||
void lpp_unload_sol(LPP *lpp, LPX *orig);
|
||||
/* unload basic solution from LP presolver workspace */
|
||||
|
||||
void lpp_delete_wksp(LPP *lpp);
|
||||
/* delete LP presolver workspace */
|
||||
|
||||
int lpp_presolve(LPP *lpp);
|
||||
/* LP presolve analysis */
|
||||
|
||||
void lpp_postsolve(LPP *lpp);
|
||||
/* LP postsolve processing */
|
||||
|
||||
#endif
|
||||
|
||||
/* eof */
|
||||
/* glplpp.h */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _GLPLPP_H
|
||||
#define _GLPLPP_H
|
||||
|
||||
#include "glplpx.h"
|
||||
|
||||
#define lpp_create_wksp glp_lpp_create_wksp
|
||||
#define lpp_add_row glp_lpp_add_row
|
||||
#define lpp_add_col glp_lpp_add_col
|
||||
#define lpp_add_aij glp_lpp_add_aij
|
||||
#define lpp_remove_row glp_lpp_remove_row
|
||||
#define lpp_remove_col glp_lpp_remove_col
|
||||
#define lpp_enque_row glp_lpp_enque_row
|
||||
#define lpp_deque_row glp_lpp_deque_row
|
||||
#define lpp_enque_col glp_lpp_enque_col
|
||||
#define lpp_deque_col glp_lpp_deque_col
|
||||
#define lpp_load_orig glp_lpp_load_orig
|
||||
#define lpp_append_tqe glp_lpp_append_tqe
|
||||
#define lpp_build_prob glp_lpp_build_prob
|
||||
#define lpp_alloc_sol glp_lpp_alloc_sol
|
||||
#define lpp_load_sol glp_lpp_load_sol
|
||||
#define lpp_unload_sol glp_lpp_unload_sol
|
||||
#define lpp_delete_wksp glp_lpp_delete_wksp
|
||||
|
||||
#define lpp_presolve glp_lpp_presolve
|
||||
#define lpp_postsolve glp_lpp_postsolve
|
||||
|
||||
typedef struct LPP LPP;
|
||||
typedef struct LPPROW LPPROW;
|
||||
typedef struct LPPCOL LPPCOL;
|
||||
typedef struct LPPAIJ LPPAIJ;
|
||||
typedef struct LPPTQE LPPTQE;
|
||||
typedef struct LPPLFE LPPLFE;
|
||||
typedef struct LPPLFX LPPLFX;
|
||||
|
||||
struct LPP
|
||||
{ /* LP presolver workspace */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* original problem segment */
|
||||
int orig_m;
|
||||
/* number of rows in the original problem */
|
||||
int orig_n;
|
||||
/* number of columns in the original problem */
|
||||
int orig_nnz;
|
||||
/* number of non-zeros in the original problem */
|
||||
int orig_dir;
|
||||
/* optimization direction for the original problem:
|
||||
LPX_MIN - minimization
|
||||
LPX_MAX - maximization */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* transformed problem segment (always minimization) */
|
||||
int nrows;
|
||||
/* number of rows introduced into the transformed problem;
|
||||
this count increases by one each time when a new row is added
|
||||
to the transformed problem and never decreases; thus, actual
|
||||
number of rows may be less than nrows due to row deletions */
|
||||
int ncols;
|
||||
/* number of columns introduced into the transformed problem;
|
||||
this count increases by one each time when a new column is
|
||||
added to the transformed problem and never decreases; thus,
|
||||
actual number of columns may be less than ncols due to column
|
||||
deletions */
|
||||
DMP *row_pool;
|
||||
/* memory pool to hold LPPROW instances */
|
||||
DMP *col_pool;
|
||||
/* memory pool to hold LPPCOL instances */
|
||||
DMP *aij_pool;
|
||||
/* memory pool to hold LPPAIJ instances */
|
||||
LPPROW *row_ptr;
|
||||
/* initial pointer to the doubly linked list of rows */
|
||||
LPPCOL *col_ptr;
|
||||
/* initial pointer to the doubly linked list of columns */
|
||||
LPPROW *row_que;
|
||||
/* initial pointer to the queue of active rows */
|
||||
LPPCOL *col_que;
|
||||
/* initial pointer to the queue of active columns */
|
||||
double c0;
|
||||
/* constant term of the objective function */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* transformation history segment */
|
||||
DMP *tqe_pool;
|
||||
/* memory pool to hold instances of data structures that describe
|
||||
transformations performed by the presolver routines */
|
||||
LPPTQE *tqe_list;
|
||||
/* pointer to the first transformation queue entry; each time
|
||||
when the presolver applies some transformation to the problem,
|
||||
the corresponding entry is built and added to the beginning of
|
||||
this linked list */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* resultant problem segment */
|
||||
int m;
|
||||
/* number of rows in the resultant problem */
|
||||
int n;
|
||||
/* number of columns in the resultant problem */
|
||||
int nnz;
|
||||
/* number of non-zeros in the resultant problem */
|
||||
int *row_ref; /* int row_ref[1+m]; */
|
||||
/* row_ref[0] is not used;
|
||||
row_ref[i], i = 1, ..., m, is the reference number assigned to
|
||||
a row, which is i-th row of the resultant problem */
|
||||
int *col_ref; /* int col_ref[1+n]; */
|
||||
/* col_ref[0] is not used;
|
||||
col_ref[j], j = 1, ..., n, is the reference number assigned to
|
||||
a column, which is j-th column of the resultant problem */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* recovered solution segment */
|
||||
int *row_stat; /* int row_stat[1+nrows]; */
|
||||
/* row_stat[0] is not used;
|
||||
row_stat[i], i = 1, ..., nrows, is the status of i-th row:
|
||||
0 - row is not recovered yet
|
||||
LPX_BS - inactive constraint
|
||||
LPX_NL - active constraint on lower bound
|
||||
LPX_NU - active constraint on upper bound
|
||||
LPX_NF - (can never be)
|
||||
LPX_NS - active equality constraint */
|
||||
double *row_prim; /* double row_prim[1+nrows]; */
|
||||
/* row_prim[0] is not used;
|
||||
row_prim[i] is a primal value of i-th auxiliary variable */
|
||||
double *row_dual; /* double row_dual[1+nrows]; */
|
||||
/* row_dual[0] is not used;
|
||||
row_dual[i] is a dual value of i-th auxiliary variable */
|
||||
int *col_stat; /* int col_stat[1+ncols]; */
|
||||
/* col_stat[0] is not used;
|
||||
col_stat[j], j = 1, ..., ncols, is the status of j-th column:
|
||||
0 - column is not recovered yet
|
||||
LPX_BS - basic variable
|
||||
LPX_NL - non-basic variable on lower bound
|
||||
LPX_NU - non-basic variable on upper bound
|
||||
LPX_NF - non-basic free variable
|
||||
LPX_NS - non-basic fixed variable */
|
||||
double *col_prim; /* double col_prim[1+ncols]; */
|
||||
/* col_prim[0] is not used;
|
||||
col_prim[j] is a primal value of j-th structural variable */
|
||||
double *col_dual; /* double col_dual[1+ncols]; */
|
||||
/* col_dual[0] is not used;
|
||||
col_dual[j] is a dual value of j-th structural variable */
|
||||
};
|
||||
|
||||
struct LPPROW
|
||||
{ /* row (constraint) */
|
||||
int i;
|
||||
/* reference number assigned to this row, 1 <= i <= nrows;
|
||||
rows of the original problem are assigned the numbers from 1
|
||||
to orig_m */
|
||||
double lb;
|
||||
/* lower bound or -DBL_MAX, if this row has no lower bound */
|
||||
double ub;
|
||||
/* upper bound or +DBL_MAX, if this row has no upper bound */
|
||||
LPPAIJ *ptr;
|
||||
/* initial pointer to the linked list of constraint coefficients
|
||||
for the row */
|
||||
int temp;
|
||||
/* auxiliary attribute used by some presolver routines */
|
||||
LPPROW *prev;
|
||||
/* pointer to the previous row in the linked list */
|
||||
LPPROW *next;
|
||||
/* pointer to the next row in the linked list */
|
||||
int q_flag;
|
||||
/* if this flag is set, the row is in the active queue */
|
||||
LPPROW *q_prev;
|
||||
/* pointer to the previous row in the active queue */
|
||||
LPPROW *q_next;
|
||||
/* pointer to the next row in the active queue */
|
||||
};
|
||||
|
||||
struct LPPCOL
|
||||
{ /* column (variable) */
|
||||
int j;
|
||||
/* reference number assigned to the column, 1 <= j <= ncols;
|
||||
columns of the original problem are assigned the numbers from
|
||||
1 to orig_n */
|
||||
double lb;
|
||||
/* lower bound or -DBL_MAX, if the column has no lower bound */
|
||||
double ub;
|
||||
/* upper bound or +DBL_MAX, if the column has no upper bound */
|
||||
double c;
|
||||
/* objective coefficient at the column */
|
||||
LPPAIJ *ptr;
|
||||
/* initial pointer to the linked list of constraint coefficients
|
||||
for the column */
|
||||
LPPCOL *prev;
|
||||
/* pointer to the previous column in the linked list */
|
||||
LPPCOL *next;
|
||||
/* pointer to the next column in the linked list */
|
||||
int q_flag;
|
||||
/* if this flag is set, the column is in the active queue */
|
||||
LPPCOL *q_prev;
|
||||
/* pointer to the previous column in the active queue */
|
||||
LPPCOL *q_next;
|
||||
/* pointer to the next column in the active queue */
|
||||
};
|
||||
|
||||
struct LPPAIJ
|
||||
{ /* element of the constraint matrix */
|
||||
LPPROW *row;
|
||||
/* pointer to the corresponding row */
|
||||
LPPCOL *col;
|
||||
/* pointer to the corresponding column */
|
||||
double val;
|
||||
/* numerical value of this element */
|
||||
LPPAIJ *r_prev;
|
||||
/* pointer to the previous element in the same row */
|
||||
LPPAIJ *r_next;
|
||||
/* pointer to the next element in the same row */
|
||||
LPPAIJ *c_prev;
|
||||
/* pointer to the previous element in the same column */
|
||||
LPPAIJ *c_next;
|
||||
/* pointer to the next element in the same column */
|
||||
};
|
||||
|
||||
struct LPPTQE
|
||||
{ /* transformation queue entry */
|
||||
int type;
|
||||
/* entry type: */
|
||||
#define LPP_EMPTY_ROW 0x01
|
||||
#define LPP_EMPTY_COL 0x02
|
||||
#define LPP_FREE_ROW 0x03
|
||||
#define LPP_FIXED_COL 0x04
|
||||
#define LPP_ROW_SNGTON1 0x05
|
||||
#define LPP_ROW_SNGTON2 0x06
|
||||
#define LPP_COL_SNGTON1 0x07
|
||||
#define LPP_COL_SNGTON2 0x08
|
||||
#define LPP_FORCING_ROW 0x09
|
||||
void *info;
|
||||
/* pointer to specific part of this entry (depends on the entry
|
||||
type) */
|
||||
LPPTQE *next;
|
||||
/* pointer to an entry, which was created *before* this entry */
|
||||
};
|
||||
|
||||
struct LPPLFE
|
||||
{ /* linear form element */
|
||||
int ref;
|
||||
/* row/column reference number */
|
||||
double val;
|
||||
/* numerical value */
|
||||
LPPLFE *next;
|
||||
/* pointer to the next element */
|
||||
};
|
||||
|
||||
struct LPPLFX
|
||||
{ /* extended linear form element */
|
||||
int ref;
|
||||
/* row/column reference number */
|
||||
int flag;
|
||||
/* row/column flag */
|
||||
double val;
|
||||
/* numerical value */
|
||||
LPPLFX *next;
|
||||
/* pointer to the next element */
|
||||
};
|
||||
|
||||
LPP *lpp_create_wksp(void);
|
||||
/* create LP presolver workspace */
|
||||
|
||||
LPPROW *lpp_add_row(LPP *lpp, double lb, double ub);
|
||||
/* add new row to the transformed problem */
|
||||
|
||||
LPPCOL *lpp_add_col(LPP *lpp, double lb, double ub, double c);
|
||||
/* add new column to the transformed problem */
|
||||
|
||||
LPPAIJ *lpp_add_aij(LPP *lpp, LPPROW *row, LPPCOL *col, double val);
|
||||
/* add new element to the constraint matrix */
|
||||
|
||||
void lpp_remove_row(LPP *lpp, LPPROW *row);
|
||||
/* remove row from the transformed problem */
|
||||
|
||||
void lpp_remove_col(LPP *lpp, LPPCOL *col);
|
||||
/* remove column from the transformed problem */
|
||||
|
||||
void lpp_enque_row(LPP *lpp, LPPROW *row);
|
||||
/* place row in the active queue */
|
||||
|
||||
void lpp_deque_row(LPP *lpp, LPPROW *row);
|
||||
/* remove row from the active queue */
|
||||
|
||||
void lpp_enque_col(LPP *lpp, LPPCOL *col);
|
||||
/* place column in the active queue */
|
||||
|
||||
void lpp_deque_col(LPP *lpp, LPPCOL *col);
|
||||
/* remove column from the active queue */
|
||||
|
||||
void lpp_load_orig(LPP *lpp, LPX *orig);
|
||||
/* load original problem into LP presolver workspace */
|
||||
|
||||
void *lpp_append_tqe(LPP *lpp, int type, int size);
|
||||
/* append new transformation queue entry */
|
||||
|
||||
LPX *lpp_build_prob(LPP *lpp);
|
||||
/* build resultant problem */
|
||||
|
||||
void lpp_alloc_sol(LPP *lpp);
|
||||
/* allocate recovered solution segment */
|
||||
|
||||
void lpp_load_sol(LPP *lpp, LPX *prob);
|
||||
/* load basic solution into LP presolver workspace */
|
||||
|
||||
void lpp_unload_sol(LPP *lpp, LPX *orig);
|
||||
/* unload basic solution from LP presolver workspace */
|
||||
|
||||
void lpp_delete_wksp(LPP *lpp);
|
||||
/* delete LP presolver workspace */
|
||||
|
||||
int lpp_presolve(LPP *lpp);
|
||||
/* LP presolve analysis */
|
||||
|
||||
void lpp_postsolve(LPP *lpp);
|
||||
/* LP postsolve processing */
|
||||
|
||||
#endif
|
||||
|
||||
/* eof */
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,234 @@
|
||||
/* glplpt.h */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _GLPLPT_H
|
||||
#define _GLPLPT_H
|
||||
|
||||
#include "glpdmp.h"
|
||||
|
||||
#define lpt_read_prob glp_lpt_read_prob
|
||||
#define lpt_free_prob glp_lpt_free_prob
|
||||
|
||||
typedef struct LPT LPT;
|
||||
typedef struct LPTROW LPTROW;
|
||||
typedef struct LPTCOL LPTCOL;
|
||||
typedef struct LPTLFE LPTLFE;
|
||||
|
||||
struct LPT
|
||||
{ /* LP/MIP problem in CPLEX LP format */
|
||||
DMP *pool;
|
||||
/* memory pool that holds all relevant data structures */
|
||||
char name[16+1];
|
||||
/* name of the objective function */
|
||||
int sense;
|
||||
/* optimization sense indicator: */
|
||||
#define LPT_MIN '-' /* minimization */
|
||||
#define LPT_MAX '+' /* maximization */
|
||||
LPTLFE *obj;
|
||||
/* pointer to a linear form for the objective function */
|
||||
int m;
|
||||
/* number of rows (constraints) */
|
||||
int n;
|
||||
/* number of columns (variables) */
|
||||
LPTROW *first_row, *last_row;
|
||||
/* pointers to the first and the last rows, respectively */
|
||||
LPTCOL *first_col, *last_col;
|
||||
/* pointers to the first and the last columns, respectively */
|
||||
};
|
||||
|
||||
struct LPTROW
|
||||
{ /* row (constraint) */
|
||||
char name[16+1];
|
||||
/* row name */
|
||||
int i;
|
||||
/* ordinal number of this row (1 <= i <= m) */
|
||||
LPTLFE *ptr;
|
||||
/* pointer to a linear form for this row */
|
||||
int sense;
|
||||
/* row sense indicator: */
|
||||
#define LPT_LE '<' /* less than or equal to */
|
||||
#define LPT_GE '>' /* greater than or equal to */
|
||||
#define LPT_EQ '=' /* equal to */
|
||||
double rhs;
|
||||
/* right-hand side */
|
||||
LPTROW *next;
|
||||
/* pointer to the next row */
|
||||
};
|
||||
|
||||
struct LPTCOL
|
||||
{ /* column (variable) */
|
||||
char name[16+1];
|
||||
/* column name */
|
||||
int j;
|
||||
/* ordinal number of this column (1 <= j <= n) */
|
||||
int kind;
|
||||
/* column kind: */
|
||||
#define LPT_CON 'C' /* continuous variable */
|
||||
#define LPT_INT 'I' /* general integer variable */
|
||||
#define LPT_BIN 'B' /* binary variable */
|
||||
double lb;
|
||||
/* lower bound or -DBL_MAX (with the meaning -inf) */
|
||||
double ub;
|
||||
/* upper bound or +DBL_MAX (with the meaning +inf) */
|
||||
LPTCOL *next;
|
||||
/* pointer to the next column */
|
||||
};
|
||||
|
||||
struct LPTLFE
|
||||
{ /* linear form entry */
|
||||
double coef;
|
||||
/* coefficient */
|
||||
LPTCOL *col;
|
||||
/* pointer to a column (variable) */
|
||||
LPTLFE *next;
|
||||
/* pointer to the next entry */
|
||||
};
|
||||
|
||||
LPT *lpt_read_prob(char *fname);
|
||||
/* read LP/MIP problem in CPLEX LP format */
|
||||
|
||||
void lpt_free_prob(LPT *lpt);
|
||||
/* free LP/MIP problem data block */
|
||||
|
||||
#endif
|
||||
|
||||
/* eof */
|
||||
/* glplpt.h */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _GLPLPT_H
|
||||
#define _GLPLPT_H
|
||||
|
||||
#include "glpdmp.h"
|
||||
|
||||
#define lpt_read_prob glp_lpt_read_prob
|
||||
#define lpt_free_prob glp_lpt_free_prob
|
||||
|
||||
typedef struct LPT LPT;
|
||||
typedef struct LPTROW LPTROW;
|
||||
typedef struct LPTCOL LPTCOL;
|
||||
typedef struct LPTLFE LPTLFE;
|
||||
|
||||
struct LPT
|
||||
{ /* LP/MIP problem in CPLEX LP format */
|
||||
DMP *pool;
|
||||
/* memory pool that holds all relevant data structures */
|
||||
char name[16+1];
|
||||
/* name of the objective function */
|
||||
int sense;
|
||||
/* optimization sense indicator: */
|
||||
#define LPT_MIN '-' /* minimization */
|
||||
#define LPT_MAX '+' /* maximization */
|
||||
LPTLFE *obj;
|
||||
/* pointer to a linear form for the objective function */
|
||||
int m;
|
||||
/* number of rows (constraints) */
|
||||
int n;
|
||||
/* number of columns (variables) */
|
||||
LPTROW *first_row, *last_row;
|
||||
/* pointers to the first and the last rows, respectively */
|
||||
LPTCOL *first_col, *last_col;
|
||||
/* pointers to the first and the last columns, respectively */
|
||||
};
|
||||
|
||||
struct LPTROW
|
||||
{ /* row (constraint) */
|
||||
char name[16+1];
|
||||
/* row name */
|
||||
int i;
|
||||
/* ordinal number of this row (1 <= i <= m) */
|
||||
LPTLFE *ptr;
|
||||
/* pointer to a linear form for this row */
|
||||
int sense;
|
||||
/* row sense indicator: */
|
||||
#define LPT_LE '<' /* less than or equal to */
|
||||
#define LPT_GE '>' /* greater than or equal to */
|
||||
#define LPT_EQ '=' /* equal to */
|
||||
double rhs;
|
||||
/* right-hand side */
|
||||
LPTROW *next;
|
||||
/* pointer to the next row */
|
||||
};
|
||||
|
||||
struct LPTCOL
|
||||
{ /* column (variable) */
|
||||
char name[16+1];
|
||||
/* column name */
|
||||
int j;
|
||||
/* ordinal number of this column (1 <= j <= n) */
|
||||
int kind;
|
||||
/* column kind: */
|
||||
#define LPT_CON 'C' /* continuous variable */
|
||||
#define LPT_INT 'I' /* general integer variable */
|
||||
#define LPT_BIN 'B' /* binary variable */
|
||||
double lb;
|
||||
/* lower bound or -DBL_MAX (with the meaning -inf) */
|
||||
double ub;
|
||||
/* upper bound or +DBL_MAX (with the meaning +inf) */
|
||||
LPTCOL *next;
|
||||
/* pointer to the next column */
|
||||
};
|
||||
|
||||
struct LPTLFE
|
||||
{ /* linear form entry */
|
||||
double coef;
|
||||
/* coefficient */
|
||||
LPTCOL *col;
|
||||
/* pointer to a column (variable) */
|
||||
LPTLFE *next;
|
||||
/* pointer to the next entry */
|
||||
};
|
||||
|
||||
LPT *lpt_read_prob(char *fname);
|
||||
/* read LP/MIP problem in CPLEX LP format */
|
||||
|
||||
void lpt_free_prob(LPT *lpt);
|
||||
/* free LP/MIP problem data block */
|
||||
|
||||
#endif
|
||||
|
||||
/* eof */
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,794 @@
|
||||
/* glplpx3.c (control parameters and statistics routines) */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#include <float.h>
|
||||
#include "glplib.h"
|
||||
#include "glplpx.h"
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- lpx_reset_parms - reset control parameters to default values.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glplpx.h"
|
||||
-- void lpx_reset_parms(LPX *lp);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The routine lpx_reset_parms resets all control parameters associated
|
||||
-- with an LP problem object, which the parameter lp points to, to their
|
||||
-- default values. */
|
||||
|
||||
void lpx_reset_parms(LPX *lp)
|
||||
{ lp->msg_lev = 3;
|
||||
lp->scale = 3;
|
||||
lp->sc_ord = 0;
|
||||
lp->sc_max = 20;
|
||||
lp->sc_eps = 0.01;
|
||||
lp->dual = 0;
|
||||
lp->price = 1;
|
||||
lp->relax = 0.07;
|
||||
lp->tol_bnd = 1e-7;
|
||||
lp->tol_dj = 1e-7;
|
||||
lp->tol_piv = 1e-9;
|
||||
lp->round = 0;
|
||||
lp->obj_ll = -DBL_MAX;
|
||||
lp->obj_ul = +DBL_MAX;
|
||||
lp->it_lim = -1;
|
||||
lp->it_cnt = 0;
|
||||
lp->tm_lim = -1.0;
|
||||
lp->out_frq = 200;
|
||||
lp->out_dly = 0.0;
|
||||
lp->branch = 2;
|
||||
lp->btrack = 2;
|
||||
lp->tol_int = 1e-6;
|
||||
lp->tol_obj = 1e-7;
|
||||
lp->mps_info = 1;
|
||||
lp->mps_obj = 2;
|
||||
lp->mps_orig = 0;
|
||||
lp->mps_wide = 1;
|
||||
lp->mps_free = 0;
|
||||
lp->mps_skip = 0;
|
||||
lp->lpt_orig = 0;
|
||||
lp->presol = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- lpx_set_int_parm - set (change) integer control parameter.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glplpx.h"
|
||||
-- void lpx_set_int_parm(LPX *lp, int parm, int val);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The routine lpx_set_int_parm sets (changes) the current value of an
|
||||
-- integer control parameter parm. The parameter val specifies a new
|
||||
-- value of the control parameter. */
|
||||
|
||||
void lpx_set_int_parm(LPX *lp, int parm, int val)
|
||||
{ switch (parm)
|
||||
{ case LPX_K_MSGLEV:
|
||||
if (!(0 <= val && val <= 3))
|
||||
fault("lpx_set_int_parm: MSGLEV = %d; invalid value",
|
||||
val);
|
||||
lp->msg_lev = val;
|
||||
break;
|
||||
case LPX_K_SCALE:
|
||||
if (!(0 <= val && val <= 3))
|
||||
fault("lpx_set_int_parm: SCALE = %d; invalid value",
|
||||
val);
|
||||
lp->scale = val;
|
||||
break;
|
||||
case LPX_K_DUAL:
|
||||
if (!(val == 0 || val == 1))
|
||||
fault("lpx_set_int_parm: DUAL = %d; invalid value",
|
||||
val);
|
||||
lp->dual = val;
|
||||
break;
|
||||
case LPX_K_PRICE:
|
||||
if (!(val == 0 || val == 1))
|
||||
fault("lpx_set_int_parm: PRICE = %d; invalid value",
|
||||
val);
|
||||
lp->price = val;
|
||||
break;
|
||||
case LPX_K_ROUND:
|
||||
if (!(val == 0 || val == 1))
|
||||
fault("lpx_set_int_parm: ROUND = %d; invalid value",
|
||||
val);
|
||||
lp->round = val;
|
||||
break;
|
||||
case LPX_K_ITLIM:
|
||||
lp->it_lim = val;
|
||||
break;
|
||||
case LPX_K_ITCNT:
|
||||
lp->it_cnt = val;
|
||||
break;
|
||||
case LPX_K_OUTFRQ:
|
||||
if (!(val > 0))
|
||||
fault("lpx_set_int_parm: OUTFRQ = %d; invalid value",
|
||||
val);
|
||||
lp->out_frq = val;
|
||||
break;
|
||||
case LPX_K_BRANCH:
|
||||
if (!(val == 0 || val == 1 || val == 2))
|
||||
fault("lpx_set_int_parm: BRANCH = %d; invalid value",
|
||||
val);
|
||||
lp->branch = val;
|
||||
break;
|
||||
case LPX_K_BTRACK:
|
||||
if (!(val == 0 || val == 1 || val == 2))
|
||||
fault("lpx_set_int_parm: BTRACK = %d; invalid value",
|
||||
val);
|
||||
lp->btrack = val;
|
||||
break;
|
||||
case LPX_K_MPSINFO:
|
||||
if (!(val == 0 || val == 1))
|
||||
fault("lpx_set_int_parm: MPSINFO = %d; invalid value",
|
||||
val);
|
||||
lp->mps_info = val;
|
||||
break;
|
||||
case LPX_K_MPSOBJ:
|
||||
if (!(val == 0 || val == 1 || val == 2))
|
||||
fault("lpx_set_int_parm: MPSOBJ = %d; invalid value",
|
||||
val);
|
||||
lp->mps_obj = val;
|
||||
break;
|
||||
case LPX_K_MPSORIG:
|
||||
if (!(val == 0 || val == 1))
|
||||
fault("lpx_set_int_parm: MPSORIG = %d; invalid value",
|
||||
val);
|
||||
lp->mps_orig = val;
|
||||
break;
|
||||
case LPX_K_MPSWIDE:
|
||||
if (!(val == 0 || val == 1))
|
||||
fault("lpx_set_int_parm: MPSWIDE = %d; invalid value",
|
||||
val);
|
||||
lp->mps_wide = val;
|
||||
break;
|
||||
case LPX_K_MPSFREE:
|
||||
if (!(val == 0 || val == 1))
|
||||
fault("lpx_set_int_parm: MPSFREE = %d; invalid value",
|
||||
val);
|
||||
lp->mps_free = val;
|
||||
break;
|
||||
case LPX_K_MPSSKIP:
|
||||
if (!(val == 0 || val == 1))
|
||||
fault("lpx_set_int_parm: MPSSKIP = %d; invalid value",
|
||||
val);
|
||||
lp->mps_skip = val;
|
||||
break;
|
||||
case LPX_K_LPTORIG:
|
||||
if (!(val == 0 || val == 1))
|
||||
fault("lpx_set_int_parm: LPTORIG = %d; invalid value",
|
||||
val);
|
||||
lp->lpt_orig = val;
|
||||
break;
|
||||
case LPX_K_PRESOL:
|
||||
if (!(val == 0 || val == 1))
|
||||
fault("lpx_set_int_parm: PRESOL = %d; invalid value",
|
||||
val);
|
||||
lp->presol = val;
|
||||
break;
|
||||
default:
|
||||
fault("lpx_set_int_parm: parm = %d; invalid parameter",
|
||||
parm);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- lpx_get_int_parm - query integer control parameter.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glplpx.h"
|
||||
-- int lpx_get_int_parm(LPX *lp, int parm);
|
||||
--
|
||||
-- *Returns*
|
||||
--
|
||||
-- The routine lpx_get_int_parm returns the current value of an integer
|
||||
-- control parameter parm. */
|
||||
|
||||
int lpx_get_int_parm(LPX *lp, int parm)
|
||||
{ int val = 0;
|
||||
switch (parm)
|
||||
{ case LPX_K_MSGLEV:
|
||||
val = lp->msg_lev; break;
|
||||
case LPX_K_SCALE:
|
||||
val = lp->scale; break;
|
||||
case LPX_K_DUAL:
|
||||
val = lp->dual; break;
|
||||
case LPX_K_PRICE:
|
||||
val = lp->price; break;
|
||||
case LPX_K_ROUND:
|
||||
val = lp->round; break;
|
||||
case LPX_K_ITLIM:
|
||||
val = lp->it_lim; break;
|
||||
case LPX_K_ITCNT:
|
||||
val = lp->it_cnt; break;
|
||||
case LPX_K_OUTFRQ:
|
||||
val = lp->out_frq; break;
|
||||
case LPX_K_BRANCH:
|
||||
val = lp->branch; break;
|
||||
case LPX_K_BTRACK:
|
||||
val = lp->btrack; break;
|
||||
case LPX_K_MPSINFO:
|
||||
val = lp->mps_info; break;
|
||||
case LPX_K_MPSOBJ:
|
||||
val = lp->mps_obj; break;
|
||||
case LPX_K_MPSORIG:
|
||||
val = lp->mps_orig; break;
|
||||
case LPX_K_MPSWIDE:
|
||||
val = lp->mps_wide; break;
|
||||
case LPX_K_MPSFREE:
|
||||
val = lp->mps_free; break;
|
||||
case LPX_K_MPSSKIP:
|
||||
val = lp->mps_skip; break;
|
||||
case LPX_K_LPTORIG:
|
||||
val = lp->lpt_orig; break;
|
||||
case LPX_K_PRESOL:
|
||||
val = lp->presol; break;
|
||||
default:
|
||||
fault("lpx_get_int_parm: parm = %d; invalid parameter",
|
||||
parm);
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- lpx_set_real_parm - set (change) real control parameter.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glplpx.h"
|
||||
-- void lpx_set_real_parm(LPX *lp, int parm, double val);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The routine lpx_set_real_parm sets (changes) the current value of
|
||||
-- a real (floating point) control parameter parm. The parameter val
|
||||
-- specifies a new value of the control parameter. */
|
||||
|
||||
void lpx_set_real_parm(LPX *lp, int parm, double val)
|
||||
{ switch (parm)
|
||||
{ case LPX_K_RELAX:
|
||||
if (!(0.0 <= val && val <= 1.0))
|
||||
fault("lpx_set_real_parm: RELAX = %g; invalid value",
|
||||
val);
|
||||
lp->relax = val;
|
||||
break;
|
||||
case LPX_K_TOLBND:
|
||||
if (!(DBL_EPSILON <= val && val <= 0.001))
|
||||
fault("lpx_set_real_parm: TOLBND = %g; invalid value",
|
||||
val);
|
||||
if (lp->tol_bnd > val)
|
||||
{ /* invalidate the basic solution */
|
||||
lp->p_stat = LPX_P_UNDEF;
|
||||
lp->d_stat = LPX_D_UNDEF;
|
||||
}
|
||||
lp->tol_bnd = val;
|
||||
break;
|
||||
case LPX_K_TOLDJ:
|
||||
if (!(DBL_EPSILON <= val && val <= 0.001))
|
||||
fault("lpx_set_real_parm: TOLDJ = %g; invalid value",
|
||||
val);
|
||||
if (lp->tol_dj > val)
|
||||
{ /* invalidate the basic solution */
|
||||
lp->p_stat = LPX_P_UNDEF;
|
||||
lp->d_stat = LPX_D_UNDEF;
|
||||
}
|
||||
lp->tol_dj = val;
|
||||
break;
|
||||
case LPX_K_TOLPIV:
|
||||
if (!(DBL_EPSILON <= val && val <= 0.001))
|
||||
fault("lpx_set_real_parm: TOLPIV = %g; invalid value",
|
||||
val);
|
||||
lp->tol_piv = val;
|
||||
break;
|
||||
case LPX_K_OBJLL:
|
||||
lp->obj_ll = val;
|
||||
break;
|
||||
case LPX_K_OBJUL:
|
||||
lp->obj_ul = val;
|
||||
break;
|
||||
case LPX_K_TMLIM:
|
||||
lp->tm_lim = val;
|
||||
break;
|
||||
case LPX_K_OUTDLY:
|
||||
lp->out_dly = val;
|
||||
break;
|
||||
case LPX_K_TOLINT:
|
||||
if (!(DBL_EPSILON <= val && val <= 0.001))
|
||||
fault("lpx_set_real_parm: TOLINT = %g; invalid value",
|
||||
val);
|
||||
lp->tol_int = val;
|
||||
break;
|
||||
case LPX_K_TOLOBJ:
|
||||
if (!(DBL_EPSILON <= val && val <= 0.001))
|
||||
fault("lpx_set_real_parm: TOLOBJ = %g; invalid value",
|
||||
val);
|
||||
lp->tol_obj = val;
|
||||
break;
|
||||
default:
|
||||
fault("lpx_set_real_parm: parm = %d; invalid parameter",
|
||||
parm);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- lpx_get_real_parm - query real control parameter.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glplpx.h"
|
||||
-- double lpx_get_real_parm(LPX *lp, int parm);
|
||||
--
|
||||
-- *Returns*
|
||||
--
|
||||
-- The routine lpx_get_real_parm returns the current value of a real
|
||||
-- (floating point) control parameter parm. */
|
||||
|
||||
double lpx_get_real_parm(LPX *lp, int parm)
|
||||
{ double val = 0.0;
|
||||
switch (parm)
|
||||
{ case LPX_K_RELAX:
|
||||
val = lp->relax;
|
||||
break;
|
||||
case LPX_K_TOLBND:
|
||||
val = lp->tol_bnd;
|
||||
break;
|
||||
case LPX_K_TOLDJ:
|
||||
val = lp->tol_dj;
|
||||
break;
|
||||
case LPX_K_TOLPIV:
|
||||
val = lp->tol_piv;
|
||||
break;
|
||||
case LPX_K_OBJLL:
|
||||
val = lp->obj_ll;
|
||||
break;
|
||||
case LPX_K_OBJUL:
|
||||
val = lp->obj_ul;
|
||||
break;
|
||||
case LPX_K_TMLIM:
|
||||
val = lp->tm_lim;
|
||||
break;
|
||||
case LPX_K_OUTDLY:
|
||||
val = lp->out_dly;
|
||||
break;
|
||||
case LPX_K_TOLINT:
|
||||
val = lp->tol_int;
|
||||
break;
|
||||
case LPX_K_TOLOBJ:
|
||||
val = lp->tol_obj;
|
||||
break;
|
||||
default:
|
||||
fault("lpx_get_real_parm: parm = %d; invalid parameter",
|
||||
parm);
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
/* eof */
|
||||
/* glplpx3.c (control parameters and statistics routines) */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#include <float.h>
|
||||
#include "glplib.h"
|
||||
#include "glplpx.h"
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- lpx_reset_parms - reset control parameters to default values.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glplpx.h"
|
||||
-- void lpx_reset_parms(LPX *lp);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The routine lpx_reset_parms resets all control parameters associated
|
||||
-- with an LP problem object, which the parameter lp points to, to their
|
||||
-- default values. */
|
||||
|
||||
void lpx_reset_parms(LPX *lp)
|
||||
{ lp->msg_lev = 3;
|
||||
lp->scale = 3;
|
||||
lp->sc_ord = 0;
|
||||
lp->sc_max = 20;
|
||||
lp->sc_eps = 0.01;
|
||||
lp->dual = 0;
|
||||
lp->price = 1;
|
||||
lp->relax = 0.07;
|
||||
lp->tol_bnd = 1e-7;
|
||||
lp->tol_dj = 1e-7;
|
||||
lp->tol_piv = 1e-9;
|
||||
lp->round = 0;
|
||||
lp->obj_ll = -DBL_MAX;
|
||||
lp->obj_ul = +DBL_MAX;
|
||||
lp->it_lim = -1;
|
||||
lp->it_cnt = 0;
|
||||
lp->tm_lim = -1.0;
|
||||
lp->out_frq = 200;
|
||||
lp->out_dly = 0.0;
|
||||
lp->branch = 2;
|
||||
lp->btrack = 2;
|
||||
lp->tol_int = 1e-6;
|
||||
lp->tol_obj = 1e-7;
|
||||
lp->mps_info = 1;
|
||||
lp->mps_obj = 2;
|
||||
lp->mps_orig = 0;
|
||||
lp->mps_wide = 1;
|
||||
lp->mps_free = 0;
|
||||
lp->mps_skip = 0;
|
||||
lp->lpt_orig = 0;
|
||||
lp->presol = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- lpx_set_int_parm - set (change) integer control parameter.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glplpx.h"
|
||||
-- void lpx_set_int_parm(LPX *lp, int parm, int val);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The routine lpx_set_int_parm sets (changes) the current value of an
|
||||
-- integer control parameter parm. The parameter val specifies a new
|
||||
-- value of the control parameter. */
|
||||
|
||||
void lpx_set_int_parm(LPX *lp, int parm, int val)
|
||||
{ switch (parm)
|
||||
{ case LPX_K_MSGLEV:
|
||||
if (!(0 <= val && val <= 3))
|
||||
fault("lpx_set_int_parm: MSGLEV = %d; invalid value",
|
||||
val);
|
||||
lp->msg_lev = val;
|
||||
break;
|
||||
case LPX_K_SCALE:
|
||||
if (!(0 <= val && val <= 3))
|
||||
fault("lpx_set_int_parm: SCALE = %d; invalid value",
|
||||
val);
|
||||
lp->scale = val;
|
||||
break;
|
||||
case LPX_K_DUAL:
|
||||
if (!(val == 0 || val == 1))
|
||||
fault("lpx_set_int_parm: DUAL = %d; invalid value",
|
||||
val);
|
||||
lp->dual = val;
|
||||
break;
|
||||
case LPX_K_PRICE:
|
||||
if (!(val == 0 || val == 1))
|
||||
fault("lpx_set_int_parm: PRICE = %d; invalid value",
|
||||
val);
|
||||
lp->price = val;
|
||||
break;
|
||||
case LPX_K_ROUND:
|
||||
if (!(val == 0 || val == 1))
|
||||
fault("lpx_set_int_parm: ROUND = %d; invalid value",
|
||||
val);
|
||||
lp->round = val;
|
||||
break;
|
||||
case LPX_K_ITLIM:
|
||||
lp->it_lim = val;
|
||||
break;
|
||||
case LPX_K_ITCNT:
|
||||
lp->it_cnt = val;
|
||||
break;
|
||||
case LPX_K_OUTFRQ:
|
||||
if (!(val > 0))
|
||||
fault("lpx_set_int_parm: OUTFRQ = %d; invalid value",
|
||||
val);
|
||||
lp->out_frq = val;
|
||||
break;
|
||||
case LPX_K_BRANCH:
|
||||
if (!(val == 0 || val == 1 || val == 2))
|
||||
fault("lpx_set_int_parm: BRANCH = %d; invalid value",
|
||||
val);
|
||||
lp->branch = val;
|
||||
break;
|
||||
case LPX_K_BTRACK:
|
||||
if (!(val == 0 || val == 1 || val == 2))
|
||||
fault("lpx_set_int_parm: BTRACK = %d; invalid value",
|
||||
val);
|
||||
lp->btrack = val;
|
||||
break;
|
||||
case LPX_K_MPSINFO:
|
||||
if (!(val == 0 || val == 1))
|
||||
fault("lpx_set_int_parm: MPSINFO = %d; invalid value",
|
||||
val);
|
||||
lp->mps_info = val;
|
||||
break;
|
||||
case LPX_K_MPSOBJ:
|
||||
if (!(val == 0 || val == 1 || val == 2))
|
||||
fault("lpx_set_int_parm: MPSOBJ = %d; invalid value",
|
||||
val);
|
||||
lp->mps_obj = val;
|
||||
break;
|
||||
case LPX_K_MPSORIG:
|
||||
if (!(val == 0 || val == 1))
|
||||
fault("lpx_set_int_parm: MPSORIG = %d; invalid value",
|
||||
val);
|
||||
lp->mps_orig = val;
|
||||
break;
|
||||
case LPX_K_MPSWIDE:
|
||||
if (!(val == 0 || val == 1))
|
||||
fault("lpx_set_int_parm: MPSWIDE = %d; invalid value",
|
||||
val);
|
||||
lp->mps_wide = val;
|
||||
break;
|
||||
case LPX_K_MPSFREE:
|
||||
if (!(val == 0 || val == 1))
|
||||
fault("lpx_set_int_parm: MPSFREE = %d; invalid value",
|
||||
val);
|
||||
lp->mps_free = val;
|
||||
break;
|
||||
case LPX_K_MPSSKIP:
|
||||
if (!(val == 0 || val == 1))
|
||||
fault("lpx_set_int_parm: MPSSKIP = %d; invalid value",
|
||||
val);
|
||||
lp->mps_skip = val;
|
||||
break;
|
||||
case LPX_K_LPTORIG:
|
||||
if (!(val == 0 || val == 1))
|
||||
fault("lpx_set_int_parm: LPTORIG = %d; invalid value",
|
||||
val);
|
||||
lp->lpt_orig = val;
|
||||
break;
|
||||
case LPX_K_PRESOL:
|
||||
if (!(val == 0 || val == 1))
|
||||
fault("lpx_set_int_parm: PRESOL = %d; invalid value",
|
||||
val);
|
||||
lp->presol = val;
|
||||
break;
|
||||
default:
|
||||
fault("lpx_set_int_parm: parm = %d; invalid parameter",
|
||||
parm);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- lpx_get_int_parm - query integer control parameter.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glplpx.h"
|
||||
-- int lpx_get_int_parm(LPX *lp, int parm);
|
||||
--
|
||||
-- *Returns*
|
||||
--
|
||||
-- The routine lpx_get_int_parm returns the current value of an integer
|
||||
-- control parameter parm. */
|
||||
|
||||
int lpx_get_int_parm(LPX *lp, int parm)
|
||||
{ int val = 0;
|
||||
switch (parm)
|
||||
{ case LPX_K_MSGLEV:
|
||||
val = lp->msg_lev; break;
|
||||
case LPX_K_SCALE:
|
||||
val = lp->scale; break;
|
||||
case LPX_K_DUAL:
|
||||
val = lp->dual; break;
|
||||
case LPX_K_PRICE:
|
||||
val = lp->price; break;
|
||||
case LPX_K_ROUND:
|
||||
val = lp->round; break;
|
||||
case LPX_K_ITLIM:
|
||||
val = lp->it_lim; break;
|
||||
case LPX_K_ITCNT:
|
||||
val = lp->it_cnt; break;
|
||||
case LPX_K_OUTFRQ:
|
||||
val = lp->out_frq; break;
|
||||
case LPX_K_BRANCH:
|
||||
val = lp->branch; break;
|
||||
case LPX_K_BTRACK:
|
||||
val = lp->btrack; break;
|
||||
case LPX_K_MPSINFO:
|
||||
val = lp->mps_info; break;
|
||||
case LPX_K_MPSOBJ:
|
||||
val = lp->mps_obj; break;
|
||||
case LPX_K_MPSORIG:
|
||||
val = lp->mps_orig; break;
|
||||
case LPX_K_MPSWIDE:
|
||||
val = lp->mps_wide; break;
|
||||
case LPX_K_MPSFREE:
|
||||
val = lp->mps_free; break;
|
||||
case LPX_K_MPSSKIP:
|
||||
val = lp->mps_skip; break;
|
||||
case LPX_K_LPTORIG:
|
||||
val = lp->lpt_orig; break;
|
||||
case LPX_K_PRESOL:
|
||||
val = lp->presol; break;
|
||||
default:
|
||||
fault("lpx_get_int_parm: parm = %d; invalid parameter",
|
||||
parm);
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- lpx_set_real_parm - set (change) real control parameter.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glplpx.h"
|
||||
-- void lpx_set_real_parm(LPX *lp, int parm, double val);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The routine lpx_set_real_parm sets (changes) the current value of
|
||||
-- a real (floating point) control parameter parm. The parameter val
|
||||
-- specifies a new value of the control parameter. */
|
||||
|
||||
void lpx_set_real_parm(LPX *lp, int parm, double val)
|
||||
{ switch (parm)
|
||||
{ case LPX_K_RELAX:
|
||||
if (!(0.0 <= val && val <= 1.0))
|
||||
fault("lpx_set_real_parm: RELAX = %g; invalid value",
|
||||
val);
|
||||
lp->relax = val;
|
||||
break;
|
||||
case LPX_K_TOLBND:
|
||||
if (!(DBL_EPSILON <= val && val <= 0.001))
|
||||
fault("lpx_set_real_parm: TOLBND = %g; invalid value",
|
||||
val);
|
||||
if (lp->tol_bnd > val)
|
||||
{ /* invalidate the basic solution */
|
||||
lp->p_stat = LPX_P_UNDEF;
|
||||
lp->d_stat = LPX_D_UNDEF;
|
||||
}
|
||||
lp->tol_bnd = val;
|
||||
break;
|
||||
case LPX_K_TOLDJ:
|
||||
if (!(DBL_EPSILON <= val && val <= 0.001))
|
||||
fault("lpx_set_real_parm: TOLDJ = %g; invalid value",
|
||||
val);
|
||||
if (lp->tol_dj > val)
|
||||
{ /* invalidate the basic solution */
|
||||
lp->p_stat = LPX_P_UNDEF;
|
||||
lp->d_stat = LPX_D_UNDEF;
|
||||
}
|
||||
lp->tol_dj = val;
|
||||
break;
|
||||
case LPX_K_TOLPIV:
|
||||
if (!(DBL_EPSILON <= val && val <= 0.001))
|
||||
fault("lpx_set_real_parm: TOLPIV = %g; invalid value",
|
||||
val);
|
||||
lp->tol_piv = val;
|
||||
break;
|
||||
case LPX_K_OBJLL:
|
||||
lp->obj_ll = val;
|
||||
break;
|
||||
case LPX_K_OBJUL:
|
||||
lp->obj_ul = val;
|
||||
break;
|
||||
case LPX_K_TMLIM:
|
||||
lp->tm_lim = val;
|
||||
break;
|
||||
case LPX_K_OUTDLY:
|
||||
lp->out_dly = val;
|
||||
break;
|
||||
case LPX_K_TOLINT:
|
||||
if (!(DBL_EPSILON <= val && val <= 0.001))
|
||||
fault("lpx_set_real_parm: TOLINT = %g; invalid value",
|
||||
val);
|
||||
lp->tol_int = val;
|
||||
break;
|
||||
case LPX_K_TOLOBJ:
|
||||
if (!(DBL_EPSILON <= val && val <= 0.001))
|
||||
fault("lpx_set_real_parm: TOLOBJ = %g; invalid value",
|
||||
val);
|
||||
lp->tol_obj = val;
|
||||
break;
|
||||
default:
|
||||
fault("lpx_set_real_parm: parm = %d; invalid parameter",
|
||||
parm);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- lpx_get_real_parm - query real control parameter.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glplpx.h"
|
||||
-- double lpx_get_real_parm(LPX *lp, int parm);
|
||||
--
|
||||
-- *Returns*
|
||||
--
|
||||
-- The routine lpx_get_real_parm returns the current value of a real
|
||||
-- (floating point) control parameter parm. */
|
||||
|
||||
double lpx_get_real_parm(LPX *lp, int parm)
|
||||
{ double val = 0.0;
|
||||
switch (parm)
|
||||
{ case LPX_K_RELAX:
|
||||
val = lp->relax;
|
||||
break;
|
||||
case LPX_K_TOLBND:
|
||||
val = lp->tol_bnd;
|
||||
break;
|
||||
case LPX_K_TOLDJ:
|
||||
val = lp->tol_dj;
|
||||
break;
|
||||
case LPX_K_TOLPIV:
|
||||
val = lp->tol_piv;
|
||||
break;
|
||||
case LPX_K_OBJLL:
|
||||
val = lp->obj_ll;
|
||||
break;
|
||||
case LPX_K_OBJUL:
|
||||
val = lp->obj_ul;
|
||||
break;
|
||||
case LPX_K_TMLIM:
|
||||
val = lp->tm_lim;
|
||||
break;
|
||||
case LPX_K_OUTDLY:
|
||||
val = lp->out_dly;
|
||||
break;
|
||||
case LPX_K_TOLINT:
|
||||
val = lp->tol_int;
|
||||
break;
|
||||
case LPX_K_TOLOBJ:
|
||||
val = lp->tol_obj;
|
||||
break;
|
||||
default:
|
||||
fault("lpx_get_real_parm: parm = %d; invalid parameter",
|
||||
parm);
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
/* eof */
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,888 @@
|
||||
/* glplpx8c.c */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "glplib.h"
|
||||
#include "glplpt.h"
|
||||
#include "glplpx.h"
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- lpx_read_lpt - read LP/MIP problem using CPLEX LP format.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glplpx.h"
|
||||
-- LPX *lpx_read_lpt(char *fname);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The routine lpx_read_lpt reads LP/MIP problem data using CPLEX LP
|
||||
-- format from a text file whose name is the character string fname.
|
||||
--
|
||||
-- *Returns*
|
||||
--
|
||||
-- If no error occurred, the routine returns a pointer to the created
|
||||
-- problem object. Otherwise the routine returns NULL. */
|
||||
|
||||
struct lpt_info
|
||||
{ /* transit information passed to the routine lpt_mat */
|
||||
LPT *lpt;
|
||||
/* LP/MIP problem data block */
|
||||
LPTROW *row;
|
||||
/* pointer to the current row (constraint) */
|
||||
LPTLFE *lfe;
|
||||
/* pointer to the next term of the corresponding linear form */
|
||||
};
|
||||
|
||||
static double lpt_mat(void *_info, int *i, int *j)
|
||||
{ /* "read" a next element of the constraint matrix */
|
||||
struct lpt_info *info = _info;
|
||||
double aij;
|
||||
read: if (info->row == NULL || info->lfe == NULL)
|
||||
{ /* either it is the first call or the current row has been
|
||||
completely read; choose the first/next row */
|
||||
if (info->row == NULL)
|
||||
info->row = info->lpt->first_row;
|
||||
else
|
||||
info->row = info->row->next;
|
||||
if (info->row == NULL)
|
||||
{ /* the entire matrix has been completely read */
|
||||
*i = *j = 0; /* end of file */
|
||||
return 0.0;
|
||||
}
|
||||
/* set the pointer to the first element of the row */
|
||||
info->lfe = info->row->ptr;
|
||||
/* the row may be empty, so repeat the check */
|
||||
goto read;
|
||||
}
|
||||
/* obtain the next element from the current row */
|
||||
*i = info->row->i;
|
||||
*j = info->lfe->col->j;
|
||||
aij = info->lfe->coef;
|
||||
/* advance the pointer */
|
||||
info->lfe = info->lfe->next;
|
||||
/* skip the element if it has zero value */
|
||||
if (aij == 0.0) goto read;
|
||||
/* bring the next element to the calling program */
|
||||
return aij;
|
||||
}
|
||||
|
||||
LPX *lpx_read_lpt(char *fname)
|
||||
{ LPX *lpx;
|
||||
LPT *lpt; LPTROW *row; LPTCOL *col; LPTLFE *lfe;
|
||||
int i, j;
|
||||
/* read LP/MIP problem in CPLEX LP format */
|
||||
lpt = lpt_read_prob(fname);
|
||||
if (lpt == NULL) return NULL;
|
||||
/* create problem object */
|
||||
lpx = lpx_create_prob();
|
||||
lpx_set_prob_name(lpx, "PROBLEM");
|
||||
lpx_add_rows(lpx, lpt->m);
|
||||
lpx_add_cols(lpx, lpt->n);
|
||||
/* process the objective function */
|
||||
lpx_set_obj_name(lpx, lpt->name);
|
||||
switch (lpt->sense)
|
||||
{ case LPT_MIN:
|
||||
lpx_set_obj_dir(lpx, LPX_MIN);
|
||||
break;
|
||||
case LPT_MAX:
|
||||
lpx_set_obj_dir(lpx, LPX_MAX);
|
||||
break;
|
||||
default:
|
||||
insist(lpt->sense != lpt->sense);
|
||||
}
|
||||
for (lfe = lpt->obj; lfe != NULL; lfe = lfe->next)
|
||||
lpx_set_col_coef(lpx, lfe->col->j, lfe->coef);
|
||||
/* process rows (constraints) */
|
||||
i = 0;
|
||||
for (row = lpt->first_row; row != NULL; row = row->next)
|
||||
{ i++;
|
||||
lpx_set_row_name(lpx, i, row->name);
|
||||
insist(row->i == i);
|
||||
switch (row->sense)
|
||||
{ case LPT_LE:
|
||||
lpx_set_row_bnds(lpx, i, LPX_UP, 0.0, row->rhs);
|
||||
break;
|
||||
case LPT_GE:
|
||||
lpx_set_row_bnds(lpx, i, LPX_LO, row->rhs, 0.0);
|
||||
break;
|
||||
case LPT_EQ:
|
||||
lpx_set_row_bnds(lpx, i, LPX_FX, row->rhs, row->rhs);
|
||||
break;
|
||||
default:
|
||||
insist(row->sense != row->sense);
|
||||
}
|
||||
}
|
||||
insist(i == lpt->m);
|
||||
/* process columns (variables) */
|
||||
j = 0;
|
||||
for (col = lpt->first_col; col != NULL; col = col->next)
|
||||
{ j++;
|
||||
lpx_set_col_name(lpx, j, col->name);
|
||||
insist(col->j == j);
|
||||
switch (col->kind)
|
||||
{ case LPT_CON:
|
||||
break;
|
||||
case LPT_INT:
|
||||
case LPT_BIN:
|
||||
lpx_set_class(lpx, LPX_MIP);
|
||||
lpx_set_col_kind(lpx, j, LPX_IV);
|
||||
break;
|
||||
default:
|
||||
insist(col->kind != col->kind);
|
||||
}
|
||||
if (col->lb == -DBL_MAX && col->ub == +DBL_MAX)
|
||||
lpx_set_col_bnds(lpx, j, LPX_FR, 0.0, 0.0);
|
||||
else if (col->ub == +DBL_MAX)
|
||||
lpx_set_col_bnds(lpx, j, LPX_LO, col->lb, 0.0);
|
||||
else if (col->lb == -DBL_MAX)
|
||||
lpx_set_col_bnds(lpx, j, LPX_UP, 0.0, col->ub);
|
||||
else if (col->lb != col->ub)
|
||||
lpx_set_col_bnds(lpx, j, LPX_DB, col->lb, col->ub);
|
||||
else
|
||||
lpx_set_col_bnds(lpx, j, LPX_FX, col->lb, col->ub);
|
||||
}
|
||||
insist(j == lpt->n);
|
||||
/* load the constraint matrix */
|
||||
{ struct lpt_info info;
|
||||
info.lpt = lpt;
|
||||
info.row = NULL;
|
||||
info.lfe = NULL;
|
||||
lpx_load_mat(lpx, &info, lpt_mat);
|
||||
}
|
||||
/* deallocate the problem block */
|
||||
lpt_free_prob(lpt);
|
||||
/* return to the calling program */
|
||||
return lpx;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- lpx_write_lpt - write problem data using CPLEX LP format.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glplpx.h"
|
||||
-- int lpx_write_lpt(LPX *lp, char *fname);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The routine lpx_write_lpt writes data from a problem object, which
|
||||
-- the parameter lp points to, to an output text file, whose name is the
|
||||
-- character string fname, using the CPLEX LP format.
|
||||
--
|
||||
-- *Returns*
|
||||
--
|
||||
-- If the operation was successful, the routine returns zero. Otherwise
|
||||
-- the routine prints an error message and returns non-zero. */
|
||||
|
||||
static int check_name(char *name)
|
||||
{ char *set = "!\"#$%&()/,.;?@_`'{}|~"; /* may appear in names */
|
||||
int t;
|
||||
if (isdigit((unsigned char)name[0])) return 1;
|
||||
if (name[0] == '.') return 1;
|
||||
for (t = 0; name[t] != '\0'; t++)
|
||||
{ if (t == 16) return 1;
|
||||
if (!isalnum((unsigned char)name[t]) &&
|
||||
strchr(set, (unsigned char)name[t]) == NULL) return 1;
|
||||
}
|
||||
return 0; /* name is ok */
|
||||
}
|
||||
|
||||
static char *row_name(LPX *lp, int i, char rname[16+1])
|
||||
{ char *str = NULL;
|
||||
if (lpx_get_int_parm(lp, LPX_K_LPTORIG))
|
||||
{ if (i == 0)
|
||||
str = lpx_get_obj_name(lp);
|
||||
else
|
||||
str = lpx_get_row_name(lp, i);
|
||||
if (str != NULL && check_name(str)) str = NULL;
|
||||
}
|
||||
if (str == NULL)
|
||||
{ if (i == 0)
|
||||
strcpy(rname, "obj");
|
||||
else
|
||||
sprintf(rname, "r(%d)", i);
|
||||
}
|
||||
else
|
||||
strcpy(rname, str);
|
||||
return rname;
|
||||
}
|
||||
|
||||
static char *col_name(LPX *lp, int j, char cname[16+1])
|
||||
{ char *str = NULL;
|
||||
if (lpx_get_int_parm(lp, LPX_K_LPTORIG))
|
||||
{ str = lpx_get_col_name(lp, j);
|
||||
if (str != NULL && check_name(str)) str = NULL;
|
||||
}
|
||||
if (str == NULL)
|
||||
sprintf(cname, "x(%d)", j);
|
||||
else
|
||||
strcpy(cname, str);
|
||||
return cname;
|
||||
}
|
||||
|
||||
int lpx_write_lpt(LPX *lp, char *fname)
|
||||
{ FILE *fp;
|
||||
int nrows, ncols, i, j, t, len, typx, flag, kind, *ndx;
|
||||
double lb, ub, *obj, *val;
|
||||
char line[72+1], term[72+1], rname[16+1], cname[16+1];
|
||||
print("lpx_write_lpt: writing problem data to `%s'...", fname);
|
||||
/* open the output text file */
|
||||
fp = ufopen(fname, "w");
|
||||
if (fp == NULL)
|
||||
{ print("lpx_write_lpt: can't create `%s' - %s", fname,
|
||||
strerror(errno));
|
||||
goto fail;
|
||||
}
|
||||
/* determine number of rows and number of columns */
|
||||
nrows = lpx_get_num_rows(lp);
|
||||
ncols = lpx_get_num_cols(lp);
|
||||
/* the problem should contain at least one row and one column */
|
||||
if (!(nrows > 0 && ncols > 0))
|
||||
fault("lpx_write_lpt: problem has no rows/columns");
|
||||
/* write problem name */
|
||||
{ char *name = lpx_get_prob_name(lp);
|
||||
if (name == NULL) name = "Unknown";
|
||||
fprintf(fp, "\\* Problem: %s *\\\n", name);
|
||||
fprintf(fp, "\n");
|
||||
}
|
||||
/* allocate working arrays */
|
||||
ndx = ucalloc(1+ncols, sizeof(int));
|
||||
val = ucalloc(1+ncols, sizeof(double));
|
||||
/* prepare coefficients of the objective function */
|
||||
obj = ucalloc(1+ncols, sizeof(double));
|
||||
for (j = 1; j <= ncols; j++)
|
||||
obj[j] = lpx_get_col_coef(lp, j);
|
||||
for (i = 1; i <= nrows; i++)
|
||||
{ double ci = lpx_get_row_coef(lp, i);
|
||||
if (ci != 0.0)
|
||||
{ len = lpx_get_mat_row(lp, i, ndx, val);
|
||||
for (t = 1; t <= len; t++)
|
||||
obj[ndx[t]] += ci * val[t];
|
||||
}
|
||||
}
|
||||
for (j = 1, len = 0; j <= ncols; j++)
|
||||
{ if (fabs(obj[j]) < 1e-12) continue;
|
||||
len++, ndx[len] = j, val[len] = obj[j];
|
||||
}
|
||||
ufree(obj);
|
||||
/* write the objective function definition and the constraints
|
||||
section */
|
||||
for (i = 0; i <= nrows; i++)
|
||||
{ if (i == 0)
|
||||
{ switch (lpx_get_obj_dir(lp))
|
||||
{ case LPX_MIN:
|
||||
fprintf(fp, "Minimize\n");
|
||||
break;
|
||||
case LPX_MAX:
|
||||
fprintf(fp, "Maximize\n");
|
||||
break;
|
||||
default:
|
||||
insist(lp != lp);
|
||||
}
|
||||
}
|
||||
else if (i == 1)
|
||||
{ double temp = lpx_get_obj_c0(lp);
|
||||
if (temp != 0.0)
|
||||
fprintf(fp, "\\* constant term = %.12g *\\\n", temp);
|
||||
fprintf(fp, "\n");
|
||||
fprintf(fp, "Subject To\n");
|
||||
}
|
||||
row_name(lp, i, rname);
|
||||
if (i > 0)
|
||||
{ lpx_get_row_bnds(lp, i, &typx, &lb, &ub);
|
||||
if (typx == LPX_FR) continue;
|
||||
len = lpx_get_mat_row(lp, i, ndx, val);
|
||||
}
|
||||
flag = 0;
|
||||
more: if (!flag)
|
||||
sprintf(line, " %s:", rname);
|
||||
else
|
||||
sprintf(line, " %*s ", strlen(rname), "");
|
||||
for (t = 1; t <= len; t++)
|
||||
{ col_name(lp, ndx[t], cname);
|
||||
if (fabs(val[t] - 1.0) < 1e-12)
|
||||
sprintf(term, " + %s", cname);
|
||||
else if (fabs(val[t] + 1.0) < 1e-12)
|
||||
sprintf(term, " - %s", cname);
|
||||
else if (val[t] > 0.0)
|
||||
sprintf(term, " + %.12g %s", + val[t], cname);
|
||||
else if (val[t] < 0.0)
|
||||
sprintf(term, " - %.12g %s", - val[t], cname);
|
||||
else
|
||||
continue;
|
||||
if (strlen(line) + strlen(term) > 72)
|
||||
fprintf(fp, "%s\n", line), line[0] = '\0';
|
||||
strcat(line, term);
|
||||
}
|
||||
if (len == 0)
|
||||
{ /* empty row */
|
||||
sprintf(term, " 0 %s", col_name(lp, 1, cname));
|
||||
strcat(line, term);
|
||||
}
|
||||
if (i > 0)
|
||||
{ switch (typx)
|
||||
{ case LPX_LO:
|
||||
case LPX_DB:
|
||||
sprintf(term, " >= %.12g", lb);
|
||||
break;
|
||||
case LPX_UP:
|
||||
sprintf(term, " <= %.12g", ub);
|
||||
break;
|
||||
case LPX_FX:
|
||||
sprintf(term, " = %.12g", lb);
|
||||
break;
|
||||
default:
|
||||
insist(typx != typx);
|
||||
}
|
||||
if (strlen(line) + strlen(term) > 72)
|
||||
fprintf(fp, "%s\n", line), line[0] = '\0';
|
||||
strcat(line, term);
|
||||
}
|
||||
fprintf(fp, "%s\n", line);
|
||||
if (i > 0 && typx == LPX_DB)
|
||||
{ /* double-bounded row needs a copy for its upper bound */
|
||||
flag = 1;
|
||||
typx = LPX_UP;
|
||||
goto more;
|
||||
}
|
||||
}
|
||||
/* free working arrays */
|
||||
ufree(ndx);
|
||||
ufree(val);
|
||||
/* write the bounds section */
|
||||
flag = 0;
|
||||
for (j = 1; j <= ncols; j++)
|
||||
{ col_name(lp, j, cname);
|
||||
lpx_get_col_bnds(lp, j, &typx, &lb, &ub);
|
||||
if (typx == LPX_LO && lb == 0.0) continue;
|
||||
if (!flag)
|
||||
{ fprintf(fp, "\n");
|
||||
fprintf(fp, "Bounds\n");
|
||||
flag = 1;
|
||||
}
|
||||
switch (typx)
|
||||
{ case LPX_FR:
|
||||
fprintf(fp, " %s free\n", cname);
|
||||
break;
|
||||
case LPX_LO:
|
||||
fprintf(fp, " %s >= %.12g\n", cname, lb);
|
||||
break;
|
||||
case LPX_UP:
|
||||
fprintf(fp, " %s <= %.12g\n", cname, ub);
|
||||
break;
|
||||
case LPX_DB:
|
||||
fprintf(fp, " %.12g <= %s <= %.12g\n", lb, cname, ub);
|
||||
break;
|
||||
case LPX_FX:
|
||||
fprintf(fp, " %s = %.12g\n", cname, lb);
|
||||
break;
|
||||
default:
|
||||
insist(typx != typx);
|
||||
}
|
||||
}
|
||||
/* write the general section */
|
||||
if (lpx_get_class(lp) == LPX_MIP)
|
||||
{ flag = 0;
|
||||
for (j = 1; j <= ncols; j++)
|
||||
{ kind = lpx_get_col_kind(lp, j);
|
||||
if (kind == LPX_CV) continue;
|
||||
insist(kind == LPX_IV);
|
||||
if (!flag)
|
||||
{ fprintf(fp, "\n");
|
||||
fprintf(fp, "Generals\n");
|
||||
flag = 1;
|
||||
}
|
||||
fprintf(fp, " %s\n", col_name(lp, j, cname));
|
||||
}
|
||||
}
|
||||
/* write the end keyword */
|
||||
fprintf(fp, "\n");
|
||||
fprintf(fp, "End\n");
|
||||
/* close the output text file */
|
||||
fflush(fp);
|
||||
if (ferror(fp))
|
||||
{ print("lpx_write_lpt: can't write to `%s' - %s", fname,
|
||||
strerror(errno));
|
||||
goto fail;
|
||||
}
|
||||
ufclose(fp);
|
||||
/* return to the calling program */
|
||||
return 0;
|
||||
fail: /* the operation failed */
|
||||
if (fp != NULL) ufclose(fp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* eof */
|
||||
/* glplpx8c.c */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "glplib.h"
|
||||
#include "glplpt.h"
|
||||
#include "glplpx.h"
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- lpx_read_lpt - read LP/MIP problem using CPLEX LP format.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glplpx.h"
|
||||
-- LPX *lpx_read_lpt(char *fname);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The routine lpx_read_lpt reads LP/MIP problem data using CPLEX LP
|
||||
-- format from a text file whose name is the character string fname.
|
||||
--
|
||||
-- *Returns*
|
||||
--
|
||||
-- If no error occurred, the routine returns a pointer to the created
|
||||
-- problem object. Otherwise the routine returns NULL. */
|
||||
|
||||
struct lpt_info
|
||||
{ /* transit information passed to the routine lpt_mat */
|
||||
LPT *lpt;
|
||||
/* LP/MIP problem data block */
|
||||
LPTROW *row;
|
||||
/* pointer to the current row (constraint) */
|
||||
LPTLFE *lfe;
|
||||
/* pointer to the next term of the corresponding linear form */
|
||||
};
|
||||
|
||||
static double lpt_mat(void *_info, int *i, int *j)
|
||||
{ /* "read" a next element of the constraint matrix */
|
||||
struct lpt_info *info = _info;
|
||||
double aij;
|
||||
read: if (info->row == NULL || info->lfe == NULL)
|
||||
{ /* either it is the first call or the current row has been
|
||||
completely read; choose the first/next row */
|
||||
if (info->row == NULL)
|
||||
info->row = info->lpt->first_row;
|
||||
else
|
||||
info->row = info->row->next;
|
||||
if (info->row == NULL)
|
||||
{ /* the entire matrix has been completely read */
|
||||
*i = *j = 0; /* end of file */
|
||||
return 0.0;
|
||||
}
|
||||
/* set the pointer to the first element of the row */
|
||||
info->lfe = info->row->ptr;
|
||||
/* the row may be empty, so repeat the check */
|
||||
goto read;
|
||||
}
|
||||
/* obtain the next element from the current row */
|
||||
*i = info->row->i;
|
||||
*j = info->lfe->col->j;
|
||||
aij = info->lfe->coef;
|
||||
/* advance the pointer */
|
||||
info->lfe = info->lfe->next;
|
||||
/* skip the element if it has zero value */
|
||||
if (aij == 0.0) goto read;
|
||||
/* bring the next element to the calling program */
|
||||
return aij;
|
||||
}
|
||||
|
||||
LPX *lpx_read_lpt(char *fname)
|
||||
{ LPX *lpx;
|
||||
LPT *lpt; LPTROW *row; LPTCOL *col; LPTLFE *lfe;
|
||||
int i, j;
|
||||
/* read LP/MIP problem in CPLEX LP format */
|
||||
lpt = lpt_read_prob(fname);
|
||||
if (lpt == NULL) return NULL;
|
||||
/* create problem object */
|
||||
lpx = lpx_create_prob();
|
||||
lpx_set_prob_name(lpx, "PROBLEM");
|
||||
lpx_add_rows(lpx, lpt->m);
|
||||
lpx_add_cols(lpx, lpt->n);
|
||||
/* process the objective function */
|
||||
lpx_set_obj_name(lpx, lpt->name);
|
||||
switch (lpt->sense)
|
||||
{ case LPT_MIN:
|
||||
lpx_set_obj_dir(lpx, LPX_MIN);
|
||||
break;
|
||||
case LPT_MAX:
|
||||
lpx_set_obj_dir(lpx, LPX_MAX);
|
||||
break;
|
||||
default:
|
||||
insist(lpt->sense != lpt->sense);
|
||||
}
|
||||
for (lfe = lpt->obj; lfe != NULL; lfe = lfe->next)
|
||||
lpx_set_col_coef(lpx, lfe->col->j, lfe->coef);
|
||||
/* process rows (constraints) */
|
||||
i = 0;
|
||||
for (row = lpt->first_row; row != NULL; row = row->next)
|
||||
{ i++;
|
||||
lpx_set_row_name(lpx, i, row->name);
|
||||
insist(row->i == i);
|
||||
switch (row->sense)
|
||||
{ case LPT_LE:
|
||||
lpx_set_row_bnds(lpx, i, LPX_UP, 0.0, row->rhs);
|
||||
break;
|
||||
case LPT_GE:
|
||||
lpx_set_row_bnds(lpx, i, LPX_LO, row->rhs, 0.0);
|
||||
break;
|
||||
case LPT_EQ:
|
||||
lpx_set_row_bnds(lpx, i, LPX_FX, row->rhs, row->rhs);
|
||||
break;
|
||||
default:
|
||||
insist(row->sense != row->sense);
|
||||
}
|
||||
}
|
||||
insist(i == lpt->m);
|
||||
/* process columns (variables) */
|
||||
j = 0;
|
||||
for (col = lpt->first_col; col != NULL; col = col->next)
|
||||
{ j++;
|
||||
lpx_set_col_name(lpx, j, col->name);
|
||||
insist(col->j == j);
|
||||
switch (col->kind)
|
||||
{ case LPT_CON:
|
||||
break;
|
||||
case LPT_INT:
|
||||
case LPT_BIN:
|
||||
lpx_set_class(lpx, LPX_MIP);
|
||||
lpx_set_col_kind(lpx, j, LPX_IV);
|
||||
break;
|
||||
default:
|
||||
insist(col->kind != col->kind);
|
||||
}
|
||||
if (col->lb == -DBL_MAX && col->ub == +DBL_MAX)
|
||||
lpx_set_col_bnds(lpx, j, LPX_FR, 0.0, 0.0);
|
||||
else if (col->ub == +DBL_MAX)
|
||||
lpx_set_col_bnds(lpx, j, LPX_LO, col->lb, 0.0);
|
||||
else if (col->lb == -DBL_MAX)
|
||||
lpx_set_col_bnds(lpx, j, LPX_UP, 0.0, col->ub);
|
||||
else if (col->lb != col->ub)
|
||||
lpx_set_col_bnds(lpx, j, LPX_DB, col->lb, col->ub);
|
||||
else
|
||||
lpx_set_col_bnds(lpx, j, LPX_FX, col->lb, col->ub);
|
||||
}
|
||||
insist(j == lpt->n);
|
||||
/* load the constraint matrix */
|
||||
{ struct lpt_info info;
|
||||
info.lpt = lpt;
|
||||
info.row = NULL;
|
||||
info.lfe = NULL;
|
||||
lpx_load_mat(lpx, &info, lpt_mat);
|
||||
}
|
||||
/* deallocate the problem block */
|
||||
lpt_free_prob(lpt);
|
||||
/* return to the calling program */
|
||||
return lpx;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- lpx_write_lpt - write problem data using CPLEX LP format.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glplpx.h"
|
||||
-- int lpx_write_lpt(LPX *lp, char *fname);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The routine lpx_write_lpt writes data from a problem object, which
|
||||
-- the parameter lp points to, to an output text file, whose name is the
|
||||
-- character string fname, using the CPLEX LP format.
|
||||
--
|
||||
-- *Returns*
|
||||
--
|
||||
-- If the operation was successful, the routine returns zero. Otherwise
|
||||
-- the routine prints an error message and returns non-zero. */
|
||||
|
||||
static int check_name(char *name)
|
||||
{ char *set = "!\"#$%&()/,.;?@_`'{}|~"; /* may appear in names */
|
||||
int t;
|
||||
if (isdigit((unsigned char)name[0])) return 1;
|
||||
if (name[0] == '.') return 1;
|
||||
for (t = 0; name[t] != '\0'; t++)
|
||||
{ if (t == 16) return 1;
|
||||
if (!isalnum((unsigned char)name[t]) &&
|
||||
strchr(set, (unsigned char)name[t]) == NULL) return 1;
|
||||
}
|
||||
return 0; /* name is ok */
|
||||
}
|
||||
|
||||
static char *row_name(LPX *lp, int i, char rname[16+1])
|
||||
{ char *str = NULL;
|
||||
if (lpx_get_int_parm(lp, LPX_K_LPTORIG))
|
||||
{ if (i == 0)
|
||||
str = lpx_get_obj_name(lp);
|
||||
else
|
||||
str = lpx_get_row_name(lp, i);
|
||||
if (str != NULL && check_name(str)) str = NULL;
|
||||
}
|
||||
if (str == NULL)
|
||||
{ if (i == 0)
|
||||
strcpy(rname, "obj");
|
||||
else
|
||||
sprintf(rname, "r(%d)", i);
|
||||
}
|
||||
else
|
||||
strcpy(rname, str);
|
||||
return rname;
|
||||
}
|
||||
|
||||
static char *col_name(LPX *lp, int j, char cname[16+1])
|
||||
{ char *str = NULL;
|
||||
if (lpx_get_int_parm(lp, LPX_K_LPTORIG))
|
||||
{ str = lpx_get_col_name(lp, j);
|
||||
if (str != NULL && check_name(str)) str = NULL;
|
||||
}
|
||||
if (str == NULL)
|
||||
sprintf(cname, "x(%d)", j);
|
||||
else
|
||||
strcpy(cname, str);
|
||||
return cname;
|
||||
}
|
||||
|
||||
int lpx_write_lpt(LPX *lp, char *fname)
|
||||
{ FILE *fp;
|
||||
int nrows, ncols, i, j, t, len, typx, flag, kind, *ndx;
|
||||
double lb, ub, *obj, *val;
|
||||
char line[72+1], term[72+1], rname[16+1], cname[16+1];
|
||||
print("lpx_write_lpt: writing problem data to `%s'...", fname);
|
||||
/* open the output text file */
|
||||
fp = ufopen(fname, "w");
|
||||
if (fp == NULL)
|
||||
{ print("lpx_write_lpt: can't create `%s' - %s", fname,
|
||||
strerror(errno));
|
||||
goto fail;
|
||||
}
|
||||
/* determine number of rows and number of columns */
|
||||
nrows = lpx_get_num_rows(lp);
|
||||
ncols = lpx_get_num_cols(lp);
|
||||
/* the problem should contain at least one row and one column */
|
||||
if (!(nrows > 0 && ncols > 0))
|
||||
fault("lpx_write_lpt: problem has no rows/columns");
|
||||
/* write problem name */
|
||||
{ char *name = lpx_get_prob_name(lp);
|
||||
if (name == NULL) name = "Unknown";
|
||||
fprintf(fp, "\\* Problem: %s *\\\n", name);
|
||||
fprintf(fp, "\n");
|
||||
}
|
||||
/* allocate working arrays */
|
||||
ndx = ucalloc(1+ncols, sizeof(int));
|
||||
val = ucalloc(1+ncols, sizeof(double));
|
||||
/* prepare coefficients of the objective function */
|
||||
obj = ucalloc(1+ncols, sizeof(double));
|
||||
for (j = 1; j <= ncols; j++)
|
||||
obj[j] = lpx_get_col_coef(lp, j);
|
||||
for (i = 1; i <= nrows; i++)
|
||||
{ double ci = lpx_get_row_coef(lp, i);
|
||||
if (ci != 0.0)
|
||||
{ len = lpx_get_mat_row(lp, i, ndx, val);
|
||||
for (t = 1; t <= len; t++)
|
||||
obj[ndx[t]] += ci * val[t];
|
||||
}
|
||||
}
|
||||
for (j = 1, len = 0; j <= ncols; j++)
|
||||
{ if (fabs(obj[j]) < 1e-12) continue;
|
||||
len++, ndx[len] = j, val[len] = obj[j];
|
||||
}
|
||||
ufree(obj);
|
||||
/* write the objective function definition and the constraints
|
||||
section */
|
||||
for (i = 0; i <= nrows; i++)
|
||||
{ if (i == 0)
|
||||
{ switch (lpx_get_obj_dir(lp))
|
||||
{ case LPX_MIN:
|
||||
fprintf(fp, "Minimize\n");
|
||||
break;
|
||||
case LPX_MAX:
|
||||
fprintf(fp, "Maximize\n");
|
||||
break;
|
||||
default:
|
||||
insist(lp != lp);
|
||||
}
|
||||
}
|
||||
else if (i == 1)
|
||||
{ double temp = lpx_get_obj_c0(lp);
|
||||
if (temp != 0.0)
|
||||
fprintf(fp, "\\* constant term = %.12g *\\\n", temp);
|
||||
fprintf(fp, "\n");
|
||||
fprintf(fp, "Subject To\n");
|
||||
}
|
||||
row_name(lp, i, rname);
|
||||
if (i > 0)
|
||||
{ lpx_get_row_bnds(lp, i, &typx, &lb, &ub);
|
||||
if (typx == LPX_FR) continue;
|
||||
len = lpx_get_mat_row(lp, i, ndx, val);
|
||||
}
|
||||
flag = 0;
|
||||
more: if (!flag)
|
||||
sprintf(line, " %s:", rname);
|
||||
else
|
||||
sprintf(line, " %*s ", strlen(rname), "");
|
||||
for (t = 1; t <= len; t++)
|
||||
{ col_name(lp, ndx[t], cname);
|
||||
if (fabs(val[t] - 1.0) < 1e-12)
|
||||
sprintf(term, " + %s", cname);
|
||||
else if (fabs(val[t] + 1.0) < 1e-12)
|
||||
sprintf(term, " - %s", cname);
|
||||
else if (val[t] > 0.0)
|
||||
sprintf(term, " + %.12g %s", + val[t], cname);
|
||||
else if (val[t] < 0.0)
|
||||
sprintf(term, " - %.12g %s", - val[t], cname);
|
||||
else
|
||||
continue;
|
||||
if (strlen(line) + strlen(term) > 72)
|
||||
fprintf(fp, "%s\n", line), line[0] = '\0';
|
||||
strcat(line, term);
|
||||
}
|
||||
if (len == 0)
|
||||
{ /* empty row */
|
||||
sprintf(term, " 0 %s", col_name(lp, 1, cname));
|
||||
strcat(line, term);
|
||||
}
|
||||
if (i > 0)
|
||||
{ switch (typx)
|
||||
{ case LPX_LO:
|
||||
case LPX_DB:
|
||||
sprintf(term, " >= %.12g", lb);
|
||||
break;
|
||||
case LPX_UP:
|
||||
sprintf(term, " <= %.12g", ub);
|
||||
break;
|
||||
case LPX_FX:
|
||||
sprintf(term, " = %.12g", lb);
|
||||
break;
|
||||
default:
|
||||
insist(typx != typx);
|
||||
}
|
||||
if (strlen(line) + strlen(term) > 72)
|
||||
fprintf(fp, "%s\n", line), line[0] = '\0';
|
||||
strcat(line, term);
|
||||
}
|
||||
fprintf(fp, "%s\n", line);
|
||||
if (i > 0 && typx == LPX_DB)
|
||||
{ /* double-bounded row needs a copy for its upper bound */
|
||||
flag = 1;
|
||||
typx = LPX_UP;
|
||||
goto more;
|
||||
}
|
||||
}
|
||||
/* free working arrays */
|
||||
ufree(ndx);
|
||||
ufree(val);
|
||||
/* write the bounds section */
|
||||
flag = 0;
|
||||
for (j = 1; j <= ncols; j++)
|
||||
{ col_name(lp, j, cname);
|
||||
lpx_get_col_bnds(lp, j, &typx, &lb, &ub);
|
||||
if (typx == LPX_LO && lb == 0.0) continue;
|
||||
if (!flag)
|
||||
{ fprintf(fp, "\n");
|
||||
fprintf(fp, "Bounds\n");
|
||||
flag = 1;
|
||||
}
|
||||
switch (typx)
|
||||
{ case LPX_FR:
|
||||
fprintf(fp, " %s free\n", cname);
|
||||
break;
|
||||
case LPX_LO:
|
||||
fprintf(fp, " %s >= %.12g\n", cname, lb);
|
||||
break;
|
||||
case LPX_UP:
|
||||
fprintf(fp, " %s <= %.12g\n", cname, ub);
|
||||
break;
|
||||
case LPX_DB:
|
||||
fprintf(fp, " %.12g <= %s <= %.12g\n", lb, cname, ub);
|
||||
break;
|
||||
case LPX_FX:
|
||||
fprintf(fp, " %s = %.12g\n", cname, lb);
|
||||
break;
|
||||
default:
|
||||
insist(typx != typx);
|
||||
}
|
||||
}
|
||||
/* write the general section */
|
||||
if (lpx_get_class(lp) == LPX_MIP)
|
||||
{ flag = 0;
|
||||
for (j = 1; j <= ncols; j++)
|
||||
{ kind = lpx_get_col_kind(lp, j);
|
||||
if (kind == LPX_CV) continue;
|
||||
insist(kind == LPX_IV);
|
||||
if (!flag)
|
||||
{ fprintf(fp, "\n");
|
||||
fprintf(fp, "Generals\n");
|
||||
flag = 1;
|
||||
}
|
||||
fprintf(fp, " %s\n", col_name(lp, j, cname));
|
||||
}
|
||||
}
|
||||
/* write the end keyword */
|
||||
fprintf(fp, "\n");
|
||||
fprintf(fp, "End\n");
|
||||
/* close the output text file */
|
||||
fflush(fp);
|
||||
if (ferror(fp))
|
||||
{ print("lpx_write_lpt: can't write to `%s' - %s", fname,
|
||||
strerror(errno));
|
||||
goto fail;
|
||||
}
|
||||
ufclose(fp);
|
||||
/* return to the calling program */
|
||||
return 0;
|
||||
fail: /* the operation failed */
|
||||
if (fp != NULL) ufclose(fp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* eof */
|
||||
@@ -0,0 +1,494 @@
|
||||
/* glplpx8d.c */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#include <math.h>
|
||||
#include "glplib.h"
|
||||
#include "glplpx.h"
|
||||
#include "glpmpl.h"
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- lpx_read_model - read LP/MIP model written in GNU MathProg language.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glplpx.h"
|
||||
-- LPX *lpx_read_model(char *model, char *data, char *output);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The routine lpx_read_model reads and translates LP/MIP model written
|
||||
-- in the GNU MathProg modeling language.
|
||||
--
|
||||
-- The character string model specifies name of input text file, which
|
||||
-- contains model section and, optionally, data section. This parameter
|
||||
-- cannot be NULL.
|
||||
--
|
||||
-- The character string data specifies name of input text file, which
|
||||
-- contains data section. If data section follows model section in the
|
||||
-- same file, the data file is not read and a warning is issued. If the
|
||||
-- parameter data is NULL, the data file is not used (that assumes the
|
||||
-- data section follows model section in the same file).
|
||||
--
|
||||
-- The character string output specifies name of output text file, to
|
||||
-- which the output produced by display statements is written. If the
|
||||
-- parameter output is NULL, the display output is sent to stdout via
|
||||
-- the routine print.
|
||||
--
|
||||
-- *Returns*
|
||||
--
|
||||
-- If no errors occurred, the routine returns a pointer to the problem
|
||||
-- object created. Otherwise the routine returns NULL. */
|
||||
|
||||
struct mpl_info
|
||||
{ /* working info used by the routine mpl_mat */
|
||||
MPL *mpl;
|
||||
/* translator database */
|
||||
int i;
|
||||
/* number of current row */
|
||||
int t;
|
||||
/* pointer to current element in current row */
|
||||
int *ndx;
|
||||
/* column indices of elements in current row */
|
||||
double *val;
|
||||
/* numeric values of elements in current row */
|
||||
};
|
||||
|
||||
static double mpl_mat(void *_info, int *i, int *j)
|
||||
{ /* "read" next element of the constraint matrix */
|
||||
struct mpl_info *info = _info;
|
||||
double aij;
|
||||
read: if (info->i == 0 || info->t == 0)
|
||||
{ /* either it is the first call or the current row has been
|
||||
completely read; the first/next row is needed */
|
||||
info->i++;
|
||||
if (info->i > mpl_get_num_rows(info->mpl))
|
||||
{ /* the entire matrix has been completely read */
|
||||
*i = *j = 0; /* end of file */
|
||||
info->i = info->t = 0; /* rewind */
|
||||
return 0.0;
|
||||
}
|
||||
/* obtain the row of the constraint matrix and set the pointer
|
||||
to its tailing element */
|
||||
info->t = mpl_get_mat_row(info->mpl, info->i, info->ndx,
|
||||
info->val);
|
||||
/* the row may be empty, so repeat the check */
|
||||
goto read;
|
||||
}
|
||||
/* obtain the current element */
|
||||
*i = info->i;
|
||||
*j = info->ndx[info->t];
|
||||
aij = info->val[info->t];
|
||||
insist(aij != 0.0);
|
||||
/* move the pointer to preceding element in the row */
|
||||
info->t--;
|
||||
/* bring the element to the calling program */
|
||||
return aij;
|
||||
}
|
||||
|
||||
LPX *lpx_read_model(char *model, char *data, char *output)
|
||||
{ struct mpl_info _info, *info = &_info;
|
||||
LPX *lp = NULL;
|
||||
MPL *mpl;
|
||||
int ret, m, n, i, j, *ndx;
|
||||
double *val;
|
||||
/* create and initialize the translator database */
|
||||
mpl = mpl_initialize();
|
||||
/* read model section and optional data section */
|
||||
ret = mpl_read_model(mpl, model);
|
||||
if (ret == 4) goto done;
|
||||
insist(ret == 1 || ret == 2);
|
||||
/* read data section, if necessary */
|
||||
if (data != NULL)
|
||||
{ if (ret == 1)
|
||||
{ ret = mpl_read_data(mpl, data);
|
||||
if (ret == 4) goto done;
|
||||
insist(ret == 2);
|
||||
}
|
||||
else
|
||||
print("lpx_read_model: data section already read; file `%s'"
|
||||
" ignored", data);
|
||||
}
|
||||
/* generate model */
|
||||
ret = mpl_generate(mpl, output);
|
||||
if (ret == 4) goto done;
|
||||
insist(ret == 3);
|
||||
/* build problem instance */
|
||||
lp = lpx_create_prob();
|
||||
/* set problem name */
|
||||
lpx_set_prob_name(lp, mpl_get_prob_name(mpl));
|
||||
/* build rows (constraints) */
|
||||
m = mpl_get_num_rows(mpl);
|
||||
if (m > 0) lpx_add_rows(lp, m);
|
||||
for (i = 1; i <= m; i++)
|
||||
{ int type;
|
||||
double lb, ub;
|
||||
/* set row name */
|
||||
lpx_set_row_name(lp, i, mpl_get_row_name(mpl, i));
|
||||
/* set row bounds */
|
||||
type = mpl_get_row_bnds(mpl, i, &lb, &ub);
|
||||
switch (type)
|
||||
{ case MPL_FR: type = LPX_FR; break;
|
||||
case MPL_LO: type = LPX_LO; break;
|
||||
case MPL_UP: type = LPX_UP; break;
|
||||
case MPL_DB: type = LPX_DB; break;
|
||||
case MPL_FX: type = LPX_FX; break;
|
||||
default: insist(type != type);
|
||||
}
|
||||
if (type == LPX_DB && fabs(lb - ub) < 1e-9 * (1.0 + fabs(lb)))
|
||||
{ type = LPX_FX;
|
||||
if (fabs(lb) <= fabs(ub)) ub = lb; else lb = ub;
|
||||
}
|
||||
lpx_set_row_bnds(lp, i, type, lb, ub);
|
||||
/* warn about non-zero constant term */
|
||||
if (mpl_get_row_c0(mpl, i) != 0.0)
|
||||
print("lpx_read_model: row %s; constant term %.12g ignored",
|
||||
mpl_get_row_name(mpl, i), mpl_get_row_c0(mpl, i));
|
||||
}
|
||||
/* build columns (variables) */
|
||||
n = mpl_get_num_cols(mpl);
|
||||
if (n > 0) lpx_add_cols(lp, n);
|
||||
for (j = 1; j <= n; j++)
|
||||
{ int kind, type;
|
||||
double lb, ub;
|
||||
/* set column name */
|
||||
lpx_set_col_name(lp, j, mpl_get_col_name(mpl, j));
|
||||
/* set column kind */
|
||||
kind = mpl_get_col_kind(mpl, j);
|
||||
switch (kind)
|
||||
{ case MPL_NUM:
|
||||
break;
|
||||
case MPL_INT:
|
||||
case MPL_BIN:
|
||||
lpx_set_class(lp, LPX_MIP);
|
||||
lpx_set_col_kind(lp, j, LPX_IV);
|
||||
break;
|
||||
default:
|
||||
insist(kind != kind);
|
||||
}
|
||||
/* set column bounds */
|
||||
type = mpl_get_col_bnds(mpl, j, &lb, &ub);
|
||||
switch (type)
|
||||
{ case MPL_FR: type = LPX_FR; break;
|
||||
case MPL_LO: type = LPX_LO; break;
|
||||
case MPL_UP: type = LPX_UP; break;
|
||||
case MPL_DB: type = LPX_DB; break;
|
||||
case MPL_FX: type = LPX_FX; break;
|
||||
default: insist(type != type);
|
||||
}
|
||||
if (kind == MPL_BIN)
|
||||
{ if (type == LPX_FR || type == LPX_UP || lb < 0.0) lb = 0.0;
|
||||
if (type == LPX_FR || type == LPX_LO || ub > 1.0) ub = 1.0;
|
||||
type = LPX_DB;
|
||||
}
|
||||
if (type == LPX_DB && fabs(lb - ub) < 1e-9 * (1.0 + fabs(lb)))
|
||||
{ type = LPX_FX;
|
||||
if (fabs(lb) <= fabs(ub)) ub = lb; else lb = ub;
|
||||
}
|
||||
lpx_set_col_bnds(lp, j, type, lb, ub);
|
||||
}
|
||||
/* allocate working arrays */
|
||||
ndx = ucalloc(1+n, sizeof(int));
|
||||
val = ucalloc(1+n, sizeof(double));
|
||||
/* load the constraint matrix */
|
||||
info->mpl = mpl;
|
||||
info->i = info->t = 0;
|
||||
info->ndx = ndx;
|
||||
info->val = val;
|
||||
lpx_load_mat(lp, info, mpl_mat);
|
||||
/* build objective function (the first objective is used) */
|
||||
for (i = 1; i <= m; i++)
|
||||
{ int kind;
|
||||
kind = mpl_get_row_kind(mpl, i);
|
||||
if (kind == MPL_MIN || kind == MPL_MAX)
|
||||
{ int len, t;
|
||||
/* set objective name */
|
||||
lpx_set_obj_name(lp, mpl_get_row_name(mpl, i));
|
||||
/* set objective coefficients */
|
||||
len = mpl_get_mat_row(mpl, i, ndx, val);
|
||||
for (t = 1; t <= len; t++)
|
||||
lpx_set_col_coef(lp, ndx[t], val[t]);
|
||||
/* set constant term */
|
||||
lpx_set_obj_c0(lp, mpl_get_row_c0(mpl, i));
|
||||
/* set optimization direction */
|
||||
lpx_set_obj_dir(lp, kind == MPL_MIN ? LPX_MIN : LPX_MAX);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* free working arrays */
|
||||
ufree(ndx);
|
||||
ufree(val);
|
||||
done: /* free resources used by the model translator */
|
||||
mpl_terminate(mpl);
|
||||
return lp;
|
||||
}
|
||||
|
||||
/* eof */
|
||||
/* glplpx8d.c */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#include <math.h>
|
||||
#include "glplib.h"
|
||||
#include "glplpx.h"
|
||||
#include "glpmpl.h"
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- lpx_read_model - read LP/MIP model written in GNU MathProg language.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glplpx.h"
|
||||
-- LPX *lpx_read_model(char *model, char *data, char *output);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The routine lpx_read_model reads and translates LP/MIP model written
|
||||
-- in the GNU MathProg modeling language.
|
||||
--
|
||||
-- The character string model specifies name of input text file, which
|
||||
-- contains model section and, optionally, data section. This parameter
|
||||
-- cannot be NULL.
|
||||
--
|
||||
-- The character string data specifies name of input text file, which
|
||||
-- contains data section. If data section follows model section in the
|
||||
-- same file, the data file is not read and a warning is issued. If the
|
||||
-- parameter data is NULL, the data file is not used (that assumes the
|
||||
-- data section follows model section in the same file).
|
||||
--
|
||||
-- The character string output specifies name of output text file, to
|
||||
-- which the output produced by display statements is written. If the
|
||||
-- parameter output is NULL, the display output is sent to stdout via
|
||||
-- the routine print.
|
||||
--
|
||||
-- *Returns*
|
||||
--
|
||||
-- If no errors occurred, the routine returns a pointer to the problem
|
||||
-- object created. Otherwise the routine returns NULL. */
|
||||
|
||||
struct mpl_info
|
||||
{ /* working info used by the routine mpl_mat */
|
||||
MPL *mpl;
|
||||
/* translator database */
|
||||
int i;
|
||||
/* number of current row */
|
||||
int t;
|
||||
/* pointer to current element in current row */
|
||||
int *ndx;
|
||||
/* column indices of elements in current row */
|
||||
double *val;
|
||||
/* numeric values of elements in current row */
|
||||
};
|
||||
|
||||
static double mpl_mat(void *_info, int *i, int *j)
|
||||
{ /* "read" next element of the constraint matrix */
|
||||
struct mpl_info *info = _info;
|
||||
double aij;
|
||||
read: if (info->i == 0 || info->t == 0)
|
||||
{ /* either it is the first call or the current row has been
|
||||
completely read; the first/next row is needed */
|
||||
info->i++;
|
||||
if (info->i > mpl_get_num_rows(info->mpl))
|
||||
{ /* the entire matrix has been completely read */
|
||||
*i = *j = 0; /* end of file */
|
||||
info->i = info->t = 0; /* rewind */
|
||||
return 0.0;
|
||||
}
|
||||
/* obtain the row of the constraint matrix and set the pointer
|
||||
to its tailing element */
|
||||
info->t = mpl_get_mat_row(info->mpl, info->i, info->ndx,
|
||||
info->val);
|
||||
/* the row may be empty, so repeat the check */
|
||||
goto read;
|
||||
}
|
||||
/* obtain the current element */
|
||||
*i = info->i;
|
||||
*j = info->ndx[info->t];
|
||||
aij = info->val[info->t];
|
||||
insist(aij != 0.0);
|
||||
/* move the pointer to preceding element in the row */
|
||||
info->t--;
|
||||
/* bring the element to the calling program */
|
||||
return aij;
|
||||
}
|
||||
|
||||
LPX *lpx_read_model(char *model, char *data, char *output)
|
||||
{ struct mpl_info _info, *info = &_info;
|
||||
LPX *lp = NULL;
|
||||
MPL *mpl;
|
||||
int ret, m, n, i, j, *ndx;
|
||||
double *val;
|
||||
/* create and initialize the translator database */
|
||||
mpl = mpl_initialize();
|
||||
/* read model section and optional data section */
|
||||
ret = mpl_read_model(mpl, model);
|
||||
if (ret == 4) goto done;
|
||||
insist(ret == 1 || ret == 2);
|
||||
/* read data section, if necessary */
|
||||
if (data != NULL)
|
||||
{ if (ret == 1)
|
||||
{ ret = mpl_read_data(mpl, data);
|
||||
if (ret == 4) goto done;
|
||||
insist(ret == 2);
|
||||
}
|
||||
else
|
||||
print("lpx_read_model: data section already read; file `%s'"
|
||||
" ignored", data);
|
||||
}
|
||||
/* generate model */
|
||||
ret = mpl_generate(mpl, output);
|
||||
if (ret == 4) goto done;
|
||||
insist(ret == 3);
|
||||
/* build problem instance */
|
||||
lp = lpx_create_prob();
|
||||
/* set problem name */
|
||||
lpx_set_prob_name(lp, mpl_get_prob_name(mpl));
|
||||
/* build rows (constraints) */
|
||||
m = mpl_get_num_rows(mpl);
|
||||
if (m > 0) lpx_add_rows(lp, m);
|
||||
for (i = 1; i <= m; i++)
|
||||
{ int type;
|
||||
double lb, ub;
|
||||
/* set row name */
|
||||
lpx_set_row_name(lp, i, mpl_get_row_name(mpl, i));
|
||||
/* set row bounds */
|
||||
type = mpl_get_row_bnds(mpl, i, &lb, &ub);
|
||||
switch (type)
|
||||
{ case MPL_FR: type = LPX_FR; break;
|
||||
case MPL_LO: type = LPX_LO; break;
|
||||
case MPL_UP: type = LPX_UP; break;
|
||||
case MPL_DB: type = LPX_DB; break;
|
||||
case MPL_FX: type = LPX_FX; break;
|
||||
default: insist(type != type);
|
||||
}
|
||||
if (type == LPX_DB && fabs(lb - ub) < 1e-9 * (1.0 + fabs(lb)))
|
||||
{ type = LPX_FX;
|
||||
if (fabs(lb) <= fabs(ub)) ub = lb; else lb = ub;
|
||||
}
|
||||
lpx_set_row_bnds(lp, i, type, lb, ub);
|
||||
/* warn about non-zero constant term */
|
||||
if (mpl_get_row_c0(mpl, i) != 0.0)
|
||||
print("lpx_read_model: row %s; constant term %.12g ignored",
|
||||
mpl_get_row_name(mpl, i), mpl_get_row_c0(mpl, i));
|
||||
}
|
||||
/* build columns (variables) */
|
||||
n = mpl_get_num_cols(mpl);
|
||||
if (n > 0) lpx_add_cols(lp, n);
|
||||
for (j = 1; j <= n; j++)
|
||||
{ int kind, type;
|
||||
double lb, ub;
|
||||
/* set column name */
|
||||
lpx_set_col_name(lp, j, mpl_get_col_name(mpl, j));
|
||||
/* set column kind */
|
||||
kind = mpl_get_col_kind(mpl, j);
|
||||
switch (kind)
|
||||
{ case MPL_NUM:
|
||||
break;
|
||||
case MPL_INT:
|
||||
case MPL_BIN:
|
||||
lpx_set_class(lp, LPX_MIP);
|
||||
lpx_set_col_kind(lp, j, LPX_IV);
|
||||
break;
|
||||
default:
|
||||
insist(kind != kind);
|
||||
}
|
||||
/* set column bounds */
|
||||
type = mpl_get_col_bnds(mpl, j, &lb, &ub);
|
||||
switch (type)
|
||||
{ case MPL_FR: type = LPX_FR; break;
|
||||
case MPL_LO: type = LPX_LO; break;
|
||||
case MPL_UP: type = LPX_UP; break;
|
||||
case MPL_DB: type = LPX_DB; break;
|
||||
case MPL_FX: type = LPX_FX; break;
|
||||
default: insist(type != type);
|
||||
}
|
||||
if (kind == MPL_BIN)
|
||||
{ if (type == LPX_FR || type == LPX_UP || lb < 0.0) lb = 0.0;
|
||||
if (type == LPX_FR || type == LPX_LO || ub > 1.0) ub = 1.0;
|
||||
type = LPX_DB;
|
||||
}
|
||||
if (type == LPX_DB && fabs(lb - ub) < 1e-9 * (1.0 + fabs(lb)))
|
||||
{ type = LPX_FX;
|
||||
if (fabs(lb) <= fabs(ub)) ub = lb; else lb = ub;
|
||||
}
|
||||
lpx_set_col_bnds(lp, j, type, lb, ub);
|
||||
}
|
||||
/* allocate working arrays */
|
||||
ndx = ucalloc(1+n, sizeof(int));
|
||||
val = ucalloc(1+n, sizeof(double));
|
||||
/* load the constraint matrix */
|
||||
info->mpl = mpl;
|
||||
info->i = info->t = 0;
|
||||
info->ndx = ndx;
|
||||
info->val = val;
|
||||
lpx_load_mat(lp, info, mpl_mat);
|
||||
/* build objective function (the first objective is used) */
|
||||
for (i = 1; i <= m; i++)
|
||||
{ int kind;
|
||||
kind = mpl_get_row_kind(mpl, i);
|
||||
if (kind == MPL_MIN || kind == MPL_MAX)
|
||||
{ int len, t;
|
||||
/* set objective name */
|
||||
lpx_set_obj_name(lp, mpl_get_row_name(mpl, i));
|
||||
/* set objective coefficients */
|
||||
len = mpl_get_mat_row(mpl, i, ndx, val);
|
||||
for (t = 1; t <= len; t++)
|
||||
lpx_set_col_coef(lp, ndx[t], val[t]);
|
||||
/* set constant term */
|
||||
lpx_set_obj_c0(lp, mpl_get_row_c0(mpl, i));
|
||||
/* set optimization direction */
|
||||
lpx_set_obj_dir(lp, kind == MPL_MIN ? LPX_MIN : LPX_MAX);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* free working arrays */
|
||||
ufree(ndx);
|
||||
ufree(val);
|
||||
done: /* free resources used by the model translator */
|
||||
mpl_terminate(mpl);
|
||||
return lp;
|
||||
}
|
||||
|
||||
/* eof */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,708 @@
|
||||
/* glpluf.h */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _GLPLUF_H
|
||||
#define _GLPLUF_H
|
||||
|
||||
#define luf_create glp_luf_create
|
||||
#define luf_defrag_sva glp_luf_defrag_sva
|
||||
#define luf_enlarge_row glp_luf_enlarge_row
|
||||
#define luf_enlarge_col glp_luf_enlarge_col
|
||||
#define luf_alloc_wa glp_luf_alloc_wa
|
||||
#define luf_free_wa glp_luf_free_wa
|
||||
#define luf_decomp glp_luf_decomp
|
||||
#define luf_f_solve glp_luf_f_solve
|
||||
#define luf_v_solve glp_luf_v_solve
|
||||
#define luf_solve glp_luf_solve
|
||||
#define luf_delete glp_luf_delete
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- The structure LUF defines LU-factorization of a square matrix A,
|
||||
-- which is the following quartet:
|
||||
--
|
||||
-- [A] = (F, V, P, Q), (1)
|
||||
--
|
||||
-- where F and V are such matrices that
|
||||
--
|
||||
-- A = F * V, (2)
|
||||
--
|
||||
-- and P and Q are such permutation matrices that the matrix
|
||||
--
|
||||
-- L = P * F * inv(P) (3)
|
||||
--
|
||||
-- is lower triangular with unity diagonal, and the matrix
|
||||
--
|
||||
-- U = P * V * Q (4)
|
||||
--
|
||||
-- is upper triangular. All the matrices have the order n.
|
||||
--
|
||||
-- The matrices F and V are stored in row/column-wise sparse format as
|
||||
-- row and column linked lists of non-zero elements. Unity elements on
|
||||
-- the main diagonal of the matrix F are not stored. Pivot elements of
|
||||
-- the matrix V (that correspond to diagonal elements of the matrix U)
|
||||
-- are also missing from the row and column lists and stored separately
|
||||
-- in an ordinary array.
|
||||
--
|
||||
-- The permutation matrices P and Q are stored as ordinary arrays using
|
||||
-- both row- and column-like formats.
|
||||
--
|
||||
-- The matrices L and U being completely defined by the matrices F, V,
|
||||
-- P, and Q are not stored explicitly.
|
||||
--
|
||||
-- It can easily be shown that the factorization (1)-(3) is a version of
|
||||
-- LU-factorization. Indeed, from (3) and (4) it follows that
|
||||
--
|
||||
-- F = inv(P) * L * P,
|
||||
--
|
||||
-- V = inv(P) * U * inv(Q),
|
||||
--
|
||||
-- and substitution into (2) gives
|
||||
--
|
||||
-- A = F * V = inv(P) * L * U * inv(Q).
|
||||
--
|
||||
-- For more details see the program documentation. */
|
||||
|
||||
typedef struct LUF LUF;
|
||||
typedef struct LUF_WA LUF_WA;
|
||||
|
||||
struct LUF
|
||||
{ /* LU-factorization of a square matrix */
|
||||
int n;
|
||||
/* order of the matrices A, F, V, P, Q */
|
||||
int valid;
|
||||
/* if this flag is not set, the factorization is invalid */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* matrix F in row-wise format */
|
||||
int *fr_ptr; /* int fr_ptr[1+n]; */
|
||||
/* fr_ptr[0] is not used;
|
||||
fr_ptr[i], i = 1, ..., n, is a pointer to the first element of
|
||||
the i-th row in the sparse vector area */
|
||||
int *fr_len; /* int fr_len[1+n]; */
|
||||
/* fr_len[0] is not used;
|
||||
fr_len[i], i = 1, ..., n, is number of elements in the i-th
|
||||
row (except unity diagonal element) */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* matrix F in column-wise format */
|
||||
int *fc_ptr; /* int fc_ptr[1+n]; */
|
||||
/* fc_ptr[0] is not used;
|
||||
fc_ptr[j], j = 1, ..., n, is a pointer to the first element of
|
||||
the j-th column in the sparse vector area */
|
||||
int *fc_len; /* int fc_len[1+n]; */
|
||||
/* fc_len[0] is not used;
|
||||
fc_len[j], j = 1, ..., n, is number of elements in the j-th
|
||||
column (except unity diagonal element) */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* matrix V in row-wise format */
|
||||
int *vr_ptr; /* int vr_ptr[1+n]; */
|
||||
/* vr_ptr[0] is not used;
|
||||
vr_ptr[i], i = 1, ..., n, is a pointer to the first element of
|
||||
the i-th row in the sparse vector area */
|
||||
int *vr_len; /* int vr_len[1+n]; */
|
||||
/* vr_len[0] is not used;
|
||||
vr_len[i], i = 1, ..., n, is number of elements in the i-th
|
||||
row (except pivot element) */
|
||||
int *vr_cap; /* int vr_cap[1+n]; */
|
||||
/* vr_cap[0] is not used;
|
||||
vr_cap[i], i = 1, ..., n, is capacity of the i-th row, i.e.
|
||||
maximal number of elements, which can be stored there without
|
||||
relocating the row, vr_cap[i] >= vr_len[i] */
|
||||
double *vr_piv; /* double vr_piv[1+n]; */
|
||||
/* vr_piv[0] is not used;
|
||||
vr_piv[p], p = 1, ..., n, is the pivot element v[p,q], which
|
||||
corresponds to a diagonal element of the matrix U = P*V*Q */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* matrix V in column-wise format */
|
||||
int *vc_ptr; /* int vc_ptr[1+n]; */
|
||||
/* vc_ptr[0] is not used;
|
||||
vc_ptr[j], j = 1, ..., n, is a pointer to the first element of
|
||||
the j-th column in the sparse vector area */
|
||||
int *vc_len; /* int vc_len[1+n]; */
|
||||
/* vc_len[0] is not used;
|
||||
vc_len[j], j = 1, ..., n, is number of elements in the j-th
|
||||
column (except pivot element) */
|
||||
int *vc_cap; /* int vc_cap[1+n]; */
|
||||
/* vc_cap[0] is not used;
|
||||
vc_cap[j], j = 1, ..., n, is capacity of the j-th column, i.e.
|
||||
maximal number of elements, which can be stored there without
|
||||
relocating the column, vc_cap[j] >= vc_len[j] */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* matrix P */
|
||||
int *pp_row; /* int pp_row[1+n]; */
|
||||
/* pp_row[0] is not used; pp_row[i] = j means that p[i,j] = 1 */
|
||||
int *pp_col; /* int pp_col[1+n]; */
|
||||
/* pp_col[0] is not used; pp_col[j] = i means that p[i,j] = 1 */
|
||||
/* if i-th row or column of the matrix F corresponds to i'-th row
|
||||
or column of the matrix L = P*F*inv(P), or if i-th row of the
|
||||
matrix V corresponds to i'-th row of the matrix U = P*V*Q, then
|
||||
pp_row[i'] = i and pp_col[i] = i' */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* matrix Q */
|
||||
int *qq_row; /* int qq_row[1+n]; */
|
||||
/* qq_row[0] is not used; qq_row[i] = j means that q[i,j] = 1 */
|
||||
int *qq_col; /* int qq_col[1+n]; */
|
||||
/* qq_col[0] is not used; qq_col[j] = i means that q[i,j] = 1 */
|
||||
/* if j-th column of the matrix V corresponds to j'-th column of
|
||||
the matrix U = P*V*Q, then qq_row[j] = j' and qq_col[j'] = j */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* sparse vector area (SVA) is a set of locations intended to
|
||||
store sparse vectors that represent rows and columns of the
|
||||
matrices F and V; each location is the doublet (ndx, val),
|
||||
where ndx is an index and val is a numerical value of a sparse
|
||||
vector element; in the whole each sparse vector is a set of
|
||||
adjacent locations defined by a pointer to the first element
|
||||
and number of elements; these pointer and number are stored in
|
||||
the corresponding matrix data structure (see above); the left
|
||||
part of SVA is used to store rows and columns of the matrix V,
|
||||
the right part is used to store rows and columns of the matrix
|
||||
F; between the left and right parts there is the middle part,
|
||||
locations of which are free */
|
||||
int sv_size;
|
||||
/* total size of the sparse vector area, in locations; locations
|
||||
are numbered by integers 1, 2, ..., sv_size, and location with
|
||||
the number 0 is not used; if it is necessary, the size of SVA
|
||||
is automatically increased */
|
||||
int sv_beg, sv_end;
|
||||
/* SVA partitioning pointers:
|
||||
locations 1, ..., sv_beg-1 belong to the left part;
|
||||
locations sv_beg, ..., sv_end-1 belong to the middle part;
|
||||
locations sv_end, ..., sv_size belong to the right part;
|
||||
number of free locations, i.e. locations that belong to the
|
||||
middle part, is (sv_end - sv_beg) */
|
||||
int *sv_ndx; /* int sv_ndx[1+sv_size]; */
|
||||
/* sv_ndx[0] is not used;
|
||||
sv_ndx[k], 1 <= k <= sv_size, is the index field of the k-th
|
||||
location */
|
||||
double *sv_val; /* double sv_val[1+sv_size]; */
|
||||
/* sv_val[0] is not used;
|
||||
sv_val[k], 1 <= k <= sv_size, is the value field of the k-th
|
||||
location */
|
||||
/* in order to efficiently defragment the left part of SVA there
|
||||
is a double linked list of rows and columns of the matrix V,
|
||||
where rows have numbers 1, ..., n, and columns have numbers
|
||||
n+1, ..., n+n, due to that each row and column can be uniquely
|
||||
identified by one integer; in this list rows and columns are
|
||||
ordered by ascending their pointers vr_ptr[i] and vc_ptr[j] */
|
||||
int sv_head;
|
||||
/* the number of the leftmost row/column */
|
||||
int sv_tail;
|
||||
/* the number of the rightmost row/column */
|
||||
int *sv_prev; /* int sv_prev[1+n+n]; */
|
||||
/* sv_prev[k], k = 1, ..., n+n, is the number of a row/column,
|
||||
which precedes the k-th row/column */
|
||||
int *sv_next; /* int sv_next[1+n+n]; */
|
||||
/* sv_next[k], k = 1, ..., n+n, is the number of a row/column,
|
||||
which succedes the k-th row/column */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* working arrays */
|
||||
int *flag; /* int flag[1+n]; */
|
||||
/* integer working array */
|
||||
double *work; /* double work[1+n]; */
|
||||
/* floating-point working array */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* control parameters */
|
||||
int new_sva;
|
||||
/* new required size of the sparse vector area, in locations; set
|
||||
automatically by the factorizing routine */
|
||||
double piv_tol;
|
||||
/* threshold pivoting tolerance, 0 < piv_tol < 1; element v[i,j]
|
||||
of the active submatrix fits to be pivot if it satisfies to the
|
||||
stability condition |v[i,j]| >= piv_tol * max|v[i,*]|, i.e. if
|
||||
this element is not very small (in absolute value) among other
|
||||
elements in the same row; decreasing this parameter involves
|
||||
better sparsity at the expense of numerical accuracy and vice
|
||||
versa */
|
||||
int piv_lim;
|
||||
/* maximal allowable number of pivot candidates to be considered;
|
||||
if piv_lim pivot candidates have been considered, the pivoting
|
||||
routine terminates the search with the best candidate found */
|
||||
int suhl;
|
||||
/* if this flag is set, the pivoting routine applies a heuristic
|
||||
rule proposed by Uwe Suhl: if a column of the active submatrix
|
||||
has no eligible pivot candidates (i.e. all its elements don't
|
||||
satisfy to the stability condition), the routine excludes such
|
||||
column from the futher consideration until it becomes a column
|
||||
singleton; in many cases this reduces a time needed for pivot
|
||||
searching */
|
||||
double eps_tol;
|
||||
/* epsilon tolerance; each element of the matrix V with absolute
|
||||
value less than eps_tol is replaced by exact zero */
|
||||
double max_gro;
|
||||
/* maximal allowable growth of elements of the matrix V during
|
||||
all the factorization process; if on some elimination step the
|
||||
ratio big_v / max_a (see below) becomes greater than max_gro,
|
||||
the matrix A is considered as ill-conditioned (it is assumed
|
||||
that the tolerance piv_tol has an adequate value) */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* some statistics */
|
||||
int nnz_a;
|
||||
/* number of non-zeros in the matrix A */
|
||||
int nnz_f;
|
||||
/* number of non-zeros in the matrix F (except diagonal elements,
|
||||
which are always equal to one and therefore not stored) */
|
||||
int nnz_v;
|
||||
/* number of non-zeros in the matrix V (except pivot elements,
|
||||
which correspond to diagonal elements of the matrix U = P*V*Q
|
||||
and which are stored separately in the array vr_piv) */
|
||||
double max_a;
|
||||
/* largest of absolute values of elements of the matrix A */
|
||||
double big_v;
|
||||
/* estimated largest of absolute values of elements appeared in
|
||||
the active submatrix during all the factorization process */
|
||||
int rank;
|
||||
/* estimated rank of the matrix A */
|
||||
};
|
||||
|
||||
struct LUF_WA
|
||||
{ /* working area (used only during factorization) */
|
||||
double *rs_max; /* double rs_max[1+n]; */
|
||||
/* rs_max[0] is not used; rs_max[i], 1 <= i <= n, is used only if
|
||||
the i-th row of the matrix V belongs to the active submatrix
|
||||
and is the largest of absolute values of elements in this row;
|
||||
rs_max[i] < 0.0 means that the largest value is not known yet
|
||||
and should be determined by the pivoting routine */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* in order to efficiently implement Markowitz strategy and Duff
|
||||
search technique there are two families {R[0], R[1], ..., R[n]}
|
||||
and {C[0], C[1], ..., C[n]}; member R[k] is a set of active
|
||||
rows of the matrix V, which have k non-zeros; similarly, member
|
||||
C[k] is a set of active columns of the matrix V, which have k
|
||||
non-zeros (in the active submatrix); each set R[k] and C[k] is
|
||||
implemented as a separate doubly linked list */
|
||||
int *rs_head; /* int rs_head[1+n]; */
|
||||
/* rs_head[k], 0 <= k <= n, is number of the first active row,
|
||||
which has k non-zeros */
|
||||
int *rs_prev; /* int rs_prev[1+n]; */
|
||||
/* rs_prev[0] is not used; rs_prev[i], 1 <= i <= n, is number of
|
||||
the previous active row, which has the same number of non-zeros
|
||||
as the i-th row */
|
||||
int *rs_next; /* int rs_next[1+n]; */
|
||||
/* rs_next[0] is not used; rs_next[i], 1 <= i <= n, is number of
|
||||
the next active row, which has the same number of non-zeros as
|
||||
the i-th row */
|
||||
int *cs_head; /* int cs_head[1+n]; */
|
||||
/* cs_head[k], 0 <= k <= n, is number of the first active column,
|
||||
which has k non-zeros (in the active submatrix) */
|
||||
int *cs_prev; /* int cs_prev[1+n]; */
|
||||
/* cs_prev[0] is not used; cs_prev[j], 1 <= j <= n, is number of
|
||||
the previous active column, which has the same number of
|
||||
non-zeros (in the active submatrix) as the j-th column */
|
||||
int *cs_next; /* int cs_next[1+n]; */
|
||||
/* cs_next[0] is not used; cs_next[j], 1 <= j <= n, is number of
|
||||
the next active column, which has the same number of non-zeros
|
||||
(in the active submatrix) as the j-th column */
|
||||
};
|
||||
|
||||
LUF *luf_create(int n, int sv_size);
|
||||
/* create LU-factorization */
|
||||
|
||||
void luf_defrag_sva(LUF *luf);
|
||||
/* defragment the sparse vector area */
|
||||
|
||||
int luf_enlarge_row(LUF *luf, int i, int cap);
|
||||
/* enlarge row capacity */
|
||||
|
||||
int luf_enlarge_col(LUF *luf, int j, int cap);
|
||||
/* enlarge column capacity */
|
||||
|
||||
LUF_WA *luf_alloc_wa(LUF *luf);
|
||||
/* pre-allocate working area */
|
||||
|
||||
void luf_free_wa(LUF_WA *wa);
|
||||
/* free working area */
|
||||
|
||||
int luf_decomp(LUF *luf,
|
||||
void *info, int (*col)(void *info, int j, int rn[], double aj[]),
|
||||
LUF_WA *wa);
|
||||
/* compute LU-factorization */
|
||||
|
||||
void luf_f_solve(LUF *luf, int tr, double x[]);
|
||||
/* solve system F*x = b or F'*x = b */
|
||||
|
||||
void luf_v_solve(LUF *luf, int tr, double x[]);
|
||||
/* solve system V*x = b or V'*x = b */
|
||||
|
||||
void luf_solve(LUF *luf, int tr, double x[]);
|
||||
/* solve system A*x = b or A'*x = b */
|
||||
|
||||
void luf_delete(LUF *luf);
|
||||
/* delete LU-factorization */
|
||||
|
||||
#endif
|
||||
|
||||
/* eof */
|
||||
/* glpluf.h */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _GLPLUF_H
|
||||
#define _GLPLUF_H
|
||||
|
||||
#define luf_create glp_luf_create
|
||||
#define luf_defrag_sva glp_luf_defrag_sva
|
||||
#define luf_enlarge_row glp_luf_enlarge_row
|
||||
#define luf_enlarge_col glp_luf_enlarge_col
|
||||
#define luf_alloc_wa glp_luf_alloc_wa
|
||||
#define luf_free_wa glp_luf_free_wa
|
||||
#define luf_decomp glp_luf_decomp
|
||||
#define luf_f_solve glp_luf_f_solve
|
||||
#define luf_v_solve glp_luf_v_solve
|
||||
#define luf_solve glp_luf_solve
|
||||
#define luf_delete glp_luf_delete
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- The structure LUF defines LU-factorization of a square matrix A,
|
||||
-- which is the following quartet:
|
||||
--
|
||||
-- [A] = (F, V, P, Q), (1)
|
||||
--
|
||||
-- where F and V are such matrices that
|
||||
--
|
||||
-- A = F * V, (2)
|
||||
--
|
||||
-- and P and Q are such permutation matrices that the matrix
|
||||
--
|
||||
-- L = P * F * inv(P) (3)
|
||||
--
|
||||
-- is lower triangular with unity diagonal, and the matrix
|
||||
--
|
||||
-- U = P * V * Q (4)
|
||||
--
|
||||
-- is upper triangular. All the matrices have the order n.
|
||||
--
|
||||
-- The matrices F and V are stored in row/column-wise sparse format as
|
||||
-- row and column linked lists of non-zero elements. Unity elements on
|
||||
-- the main diagonal of the matrix F are not stored. Pivot elements of
|
||||
-- the matrix V (that correspond to diagonal elements of the matrix U)
|
||||
-- are also missing from the row and column lists and stored separately
|
||||
-- in an ordinary array.
|
||||
--
|
||||
-- The permutation matrices P and Q are stored as ordinary arrays using
|
||||
-- both row- and column-like formats.
|
||||
--
|
||||
-- The matrices L and U being completely defined by the matrices F, V,
|
||||
-- P, and Q are not stored explicitly.
|
||||
--
|
||||
-- It can easily be shown that the factorization (1)-(3) is a version of
|
||||
-- LU-factorization. Indeed, from (3) and (4) it follows that
|
||||
--
|
||||
-- F = inv(P) * L * P,
|
||||
--
|
||||
-- V = inv(P) * U * inv(Q),
|
||||
--
|
||||
-- and substitution into (2) gives
|
||||
--
|
||||
-- A = F * V = inv(P) * L * U * inv(Q).
|
||||
--
|
||||
-- For more details see the program documentation. */
|
||||
|
||||
typedef struct LUF LUF;
|
||||
typedef struct LUF_WA LUF_WA;
|
||||
|
||||
struct LUF
|
||||
{ /* LU-factorization of a square matrix */
|
||||
int n;
|
||||
/* order of the matrices A, F, V, P, Q */
|
||||
int valid;
|
||||
/* if this flag is not set, the factorization is invalid */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* matrix F in row-wise format */
|
||||
int *fr_ptr; /* int fr_ptr[1+n]; */
|
||||
/* fr_ptr[0] is not used;
|
||||
fr_ptr[i], i = 1, ..., n, is a pointer to the first element of
|
||||
the i-th row in the sparse vector area */
|
||||
int *fr_len; /* int fr_len[1+n]; */
|
||||
/* fr_len[0] is not used;
|
||||
fr_len[i], i = 1, ..., n, is number of elements in the i-th
|
||||
row (except unity diagonal element) */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* matrix F in column-wise format */
|
||||
int *fc_ptr; /* int fc_ptr[1+n]; */
|
||||
/* fc_ptr[0] is not used;
|
||||
fc_ptr[j], j = 1, ..., n, is a pointer to the first element of
|
||||
the j-th column in the sparse vector area */
|
||||
int *fc_len; /* int fc_len[1+n]; */
|
||||
/* fc_len[0] is not used;
|
||||
fc_len[j], j = 1, ..., n, is number of elements in the j-th
|
||||
column (except unity diagonal element) */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* matrix V in row-wise format */
|
||||
int *vr_ptr; /* int vr_ptr[1+n]; */
|
||||
/* vr_ptr[0] is not used;
|
||||
vr_ptr[i], i = 1, ..., n, is a pointer to the first element of
|
||||
the i-th row in the sparse vector area */
|
||||
int *vr_len; /* int vr_len[1+n]; */
|
||||
/* vr_len[0] is not used;
|
||||
vr_len[i], i = 1, ..., n, is number of elements in the i-th
|
||||
row (except pivot element) */
|
||||
int *vr_cap; /* int vr_cap[1+n]; */
|
||||
/* vr_cap[0] is not used;
|
||||
vr_cap[i], i = 1, ..., n, is capacity of the i-th row, i.e.
|
||||
maximal number of elements, which can be stored there without
|
||||
relocating the row, vr_cap[i] >= vr_len[i] */
|
||||
double *vr_piv; /* double vr_piv[1+n]; */
|
||||
/* vr_piv[0] is not used;
|
||||
vr_piv[p], p = 1, ..., n, is the pivot element v[p,q], which
|
||||
corresponds to a diagonal element of the matrix U = P*V*Q */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* matrix V in column-wise format */
|
||||
int *vc_ptr; /* int vc_ptr[1+n]; */
|
||||
/* vc_ptr[0] is not used;
|
||||
vc_ptr[j], j = 1, ..., n, is a pointer to the first element of
|
||||
the j-th column in the sparse vector area */
|
||||
int *vc_len; /* int vc_len[1+n]; */
|
||||
/* vc_len[0] is not used;
|
||||
vc_len[j], j = 1, ..., n, is number of elements in the j-th
|
||||
column (except pivot element) */
|
||||
int *vc_cap; /* int vc_cap[1+n]; */
|
||||
/* vc_cap[0] is not used;
|
||||
vc_cap[j], j = 1, ..., n, is capacity of the j-th column, i.e.
|
||||
maximal number of elements, which can be stored there without
|
||||
relocating the column, vc_cap[j] >= vc_len[j] */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* matrix P */
|
||||
int *pp_row; /* int pp_row[1+n]; */
|
||||
/* pp_row[0] is not used; pp_row[i] = j means that p[i,j] = 1 */
|
||||
int *pp_col; /* int pp_col[1+n]; */
|
||||
/* pp_col[0] is not used; pp_col[j] = i means that p[i,j] = 1 */
|
||||
/* if i-th row or column of the matrix F corresponds to i'-th row
|
||||
or column of the matrix L = P*F*inv(P), or if i-th row of the
|
||||
matrix V corresponds to i'-th row of the matrix U = P*V*Q, then
|
||||
pp_row[i'] = i and pp_col[i] = i' */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* matrix Q */
|
||||
int *qq_row; /* int qq_row[1+n]; */
|
||||
/* qq_row[0] is not used; qq_row[i] = j means that q[i,j] = 1 */
|
||||
int *qq_col; /* int qq_col[1+n]; */
|
||||
/* qq_col[0] is not used; qq_col[j] = i means that q[i,j] = 1 */
|
||||
/* if j-th column of the matrix V corresponds to j'-th column of
|
||||
the matrix U = P*V*Q, then qq_row[j] = j' and qq_col[j'] = j */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* sparse vector area (SVA) is a set of locations intended to
|
||||
store sparse vectors that represent rows and columns of the
|
||||
matrices F and V; each location is the doublet (ndx, val),
|
||||
where ndx is an index and val is a numerical value of a sparse
|
||||
vector element; in the whole each sparse vector is a set of
|
||||
adjacent locations defined by a pointer to the first element
|
||||
and number of elements; these pointer and number are stored in
|
||||
the corresponding matrix data structure (see above); the left
|
||||
part of SVA is used to store rows and columns of the matrix V,
|
||||
the right part is used to store rows and columns of the matrix
|
||||
F; between the left and right parts there is the middle part,
|
||||
locations of which are free */
|
||||
int sv_size;
|
||||
/* total size of the sparse vector area, in locations; locations
|
||||
are numbered by integers 1, 2, ..., sv_size, and location with
|
||||
the number 0 is not used; if it is necessary, the size of SVA
|
||||
is automatically increased */
|
||||
int sv_beg, sv_end;
|
||||
/* SVA partitioning pointers:
|
||||
locations 1, ..., sv_beg-1 belong to the left part;
|
||||
locations sv_beg, ..., sv_end-1 belong to the middle part;
|
||||
locations sv_end, ..., sv_size belong to the right part;
|
||||
number of free locations, i.e. locations that belong to the
|
||||
middle part, is (sv_end - sv_beg) */
|
||||
int *sv_ndx; /* int sv_ndx[1+sv_size]; */
|
||||
/* sv_ndx[0] is not used;
|
||||
sv_ndx[k], 1 <= k <= sv_size, is the index field of the k-th
|
||||
location */
|
||||
double *sv_val; /* double sv_val[1+sv_size]; */
|
||||
/* sv_val[0] is not used;
|
||||
sv_val[k], 1 <= k <= sv_size, is the value field of the k-th
|
||||
location */
|
||||
/* in order to efficiently defragment the left part of SVA there
|
||||
is a double linked list of rows and columns of the matrix V,
|
||||
where rows have numbers 1, ..., n, and columns have numbers
|
||||
n+1, ..., n+n, due to that each row and column can be uniquely
|
||||
identified by one integer; in this list rows and columns are
|
||||
ordered by ascending their pointers vr_ptr[i] and vc_ptr[j] */
|
||||
int sv_head;
|
||||
/* the number of the leftmost row/column */
|
||||
int sv_tail;
|
||||
/* the number of the rightmost row/column */
|
||||
int *sv_prev; /* int sv_prev[1+n+n]; */
|
||||
/* sv_prev[k], k = 1, ..., n+n, is the number of a row/column,
|
||||
which precedes the k-th row/column */
|
||||
int *sv_next; /* int sv_next[1+n+n]; */
|
||||
/* sv_next[k], k = 1, ..., n+n, is the number of a row/column,
|
||||
which succedes the k-th row/column */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* working arrays */
|
||||
int *flag; /* int flag[1+n]; */
|
||||
/* integer working array */
|
||||
double *work; /* double work[1+n]; */
|
||||
/* floating-point working array */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* control parameters */
|
||||
int new_sva;
|
||||
/* new required size of the sparse vector area, in locations; set
|
||||
automatically by the factorizing routine */
|
||||
double piv_tol;
|
||||
/* threshold pivoting tolerance, 0 < piv_tol < 1; element v[i,j]
|
||||
of the active submatrix fits to be pivot if it satisfies to the
|
||||
stability condition |v[i,j]| >= piv_tol * max|v[i,*]|, i.e. if
|
||||
this element is not very small (in absolute value) among other
|
||||
elements in the same row; decreasing this parameter involves
|
||||
better sparsity at the expense of numerical accuracy and vice
|
||||
versa */
|
||||
int piv_lim;
|
||||
/* maximal allowable number of pivot candidates to be considered;
|
||||
if piv_lim pivot candidates have been considered, the pivoting
|
||||
routine terminates the search with the best candidate found */
|
||||
int suhl;
|
||||
/* if this flag is set, the pivoting routine applies a heuristic
|
||||
rule proposed by Uwe Suhl: if a column of the active submatrix
|
||||
has no eligible pivot candidates (i.e. all its elements don't
|
||||
satisfy to the stability condition), the routine excludes such
|
||||
column from the futher consideration until it becomes a column
|
||||
singleton; in many cases this reduces a time needed for pivot
|
||||
searching */
|
||||
double eps_tol;
|
||||
/* epsilon tolerance; each element of the matrix V with absolute
|
||||
value less than eps_tol is replaced by exact zero */
|
||||
double max_gro;
|
||||
/* maximal allowable growth of elements of the matrix V during
|
||||
all the factorization process; if on some elimination step the
|
||||
ratio big_v / max_a (see below) becomes greater than max_gro,
|
||||
the matrix A is considered as ill-conditioned (it is assumed
|
||||
that the tolerance piv_tol has an adequate value) */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* some statistics */
|
||||
int nnz_a;
|
||||
/* number of non-zeros in the matrix A */
|
||||
int nnz_f;
|
||||
/* number of non-zeros in the matrix F (except diagonal elements,
|
||||
which are always equal to one and therefore not stored) */
|
||||
int nnz_v;
|
||||
/* number of non-zeros in the matrix V (except pivot elements,
|
||||
which correspond to diagonal elements of the matrix U = P*V*Q
|
||||
and which are stored separately in the array vr_piv) */
|
||||
double max_a;
|
||||
/* largest of absolute values of elements of the matrix A */
|
||||
double big_v;
|
||||
/* estimated largest of absolute values of elements appeared in
|
||||
the active submatrix during all the factorization process */
|
||||
int rank;
|
||||
/* estimated rank of the matrix A */
|
||||
};
|
||||
|
||||
struct LUF_WA
|
||||
{ /* working area (used only during factorization) */
|
||||
double *rs_max; /* double rs_max[1+n]; */
|
||||
/* rs_max[0] is not used; rs_max[i], 1 <= i <= n, is used only if
|
||||
the i-th row of the matrix V belongs to the active submatrix
|
||||
and is the largest of absolute values of elements in this row;
|
||||
rs_max[i] < 0.0 means that the largest value is not known yet
|
||||
and should be determined by the pivoting routine */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* in order to efficiently implement Markowitz strategy and Duff
|
||||
search technique there are two families {R[0], R[1], ..., R[n]}
|
||||
and {C[0], C[1], ..., C[n]}; member R[k] is a set of active
|
||||
rows of the matrix V, which have k non-zeros; similarly, member
|
||||
C[k] is a set of active columns of the matrix V, which have k
|
||||
non-zeros (in the active submatrix); each set R[k] and C[k] is
|
||||
implemented as a separate doubly linked list */
|
||||
int *rs_head; /* int rs_head[1+n]; */
|
||||
/* rs_head[k], 0 <= k <= n, is number of the first active row,
|
||||
which has k non-zeros */
|
||||
int *rs_prev; /* int rs_prev[1+n]; */
|
||||
/* rs_prev[0] is not used; rs_prev[i], 1 <= i <= n, is number of
|
||||
the previous active row, which has the same number of non-zeros
|
||||
as the i-th row */
|
||||
int *rs_next; /* int rs_next[1+n]; */
|
||||
/* rs_next[0] is not used; rs_next[i], 1 <= i <= n, is number of
|
||||
the next active row, which has the same number of non-zeros as
|
||||
the i-th row */
|
||||
int *cs_head; /* int cs_head[1+n]; */
|
||||
/* cs_head[k], 0 <= k <= n, is number of the first active column,
|
||||
which has k non-zeros (in the active submatrix) */
|
||||
int *cs_prev; /* int cs_prev[1+n]; */
|
||||
/* cs_prev[0] is not used; cs_prev[j], 1 <= j <= n, is number of
|
||||
the previous active column, which has the same number of
|
||||
non-zeros (in the active submatrix) as the j-th column */
|
||||
int *cs_next; /* int cs_next[1+n]; */
|
||||
/* cs_next[0] is not used; cs_next[j], 1 <= j <= n, is number of
|
||||
the next active column, which has the same number of non-zeros
|
||||
(in the active submatrix) as the j-th column */
|
||||
};
|
||||
|
||||
LUF *luf_create(int n, int sv_size);
|
||||
/* create LU-factorization */
|
||||
|
||||
void luf_defrag_sva(LUF *luf);
|
||||
/* defragment the sparse vector area */
|
||||
|
||||
int luf_enlarge_row(LUF *luf, int i, int cap);
|
||||
/* enlarge row capacity */
|
||||
|
||||
int luf_enlarge_col(LUF *luf, int j, int cap);
|
||||
/* enlarge column capacity */
|
||||
|
||||
LUF_WA *luf_alloc_wa(LUF *luf);
|
||||
/* pre-allocate working area */
|
||||
|
||||
void luf_free_wa(LUF_WA *wa);
|
||||
/* free working area */
|
||||
|
||||
int luf_decomp(LUF *luf,
|
||||
void *info, int (*col)(void *info, int j, int rn[], double aj[]),
|
||||
LUF_WA *wa);
|
||||
/* compute LU-factorization */
|
||||
|
||||
void luf_f_solve(LUF *luf, int tr, double x[]);
|
||||
/* solve system F*x = b or F'*x = b */
|
||||
|
||||
void luf_v_solve(LUF *luf, int tr, double x[]);
|
||||
/* solve system V*x = b or V'*x = b */
|
||||
|
||||
void luf_solve(LUF *luf, int tr, double x[]);
|
||||
/* solve system A*x = b or A'*x = b */
|
||||
|
||||
void luf_delete(LUF *luf);
|
||||
/* delete LU-factorization */
|
||||
|
||||
#endif
|
||||
|
||||
/* eof */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,546 @@
|
||||
/* glpmat.h */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _GLPMAT_H
|
||||
#define _GLPMAT_H
|
||||
|
||||
#include "glpdmp.h"
|
||||
|
||||
#define aat_numb glp_aat_numb
|
||||
#define aat_symb glp_aat_symb
|
||||
#define append_lines glp_append_lines
|
||||
#define check_mat glp_check_mat
|
||||
#define check_mplets glp_check_mplets
|
||||
#define check_per glp_check_per
|
||||
#define clear_line glp_clear_line
|
||||
#define clear_lines glp_clear_lines
|
||||
#define clear_mat glp_clear_mat
|
||||
#define copy_mat glp_copy_mat
|
||||
#define copy_per glp_copy_per
|
||||
#define count_nz glp_count_nz
|
||||
#define create_mat glp_create_mat
|
||||
#define create_per glp_create_per
|
||||
#define delete_lines glp_delete_lines
|
||||
#define delete_mat glp_delete_mat
|
||||
#define delete_per glp_delete_per
|
||||
#define eq_scaling glp_eq_scaling
|
||||
#define gm_scaling glp_gm_scaling
|
||||
#define inv_per glp_inv_per
|
||||
#define iper_vec glp_iper_vec
|
||||
#define l_solve glp_l_solve
|
||||
#define lt_solve glp_lt_solve
|
||||
#define mat_per glp_mat_per
|
||||
#define mat_vec glp_mat_vec
|
||||
#define mprd_numb glp_mprd_numb
|
||||
#define mprd_symb glp_mprd_symb
|
||||
#define new_elem glp_new_elem
|
||||
#define per_mat glp_per_mat
|
||||
#define per_sym glp_per_sym
|
||||
#define per_vec glp_per_vec
|
||||
#define reset_per glp_reset_per
|
||||
#define scrape_mat glp_scrape_mat
|
||||
#define sort_mat glp_sort_mat
|
||||
#define submatrix glp_submatrix
|
||||
#define sum_mplets glp_sum_mplets
|
||||
#define sym_vec glp_sym_vec
|
||||
#define test_mat_d glp_test_mat_d
|
||||
#define test_mat_e glp_test_mat_e
|
||||
#define tmat_vec glp_tmat_vec
|
||||
#define trn_mat glp_trn_mat
|
||||
#define u_solve glp_u_solve
|
||||
#define ut_solve glp_ut_solve
|
||||
#define v_solve glp_v_solve
|
||||
#define vt_solve glp_vt_solve
|
||||
|
||||
typedef struct MAT MAT;
|
||||
typedef struct ELEM ELEM;
|
||||
typedef struct PER PER;
|
||||
|
||||
struct MAT
|
||||
{ /* sparse matrix */
|
||||
DMP *pool;
|
||||
/* memory pool for allocating matrix elements */
|
||||
int m_max;
|
||||
/* current dimension of array of row pointers; this dimension is
|
||||
automatically increased when necessary */
|
||||
int n_max;
|
||||
/* current dimension of array of column pointers; this dimension
|
||||
is automatically increased when necessary */
|
||||
int m;
|
||||
/* number of rows (>= 0) */
|
||||
int n;
|
||||
/* number of columns (>= 0) */
|
||||
ELEM **row; /* ELEM *row[1+m_max]; */
|
||||
/* array of row pointers; row[0] is not used; row[i] points to
|
||||
the i-th row (i = 1, ..., m); row[m+1], ..., row[m_max] are
|
||||
reserved for new rows that can be added to the matrix */
|
||||
ELEM **col; /* ELEM *col[1+n_max]; */
|
||||
/* array of column pointers; col[0] is not used; col[i] points to
|
||||
the j-th column (j = 1, ..., n); col[n+1], ..., col[n_max] are
|
||||
reserved for new columns that can be added to the matrix */
|
||||
};
|
||||
|
||||
struct ELEM
|
||||
{ /* element of sparse matrix */
|
||||
int i;
|
||||
/* row number (1 <= i <= m) */
|
||||
int j;
|
||||
/* column number (1 <= j <= n) */
|
||||
double val;
|
||||
/* element value (usually non-zero, but may be zero) */
|
||||
ELEM *row;
|
||||
/* pointer to the next element in the same row (this linked list
|
||||
is unordered) */
|
||||
ELEM *col;
|
||||
/* pointer to the next element in the same column (this linked
|
||||
list is unordered) */
|
||||
};
|
||||
|
||||
struct PER
|
||||
{ /* permutation matrix */
|
||||
int n;
|
||||
/* order of matrix */
|
||||
int *row; /* int row[1+n]; */
|
||||
/* row-wise format: if P[i,j] = 1 then row[i] = j (row[0] is not
|
||||
used) */
|
||||
int *col; /* int col[1+n]; */
|
||||
/* column-wise format: if P[i,j] = 1 then col[j] = i (col[0] is
|
||||
not used) */
|
||||
};
|
||||
|
||||
extern MAT *aat_numb(MAT *S, MAT *A, double D[], double work[]);
|
||||
/* compute matrix product S = A * D * A'; numeric phase */
|
||||
|
||||
extern MAT *aat_symb(MAT *S, MAT *A, char work[]);
|
||||
/* compute matrix product S = A * A'; symbolic phase */
|
||||
|
||||
extern MAT *append_lines(MAT *A, int dm, int dn);
|
||||
/* append new rows and columns to sparse matrix */
|
||||
|
||||
extern void check_mat(MAT *A);
|
||||
/* check sparse matrix for correctness */
|
||||
|
||||
extern ELEM *check_mplets(MAT *A);
|
||||
/* check whether sparse matrix has multiplets */
|
||||
|
||||
extern void check_per(PER *P);
|
||||
/* check permutation matrix for correctness */
|
||||
|
||||
extern MAT *clear_line(MAT *A, int k);
|
||||
/* clear row or column of sparse matrix */
|
||||
|
||||
extern MAT *clear_lines(MAT *A, int rs[], int cs[]);
|
||||
/* clear rows and columns of sparse matrix */
|
||||
|
||||
extern MAT *clear_mat(MAT *A);
|
||||
/* clear sparse matrix (A := 0) */
|
||||
|
||||
extern MAT *copy_mat(MAT *B, MAT *A);
|
||||
/* copy sparse matrix (B := A) */
|
||||
|
||||
extern PER *copy_per(PER *Q, PER *P);
|
||||
/* copy permutation matrix (Q := P) */
|
||||
|
||||
extern int count_nz(MAT *A, int k);
|
||||
/* count non-zeros of sparse matrix */
|
||||
|
||||
extern MAT *create_mat(int m, int n);
|
||||
/* create sparse matrix */
|
||||
|
||||
extern PER *create_per(int n);
|
||||
/* create permutation matrix */
|
||||
|
||||
extern MAT *delete_lines(MAT *A, int rs[], int cs[]);
|
||||
/* delete rows and columns from sparse matrix */
|
||||
|
||||
extern void delete_mat(MAT *A);
|
||||
/* delete sparse matrix */
|
||||
|
||||
extern void delete_per(PER *P);
|
||||
/* delete permutation matrix */
|
||||
|
||||
extern void eq_scaling(MAT *A, double R[], double S[], int ord);
|
||||
/* implicit equilibration scaling */
|
||||
|
||||
extern void gm_scaling(MAT *A, double R[], double S[], int ord,
|
||||
double eps, int itmax);
|
||||
/* implicit geometric mean scaling */
|
||||
|
||||
extern PER *inv_per(PER *P);
|
||||
/* invert permutation matrix */
|
||||
|
||||
extern double *iper_vec(double y[], PER *P, double x[]);
|
||||
/* permute vector elements in inverse order (y := P' * x) */
|
||||
|
||||
extern double *l_solve(MAT *L, double x[]);
|
||||
/* solve lower triangular system L*x = b */
|
||||
|
||||
extern double *lt_solve(MAT *L, double x[]);
|
||||
/* solve transposed lower triangular system L'*x = b */
|
||||
|
||||
extern MAT *mat_per(MAT *A, PER *P, void *work[]);
|
||||
/* permute matrix columns (A := A * P) */
|
||||
|
||||
extern double *mat_vec(double y[], MAT *A, double x[]);
|
||||
/* multiply matrix on vector (y := A * x) */
|
||||
|
||||
extern MAT *mprd_numb(MAT *C, MAT *A, MAT *B, double _work[]);
|
||||
/* multiply matrices (C := A * B); numeric phase */
|
||||
|
||||
extern MAT *mprd_symb(MAT *C, MAT *A, MAT *B, char work[]);
|
||||
/* multiply matrices (C := A * B); symbolic phase */
|
||||
|
||||
extern ELEM *new_elem(MAT *A, int i, int j, double val);
|
||||
/* create new element of matrix */
|
||||
|
||||
extern MAT *per_mat(PER *P, MAT *A, void *work[]);
|
||||
/* permute matrix rows (A := P * A) */
|
||||
|
||||
extern MAT *per_sym(PER *P, MAT *A, void *work[]);
|
||||
/* permute symmetric matrix (A := P*A*P') */
|
||||
|
||||
extern double *per_vec(double y[], PER *P, double x[]);
|
||||
/* permute vector elements (y := P * x) */
|
||||
|
||||
extern PER *reset_per(PER *P);
|
||||
/* reset permutation matrix (P := I) */
|
||||
|
||||
extern int scrape_mat(MAT *A, double eps);
|
||||
/* remove tiny elements from sparse matrix */
|
||||
|
||||
extern MAT *sort_mat(MAT *A);
|
||||
/* ordering row and column lists of sparse matrix */
|
||||
|
||||
extern MAT *submatrix(MAT *B, MAT *A, int i1, int i2, int j1, int j2);
|
||||
/* copy submatrix */
|
||||
|
||||
extern int sum_mplets(MAT *A, double eps);
|
||||
/* sum multiplets of sparse matrix */
|
||||
|
||||
extern double *sym_vec(double y[], MAT *A, double x[]);
|
||||
/* multiply symmetric matrix on vector (y := A * x) */
|
||||
|
||||
extern MAT *test_mat_d(int n, int c);
|
||||
/* create test sparse matrix of D(n,c) class */
|
||||
|
||||
extern MAT *test_mat_e(int n, int c);
|
||||
/* create test sparse matrix of E(n,c) class */
|
||||
|
||||
extern double *tmat_vec(double y[], MAT *A, double x[]);
|
||||
/* multiply transposed matrix on vector (y := A' * x) */
|
||||
|
||||
extern MAT *trn_mat(MAT *A);
|
||||
/* transpose sparse matrix */
|
||||
|
||||
extern double *u_solve(MAT *U, double x[]);
|
||||
/* solve upper triangular system U*x = b */
|
||||
|
||||
extern double *ut_solve(MAT *U, double x[]);
|
||||
/* solve transposed upper triangular system U'*x = b */
|
||||
|
||||
extern double *v_solve(PER *P, MAT *V, PER *Q, double x[],
|
||||
double work[]);
|
||||
/* solve implicit upper triangular system V*x = b */
|
||||
|
||||
extern double *vt_solve(PER *P, MAT *V, PER *Q, double x[],
|
||||
double work[]);
|
||||
/* solve implicit transposed upper triangular system V'*x = b */
|
||||
|
||||
#endif
|
||||
|
||||
/* eof */
|
||||
/* glpmat.h */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _GLPMAT_H
|
||||
#define _GLPMAT_H
|
||||
|
||||
#include "glpdmp.h"
|
||||
|
||||
#define aat_numb glp_aat_numb
|
||||
#define aat_symb glp_aat_symb
|
||||
#define append_lines glp_append_lines
|
||||
#define check_mat glp_check_mat
|
||||
#define check_mplets glp_check_mplets
|
||||
#define check_per glp_check_per
|
||||
#define clear_line glp_clear_line
|
||||
#define clear_lines glp_clear_lines
|
||||
#define clear_mat glp_clear_mat
|
||||
#define copy_mat glp_copy_mat
|
||||
#define copy_per glp_copy_per
|
||||
#define count_nz glp_count_nz
|
||||
#define create_mat glp_create_mat
|
||||
#define create_per glp_create_per
|
||||
#define delete_lines glp_delete_lines
|
||||
#define delete_mat glp_delete_mat
|
||||
#define delete_per glp_delete_per
|
||||
#define eq_scaling glp_eq_scaling
|
||||
#define gm_scaling glp_gm_scaling
|
||||
#define inv_per glp_inv_per
|
||||
#define iper_vec glp_iper_vec
|
||||
#define l_solve glp_l_solve
|
||||
#define lt_solve glp_lt_solve
|
||||
#define mat_per glp_mat_per
|
||||
#define mat_vec glp_mat_vec
|
||||
#define mprd_numb glp_mprd_numb
|
||||
#define mprd_symb glp_mprd_symb
|
||||
#define new_elem glp_new_elem
|
||||
#define per_mat glp_per_mat
|
||||
#define per_sym glp_per_sym
|
||||
#define per_vec glp_per_vec
|
||||
#define reset_per glp_reset_per
|
||||
#define scrape_mat glp_scrape_mat
|
||||
#define sort_mat glp_sort_mat
|
||||
#define submatrix glp_submatrix
|
||||
#define sum_mplets glp_sum_mplets
|
||||
#define sym_vec glp_sym_vec
|
||||
#define test_mat_d glp_test_mat_d
|
||||
#define test_mat_e glp_test_mat_e
|
||||
#define tmat_vec glp_tmat_vec
|
||||
#define trn_mat glp_trn_mat
|
||||
#define u_solve glp_u_solve
|
||||
#define ut_solve glp_ut_solve
|
||||
#define v_solve glp_v_solve
|
||||
#define vt_solve glp_vt_solve
|
||||
|
||||
typedef struct MAT MAT;
|
||||
typedef struct ELEM ELEM;
|
||||
typedef struct PER PER;
|
||||
|
||||
struct MAT
|
||||
{ /* sparse matrix */
|
||||
DMP *pool;
|
||||
/* memory pool for allocating matrix elements */
|
||||
int m_max;
|
||||
/* current dimension of array of row pointers; this dimension is
|
||||
automatically increased when necessary */
|
||||
int n_max;
|
||||
/* current dimension of array of column pointers; this dimension
|
||||
is automatically increased when necessary */
|
||||
int m;
|
||||
/* number of rows (>= 0) */
|
||||
int n;
|
||||
/* number of columns (>= 0) */
|
||||
ELEM **row; /* ELEM *row[1+m_max]; */
|
||||
/* array of row pointers; row[0] is not used; row[i] points to
|
||||
the i-th row (i = 1, ..., m); row[m+1], ..., row[m_max] are
|
||||
reserved for new rows that can be added to the matrix */
|
||||
ELEM **col; /* ELEM *col[1+n_max]; */
|
||||
/* array of column pointers; col[0] is not used; col[i] points to
|
||||
the j-th column (j = 1, ..., n); col[n+1], ..., col[n_max] are
|
||||
reserved for new columns that can be added to the matrix */
|
||||
};
|
||||
|
||||
struct ELEM
|
||||
{ /* element of sparse matrix */
|
||||
int i;
|
||||
/* row number (1 <= i <= m) */
|
||||
int j;
|
||||
/* column number (1 <= j <= n) */
|
||||
double val;
|
||||
/* element value (usually non-zero, but may be zero) */
|
||||
ELEM *row;
|
||||
/* pointer to the next element in the same row (this linked list
|
||||
is unordered) */
|
||||
ELEM *col;
|
||||
/* pointer to the next element in the same column (this linked
|
||||
list is unordered) */
|
||||
};
|
||||
|
||||
struct PER
|
||||
{ /* permutation matrix */
|
||||
int n;
|
||||
/* order of matrix */
|
||||
int *row; /* int row[1+n]; */
|
||||
/* row-wise format: if P[i,j] = 1 then row[i] = j (row[0] is not
|
||||
used) */
|
||||
int *col; /* int col[1+n]; */
|
||||
/* column-wise format: if P[i,j] = 1 then col[j] = i (col[0] is
|
||||
not used) */
|
||||
};
|
||||
|
||||
extern MAT *aat_numb(MAT *S, MAT *A, double D[], double work[]);
|
||||
/* compute matrix product S = A * D * A'; numeric phase */
|
||||
|
||||
extern MAT *aat_symb(MAT *S, MAT *A, char work[]);
|
||||
/* compute matrix product S = A * A'; symbolic phase */
|
||||
|
||||
extern MAT *append_lines(MAT *A, int dm, int dn);
|
||||
/* append new rows and columns to sparse matrix */
|
||||
|
||||
extern void check_mat(MAT *A);
|
||||
/* check sparse matrix for correctness */
|
||||
|
||||
extern ELEM *check_mplets(MAT *A);
|
||||
/* check whether sparse matrix has multiplets */
|
||||
|
||||
extern void check_per(PER *P);
|
||||
/* check permutation matrix for correctness */
|
||||
|
||||
extern MAT *clear_line(MAT *A, int k);
|
||||
/* clear row or column of sparse matrix */
|
||||
|
||||
extern MAT *clear_lines(MAT *A, int rs[], int cs[]);
|
||||
/* clear rows and columns of sparse matrix */
|
||||
|
||||
extern MAT *clear_mat(MAT *A);
|
||||
/* clear sparse matrix (A := 0) */
|
||||
|
||||
extern MAT *copy_mat(MAT *B, MAT *A);
|
||||
/* copy sparse matrix (B := A) */
|
||||
|
||||
extern PER *copy_per(PER *Q, PER *P);
|
||||
/* copy permutation matrix (Q := P) */
|
||||
|
||||
extern int count_nz(MAT *A, int k);
|
||||
/* count non-zeros of sparse matrix */
|
||||
|
||||
extern MAT *create_mat(int m, int n);
|
||||
/* create sparse matrix */
|
||||
|
||||
extern PER *create_per(int n);
|
||||
/* create permutation matrix */
|
||||
|
||||
extern MAT *delete_lines(MAT *A, int rs[], int cs[]);
|
||||
/* delete rows and columns from sparse matrix */
|
||||
|
||||
extern void delete_mat(MAT *A);
|
||||
/* delete sparse matrix */
|
||||
|
||||
extern void delete_per(PER *P);
|
||||
/* delete permutation matrix */
|
||||
|
||||
extern void eq_scaling(MAT *A, double R[], double S[], int ord);
|
||||
/* implicit equilibration scaling */
|
||||
|
||||
extern void gm_scaling(MAT *A, double R[], double S[], int ord,
|
||||
double eps, int itmax);
|
||||
/* implicit geometric mean scaling */
|
||||
|
||||
extern PER *inv_per(PER *P);
|
||||
/* invert permutation matrix */
|
||||
|
||||
extern double *iper_vec(double y[], PER *P, double x[]);
|
||||
/* permute vector elements in inverse order (y := P' * x) */
|
||||
|
||||
extern double *l_solve(MAT *L, double x[]);
|
||||
/* solve lower triangular system L*x = b */
|
||||
|
||||
extern double *lt_solve(MAT *L, double x[]);
|
||||
/* solve transposed lower triangular system L'*x = b */
|
||||
|
||||
extern MAT *mat_per(MAT *A, PER *P, void *work[]);
|
||||
/* permute matrix columns (A := A * P) */
|
||||
|
||||
extern double *mat_vec(double y[], MAT *A, double x[]);
|
||||
/* multiply matrix on vector (y := A * x) */
|
||||
|
||||
extern MAT *mprd_numb(MAT *C, MAT *A, MAT *B, double _work[]);
|
||||
/* multiply matrices (C := A * B); numeric phase */
|
||||
|
||||
extern MAT *mprd_symb(MAT *C, MAT *A, MAT *B, char work[]);
|
||||
/* multiply matrices (C := A * B); symbolic phase */
|
||||
|
||||
extern ELEM *new_elem(MAT *A, int i, int j, double val);
|
||||
/* create new element of matrix */
|
||||
|
||||
extern MAT *per_mat(PER *P, MAT *A, void *work[]);
|
||||
/* permute matrix rows (A := P * A) */
|
||||
|
||||
extern MAT *per_sym(PER *P, MAT *A, void *work[]);
|
||||
/* permute symmetric matrix (A := P*A*P') */
|
||||
|
||||
extern double *per_vec(double y[], PER *P, double x[]);
|
||||
/* permute vector elements (y := P * x) */
|
||||
|
||||
extern PER *reset_per(PER *P);
|
||||
/* reset permutation matrix (P := I) */
|
||||
|
||||
extern int scrape_mat(MAT *A, double eps);
|
||||
/* remove tiny elements from sparse matrix */
|
||||
|
||||
extern MAT *sort_mat(MAT *A);
|
||||
/* ordering row and column lists of sparse matrix */
|
||||
|
||||
extern MAT *submatrix(MAT *B, MAT *A, int i1, int i2, int j1, int j2);
|
||||
/* copy submatrix */
|
||||
|
||||
extern int sum_mplets(MAT *A, double eps);
|
||||
/* sum multiplets of sparse matrix */
|
||||
|
||||
extern double *sym_vec(double y[], MAT *A, double x[]);
|
||||
/* multiply symmetric matrix on vector (y := A * x) */
|
||||
|
||||
extern MAT *test_mat_d(int n, int c);
|
||||
/* create test sparse matrix of D(n,c) class */
|
||||
|
||||
extern MAT *test_mat_e(int n, int c);
|
||||
/* create test sparse matrix of E(n,c) class */
|
||||
|
||||
extern double *tmat_vec(double y[], MAT *A, double x[]);
|
||||
/* multiply transposed matrix on vector (y := A' * x) */
|
||||
|
||||
extern MAT *trn_mat(MAT *A);
|
||||
/* transpose sparse matrix */
|
||||
|
||||
extern double *u_solve(MAT *U, double x[]);
|
||||
/* solve upper triangular system U*x = b */
|
||||
|
||||
extern double *ut_solve(MAT *U, double x[]);
|
||||
/* solve transposed upper triangular system U'*x = b */
|
||||
|
||||
extern double *v_solve(PER *P, MAT *V, PER *Q, double x[],
|
||||
double work[]);
|
||||
/* solve implicit upper triangular system V*x = b */
|
||||
|
||||
extern double *vt_solve(PER *P, MAT *V, PER *Q, double x[],
|
||||
double work[]);
|
||||
/* solve implicit transposed upper triangular system V'*x = b */
|
||||
|
||||
#endif
|
||||
|
||||
/* eof */
|
||||
@@ -0,0 +1,522 @@
|
||||
/* glpmip.h */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _GLPMIP_H
|
||||
#define _GLPMIP_H
|
||||
|
||||
#include "glpies.h"
|
||||
|
||||
#define mip_create_tree glp_mip_create_tree
|
||||
#define mip_driver glp_mip_driver
|
||||
#define mip_delete_tree glp_mip_delete_tree
|
||||
|
||||
typedef struct MIPTREE MIPTREE;
|
||||
typedef struct MIPROW MIPROW;
|
||||
typedef struct MIPCOL MIPCOL;
|
||||
typedef struct MIPNODE MIPNODE;
|
||||
|
||||
struct MIPTREE
|
||||
{ /* MIP solver workspace */
|
||||
DMP *row_pool;
|
||||
/* memory pool for rows (constraints) */
|
||||
DMP *col_pool;
|
||||
/* memory pool for columns (variables) */
|
||||
DMP *node_pool;
|
||||
/* memory pool for nodes (subproblems) */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* original problem information */
|
||||
int orig_m;
|
||||
/* number of rows in the original problem */
|
||||
int orig_n;
|
||||
/* number of columns in the original problem */
|
||||
int dir;
|
||||
/* optimization direction:
|
||||
LPX_MIN - minimization
|
||||
LPX_MAX - maximization */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* application interface */
|
||||
void *info;
|
||||
/* transit pointer passed to the application procedure */
|
||||
void (*appl)(void *info, MIPTREE *tree);
|
||||
/* event-driven application procedure */
|
||||
int event;
|
||||
/* current event code: */
|
||||
#define MIP_V_UNDEF 1100 /* undefined event (never raised) */
|
||||
#define MIP_V_SELECT 1101 /* subproblem selection required */
|
||||
#define MIP_V_BEGSUB 1102 /* subproblem processing begins */
|
||||
#define MIP_V_BEGLP 1103 /* LP optimization begins */
|
||||
#define MIP_V_ENDLP 1104 /* LP optimization ended */
|
||||
#define MIP_V_REJECT 1105 /* subproblem rejected */
|
||||
#define MIP_V_BINGO 1106 /* better MIP solution found */
|
||||
#define MIP_V_BRANCH 1107 /* branching variable required */
|
||||
#define MIP_V_ENDSUB 1108 /* subproblem processing ended */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* MIP solver segment */
|
||||
IESTREE *tree;
|
||||
/* implicit enumeration tree */
|
||||
MIPNODE *glob;
|
||||
/* pointer to a subproblem, which is the highest-leveled common
|
||||
ancestor of all active and the current subproblems (initially
|
||||
it is the root subproblem); an optimal value of the objective
|
||||
for LP relaxation of this subproblem is the global lower (in
|
||||
case of minimization) or upper (in case of maximization) bound
|
||||
for the original MIP problem */
|
||||
MIPNODE *curr;
|
||||
/* pointer to the current subproblem being solved; NULL means the
|
||||
current subproblem is undefined (not selected yet) */
|
||||
int m_max;
|
||||
/* current length of the array row (if necessary, this parameter
|
||||
is automatically increased) */
|
||||
MIPROW **row; /* MIPROW *row[1+m_max]; */
|
||||
/* array of pointers to rows of the current subproblem;
|
||||
row[1], ..., row[m] are pointers to rows, which are presented
|
||||
in the current subproblem, where m = mip_get_num_rows;
|
||||
row[m+1], ..., row[m+nrs] are pointers to rows, which will be
|
||||
added to the current subproblem before re-optimization;
|
||||
row[m+nrs+1], ..., row[m_max] are free entries */
|
||||
MIPCOL **col; /* MIPCOL *col[1+n]; */
|
||||
/* array of pointers to columns of the current subproblem, where
|
||||
n = mip_get_num_cols = orig_n */
|
||||
int reopt;
|
||||
/* this count is reset to zero when a new subproblem is selected
|
||||
from the active list and then increased by one each time when
|
||||
the subproblem is re-optimized */
|
||||
int e_code;
|
||||
/* exit code returned by the lpx_simplex routine after solving LP
|
||||
relaxation of the current subproblem */
|
||||
int better;
|
||||
/* this flag is set if optimal solution of the LP relaxation of
|
||||
the current subproblem is better than the best known integer
|
||||
feasible solution; otherwise this flag is clear */
|
||||
int unsat;
|
||||
/* number of columns (structural variables) of integer kind that
|
||||
have fractional values in the basic solution of LP relaxation
|
||||
of the current subproblem */
|
||||
double ii_sum;
|
||||
/* the sum of integer infeasibilites for the basic solution of LP
|
||||
relaxation of the current subproblem */
|
||||
int *del; /* int del[1+m_max]; */
|
||||
/* if the flag del[i] (1 <= i <= m, where m = mip_get_num_rows)
|
||||
is set, i-th row will be removed from the current subproblem
|
||||
before re-optimization */
|
||||
int nrs;
|
||||
/* number of additional rows, which will be added to the current
|
||||
subproblem before re-optimization; pointers to these new rows
|
||||
are stored in locations row[m+1], ..., row[m+nrs] */
|
||||
int j_br;
|
||||
/* number of column (structural variable) chosen to branch on */
|
||||
int heir;
|
||||
/* this flag specifies which subproblem created as the result of
|
||||
branching on the column j_br should be selected next:
|
||||
0 - selected using a backtracking heuristic
|
||||
1 - down branch (subproblem, where the branching variable has
|
||||
a new, decreased upper bound)
|
||||
2 - up branch (subproblem, where the branching variable has a
|
||||
new, increased lower bound) */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* best known solution */
|
||||
int found;
|
||||
/* this flag is set if the solver has found some integer feasible
|
||||
solution; otherwise this flag is clear */
|
||||
double *best; /* double best[1+orig_m+orig_n]; */
|
||||
/* best[0] is a numerical value of the objective function;
|
||||
best[1], ..., best[orig_m] are numerical values of auxiliary
|
||||
variables (rows) of the original problem;
|
||||
best[orig_m+1], ..., best[orig_m+orig_n] are numerical values
|
||||
of structural variables (columns) of the original problem;
|
||||
if the flag found is not set, all components of the array best
|
||||
are undefined */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* control parameters and statistics */
|
||||
int msg_lev;
|
||||
/* level of messages output by the solver:
|
||||
0 - no output
|
||||
1 - error messages only
|
||||
2 - normal output
|
||||
3 - full output (includes informational messages) */
|
||||
double tol_int;
|
||||
/* relative tolerance used to check if the current basic solution
|
||||
is integer feasible */
|
||||
double tol_obj;
|
||||
/* relative tolerance used to check if a value of the objective
|
||||
function is not better than in the best known integer feasible
|
||||
solution */
|
||||
int it_lim;
|
||||
/* simplex iterations limit; if this value is positive, it is
|
||||
decreased by one each time when one simplex iteration has been
|
||||
performed, and reaching zero value signals the solver to stop
|
||||
the search; negative value means no iterations limit */
|
||||
int sn_lim;
|
||||
/* solved subproblems limit; if this value is positive, it is
|
||||
decreased by one each time when one active subroblem has been
|
||||
solved, and reaching zero value signals the solver to stop the
|
||||
search; negative value means no subproblems limit */
|
||||
double tm_lim;
|
||||
/* searching time limit, in seconds; if this value is positive,
|
||||
it is decreased each time when one complete round of the
|
||||
search is performed by the amount of time spent for the round,
|
||||
and reaching zero value signals the solver to stop the search;
|
||||
negative value means no time limit */
|
||||
double out_frq;
|
||||
/* output frequency, in seconds; this parameter specifies how
|
||||
frequently the solver sends information about progress of the
|
||||
search to the standard output */
|
||||
int an_cnt;
|
||||
/* number of subproblems in the active list */
|
||||
int sn_cnt;
|
||||
/* number of solved subproblems (including those ones which were
|
||||
rejected not being actually solved); some of them can still be
|
||||
in the tree if they have active descendants; at the end of the
|
||||
search this count is total number of explored subproblems */
|
||||
double tm_last;
|
||||
/* most recent time, at which visual information was displayed */
|
||||
};
|
||||
|
||||
struct MIPROW
|
||||
{ /* row (constraint) */
|
||||
int i;
|
||||
/* ordinal number of this row */
|
||||
IESITEM *row;
|
||||
/* pointer to the corresponding master row; the field link in the
|
||||
master row structure refers to this structure */
|
||||
MIPNODE *node;
|
||||
/* pointer to the subproblem, which was the current when this row
|
||||
was added */
|
||||
};
|
||||
|
||||
struct MIPCOL
|
||||
{ /* column (variable) */
|
||||
int j;
|
||||
/* ordinal number of this column */
|
||||
IESITEM *col;
|
||||
/* pointer to the corresponding master column; the field link in
|
||||
the master column structure refers to this structure */
|
||||
int intvar;
|
||||
/* if this flag is set, the variable is of integer kind; if this
|
||||
flag is clear, the variable is of continuous kind */
|
||||
int infeas;
|
||||
/* if this flag is set, the variable is of integer kind and its
|
||||
value in a basic solution of the current subproblem is integer
|
||||
infeasible (fractional); otherwise this flag is clear */
|
||||
};
|
||||
|
||||
struct MIPNODE
|
||||
{ /* subproblem */
|
||||
IESNODE *node;
|
||||
/* pointer to the corresponding node problem; the field link in
|
||||
the node problem structure refers to this structure */
|
||||
double lp_obj;
|
||||
/* optimal value of the objective function for LP relaxation of
|
||||
this subproblem; if this subproblem is in the active list and
|
||||
therefore never solved yet, lp_obj is an estimation of the
|
||||
objective function, which is a lower (in case of minimization)
|
||||
or an upper (in case of maximization) bound of a true optimal
|
||||
value; the estimation can be obtained in different ways, for
|
||||
example, it can be just lp_obj from the parent subproblem */
|
||||
double temp;
|
||||
/* reserved for internal needs */
|
||||
};
|
||||
|
||||
/* exit codes returned by the routine mip_driver: */
|
||||
#define MIP_E_OK 1200 /* the search is completed */
|
||||
#define MIP_E_ITLIM 1201 /* iterations limit exhausted */
|
||||
#define MIP_E_SNLIM 1202 /* subproblems limit exhausted */
|
||||
#define MIP_E_TMLIM 1203 /* time limit exhausted */
|
||||
#define MIP_E_ERROR 1204 /* can't solve LP relaxation */
|
||||
|
||||
MIPTREE *mip_create_tree(LPX *mip,
|
||||
void *info, void appl(void *info, MIPTREE *tree));
|
||||
/* create MIP solver wprkspace */
|
||||
|
||||
int mip_driver(MIPTREE *tree);
|
||||
/* branch-and-bound driver */
|
||||
|
||||
void mip_delete_tree(MIPTREE *tree);
|
||||
/* delete MIP solver workspace */
|
||||
|
||||
#endif
|
||||
|
||||
/* eof */
|
||||
/* glpmip.h */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _GLPMIP_H
|
||||
#define _GLPMIP_H
|
||||
|
||||
#include "glpies.h"
|
||||
|
||||
#define mip_create_tree glp_mip_create_tree
|
||||
#define mip_driver glp_mip_driver
|
||||
#define mip_delete_tree glp_mip_delete_tree
|
||||
|
||||
typedef struct MIPTREE MIPTREE;
|
||||
typedef struct MIPROW MIPROW;
|
||||
typedef struct MIPCOL MIPCOL;
|
||||
typedef struct MIPNODE MIPNODE;
|
||||
|
||||
struct MIPTREE
|
||||
{ /* MIP solver workspace */
|
||||
DMP *row_pool;
|
||||
/* memory pool for rows (constraints) */
|
||||
DMP *col_pool;
|
||||
/* memory pool for columns (variables) */
|
||||
DMP *node_pool;
|
||||
/* memory pool for nodes (subproblems) */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* original problem information */
|
||||
int orig_m;
|
||||
/* number of rows in the original problem */
|
||||
int orig_n;
|
||||
/* number of columns in the original problem */
|
||||
int dir;
|
||||
/* optimization direction:
|
||||
LPX_MIN - minimization
|
||||
LPX_MAX - maximization */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* application interface */
|
||||
void *info;
|
||||
/* transit pointer passed to the application procedure */
|
||||
void (*appl)(void *info, MIPTREE *tree);
|
||||
/* event-driven application procedure */
|
||||
int event;
|
||||
/* current event code: */
|
||||
#define MIP_V_UNDEF 1100 /* undefined event (never raised) */
|
||||
#define MIP_V_SELECT 1101 /* subproblem selection required */
|
||||
#define MIP_V_BEGSUB 1102 /* subproblem processing begins */
|
||||
#define MIP_V_BEGLP 1103 /* LP optimization begins */
|
||||
#define MIP_V_ENDLP 1104 /* LP optimization ended */
|
||||
#define MIP_V_REJECT 1105 /* subproblem rejected */
|
||||
#define MIP_V_BINGO 1106 /* better MIP solution found */
|
||||
#define MIP_V_BRANCH 1107 /* branching variable required */
|
||||
#define MIP_V_ENDSUB 1108 /* subproblem processing ended */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* MIP solver segment */
|
||||
IESTREE *tree;
|
||||
/* implicit enumeration tree */
|
||||
MIPNODE *glob;
|
||||
/* pointer to a subproblem, which is the highest-leveled common
|
||||
ancestor of all active and the current subproblems (initially
|
||||
it is the root subproblem); an optimal value of the objective
|
||||
for LP relaxation of this subproblem is the global lower (in
|
||||
case of minimization) or upper (in case of maximization) bound
|
||||
for the original MIP problem */
|
||||
MIPNODE *curr;
|
||||
/* pointer to the current subproblem being solved; NULL means the
|
||||
current subproblem is undefined (not selected yet) */
|
||||
int m_max;
|
||||
/* current length of the array row (if necessary, this parameter
|
||||
is automatically increased) */
|
||||
MIPROW **row; /* MIPROW *row[1+m_max]; */
|
||||
/* array of pointers to rows of the current subproblem;
|
||||
row[1], ..., row[m] are pointers to rows, which are presented
|
||||
in the current subproblem, where m = mip_get_num_rows;
|
||||
row[m+1], ..., row[m+nrs] are pointers to rows, which will be
|
||||
added to the current subproblem before re-optimization;
|
||||
row[m+nrs+1], ..., row[m_max] are free entries */
|
||||
MIPCOL **col; /* MIPCOL *col[1+n]; */
|
||||
/* array of pointers to columns of the current subproblem, where
|
||||
n = mip_get_num_cols = orig_n */
|
||||
int reopt;
|
||||
/* this count is reset to zero when a new subproblem is selected
|
||||
from the active list and then increased by one each time when
|
||||
the subproblem is re-optimized */
|
||||
int e_code;
|
||||
/* exit code returned by the lpx_simplex routine after solving LP
|
||||
relaxation of the current subproblem */
|
||||
int better;
|
||||
/* this flag is set if optimal solution of the LP relaxation of
|
||||
the current subproblem is better than the best known integer
|
||||
feasible solution; otherwise this flag is clear */
|
||||
int unsat;
|
||||
/* number of columns (structural variables) of integer kind that
|
||||
have fractional values in the basic solution of LP relaxation
|
||||
of the current subproblem */
|
||||
double ii_sum;
|
||||
/* the sum of integer infeasibilites for the basic solution of LP
|
||||
relaxation of the current subproblem */
|
||||
int *del; /* int del[1+m_max]; */
|
||||
/* if the flag del[i] (1 <= i <= m, where m = mip_get_num_rows)
|
||||
is set, i-th row will be removed from the current subproblem
|
||||
before re-optimization */
|
||||
int nrs;
|
||||
/* number of additional rows, which will be added to the current
|
||||
subproblem before re-optimization; pointers to these new rows
|
||||
are stored in locations row[m+1], ..., row[m+nrs] */
|
||||
int j_br;
|
||||
/* number of column (structural variable) chosen to branch on */
|
||||
int heir;
|
||||
/* this flag specifies which subproblem created as the result of
|
||||
branching on the column j_br should be selected next:
|
||||
0 - selected using a backtracking heuristic
|
||||
1 - down branch (subproblem, where the branching variable has
|
||||
a new, decreased upper bound)
|
||||
2 - up branch (subproblem, where the branching variable has a
|
||||
new, increased lower bound) */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* best known solution */
|
||||
int found;
|
||||
/* this flag is set if the solver has found some integer feasible
|
||||
solution; otherwise this flag is clear */
|
||||
double *best; /* double best[1+orig_m+orig_n]; */
|
||||
/* best[0] is a numerical value of the objective function;
|
||||
best[1], ..., best[orig_m] are numerical values of auxiliary
|
||||
variables (rows) of the original problem;
|
||||
best[orig_m+1], ..., best[orig_m+orig_n] are numerical values
|
||||
of structural variables (columns) of the original problem;
|
||||
if the flag found is not set, all components of the array best
|
||||
are undefined */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* control parameters and statistics */
|
||||
int msg_lev;
|
||||
/* level of messages output by the solver:
|
||||
0 - no output
|
||||
1 - error messages only
|
||||
2 - normal output
|
||||
3 - full output (includes informational messages) */
|
||||
double tol_int;
|
||||
/* relative tolerance used to check if the current basic solution
|
||||
is integer feasible */
|
||||
double tol_obj;
|
||||
/* relative tolerance used to check if a value of the objective
|
||||
function is not better than in the best known integer feasible
|
||||
solution */
|
||||
int it_lim;
|
||||
/* simplex iterations limit; if this value is positive, it is
|
||||
decreased by one each time when one simplex iteration has been
|
||||
performed, and reaching zero value signals the solver to stop
|
||||
the search; negative value means no iterations limit */
|
||||
int sn_lim;
|
||||
/* solved subproblems limit; if this value is positive, it is
|
||||
decreased by one each time when one active subroblem has been
|
||||
solved, and reaching zero value signals the solver to stop the
|
||||
search; negative value means no subproblems limit */
|
||||
double tm_lim;
|
||||
/* searching time limit, in seconds; if this value is positive,
|
||||
it is decreased each time when one complete round of the
|
||||
search is performed by the amount of time spent for the round,
|
||||
and reaching zero value signals the solver to stop the search;
|
||||
negative value means no time limit */
|
||||
double out_frq;
|
||||
/* output frequency, in seconds; this parameter specifies how
|
||||
frequently the solver sends information about progress of the
|
||||
search to the standard output */
|
||||
int an_cnt;
|
||||
/* number of subproblems in the active list */
|
||||
int sn_cnt;
|
||||
/* number of solved subproblems (including those ones which were
|
||||
rejected not being actually solved); some of them can still be
|
||||
in the tree if they have active descendants; at the end of the
|
||||
search this count is total number of explored subproblems */
|
||||
double tm_last;
|
||||
/* most recent time, at which visual information was displayed */
|
||||
};
|
||||
|
||||
struct MIPROW
|
||||
{ /* row (constraint) */
|
||||
int i;
|
||||
/* ordinal number of this row */
|
||||
IESITEM *row;
|
||||
/* pointer to the corresponding master row; the field link in the
|
||||
master row structure refers to this structure */
|
||||
MIPNODE *node;
|
||||
/* pointer to the subproblem, which was the current when this row
|
||||
was added */
|
||||
};
|
||||
|
||||
struct MIPCOL
|
||||
{ /* column (variable) */
|
||||
int j;
|
||||
/* ordinal number of this column */
|
||||
IESITEM *col;
|
||||
/* pointer to the corresponding master column; the field link in
|
||||
the master column structure refers to this structure */
|
||||
int intvar;
|
||||
/* if this flag is set, the variable is of integer kind; if this
|
||||
flag is clear, the variable is of continuous kind */
|
||||
int infeas;
|
||||
/* if this flag is set, the variable is of integer kind and its
|
||||
value in a basic solution of the current subproblem is integer
|
||||
infeasible (fractional); otherwise this flag is clear */
|
||||
};
|
||||
|
||||
struct MIPNODE
|
||||
{ /* subproblem */
|
||||
IESNODE *node;
|
||||
/* pointer to the corresponding node problem; the field link in
|
||||
the node problem structure refers to this structure */
|
||||
double lp_obj;
|
||||
/* optimal value of the objective function for LP relaxation of
|
||||
this subproblem; if this subproblem is in the active list and
|
||||
therefore never solved yet, lp_obj is an estimation of the
|
||||
objective function, which is a lower (in case of minimization)
|
||||
or an upper (in case of maximization) bound of a true optimal
|
||||
value; the estimation can be obtained in different ways, for
|
||||
example, it can be just lp_obj from the parent subproblem */
|
||||
double temp;
|
||||
/* reserved for internal needs */
|
||||
};
|
||||
|
||||
/* exit codes returned by the routine mip_driver: */
|
||||
#define MIP_E_OK 1200 /* the search is completed */
|
||||
#define MIP_E_ITLIM 1201 /* iterations limit exhausted */
|
||||
#define MIP_E_SNLIM 1202 /* subproblems limit exhausted */
|
||||
#define MIP_E_TMLIM 1203 /* time limit exhausted */
|
||||
#define MIP_E_ERROR 1204 /* can't solve LP relaxation */
|
||||
|
||||
MIPTREE *mip_create_tree(LPX *mip,
|
||||
void *info, void appl(void *info, MIPTREE *tree));
|
||||
/* create MIP solver wprkspace */
|
||||
|
||||
int mip_driver(MIPTREE *tree);
|
||||
/* branch-and-bound driver */
|
||||
|
||||
void mip_delete_tree(MIPTREE *tree);
|
||||
/* delete MIP solver workspace */
|
||||
|
||||
#endif
|
||||
|
||||
/* eof */
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,318 @@
|
||||
/* glpmps.h */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _GLPMPS_H
|
||||
#define _GLPMPS_H
|
||||
|
||||
#define load_mps glp_load_mps
|
||||
#define free_mps glp_free_mps
|
||||
|
||||
typedef struct MPS MPS;
|
||||
typedef struct MPSROW MPSROW;
|
||||
typedef struct MPSCOL MPSCOL;
|
||||
typedef struct MPSCQE MPSCQE;
|
||||
typedef struct MPSBND MPSBND;
|
||||
typedef struct MPSBQE MPSBQE;
|
||||
typedef struct MPSQFE MPSQFE;
|
||||
|
||||
struct MPS
|
||||
{ /* linear programming model in MPS format */
|
||||
DMP *pool;
|
||||
/* memory pool holding all relevant data structures */
|
||||
char *name;
|
||||
/* model name */
|
||||
int n_row;
|
||||
/* number of rows */
|
||||
int n_col;
|
||||
/* number of columns */
|
||||
int n_rhs;
|
||||
/* number of right-hand side constraint vectors */
|
||||
int n_rng;
|
||||
/* number of range vectors */
|
||||
int n_bnd;
|
||||
/* number of bound vectors */
|
||||
MPSROW **row; /* MPSROW *row[1+n_row]; */
|
||||
/* ordered list of rows */
|
||||
MPSCOL **col; /* MPSCOL *col[1+n_col]; */
|
||||
/* ordered list of columns */
|
||||
MPSCOL **rhs; /* MPSCOL *rhs[1+n_rhs]; */
|
||||
/* ordered list of right-hand side constraint vectors */
|
||||
MPSCOL **rng; /* MPSCOL *rng[1+n_rng]; */
|
||||
/* ordered list of range vectors */
|
||||
MPSBND **bnd; /* MPSBND *bnd[1+n_bnd]; */
|
||||
/* ordered list of bound vectors */
|
||||
MPSQFE *quad;
|
||||
/* pointer to the linked list of quadratic form elements; these
|
||||
elements specify quadratic part of the objective function */
|
||||
};
|
||||
|
||||
struct MPSROW
|
||||
{ /* row (constraint) */
|
||||
char *name;
|
||||
/* row name */
|
||||
char type[2+1];
|
||||
/* row type:
|
||||
"N" - no constraint
|
||||
"G" - greater than or equal to
|
||||
"L" - less than or equal to
|
||||
"E" - equality */
|
||||
};
|
||||
|
||||
struct MPSCOL
|
||||
{ /* column (structural variable), right-hand side constraint
|
||||
vector, or range vector */
|
||||
char *name;
|
||||
/* column or vector name */
|
||||
int flag;
|
||||
/* column flag:
|
||||
0 - continuous variable
|
||||
1 - integer variable (between INTORG and INTEND markers) */
|
||||
MPSCQE *ptr;
|
||||
/* pointer to the linked list of column or vector elements */
|
||||
};
|
||||
|
||||
struct MPSCQE
|
||||
{ /* column or vector element */
|
||||
int ind;
|
||||
/* row number */
|
||||
double val;
|
||||
/* element value */
|
||||
MPSCQE *next;
|
||||
/* pointer to the next element of the same column or vector (in
|
||||
this list elements follow in the same order as in the original
|
||||
MPS file) */
|
||||
};
|
||||
|
||||
struct MPSBND
|
||||
{ /* bound vector */
|
||||
char *name;
|
||||
/* vector name */
|
||||
MPSBQE *ptr;
|
||||
/* pointer to the linked list of vector elements */
|
||||
};
|
||||
|
||||
struct MPSBQE
|
||||
{ /* bound vector element */
|
||||
char type[2+1];
|
||||
/* bound type:
|
||||
"LO" - lower bound
|
||||
"UP" - upper bound
|
||||
"FX" - fixed value
|
||||
"FR" - free variable
|
||||
"MI" - no lower bound (lower bound is -inf)
|
||||
"PL" - no upper bound (upper bound is +inf)
|
||||
"UI" - upper integer
|
||||
"BV" - binary variable */
|
||||
int ind;
|
||||
/* column number */
|
||||
double val;
|
||||
/* element value */
|
||||
MPSBQE *next;
|
||||
/* pointer to the next element of the same bound vector (in this
|
||||
list elements follow in the same order as in the original MPS
|
||||
file) */
|
||||
};
|
||||
|
||||
struct MPSQFE
|
||||
{ /* quadratic form element */
|
||||
int ind1;
|
||||
/* first column number */
|
||||
int ind2;
|
||||
/* second column number */
|
||||
double val;
|
||||
/* element value */
|
||||
MPSQFE *next;
|
||||
/* pointer to the next element (in this list elements follow in
|
||||
the same order as in the original MPS file) */
|
||||
};
|
||||
|
||||
extern MPS *load_mps(char *fname);
|
||||
/* load linear programming model in MPS format */
|
||||
|
||||
extern void free_mps(MPS *mps);
|
||||
/* free linear programming model in MPS format */
|
||||
|
||||
#endif
|
||||
|
||||
/* eof */
|
||||
/* glpmps.h */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _GLPMPS_H
|
||||
#define _GLPMPS_H
|
||||
|
||||
#define load_mps glp_load_mps
|
||||
#define free_mps glp_free_mps
|
||||
|
||||
typedef struct MPS MPS;
|
||||
typedef struct MPSROW MPSROW;
|
||||
typedef struct MPSCOL MPSCOL;
|
||||
typedef struct MPSCQE MPSCQE;
|
||||
typedef struct MPSBND MPSBND;
|
||||
typedef struct MPSBQE MPSBQE;
|
||||
typedef struct MPSQFE MPSQFE;
|
||||
|
||||
struct MPS
|
||||
{ /* linear programming model in MPS format */
|
||||
DMP *pool;
|
||||
/* memory pool holding all relevant data structures */
|
||||
char *name;
|
||||
/* model name */
|
||||
int n_row;
|
||||
/* number of rows */
|
||||
int n_col;
|
||||
/* number of columns */
|
||||
int n_rhs;
|
||||
/* number of right-hand side constraint vectors */
|
||||
int n_rng;
|
||||
/* number of range vectors */
|
||||
int n_bnd;
|
||||
/* number of bound vectors */
|
||||
MPSROW **row; /* MPSROW *row[1+n_row]; */
|
||||
/* ordered list of rows */
|
||||
MPSCOL **col; /* MPSCOL *col[1+n_col]; */
|
||||
/* ordered list of columns */
|
||||
MPSCOL **rhs; /* MPSCOL *rhs[1+n_rhs]; */
|
||||
/* ordered list of right-hand side constraint vectors */
|
||||
MPSCOL **rng; /* MPSCOL *rng[1+n_rng]; */
|
||||
/* ordered list of range vectors */
|
||||
MPSBND **bnd; /* MPSBND *bnd[1+n_bnd]; */
|
||||
/* ordered list of bound vectors */
|
||||
MPSQFE *quad;
|
||||
/* pointer to the linked list of quadratic form elements; these
|
||||
elements specify quadratic part of the objective function */
|
||||
};
|
||||
|
||||
struct MPSROW
|
||||
{ /* row (constraint) */
|
||||
char *name;
|
||||
/* row name */
|
||||
char type[2+1];
|
||||
/* row type:
|
||||
"N" - no constraint
|
||||
"G" - greater than or equal to
|
||||
"L" - less than or equal to
|
||||
"E" - equality */
|
||||
};
|
||||
|
||||
struct MPSCOL
|
||||
{ /* column (structural variable), right-hand side constraint
|
||||
vector, or range vector */
|
||||
char *name;
|
||||
/* column or vector name */
|
||||
int flag;
|
||||
/* column flag:
|
||||
0 - continuous variable
|
||||
1 - integer variable (between INTORG and INTEND markers) */
|
||||
MPSCQE *ptr;
|
||||
/* pointer to the linked list of column or vector elements */
|
||||
};
|
||||
|
||||
struct MPSCQE
|
||||
{ /* column or vector element */
|
||||
int ind;
|
||||
/* row number */
|
||||
double val;
|
||||
/* element value */
|
||||
MPSCQE *next;
|
||||
/* pointer to the next element of the same column or vector (in
|
||||
this list elements follow in the same order as in the original
|
||||
MPS file) */
|
||||
};
|
||||
|
||||
struct MPSBND
|
||||
{ /* bound vector */
|
||||
char *name;
|
||||
/* vector name */
|
||||
MPSBQE *ptr;
|
||||
/* pointer to the linked list of vector elements */
|
||||
};
|
||||
|
||||
struct MPSBQE
|
||||
{ /* bound vector element */
|
||||
char type[2+1];
|
||||
/* bound type:
|
||||
"LO" - lower bound
|
||||
"UP" - upper bound
|
||||
"FX" - fixed value
|
||||
"FR" - free variable
|
||||
"MI" - no lower bound (lower bound is -inf)
|
||||
"PL" - no upper bound (upper bound is +inf)
|
||||
"UI" - upper integer
|
||||
"BV" - binary variable */
|
||||
int ind;
|
||||
/* column number */
|
||||
double val;
|
||||
/* element value */
|
||||
MPSBQE *next;
|
||||
/* pointer to the next element of the same bound vector (in this
|
||||
list elements follow in the same order as in the original MPS
|
||||
file) */
|
||||
};
|
||||
|
||||
struct MPSQFE
|
||||
{ /* quadratic form element */
|
||||
int ind1;
|
||||
/* first column number */
|
||||
int ind2;
|
||||
/* second column number */
|
||||
double val;
|
||||
/* element value */
|
||||
MPSQFE *next;
|
||||
/* pointer to the next element (in this list elements follow in
|
||||
the same order as in the original MPS file) */
|
||||
};
|
||||
|
||||
extern MPS *load_mps(char *fname);
|
||||
/* load linear programming model in MPS format */
|
||||
|
||||
extern void free_mps(MPS *mps);
|
||||
/* free linear programming model in MPS format */
|
||||
|
||||
#endif
|
||||
|
||||
/* eof */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,142 @@
|
||||
/* glpqmd.h */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- THIS CODE IS THE RESULT OF TRANSLATION OF THE FORTRAN SUBROUTINES
|
||||
-- GENQMD, QMDRCH, QMDQT, QMDUPD, AND QMDMRG FROM THE BOOK:
|
||||
--
|
||||
-- ALAN GEORGE, JOSEPH W-H LIU. COMPUTER SOLUTION OF LARGE SPARSE
|
||||
-- POSITIVE DEFINITE SYSTEMS. PRENTICE-HALL, 1981.
|
||||
--
|
||||
-- THE TRANSLATION HAS BEEN DONE WITH THE PERMISSION OF THE AUTHORS
|
||||
-- OF THE ORIGINAL FORTRAN SUBROUTINES: ALAN GEORGE AND JOSEPH LIU,
|
||||
-- UNIVERSITY OF WATERLOO, WATERLOO, ONTARIO, CANADA.
|
||||
--
|
||||
-- The translation was made by Andrew Makhorin <mao@mai2.rcnet.ru>,
|
||||
-- <mao@gnu.org>, Department for Applied Informatics, Moscow Aviation
|
||||
-- Institute, Moscow, Russia.
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _GLPQMD_H
|
||||
#define _GLPQMD_H
|
||||
|
||||
#define genqmd glp_genqmd
|
||||
#define qmdrch glp_qmdrch
|
||||
#define qmdqt glp_qmdqt
|
||||
#define qmdupd glp_qmdupd
|
||||
#define qmdmrg glp_qmdmrg
|
||||
|
||||
extern void genqmd(int *neqns, int xadj[], int adjncy[], int perm[],
|
||||
int invp[], int deg[], int marker[], int rchset[], int nbrhd[],
|
||||
int qsize[], int qlink[], int *nofsub);
|
||||
/* GENeral Quotient Minimum Degree algorithm */
|
||||
|
||||
extern void qmdrch(int *root, int xadj[], int adjncy[], int deg[],
|
||||
int marker[], int *rchsze, int rchset[], int *nhdsze,
|
||||
int nbrhd[]);
|
||||
/* Quotient MD ReaCHable set */
|
||||
|
||||
extern void qmdqt(int *root, int xadj[], int adjncy[], int marker[],
|
||||
int *rchsze, int rchset[], int nbrhd[]);
|
||||
/* Quotient MD Quotient graph Transformation */
|
||||
|
||||
extern void qmdupd(int xadj[], int adjncy[], int *nlist, int list[],
|
||||
int deg[], int qsize[], int qlink[], int marker[], int rchset[],
|
||||
int nbrhd[]);
|
||||
/* Quotient MD UPDate */
|
||||
|
||||
extern void qmdmrg(int xadj[], int adjncy[], int deg[], int qsize[],
|
||||
int qlink[], int marker[], int *deg0, int *nhdsze, int nbrhd[],
|
||||
int rchset[], int ovrlp[]);
|
||||
/* Quotient MD MeRGe */
|
||||
|
||||
#endif
|
||||
|
||||
/* eof */
|
||||
/* glpqmd.h */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- THIS CODE IS THE RESULT OF TRANSLATION OF THE FORTRAN SUBROUTINES
|
||||
-- GENQMD, QMDRCH, QMDQT, QMDUPD, AND QMDMRG FROM THE BOOK:
|
||||
--
|
||||
-- ALAN GEORGE, JOSEPH W-H LIU. COMPUTER SOLUTION OF LARGE SPARSE
|
||||
-- POSITIVE DEFINITE SYSTEMS. PRENTICE-HALL, 1981.
|
||||
--
|
||||
-- THE TRANSLATION HAS BEEN DONE WITH THE PERMISSION OF THE AUTHORS
|
||||
-- OF THE ORIGINAL FORTRAN SUBROUTINES: ALAN GEORGE AND JOSEPH LIU,
|
||||
-- UNIVERSITY OF WATERLOO, WATERLOO, ONTARIO, CANADA.
|
||||
--
|
||||
-- The translation was made by Andrew Makhorin <mao@mai2.rcnet.ru>,
|
||||
-- <mao@gnu.org>, Department for Applied Informatics, Moscow Aviation
|
||||
-- Institute, Moscow, Russia.
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _GLPQMD_H
|
||||
#define _GLPQMD_H
|
||||
|
||||
#define genqmd glp_genqmd
|
||||
#define qmdrch glp_qmdrch
|
||||
#define qmdqt glp_qmdqt
|
||||
#define qmdupd glp_qmdupd
|
||||
#define qmdmrg glp_qmdmrg
|
||||
|
||||
extern void genqmd(int *neqns, int xadj[], int adjncy[], int perm[],
|
||||
int invp[], int deg[], int marker[], int rchset[], int nbrhd[],
|
||||
int qsize[], int qlink[], int *nofsub);
|
||||
/* GENeral Quotient Minimum Degree algorithm */
|
||||
|
||||
extern void qmdrch(int *root, int xadj[], int adjncy[], int deg[],
|
||||
int marker[], int *rchsze, int rchset[], int *nhdsze,
|
||||
int nbrhd[]);
|
||||
/* Quotient MD ReaCHable set */
|
||||
|
||||
extern void qmdqt(int *root, int xadj[], int adjncy[], int marker[],
|
||||
int *rchsze, int rchset[], int nbrhd[]);
|
||||
/* Quotient MD Quotient graph Transformation */
|
||||
|
||||
extern void qmdupd(int xadj[], int adjncy[], int *nlist, int list[],
|
||||
int deg[], int qsize[], int qlink[], int marker[], int rchset[],
|
||||
int nbrhd[]);
|
||||
/* Quotient MD UPDate */
|
||||
|
||||
extern void qmdmrg(int xadj[], int adjncy[], int deg[], int qsize[],
|
||||
int qlink[], int marker[], int *deg0, int *nhdsze, int nbrhd[],
|
||||
int rchset[], int ovrlp[]);
|
||||
/* Quotient MD MeRGe */
|
||||
|
||||
#endif
|
||||
|
||||
/* eof */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,344 @@
|
||||
/* glpspm.h */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _GLPSPM_H
|
||||
#define _GLPSPM_H
|
||||
|
||||
#define spm_create glp_spm_create
|
||||
#define spm_check_data glp_spm_check_data
|
||||
#define spm_realloc glp_spm_realloc
|
||||
#define spm_add_rows glp_spm_add_rows
|
||||
#define spm_add_cols glp_spm_add_cols
|
||||
#define spm_load_data glp_spm_load_data
|
||||
#define spm_defrag_sva glp_spm_defrag_sva
|
||||
#define spm_enlarge_cap glp_spm_enlarge_cap
|
||||
#define spm_set_row glp_spm_set_row
|
||||
#define spm_set_col glp_spm_set_col
|
||||
#define spm_clear_rows glp_spm_clear_rows
|
||||
#define spm_clear_cols glp_spm_clear_cols
|
||||
#define spm_del_rows glp_spm_del_rows
|
||||
#define spm_del_cols glp_spm_del_cols
|
||||
#define spm_delete glp_spm_delete
|
||||
|
||||
typedef struct SPM SPM;
|
||||
|
||||
struct SPM
|
||||
{ /* sparse matrix in row/column-wise format */
|
||||
int m_max;
|
||||
/* maximal number of rows (if necessary, this parameter can be
|
||||
automatically changed) */
|
||||
int n_max;
|
||||
/* maximal number of columns (if necessary, this parameter can be
|
||||
automatically changed) */
|
||||
int m;
|
||||
/* current number of rows, 0 <= m <= m_max */
|
||||
int n;
|
||||
/* current number of columns, 0 <= n <= n_max */
|
||||
int *ptr; /* int ptr[1+m_max+n_max]; */
|
||||
/* ptr[0] is not used;
|
||||
ptr[i], 1 <= i <= m, is a pointer to the first element of the
|
||||
i-th row in the sparse vector area;
|
||||
ptr[m+j], 1 <= j <= n, is a pointer to the first element of the
|
||||
j-th column in the sparse vector area */
|
||||
int *len; /* int len[1+m_max+n_max]; */
|
||||
/* len[0] is not used;
|
||||
len[i], 1 <= i <= m, is number of (non-zero) elements in the
|
||||
i-th row, 0 <= len[i] <= n;
|
||||
len[m+j], 1 <= j <= n, is number of (non-zero) elements in the
|
||||
j-th column, 0 <= len[m+j] <= m */
|
||||
int *cap; /* int cap[1+m_max+n_max]; */
|
||||
/* cap[0] is not used;
|
||||
cap[i], 1 <= i <= m, is capacity of the i-th row; this is
|
||||
number of locations, which can be used without relocating the
|
||||
row, cap[i] >= len[i];
|
||||
cap[m+j], 1 <= j <= n, is capacity of the j-th column; this is
|
||||
number of locations, which can be used without relocating the
|
||||
column, cap[m+j] >= len[m+j] */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* sparse vector area (SVA) is a set of locations intended to
|
||||
store sparse vectors that represent rows and columns of the
|
||||
matrix; each location is a doublet (ndx, val), where ndx is an
|
||||
index and val is a numerical value of sparse vector element;
|
||||
in the whole each sparse vector is a set of adjacent locations
|
||||
defined by a pointer to the first element ptr[*] and number of
|
||||
its non-zero elements len[*] */
|
||||
int size;
|
||||
/* current size of SVA, in locations; locations are numbered by
|
||||
integers 1, 2, ..., size (the location number 0 is not used);
|
||||
if necessary, this parameter can be automatically changed */
|
||||
int used;
|
||||
/* locations that have the numbers 1, 2, ..., used are used by
|
||||
rows and columns of the matrix (this extent may contain holes
|
||||
because of fragmentation);
|
||||
locations that have the numbers used+1, used+2, ..., size are
|
||||
currently free;
|
||||
total number of free locations is (size - used) */
|
||||
int *ndx; /* int ndx[1+size]; */
|
||||
/* ndx[0] is not used;
|
||||
ndx[k] is the index field of the k-th location */
|
||||
double *val; /* double val[1+size]; */
|
||||
/* val[0] is not used;
|
||||
val[k] is the value field of the k-th location */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* in order to efficiently defragment SVA a doubly linked list of
|
||||
rows and columns is used, where rows have numbers 1, ..., m,
|
||||
and column have numbers m+1, ..., m+n, so each row and column
|
||||
can be uniquely identified by only one integer; in this linked
|
||||
rows and columns are ordered by ascending their pointers */
|
||||
int head;
|
||||
/* the number of the leftmost (in SVA) row/column */
|
||||
int tail;
|
||||
/* the number of the rightmost (in SVA) row/column */
|
||||
int *prev; /* int prev[1+m_max+n_max]; */
|
||||
/* prev[k], 1 <= k <= m+n, is the number of a row/column, which
|
||||
precedes (in SVA) the k-th row/column */
|
||||
int *next; /* int next[1+m_max+n_max]; */
|
||||
/* next[k], 1 <= k <= m+n, is the number of a row/column, which
|
||||
succedes (in SVA) the k-th row/column */
|
||||
};
|
||||
|
||||
SPM *spm_create(void);
|
||||
/* create sparse matrix */
|
||||
|
||||
void spm_check_data(SPM *A);
|
||||
/* check sparse matrix data structure */
|
||||
|
||||
void spm_realloc(SPM *A, int m_max, int n_max);
|
||||
/* reallocate sparse matrix */
|
||||
|
||||
void spm_add_rows(SPM *A, int nrs);
|
||||
/* add new rows to sparse matrix */
|
||||
|
||||
void spm_add_cols(SPM *A, int ncs);
|
||||
/* add new columns to sparse matrix */
|
||||
|
||||
void spm_load_data(SPM *A,
|
||||
void *info, double (*mat)(void *info, int *i, int *j));
|
||||
/* load sparse matrix data */
|
||||
|
||||
void spm_defrag_sva(SPM *A);
|
||||
/* defragment the sparse vector area */
|
||||
|
||||
int spm_enlarge_cap(SPM *A, int k, int new_cap);
|
||||
/* enlarge capacity of row or column */
|
||||
|
||||
void spm_set_row(SPM *A, int i, int len, int ndx[], double val[],
|
||||
double R[], double S[]);
|
||||
/* set (replace) row of sparse matrix */
|
||||
|
||||
void spm_set_col(SPM *A, int j, int len, int ndx[], double val[],
|
||||
double R[], double S[]);
|
||||
/* set (replace) column of sparse matrix */
|
||||
|
||||
void spm_clear_rows(SPM *A, int mark[]);
|
||||
/* clear marked rows of sparse matrix */
|
||||
|
||||
void spm_clear_cols(SPM *A, int mark[]);
|
||||
/* clear marked columns of sparse matrix */
|
||||
|
||||
void spm_del_rows(SPM *A, int mark[]);
|
||||
/* delete marked rows of sparse matrix */
|
||||
|
||||
void spm_del_cols(SPM *A, int mark[]);
|
||||
/* delete marked columns of sparse matrix */
|
||||
|
||||
void spm_delete(SPM *A);
|
||||
/* delete sparse matrix */
|
||||
|
||||
#endif
|
||||
|
||||
/* eof */
|
||||
/* glpspm.h */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _GLPSPM_H
|
||||
#define _GLPSPM_H
|
||||
|
||||
#define spm_create glp_spm_create
|
||||
#define spm_check_data glp_spm_check_data
|
||||
#define spm_realloc glp_spm_realloc
|
||||
#define spm_add_rows glp_spm_add_rows
|
||||
#define spm_add_cols glp_spm_add_cols
|
||||
#define spm_load_data glp_spm_load_data
|
||||
#define spm_defrag_sva glp_spm_defrag_sva
|
||||
#define spm_enlarge_cap glp_spm_enlarge_cap
|
||||
#define spm_set_row glp_spm_set_row
|
||||
#define spm_set_col glp_spm_set_col
|
||||
#define spm_clear_rows glp_spm_clear_rows
|
||||
#define spm_clear_cols glp_spm_clear_cols
|
||||
#define spm_del_rows glp_spm_del_rows
|
||||
#define spm_del_cols glp_spm_del_cols
|
||||
#define spm_delete glp_spm_delete
|
||||
|
||||
typedef struct SPM SPM;
|
||||
|
||||
struct SPM
|
||||
{ /* sparse matrix in row/column-wise format */
|
||||
int m_max;
|
||||
/* maximal number of rows (if necessary, this parameter can be
|
||||
automatically changed) */
|
||||
int n_max;
|
||||
/* maximal number of columns (if necessary, this parameter can be
|
||||
automatically changed) */
|
||||
int m;
|
||||
/* current number of rows, 0 <= m <= m_max */
|
||||
int n;
|
||||
/* current number of columns, 0 <= n <= n_max */
|
||||
int *ptr; /* int ptr[1+m_max+n_max]; */
|
||||
/* ptr[0] is not used;
|
||||
ptr[i], 1 <= i <= m, is a pointer to the first element of the
|
||||
i-th row in the sparse vector area;
|
||||
ptr[m+j], 1 <= j <= n, is a pointer to the first element of the
|
||||
j-th column in the sparse vector area */
|
||||
int *len; /* int len[1+m_max+n_max]; */
|
||||
/* len[0] is not used;
|
||||
len[i], 1 <= i <= m, is number of (non-zero) elements in the
|
||||
i-th row, 0 <= len[i] <= n;
|
||||
len[m+j], 1 <= j <= n, is number of (non-zero) elements in the
|
||||
j-th column, 0 <= len[m+j] <= m */
|
||||
int *cap; /* int cap[1+m_max+n_max]; */
|
||||
/* cap[0] is not used;
|
||||
cap[i], 1 <= i <= m, is capacity of the i-th row; this is
|
||||
number of locations, which can be used without relocating the
|
||||
row, cap[i] >= len[i];
|
||||
cap[m+j], 1 <= j <= n, is capacity of the j-th column; this is
|
||||
number of locations, which can be used without relocating the
|
||||
column, cap[m+j] >= len[m+j] */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* sparse vector area (SVA) is a set of locations intended to
|
||||
store sparse vectors that represent rows and columns of the
|
||||
matrix; each location is a doublet (ndx, val), where ndx is an
|
||||
index and val is a numerical value of sparse vector element;
|
||||
in the whole each sparse vector is a set of adjacent locations
|
||||
defined by a pointer to the first element ptr[*] and number of
|
||||
its non-zero elements len[*] */
|
||||
int size;
|
||||
/* current size of SVA, in locations; locations are numbered by
|
||||
integers 1, 2, ..., size (the location number 0 is not used);
|
||||
if necessary, this parameter can be automatically changed */
|
||||
int used;
|
||||
/* locations that have the numbers 1, 2, ..., used are used by
|
||||
rows and columns of the matrix (this extent may contain holes
|
||||
because of fragmentation);
|
||||
locations that have the numbers used+1, used+2, ..., size are
|
||||
currently free;
|
||||
total number of free locations is (size - used) */
|
||||
int *ndx; /* int ndx[1+size]; */
|
||||
/* ndx[0] is not used;
|
||||
ndx[k] is the index field of the k-th location */
|
||||
double *val; /* double val[1+size]; */
|
||||
/* val[0] is not used;
|
||||
val[k] is the value field of the k-th location */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* in order to efficiently defragment SVA a doubly linked list of
|
||||
rows and columns is used, where rows have numbers 1, ..., m,
|
||||
and column have numbers m+1, ..., m+n, so each row and column
|
||||
can be uniquely identified by only one integer; in this linked
|
||||
rows and columns are ordered by ascending their pointers */
|
||||
int head;
|
||||
/* the number of the leftmost (in SVA) row/column */
|
||||
int tail;
|
||||
/* the number of the rightmost (in SVA) row/column */
|
||||
int *prev; /* int prev[1+m_max+n_max]; */
|
||||
/* prev[k], 1 <= k <= m+n, is the number of a row/column, which
|
||||
precedes (in SVA) the k-th row/column */
|
||||
int *next; /* int next[1+m_max+n_max]; */
|
||||
/* next[k], 1 <= k <= m+n, is the number of a row/column, which
|
||||
succedes (in SVA) the k-th row/column */
|
||||
};
|
||||
|
||||
SPM *spm_create(void);
|
||||
/* create sparse matrix */
|
||||
|
||||
void spm_check_data(SPM *A);
|
||||
/* check sparse matrix data structure */
|
||||
|
||||
void spm_realloc(SPM *A, int m_max, int n_max);
|
||||
/* reallocate sparse matrix */
|
||||
|
||||
void spm_add_rows(SPM *A, int nrs);
|
||||
/* add new rows to sparse matrix */
|
||||
|
||||
void spm_add_cols(SPM *A, int ncs);
|
||||
/* add new columns to sparse matrix */
|
||||
|
||||
void spm_load_data(SPM *A,
|
||||
void *info, double (*mat)(void *info, int *i, int *j));
|
||||
/* load sparse matrix data */
|
||||
|
||||
void spm_defrag_sva(SPM *A);
|
||||
/* defragment the sparse vector area */
|
||||
|
||||
int spm_enlarge_cap(SPM *A, int k, int new_cap);
|
||||
/* enlarge capacity of row or column */
|
||||
|
||||
void spm_set_row(SPM *A, int i, int len, int ndx[], double val[],
|
||||
double R[], double S[]);
|
||||
/* set (replace) row of sparse matrix */
|
||||
|
||||
void spm_set_col(SPM *A, int j, int len, int ndx[], double val[],
|
||||
double R[], double S[]);
|
||||
/* set (replace) column of sparse matrix */
|
||||
|
||||
void spm_clear_rows(SPM *A, int mark[]);
|
||||
/* clear marked rows of sparse matrix */
|
||||
|
||||
void spm_clear_cols(SPM *A, int mark[]);
|
||||
/* clear marked columns of sparse matrix */
|
||||
|
||||
void spm_del_rows(SPM *A, int mark[]);
|
||||
/* delete marked rows of sparse matrix */
|
||||
|
||||
void spm_del_cols(SPM *A, int mark[]);
|
||||
/* delete marked columns of sparse matrix */
|
||||
|
||||
void spm_delete(SPM *A);
|
||||
/* delete sparse matrix */
|
||||
|
||||
#endif
|
||||
|
||||
/* eof */
|
||||
@@ -0,0 +1,460 @@
|
||||
/* glpspx.h */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _GLPSPX_H
|
||||
#define _GLPSPX_H
|
||||
|
||||
#include "glplpx.h"
|
||||
|
||||
#define spx_invert glp_spx_invert
|
||||
#define spx_ftran glp_spx_ftran
|
||||
#define spx_btran glp_spx_btran
|
||||
#define spx_update glp_spx_update
|
||||
|
||||
#define spx_eval_xn_j glp_spx_eval_xn_j
|
||||
#define spx_eval_bbar glp_spx_eval_bbar
|
||||
#define spx_eval_pi glp_spx_eval_pi
|
||||
#define spx_eval_cbar glp_spx_eval_cbar
|
||||
#define spx_eval_obj glp_spx_eval_obj
|
||||
#define spx_eval_col glp_spx_eval_col
|
||||
#define spx_eval_rho glp_spx_eval_rho
|
||||
#define spx_eval_row glp_spx_eval_row
|
||||
#define spx_check_bbar glp_spx_check_bbar
|
||||
#define spx_check_cbar glp_spx_check_cbar
|
||||
#define spx_prim_chuzc glp_spx_prim_chuzc
|
||||
#define spx_prim_chuzr glp_spx_prim_chuzr
|
||||
#define spx_dual_chuzr glp_spx_dual_chuzr
|
||||
#define spx_dual_chuzc glp_spx_dual_chuzc
|
||||
#define spx_update_bbar glp_spx_update_bbar
|
||||
#define spx_update_pi glp_spx_update_pi
|
||||
#define spx_update_cbar glp_spx_update_cbar
|
||||
#define spx_change_basis glp_spx_change_basis
|
||||
#define spx_err_in_bbar glp_spx_err_in_bbar
|
||||
#define spx_err_in_pi glp_spx_err_in_pi
|
||||
#define spx_err_in_cbar glp_spx_err_in_cbar
|
||||
#define spx_reset_refsp glp_spx_reset_refsp
|
||||
#define spx_update_gvec glp_spx_update_gvec
|
||||
#define spx_err_in_gvec glp_spx_err_in_gvec
|
||||
#define spx_update_dvec glp_spx_update_dvec
|
||||
#define spx_err_in_dvec glp_spx_err_in_dvec
|
||||
|
||||
typedef struct SPX SPX;
|
||||
|
||||
struct SPX
|
||||
{ /* common block used by the simplex method routines */
|
||||
LPX *lp;
|
||||
/* LP problem object */
|
||||
int meth;
|
||||
/* what method is used:
|
||||
'P' - primal simplex
|
||||
'D' - dual simplex */
|
||||
int p;
|
||||
/* the number of basic variable xB[p], 1 <= p <= m, chosen to
|
||||
leave the basis; the special case p < 0 means that non-basic
|
||||
double-bounded variable xN[q] just goes to its opposite bound,
|
||||
and the basis remains unchanged; p = 0 means that no choice
|
||||
can be made (in the case of primal simplex non-basic variable
|
||||
xN[q] can infinitely change, in the case of dual simplex the
|
||||
current basis is primal feasible) */
|
||||
int p_tag;
|
||||
/* if 1 <= p <= m, p_tag is a non-basic tag, which should be set
|
||||
for the variable xB[p] after it has left the basis */
|
||||
int q;
|
||||
/* the number of non-basic variable xN[q], 1 <= q <= n, chosen to
|
||||
enter the basis; q = 0 means that no choice can be made (in
|
||||
the case of primal simplex the current basis is dual feasible,
|
||||
in the case of dual simplex the dual variable that corresponds
|
||||
to xB[p] can infinitely change) */
|
||||
double *zeta; /* double zeta[1+m]; */
|
||||
/* the p-th row of the inverse inv(B) */
|
||||
double *ap; /* double ap[1+n]; */
|
||||
/* the p-th row of the current simplex table:
|
||||
ap[0] is not used;
|
||||
ap[j], 1 <= j <= n, is an influence coefficient, which defines
|
||||
how the non-basic variable xN[j] affects on the basic variable
|
||||
xB[p] = ... + ap[j] * xN[j] + ... */
|
||||
double *aq; /* double aq[1+m]; */
|
||||
/* the q-th column of the current simplex table;
|
||||
aq[0] is not used;
|
||||
aq[i], 1 <= i <= m, is an influence coefficient, which defines
|
||||
how the non-basic variable xN[q] affects on the basic variable
|
||||
xB[i] = ... + aq[i] * xN[q] + ... */
|
||||
double *gvec; /* double gvec[1+n]; */
|
||||
/* gvec[0] is not used;
|
||||
gvec[j], 1 <= j <= n, is a weight of non-basic variable xN[j];
|
||||
this vector is used to price non-basic variables in the primal
|
||||
simplex (for example, using the steepest edge technique) */
|
||||
double *dvec; /* double dvec[1+m]; */
|
||||
/* dvec[0] is not used;
|
||||
dvec[i], 1 <= i <= m, is a weight of basic variable xB[i]; it
|
||||
is used to price basic variables in the dual simplex */
|
||||
int *refsp; /* int refsp[1+m+n]; */
|
||||
/* the current reference space (used in the projected steepest
|
||||
edge technique); the flag refsp[k], 1 <= k <= m+n, is set if
|
||||
the variable x[k] belongs to the current reference space */
|
||||
int count;
|
||||
/* if this count (used in the projected steepest edge technique)
|
||||
gets zero, the reference space is automatically redefined */
|
||||
double *work; /* double work[1+m+n]; */
|
||||
/* working array (used for various purposes) */
|
||||
int *orig_typx; /* orig_typx[1+m+n]; */
|
||||
/* is used to save the original types of variables */
|
||||
double *orig_lb; /* orig_lb[1+m+n]; */
|
||||
/* is used to save the original lower bounds of variables */
|
||||
double *orig_ub; /* orig_ub[1+m+n]; */
|
||||
/* is used to save the original upper bounds of variables */
|
||||
int orig_dir;
|
||||
/* is used to save the original optimization direction */
|
||||
double *orig_coef; /* orig_coef[1+m+n]; */
|
||||
/* is used to save the original objective coefficients */
|
||||
};
|
||||
|
||||
/* basis maintenance routines ----------------------------------------*/
|
||||
|
||||
int spx_invert(LPX *lp);
|
||||
/* reinvert the basis matrix */
|
||||
|
||||
void spx_ftran(LPX *lp, double x[], int save);
|
||||
/* perform forward transformation (FTRAN) */
|
||||
|
||||
void spx_btran(LPX *lp, double x[]);
|
||||
/* perform backward transformation (BTRAN) */
|
||||
|
||||
int spx_update(LPX *lp, int j);
|
||||
/* update factorization for adjacent basis matrix */
|
||||
|
||||
/* generic simplex method routines -----------------------------------*/
|
||||
|
||||
double spx_eval_xn_j(LPX *lp, int j);
|
||||
/* determine value of non-basic variable */
|
||||
|
||||
void spx_eval_bbar(LPX *lp);
|
||||
/* compute values of basic variables */
|
||||
|
||||
void spx_eval_pi(LPX *lp);
|
||||
/* compute simplex multipliers */
|
||||
|
||||
void spx_eval_cbar(LPX *lp);
|
||||
/* compute reduced costs of non-basic variables */
|
||||
|
||||
double spx_eval_obj(LPX *lp);
|
||||
/* compute value of the objective function */
|
||||
|
||||
void spx_eval_col(LPX *lp, int j, double col[], int save);
|
||||
/* compute column of the simplex table */
|
||||
|
||||
void spx_eval_rho(LPX *lp, int i, double rho[]);
|
||||
/* compute row of the inverse */
|
||||
|
||||
void spx_eval_row(LPX *lp, double rho[], double row[]);
|
||||
/* compute row of the simplex table */
|
||||
|
||||
double spx_check_bbar(LPX *lp, double tol);
|
||||
/* check primal feasibility */
|
||||
|
||||
double spx_check_cbar(LPX *lp, double tol);
|
||||
/* check dual feasibility */
|
||||
|
||||
int spx_prim_chuzc(SPX *spx, double tol);
|
||||
/* choose non-basic variable (primal simplex) */
|
||||
|
||||
int spx_prim_chuzr(SPX *spx, double relax);
|
||||
/* choose basic variable (primal simplex) */
|
||||
|
||||
void spx_dual_chuzr(SPX *spx, double tol);
|
||||
/* choose basic variable (dual simplex) */
|
||||
|
||||
int spx_dual_chuzc(SPX *spx, double relax);
|
||||
/* choose non-basic variable (dual simplex) */
|
||||
|
||||
void spx_update_bbar(SPX *spx, double *obj);
|
||||
/* update values of basic variables */
|
||||
|
||||
void spx_update_pi(SPX *spx);
|
||||
/* update simplex multipliers */
|
||||
|
||||
void spx_update_cbar(SPX *spx, int all);
|
||||
/* update reduced costs of non-basic variables */
|
||||
|
||||
int spx_change_basis(SPX *spx);
|
||||
/* change basis and update the factorization */
|
||||
|
||||
double spx_err_in_bbar(SPX *spx);
|
||||
/* compute maximal absolute error in bbar */
|
||||
|
||||
double spx_err_in_pi(SPX *spx);
|
||||
/* compute maximal absolute error in pi */
|
||||
|
||||
double spx_err_in_cbar(SPX *spx, int all);
|
||||
/* compute maximal absolute error in cbar */
|
||||
|
||||
void spx_reset_refsp(SPX *spx);
|
||||
/* reset the reference space */
|
||||
|
||||
void spx_update_gvec(SPX *spx);
|
||||
/* update the vector gamma for adjacent basis */
|
||||
|
||||
double spx_err_in_gvec(SPX *spx);
|
||||
/* compute maximal absolute error in gvec */
|
||||
|
||||
void spx_update_dvec(SPX *spx);
|
||||
/* update the vector delta for adjacent basis */
|
||||
|
||||
double spx_err_in_dvec(SPX *spx);
|
||||
/* compute maximal absolute error in dvec */
|
||||
|
||||
#endif
|
||||
|
||||
/* eof */
|
||||
/* glpspx.h */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _GLPSPX_H
|
||||
#define _GLPSPX_H
|
||||
|
||||
#include "glplpx.h"
|
||||
|
||||
#define spx_invert glp_spx_invert
|
||||
#define spx_ftran glp_spx_ftran
|
||||
#define spx_btran glp_spx_btran
|
||||
#define spx_update glp_spx_update
|
||||
|
||||
#define spx_eval_xn_j glp_spx_eval_xn_j
|
||||
#define spx_eval_bbar glp_spx_eval_bbar
|
||||
#define spx_eval_pi glp_spx_eval_pi
|
||||
#define spx_eval_cbar glp_spx_eval_cbar
|
||||
#define spx_eval_obj glp_spx_eval_obj
|
||||
#define spx_eval_col glp_spx_eval_col
|
||||
#define spx_eval_rho glp_spx_eval_rho
|
||||
#define spx_eval_row glp_spx_eval_row
|
||||
#define spx_check_bbar glp_spx_check_bbar
|
||||
#define spx_check_cbar glp_spx_check_cbar
|
||||
#define spx_prim_chuzc glp_spx_prim_chuzc
|
||||
#define spx_prim_chuzr glp_spx_prim_chuzr
|
||||
#define spx_dual_chuzr glp_spx_dual_chuzr
|
||||
#define spx_dual_chuzc glp_spx_dual_chuzc
|
||||
#define spx_update_bbar glp_spx_update_bbar
|
||||
#define spx_update_pi glp_spx_update_pi
|
||||
#define spx_update_cbar glp_spx_update_cbar
|
||||
#define spx_change_basis glp_spx_change_basis
|
||||
#define spx_err_in_bbar glp_spx_err_in_bbar
|
||||
#define spx_err_in_pi glp_spx_err_in_pi
|
||||
#define spx_err_in_cbar glp_spx_err_in_cbar
|
||||
#define spx_reset_refsp glp_spx_reset_refsp
|
||||
#define spx_update_gvec glp_spx_update_gvec
|
||||
#define spx_err_in_gvec glp_spx_err_in_gvec
|
||||
#define spx_update_dvec glp_spx_update_dvec
|
||||
#define spx_err_in_dvec glp_spx_err_in_dvec
|
||||
|
||||
typedef struct SPX SPX;
|
||||
|
||||
struct SPX
|
||||
{ /* common block used by the simplex method routines */
|
||||
LPX *lp;
|
||||
/* LP problem object */
|
||||
int meth;
|
||||
/* what method is used:
|
||||
'P' - primal simplex
|
||||
'D' - dual simplex */
|
||||
int p;
|
||||
/* the number of basic variable xB[p], 1 <= p <= m, chosen to
|
||||
leave the basis; the special case p < 0 means that non-basic
|
||||
double-bounded variable xN[q] just goes to its opposite bound,
|
||||
and the basis remains unchanged; p = 0 means that no choice
|
||||
can be made (in the case of primal simplex non-basic variable
|
||||
xN[q] can infinitely change, in the case of dual simplex the
|
||||
current basis is primal feasible) */
|
||||
int p_tag;
|
||||
/* if 1 <= p <= m, p_tag is a non-basic tag, which should be set
|
||||
for the variable xB[p] after it has left the basis */
|
||||
int q;
|
||||
/* the number of non-basic variable xN[q], 1 <= q <= n, chosen to
|
||||
enter the basis; q = 0 means that no choice can be made (in
|
||||
the case of primal simplex the current basis is dual feasible,
|
||||
in the case of dual simplex the dual variable that corresponds
|
||||
to xB[p] can infinitely change) */
|
||||
double *zeta; /* double zeta[1+m]; */
|
||||
/* the p-th row of the inverse inv(B) */
|
||||
double *ap; /* double ap[1+n]; */
|
||||
/* the p-th row of the current simplex table:
|
||||
ap[0] is not used;
|
||||
ap[j], 1 <= j <= n, is an influence coefficient, which defines
|
||||
how the non-basic variable xN[j] affects on the basic variable
|
||||
xB[p] = ... + ap[j] * xN[j] + ... */
|
||||
double *aq; /* double aq[1+m]; */
|
||||
/* the q-th column of the current simplex table;
|
||||
aq[0] is not used;
|
||||
aq[i], 1 <= i <= m, is an influence coefficient, which defines
|
||||
how the non-basic variable xN[q] affects on the basic variable
|
||||
xB[i] = ... + aq[i] * xN[q] + ... */
|
||||
double *gvec; /* double gvec[1+n]; */
|
||||
/* gvec[0] is not used;
|
||||
gvec[j], 1 <= j <= n, is a weight of non-basic variable xN[j];
|
||||
this vector is used to price non-basic variables in the primal
|
||||
simplex (for example, using the steepest edge technique) */
|
||||
double *dvec; /* double dvec[1+m]; */
|
||||
/* dvec[0] is not used;
|
||||
dvec[i], 1 <= i <= m, is a weight of basic variable xB[i]; it
|
||||
is used to price basic variables in the dual simplex */
|
||||
int *refsp; /* int refsp[1+m+n]; */
|
||||
/* the current reference space (used in the projected steepest
|
||||
edge technique); the flag refsp[k], 1 <= k <= m+n, is set if
|
||||
the variable x[k] belongs to the current reference space */
|
||||
int count;
|
||||
/* if this count (used in the projected steepest edge technique)
|
||||
gets zero, the reference space is automatically redefined */
|
||||
double *work; /* double work[1+m+n]; */
|
||||
/* working array (used for various purposes) */
|
||||
int *orig_typx; /* orig_typx[1+m+n]; */
|
||||
/* is used to save the original types of variables */
|
||||
double *orig_lb; /* orig_lb[1+m+n]; */
|
||||
/* is used to save the original lower bounds of variables */
|
||||
double *orig_ub; /* orig_ub[1+m+n]; */
|
||||
/* is used to save the original upper bounds of variables */
|
||||
int orig_dir;
|
||||
/* is used to save the original optimization direction */
|
||||
double *orig_coef; /* orig_coef[1+m+n]; */
|
||||
/* is used to save the original objective coefficients */
|
||||
};
|
||||
|
||||
/* basis maintenance routines ----------------------------------------*/
|
||||
|
||||
int spx_invert(LPX *lp);
|
||||
/* reinvert the basis matrix */
|
||||
|
||||
void spx_ftran(LPX *lp, double x[], int save);
|
||||
/* perform forward transformation (FTRAN) */
|
||||
|
||||
void spx_btran(LPX *lp, double x[]);
|
||||
/* perform backward transformation (BTRAN) */
|
||||
|
||||
int spx_update(LPX *lp, int j);
|
||||
/* update factorization for adjacent basis matrix */
|
||||
|
||||
/* generic simplex method routines -----------------------------------*/
|
||||
|
||||
double spx_eval_xn_j(LPX *lp, int j);
|
||||
/* determine value of non-basic variable */
|
||||
|
||||
void spx_eval_bbar(LPX *lp);
|
||||
/* compute values of basic variables */
|
||||
|
||||
void spx_eval_pi(LPX *lp);
|
||||
/* compute simplex multipliers */
|
||||
|
||||
void spx_eval_cbar(LPX *lp);
|
||||
/* compute reduced costs of non-basic variables */
|
||||
|
||||
double spx_eval_obj(LPX *lp);
|
||||
/* compute value of the objective function */
|
||||
|
||||
void spx_eval_col(LPX *lp, int j, double col[], int save);
|
||||
/* compute column of the simplex table */
|
||||
|
||||
void spx_eval_rho(LPX *lp, int i, double rho[]);
|
||||
/* compute row of the inverse */
|
||||
|
||||
void spx_eval_row(LPX *lp, double rho[], double row[]);
|
||||
/* compute row of the simplex table */
|
||||
|
||||
double spx_check_bbar(LPX *lp, double tol);
|
||||
/* check primal feasibility */
|
||||
|
||||
double spx_check_cbar(LPX *lp, double tol);
|
||||
/* check dual feasibility */
|
||||
|
||||
int spx_prim_chuzc(SPX *spx, double tol);
|
||||
/* choose non-basic variable (primal simplex) */
|
||||
|
||||
int spx_prim_chuzr(SPX *spx, double relax);
|
||||
/* choose basic variable (primal simplex) */
|
||||
|
||||
void spx_dual_chuzr(SPX *spx, double tol);
|
||||
/* choose basic variable (dual simplex) */
|
||||
|
||||
int spx_dual_chuzc(SPX *spx, double relax);
|
||||
/* choose non-basic variable (dual simplex) */
|
||||
|
||||
void spx_update_bbar(SPX *spx, double *obj);
|
||||
/* update values of basic variables */
|
||||
|
||||
void spx_update_pi(SPX *spx);
|
||||
/* update simplex multipliers */
|
||||
|
||||
void spx_update_cbar(SPX *spx, int all);
|
||||
/* update reduced costs of non-basic variables */
|
||||
|
||||
int spx_change_basis(SPX *spx);
|
||||
/* change basis and update the factorization */
|
||||
|
||||
double spx_err_in_bbar(SPX *spx);
|
||||
/* compute maximal absolute error in bbar */
|
||||
|
||||
double spx_err_in_pi(SPX *spx);
|
||||
/* compute maximal absolute error in pi */
|
||||
|
||||
double spx_err_in_cbar(SPX *spx, int all);
|
||||
/* compute maximal absolute error in cbar */
|
||||
|
||||
void spx_reset_refsp(SPX *spx);
|
||||
/* reset the reference space */
|
||||
|
||||
void spx_update_gvec(SPX *spx);
|
||||
/* update the vector gamma for adjacent basis */
|
||||
|
||||
double spx_err_in_gvec(SPX *spx);
|
||||
/* compute maximal absolute error in gvec */
|
||||
|
||||
void spx_update_dvec(SPX *spx);
|
||||
/* update the vector delta for adjacent basis */
|
||||
|
||||
double spx_err_in_dvec(SPX *spx);
|
||||
/* compute maximal absolute error in dvec */
|
||||
|
||||
#endif
|
||||
|
||||
/* eof */
|
||||
@@ -0,0 +1,466 @@
|
||||
/* glpspx1.c (basis maintenance routines) */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#include <string.h>
|
||||
#include "glplib.h"
|
||||
#include "glpspx.h"
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- spx_invert - reinvert the basis matrix.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glpspx.h"
|
||||
-- int spx_invert(LPX *lp);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The routine spx_invert computes a factorization of the current basis
|
||||
-- matrix B specified by the arrays lp->tagx, lp->posx, and lp->indx.
|
||||
--
|
||||
-- *Returns*
|
||||
--
|
||||
-- The routine returns one of the following codes:
|
||||
--
|
||||
-- 0 - the basis matrix has been successfully factorized;
|
||||
-- 1 - the basis matrix is singular;
|
||||
-- 2 - the basis matrix is ill-conditioned.
|
||||
--
|
||||
-- In the case of non-zero return code the calling program can "repair"
|
||||
-- the basis matrix replacing linearly dependent columns by appropriate
|
||||
-- unity columns of auxiliary variable using information stored by the
|
||||
-- factorizing routine in the object lp->inv (for details see comments
|
||||
-- in the module GLPINV). */
|
||||
|
||||
static int inv_col(void *info, int j, int rn[], double bj[])
|
||||
{ /* this auxiliary routine returns row indices and numerical
|
||||
values of non-zero elements of the j-th column of the current
|
||||
basis matrix B, which has to be reinverted */
|
||||
LPX *lp = info;
|
||||
int m = lp->m;
|
||||
int n = lp->n;
|
||||
int *aa_ptr = lp->A->ptr;
|
||||
int *aa_len = lp->A->len;
|
||||
int *sv_ndx = lp->A->ndx;
|
||||
double *sv_val = lp->A->val;
|
||||
int *indx = lp->indx;
|
||||
int k, ptr, len, t;
|
||||
insist(1 <= j && j <= m);
|
||||
k = indx[j]; /* x[k] = xB[j] */
|
||||
insist(1 <= k && k <= m+n);
|
||||
if (k <= m)
|
||||
{ /* x[k] is auxiliary variable */
|
||||
len = 1;
|
||||
rn[1] = k;
|
||||
bj[1] = +1.0;
|
||||
}
|
||||
else
|
||||
{ /* x[k] is structural variable */
|
||||
ptr = aa_ptr[k];
|
||||
len = aa_len[k];
|
||||
memcpy(&rn[1], &sv_ndx[ptr], len * sizeof(int));
|
||||
memcpy(&bj[1], &sv_val[ptr], len * sizeof(double));
|
||||
for (t = len; t >= 1; t--) bj[t] = - bj[t];
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
int spx_invert(LPX *lp)
|
||||
{ static double piv_tol[1+3] = { 0.00, 0.10, 0.30, 0.70 };
|
||||
int try, ret;
|
||||
/* if the invertable form has a wrong size, delete it */
|
||||
if (lp->inv != NULL && lp->inv->m != lp->m)
|
||||
inv_delete(lp->inv), lp->inv = NULL;
|
||||
/* if the invertable form does not exist, create it */
|
||||
#if 0
|
||||
if (lp->inv == NULL) lp->inv = inv_create(lp->m, 100);
|
||||
#else
|
||||
if (lp->inv == NULL) lp->inv = inv_create(lp->m, 50);
|
||||
#endif
|
||||
/* try to factorize the basis matrix */
|
||||
for (try = 1; try <= 3; try++)
|
||||
{ if (try > 1 && lp->msg_lev >= 3)
|
||||
print("spx_invert: trying to factorize the basis using thre"
|
||||
"shold tolerance %g", piv_tol[try]);
|
||||
lp->inv->luf->piv_tol = piv_tol[try];
|
||||
ret = inv_decomp(lp->inv, lp, inv_col);
|
||||
if (ret == 0) break;
|
||||
}
|
||||
/* analyze the return code */
|
||||
switch (ret)
|
||||
{ case 0:
|
||||
/* success */
|
||||
lp->b_stat = LPX_B_VALID;
|
||||
break;
|
||||
case 1:
|
||||
if (lp->msg_lev >= 1)
|
||||
print("spx_invert: the basis matrix is singular");
|
||||
lp->b_stat = LPX_B_UNDEF;
|
||||
break;
|
||||
case 2:
|
||||
if (lp->msg_lev >= 1)
|
||||
print("spx_invert: the basis matrix is ill-conditioned");
|
||||
lp->b_stat = LPX_B_UNDEF;
|
||||
break;
|
||||
default:
|
||||
insist(ret != ret);
|
||||
}
|
||||
/* return to the calling program */
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- spx_ftran - perform forward transformation (FTRAN).
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glpspx.h"
|
||||
-- void spx_ftran(LPX *lp, double x[], int save);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The routine spx_ftran performs forward transformation (FTRAN) of the
|
||||
-- given vector using the factorization of the basis matrix.
|
||||
--
|
||||
-- In order to perform FTRAN the routine solves the system B*x' = x,
|
||||
-- where B is the basis matrix, x' is vector of unknowns (transformed
|
||||
-- vector that should be computed), x is vector of right-hand sides
|
||||
-- (input vector that should be transformed).
|
||||
--
|
||||
-- On entry the array x should contain components of the vector x in
|
||||
-- locations x[1], x[2], ..., x[m], where m is the order of the basis
|
||||
-- matrix. On exit this array will contain components of the vector x'
|
||||
-- in the same locations.
|
||||
--
|
||||
-- The parameter save is a flag. If this flag is set, it means that the
|
||||
-- input vector x is a column of the non-basic variable, which has been
|
||||
-- chosen to enter the basis. In this case the routine spx_ftran saves
|
||||
-- this column (after partial transformation) in order that the routine
|
||||
-- spx_update could update (recompute) the factorization for an adjacent
|
||||
-- basis using this partially transformed column. The simplex method
|
||||
-- routine should call the routine spx_ftran with the save flag set at
|
||||
-- least once before a subsequent call to the routine spx_update. */
|
||||
|
||||
void spx_ftran(LPX *lp, double x[], int save)
|
||||
{ insist(lp->b_stat == LPX_B_VALID);
|
||||
inv_ftran(lp->inv, x, save);
|
||||
return;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- spx_btran - perform backward transformation (BTRAN).
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glpspx.h"
|
||||
-- void spx_btran(LPX *lp, double x[]);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The routine spx_btran performs backward transformation (BTRAN) of the
|
||||
-- given vector using the factorization of the basis matrix.
|
||||
--
|
||||
-- In order to perform BTRAN the routine solves the system B'*x' = x,
|
||||
-- where B' is a matrix transposed to the basis matrix B, x' is vector
|
||||
-- of unknowns (transformed vector that should be computed), x is vector
|
||||
-- of right-hand sides (input vector that should be transformed).
|
||||
--
|
||||
-- On entry the array x should contain components of the vector x in
|
||||
-- locations x[1], x[2], ..., x[m], where m is the order of the basis
|
||||
-- matrix. On exit this array will contain components of the vector x'
|
||||
-- in the same locations. */
|
||||
|
||||
void spx_btran(LPX *lp, double x[])
|
||||
{ insist(lp->b_stat == LPX_B_VALID);
|
||||
inv_btran(lp->inv, x);
|
||||
return;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- spx_update - update factorization for adjacent basis matrix.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glpspx.h"
|
||||
-- int spx_update(LPX *lp, int j);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The routine spx_update recomputes the factorization, which on entry
|
||||
-- corresponds to the current basis matrix B, in order that the updated
|
||||
-- factorization would correspond to the adjacent basis matrix B' that
|
||||
-- differs from B in the j-th column.
|
||||
--
|
||||
-- The new j-th column of the basis matrix is passed implicitly to the
|
||||
-- routine spx_update. It is assumed that this column was saved before
|
||||
-- by the routine spx_ftran (see above).
|
||||
--
|
||||
-- *Returns*
|
||||
--
|
||||
-- Zero return code means that the factorization has been successfully
|
||||
-- updated. Non-zero return code means that the factorization should be
|
||||
-- reinverted by the routine spx_invert. */
|
||||
|
||||
int spx_update(LPX *lp, int j)
|
||||
{ int ret;
|
||||
insist(1 <= j && j <= lp->m);
|
||||
ret = inv_update(lp->inv, j);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* eof */
|
||||
/* glpspx1.c (basis maintenance routines) */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#include <string.h>
|
||||
#include "glplib.h"
|
||||
#include "glpspx.h"
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- spx_invert - reinvert the basis matrix.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glpspx.h"
|
||||
-- int spx_invert(LPX *lp);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The routine spx_invert computes a factorization of the current basis
|
||||
-- matrix B specified by the arrays lp->tagx, lp->posx, and lp->indx.
|
||||
--
|
||||
-- *Returns*
|
||||
--
|
||||
-- The routine returns one of the following codes:
|
||||
--
|
||||
-- 0 - the basis matrix has been successfully factorized;
|
||||
-- 1 - the basis matrix is singular;
|
||||
-- 2 - the basis matrix is ill-conditioned.
|
||||
--
|
||||
-- In the case of non-zero return code the calling program can "repair"
|
||||
-- the basis matrix replacing linearly dependent columns by appropriate
|
||||
-- unity columns of auxiliary variable using information stored by the
|
||||
-- factorizing routine in the object lp->inv (for details see comments
|
||||
-- in the module GLPINV). */
|
||||
|
||||
static int inv_col(void *info, int j, int rn[], double bj[])
|
||||
{ /* this auxiliary routine returns row indices and numerical
|
||||
values of non-zero elements of the j-th column of the current
|
||||
basis matrix B, which has to be reinverted */
|
||||
LPX *lp = info;
|
||||
int m = lp->m;
|
||||
int n = lp->n;
|
||||
int *aa_ptr = lp->A->ptr;
|
||||
int *aa_len = lp->A->len;
|
||||
int *sv_ndx = lp->A->ndx;
|
||||
double *sv_val = lp->A->val;
|
||||
int *indx = lp->indx;
|
||||
int k, ptr, len, t;
|
||||
insist(1 <= j && j <= m);
|
||||
k = indx[j]; /* x[k] = xB[j] */
|
||||
insist(1 <= k && k <= m+n);
|
||||
if (k <= m)
|
||||
{ /* x[k] is auxiliary variable */
|
||||
len = 1;
|
||||
rn[1] = k;
|
||||
bj[1] = +1.0;
|
||||
}
|
||||
else
|
||||
{ /* x[k] is structural variable */
|
||||
ptr = aa_ptr[k];
|
||||
len = aa_len[k];
|
||||
memcpy(&rn[1], &sv_ndx[ptr], len * sizeof(int));
|
||||
memcpy(&bj[1], &sv_val[ptr], len * sizeof(double));
|
||||
for (t = len; t >= 1; t--) bj[t] = - bj[t];
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
int spx_invert(LPX *lp)
|
||||
{ static double piv_tol[1+3] = { 0.00, 0.10, 0.30, 0.70 };
|
||||
int try, ret;
|
||||
/* if the invertable form has a wrong size, delete it */
|
||||
if (lp->inv != NULL && lp->inv->m != lp->m)
|
||||
inv_delete(lp->inv), lp->inv = NULL;
|
||||
/* if the invertable form does not exist, create it */
|
||||
#if 0
|
||||
if (lp->inv == NULL) lp->inv = inv_create(lp->m, 100);
|
||||
#else
|
||||
if (lp->inv == NULL) lp->inv = inv_create(lp->m, 50);
|
||||
#endif
|
||||
/* try to factorize the basis matrix */
|
||||
for (try = 1; try <= 3; try++)
|
||||
{ if (try > 1 && lp->msg_lev >= 3)
|
||||
print("spx_invert: trying to factorize the basis using thre"
|
||||
"shold tolerance %g", piv_tol[try]);
|
||||
lp->inv->luf->piv_tol = piv_tol[try];
|
||||
ret = inv_decomp(lp->inv, lp, inv_col);
|
||||
if (ret == 0) break;
|
||||
}
|
||||
/* analyze the return code */
|
||||
switch (ret)
|
||||
{ case 0:
|
||||
/* success */
|
||||
lp->b_stat = LPX_B_VALID;
|
||||
break;
|
||||
case 1:
|
||||
if (lp->msg_lev >= 1)
|
||||
print("spx_invert: the basis matrix is singular");
|
||||
lp->b_stat = LPX_B_UNDEF;
|
||||
break;
|
||||
case 2:
|
||||
if (lp->msg_lev >= 1)
|
||||
print("spx_invert: the basis matrix is ill-conditioned");
|
||||
lp->b_stat = LPX_B_UNDEF;
|
||||
break;
|
||||
default:
|
||||
insist(ret != ret);
|
||||
}
|
||||
/* return to the calling program */
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- spx_ftran - perform forward transformation (FTRAN).
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glpspx.h"
|
||||
-- void spx_ftran(LPX *lp, double x[], int save);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The routine spx_ftran performs forward transformation (FTRAN) of the
|
||||
-- given vector using the factorization of the basis matrix.
|
||||
--
|
||||
-- In order to perform FTRAN the routine solves the system B*x' = x,
|
||||
-- where B is the basis matrix, x' is vector of unknowns (transformed
|
||||
-- vector that should be computed), x is vector of right-hand sides
|
||||
-- (input vector that should be transformed).
|
||||
--
|
||||
-- On entry the array x should contain components of the vector x in
|
||||
-- locations x[1], x[2], ..., x[m], where m is the order of the basis
|
||||
-- matrix. On exit this array will contain components of the vector x'
|
||||
-- in the same locations.
|
||||
--
|
||||
-- The parameter save is a flag. If this flag is set, it means that the
|
||||
-- input vector x is a column of the non-basic variable, which has been
|
||||
-- chosen to enter the basis. In this case the routine spx_ftran saves
|
||||
-- this column (after partial transformation) in order that the routine
|
||||
-- spx_update could update (recompute) the factorization for an adjacent
|
||||
-- basis using this partially transformed column. The simplex method
|
||||
-- routine should call the routine spx_ftran with the save flag set at
|
||||
-- least once before a subsequent call to the routine spx_update. */
|
||||
|
||||
void spx_ftran(LPX *lp, double x[], int save)
|
||||
{ insist(lp->b_stat == LPX_B_VALID);
|
||||
inv_ftran(lp->inv, x, save);
|
||||
return;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- spx_btran - perform backward transformation (BTRAN).
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glpspx.h"
|
||||
-- void spx_btran(LPX *lp, double x[]);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The routine spx_btran performs backward transformation (BTRAN) of the
|
||||
-- given vector using the factorization of the basis matrix.
|
||||
--
|
||||
-- In order to perform BTRAN the routine solves the system B'*x' = x,
|
||||
-- where B' is a matrix transposed to the basis matrix B, x' is vector
|
||||
-- of unknowns (transformed vector that should be computed), x is vector
|
||||
-- of right-hand sides (input vector that should be transformed).
|
||||
--
|
||||
-- On entry the array x should contain components of the vector x in
|
||||
-- locations x[1], x[2], ..., x[m], where m is the order of the basis
|
||||
-- matrix. On exit this array will contain components of the vector x'
|
||||
-- in the same locations. */
|
||||
|
||||
void spx_btran(LPX *lp, double x[])
|
||||
{ insist(lp->b_stat == LPX_B_VALID);
|
||||
inv_btran(lp->inv, x);
|
||||
return;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- spx_update - update factorization for adjacent basis matrix.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glpspx.h"
|
||||
-- int spx_update(LPX *lp, int j);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The routine spx_update recomputes the factorization, which on entry
|
||||
-- corresponds to the current basis matrix B, in order that the updated
|
||||
-- factorization would correspond to the adjacent basis matrix B' that
|
||||
-- differs from B in the j-th column.
|
||||
--
|
||||
-- The new j-th column of the basis matrix is passed implicitly to the
|
||||
-- routine spx_update. It is assumed that this column was saved before
|
||||
-- by the routine spx_ftran (see above).
|
||||
--
|
||||
-- *Returns*
|
||||
--
|
||||
-- Zero return code means that the factorization has been successfully
|
||||
-- updated. Non-zero return code means that the factorization should be
|
||||
-- reinverted by the routine spx_invert. */
|
||||
|
||||
int spx_update(LPX *lp, int j)
|
||||
{ int ret;
|
||||
insist(1 <= j && j <= lp->m);
|
||||
ret = inv_update(lp->inv, j);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* eof */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,504 @@
|
||||
/* glpstr.c */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#include <string.h>
|
||||
#include "glplib.h"
|
||||
#include "glpstr.h"
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- create_str_pool - create pool for segmented character strings.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glpstr.h"
|
||||
-- DMP *create_str_pool(void);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The create_str_pool routine creates a memory pool which may be used
|
||||
-- in subsequent operations on segmented character strings. Should note
|
||||
-- that different strings can share the same pool.
|
||||
--
|
||||
-- *Returns*
|
||||
--
|
||||
-- The create_str_pool routine returns a pointer to the created memory
|
||||
-- pool. */
|
||||
|
||||
DMP *create_str_pool(void)
|
||||
{ DMP *pool;
|
||||
int size1 = sizeof(STR);
|
||||
int size2 = sizeof(SQE);
|
||||
pool = dmp_create_pool(size1 >= size2 ? size1 : size2);
|
||||
return pool;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- create_str - create segmented character string.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glpstr.h"
|
||||
-- STR *create_str(DMP *pool);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The create_str routine creates empty segmented character string.
|
||||
--
|
||||
-- The parameter pool specifies the memory pool created by the
|
||||
-- create_str_pool routine. The create_str routine connects this pool
|
||||
-- with the string, so it will be used in all subsequent operations on
|
||||
-- this string.
|
||||
--
|
||||
-- Should note that the same pool may be shared by different strings.
|
||||
--
|
||||
-- *Returns*
|
||||
--
|
||||
-- The create_str routine returns a pointer to the created string. */
|
||||
|
||||
STR *create_str(DMP *pool)
|
||||
{ STR *str;
|
||||
str = dmp_get_atom(pool);
|
||||
str->pool = pool;
|
||||
str->len = 0;
|
||||
str->head = str->tail = NULL;
|
||||
return str;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- get_str - extract value from segmented character string.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glpstr.h"
|
||||
-- char *get_str(char *to, STR *str);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The get_str routine copies data from the segmented character string
|
||||
-- str to the plain character string to. The array of char type should
|
||||
-- have at least len+1 characters, where len is current length of the
|
||||
-- string str.
|
||||
--
|
||||
-- *Returns*
|
||||
--
|
||||
-- The get_str routine returns a pointer to the string to. */
|
||||
|
||||
char *get_str(char *to, STR *str)
|
||||
{ SQE *sqe;
|
||||
int len = str->len;
|
||||
char *ptr = to;
|
||||
for (sqe = str->head; len > 0; sqe = sqe->next)
|
||||
{ int n = (len <= SQE_SIZE ? len : SQE_SIZE);
|
||||
insist(sqe != NULL);
|
||||
memcpy(ptr, sqe->data, n);
|
||||
ptr += n, len -= n;
|
||||
}
|
||||
*ptr = '\0';
|
||||
return to;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- set_str - assign value to segmented character string.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glpstr.h"
|
||||
-- STR *set_str(STR *str, char *from);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The set_str routine copies data from the plain character string to
|
||||
-- the segmented character string str.
|
||||
--
|
||||
-- *Returns*
|
||||
--
|
||||
-- The set_str routine returns a pointer to the string str. */
|
||||
|
||||
STR *set_str(STR *str, char *from)
|
||||
{ SQE *sqe;
|
||||
int len = strlen(from);
|
||||
char *ptr = from;
|
||||
clear_str(str);
|
||||
while (len > 0)
|
||||
{ int n = (len <= SQE_SIZE ? len : SQE_SIZE);
|
||||
sqe = dmp_get_atom(str->pool);
|
||||
memcpy(sqe->data, ptr, n);
|
||||
ptr += n, len -= n;
|
||||
sqe->next = NULL;
|
||||
str->len += n;
|
||||
if (str->head == NULL)
|
||||
str->head = sqe;
|
||||
else
|
||||
str->tail->next = sqe;
|
||||
str->tail = sqe;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- clear_str - clear segmented character string.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glpstr.h"
|
||||
-- STR *clear_str(STR *str);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The clear_str routine makes the segmented character string str empty.
|
||||
--
|
||||
-- *Returns*
|
||||
--
|
||||
-- The clear_str routine returns a pointer to the string str. */
|
||||
|
||||
STR *clear_str(STR *str)
|
||||
{ str->len = 0;
|
||||
while (str->head != NULL)
|
||||
{ SQE *sqe = str->head;
|
||||
str->head = sqe->next;
|
||||
dmp_free_atom(str->pool, sqe);
|
||||
}
|
||||
str->tail = NULL;
|
||||
return str;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- compare_str - compare segmented character strings.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glpstr.h"
|
||||
-- int compare_str(STR *str1, STR *str2);
|
||||
--
|
||||
-- *Returns*
|
||||
--
|
||||
-- The compare_str compares segmented character strings str1 and str2,
|
||||
-- and returns one of the following values:
|
||||
--
|
||||
-- < 0, if str1 is lexicographically less than str2;
|
||||
-- = 0, if str1 and str2 are identical;
|
||||
-- > 0, if str1 is lexicographically greater than str2.
|
||||
--
|
||||
-- If compared strings have different length, the shorter string is
|
||||
-- considered as if it would be padded by binary zeros to the length of
|
||||
-- the longer string. */
|
||||
|
||||
int compare_str(STR *str1, STR *str2)
|
||||
{ SQE *sqe1 = str1->head, *sqe2 = str2->head;
|
||||
int len1 = str1->len, len2 = str2->len, ret = 0;
|
||||
while (len1 > 0 || len2 > 0)
|
||||
{ int n1 = (len1 <= SQE_SIZE ? len1 : SQE_SIZE);
|
||||
int n2 = (len2 <= SQE_SIZE ? len2 : SQE_SIZE);
|
||||
char buf1[SQE_SIZE], buf2[SQE_SIZE];
|
||||
memset(buf1, '\0', SQE_SIZE);
|
||||
if (n1 > 0)
|
||||
{ insist(sqe1 != NULL);
|
||||
memcpy(buf1, sqe1->data, n1);
|
||||
len1 -= n1, sqe1 = sqe1->next;
|
||||
}
|
||||
memset(buf2, '\0', SQE_SIZE);
|
||||
if (n2 > 0)
|
||||
{ insist(sqe2 != NULL);
|
||||
memcpy(buf2, sqe2->data, n2);
|
||||
len2 -= n2, sqe2 = sqe2->next;
|
||||
}
|
||||
ret = memcmp(buf1, buf2, SQE_SIZE);
|
||||
if (ret != 0) break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- delete_str - delete segmented character string.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glpstr.h"
|
||||
-- void delete_str(STR *str);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The delete_str routine deletes the segmented character string str,
|
||||
-- returning all its memory to the corresponding memory pool. */
|
||||
|
||||
void delete_str(STR *str)
|
||||
{ clear_str(str);
|
||||
dmp_free_atom(str->pool, str);
|
||||
return;
|
||||
}
|
||||
|
||||
/* eof */
|
||||
/* glpstr.c */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#include <string.h>
|
||||
#include "glplib.h"
|
||||
#include "glpstr.h"
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- create_str_pool - create pool for segmented character strings.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glpstr.h"
|
||||
-- DMP *create_str_pool(void);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The create_str_pool routine creates a memory pool which may be used
|
||||
-- in subsequent operations on segmented character strings. Should note
|
||||
-- that different strings can share the same pool.
|
||||
--
|
||||
-- *Returns*
|
||||
--
|
||||
-- The create_str_pool routine returns a pointer to the created memory
|
||||
-- pool. */
|
||||
|
||||
DMP *create_str_pool(void)
|
||||
{ DMP *pool;
|
||||
int size1 = sizeof(STR);
|
||||
int size2 = sizeof(SQE);
|
||||
pool = dmp_create_pool(size1 >= size2 ? size1 : size2);
|
||||
return pool;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- create_str - create segmented character string.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glpstr.h"
|
||||
-- STR *create_str(DMP *pool);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The create_str routine creates empty segmented character string.
|
||||
--
|
||||
-- The parameter pool specifies the memory pool created by the
|
||||
-- create_str_pool routine. The create_str routine connects this pool
|
||||
-- with the string, so it will be used in all subsequent operations on
|
||||
-- this string.
|
||||
--
|
||||
-- Should note that the same pool may be shared by different strings.
|
||||
--
|
||||
-- *Returns*
|
||||
--
|
||||
-- The create_str routine returns a pointer to the created string. */
|
||||
|
||||
STR *create_str(DMP *pool)
|
||||
{ STR *str;
|
||||
str = dmp_get_atom(pool);
|
||||
str->pool = pool;
|
||||
str->len = 0;
|
||||
str->head = str->tail = NULL;
|
||||
return str;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- get_str - extract value from segmented character string.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glpstr.h"
|
||||
-- char *get_str(char *to, STR *str);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The get_str routine copies data from the segmented character string
|
||||
-- str to the plain character string to. The array of char type should
|
||||
-- have at least len+1 characters, where len is current length of the
|
||||
-- string str.
|
||||
--
|
||||
-- *Returns*
|
||||
--
|
||||
-- The get_str routine returns a pointer to the string to. */
|
||||
|
||||
char *get_str(char *to, STR *str)
|
||||
{ SQE *sqe;
|
||||
int len = str->len;
|
||||
char *ptr = to;
|
||||
for (sqe = str->head; len > 0; sqe = sqe->next)
|
||||
{ int n = (len <= SQE_SIZE ? len : SQE_SIZE);
|
||||
insist(sqe != NULL);
|
||||
memcpy(ptr, sqe->data, n);
|
||||
ptr += n, len -= n;
|
||||
}
|
||||
*ptr = '\0';
|
||||
return to;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- set_str - assign value to segmented character string.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glpstr.h"
|
||||
-- STR *set_str(STR *str, char *from);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The set_str routine copies data from the plain character string to
|
||||
-- the segmented character string str.
|
||||
--
|
||||
-- *Returns*
|
||||
--
|
||||
-- The set_str routine returns a pointer to the string str. */
|
||||
|
||||
STR *set_str(STR *str, char *from)
|
||||
{ SQE *sqe;
|
||||
int len = strlen(from);
|
||||
char *ptr = from;
|
||||
clear_str(str);
|
||||
while (len > 0)
|
||||
{ int n = (len <= SQE_SIZE ? len : SQE_SIZE);
|
||||
sqe = dmp_get_atom(str->pool);
|
||||
memcpy(sqe->data, ptr, n);
|
||||
ptr += n, len -= n;
|
||||
sqe->next = NULL;
|
||||
str->len += n;
|
||||
if (str->head == NULL)
|
||||
str->head = sqe;
|
||||
else
|
||||
str->tail->next = sqe;
|
||||
str->tail = sqe;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- clear_str - clear segmented character string.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glpstr.h"
|
||||
-- STR *clear_str(STR *str);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The clear_str routine makes the segmented character string str empty.
|
||||
--
|
||||
-- *Returns*
|
||||
--
|
||||
-- The clear_str routine returns a pointer to the string str. */
|
||||
|
||||
STR *clear_str(STR *str)
|
||||
{ str->len = 0;
|
||||
while (str->head != NULL)
|
||||
{ SQE *sqe = str->head;
|
||||
str->head = sqe->next;
|
||||
dmp_free_atom(str->pool, sqe);
|
||||
}
|
||||
str->tail = NULL;
|
||||
return str;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- compare_str - compare segmented character strings.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glpstr.h"
|
||||
-- int compare_str(STR *str1, STR *str2);
|
||||
--
|
||||
-- *Returns*
|
||||
--
|
||||
-- The compare_str compares segmented character strings str1 and str2,
|
||||
-- and returns one of the following values:
|
||||
--
|
||||
-- < 0, if str1 is lexicographically less than str2;
|
||||
-- = 0, if str1 and str2 are identical;
|
||||
-- > 0, if str1 is lexicographically greater than str2.
|
||||
--
|
||||
-- If compared strings have different length, the shorter string is
|
||||
-- considered as if it would be padded by binary zeros to the length of
|
||||
-- the longer string. */
|
||||
|
||||
int compare_str(STR *str1, STR *str2)
|
||||
{ SQE *sqe1 = str1->head, *sqe2 = str2->head;
|
||||
int len1 = str1->len, len2 = str2->len, ret = 0;
|
||||
while (len1 > 0 || len2 > 0)
|
||||
{ int n1 = (len1 <= SQE_SIZE ? len1 : SQE_SIZE);
|
||||
int n2 = (len2 <= SQE_SIZE ? len2 : SQE_SIZE);
|
||||
char buf1[SQE_SIZE], buf2[SQE_SIZE];
|
||||
memset(buf1, '\0', SQE_SIZE);
|
||||
if (n1 > 0)
|
||||
{ insist(sqe1 != NULL);
|
||||
memcpy(buf1, sqe1->data, n1);
|
||||
len1 -= n1, sqe1 = sqe1->next;
|
||||
}
|
||||
memset(buf2, '\0', SQE_SIZE);
|
||||
if (n2 > 0)
|
||||
{ insist(sqe2 != NULL);
|
||||
memcpy(buf2, sqe2->data, n2);
|
||||
len2 -= n2, sqe2 = sqe2->next;
|
||||
}
|
||||
ret = memcmp(buf1, buf2, SQE_SIZE);
|
||||
if (ret != 0) break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- delete_str - delete segmented character string.
|
||||
--
|
||||
-- *Synopsis*
|
||||
--
|
||||
-- #include "glpstr.h"
|
||||
-- void delete_str(STR *str);
|
||||
--
|
||||
-- *Description*
|
||||
--
|
||||
-- The delete_str routine deletes the segmented character string str,
|
||||
-- returning all its memory to the corresponding memory pool. */
|
||||
|
||||
void delete_str(STR *str)
|
||||
{ clear_str(str);
|
||||
dmp_free_atom(str->pool, str);
|
||||
return;
|
||||
}
|
||||
|
||||
/* eof */
|
||||
@@ -0,0 +1,176 @@
|
||||
/* glpstr.h */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _GLPSTR_H
|
||||
#define _GLPSTR_H
|
||||
|
||||
#include "glpdmp.h"
|
||||
|
||||
#define clear_str glp_clear_str
|
||||
#define compare_str glp_compare_str
|
||||
#define create_str glp_create_str
|
||||
#define create_str_pool glp_create_str_pool
|
||||
#define delete_str glp_delete_str
|
||||
#define get_str glp_get_str
|
||||
#define set_str glp_set_str
|
||||
|
||||
typedef struct STR STR;
|
||||
typedef struct SQE SQE;
|
||||
|
||||
struct STR
|
||||
{ /* segmented character string of arbitrary length */
|
||||
DMP *pool;
|
||||
/* memory pool holding string elements */
|
||||
int len;
|
||||
/* current string length */
|
||||
SQE *head;
|
||||
/* pointer to the first string element */
|
||||
SQE *tail;
|
||||
/* pointer to the last string element */
|
||||
};
|
||||
|
||||
#define SQE_SIZE 12
|
||||
/* number of characters allocated in each string element */
|
||||
|
||||
struct SQE
|
||||
{ /* element of segmented character string */
|
||||
char data[SQE_SIZE];
|
||||
/* characters allocated in this element */
|
||||
SQE *next;
|
||||
/* pointer to the next string element */
|
||||
};
|
||||
|
||||
extern STR *clear_str(STR *str);
|
||||
/* clear segmented character string */
|
||||
|
||||
extern int compare_str(STR *str1, STR *str2);
|
||||
/* compare segmented character strings */
|
||||
|
||||
extern STR *create_str(DMP *pool);
|
||||
/* create segmented character string */
|
||||
|
||||
extern DMP *create_str_pool(void);
|
||||
/* create pool for segmented character strings */
|
||||
|
||||
extern void delete_str(STR *str);
|
||||
/* delete segmented character string */
|
||||
|
||||
extern char *get_str(char *to, STR *str);
|
||||
/* extract value from segmented character string */
|
||||
|
||||
extern STR *set_str(STR *str, char *from);
|
||||
/* assign value to segmented character string */
|
||||
|
||||
#endif
|
||||
|
||||
/* eof */
|
||||
/* glpstr.h */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _GLPSTR_H
|
||||
#define _GLPSTR_H
|
||||
|
||||
#include "glpdmp.h"
|
||||
|
||||
#define clear_str glp_clear_str
|
||||
#define compare_str glp_compare_str
|
||||
#define create_str glp_create_str
|
||||
#define create_str_pool glp_create_str_pool
|
||||
#define delete_str glp_delete_str
|
||||
#define get_str glp_get_str
|
||||
#define set_str glp_set_str
|
||||
|
||||
typedef struct STR STR;
|
||||
typedef struct SQE SQE;
|
||||
|
||||
struct STR
|
||||
{ /* segmented character string of arbitrary length */
|
||||
DMP *pool;
|
||||
/* memory pool holding string elements */
|
||||
int len;
|
||||
/* current string length */
|
||||
SQE *head;
|
||||
/* pointer to the first string element */
|
||||
SQE *tail;
|
||||
/* pointer to the last string element */
|
||||
};
|
||||
|
||||
#define SQE_SIZE 12
|
||||
/* number of characters allocated in each string element */
|
||||
|
||||
struct SQE
|
||||
{ /* element of segmented character string */
|
||||
char data[SQE_SIZE];
|
||||
/* characters allocated in this element */
|
||||
SQE *next;
|
||||
/* pointer to the next string element */
|
||||
};
|
||||
|
||||
extern STR *clear_str(STR *str);
|
||||
/* clear segmented character string */
|
||||
|
||||
extern int compare_str(STR *str1, STR *str2);
|
||||
/* compare segmented character strings */
|
||||
|
||||
extern STR *create_str(DMP *pool);
|
||||
/* create segmented character string */
|
||||
|
||||
extern DMP *create_str_pool(void);
|
||||
/* create pool for segmented character strings */
|
||||
|
||||
extern void delete_str(STR *str);
|
||||
/* delete segmented character string */
|
||||
|
||||
extern char *get_str(char *to, STR *str);
|
||||
/* extract value from segmented character string */
|
||||
|
||||
extern STR *set_str(STR *str, char *from);
|
||||
/* assign value to segmented character string */
|
||||
|
||||
#endif
|
||||
|
||||
/* eof */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,210 @@
|
||||
/* glptsp.h */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _GLPTSP_H
|
||||
#define _GLPTSP_H
|
||||
|
||||
#define tsp_read_data glp_tsp_read_data
|
||||
#define tsp_free_data glp_tsp_free_data
|
||||
#define tsp_distance glp_tsp_distance
|
||||
|
||||
typedef struct TSP TSP;
|
||||
|
||||
struct TSP
|
||||
{ /* TSP (or related problem) instance in the format described in
|
||||
the report: G.Reinelt, TSPLIB 95 */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* the specification part */
|
||||
char *name;
|
||||
/* identifies the data file */
|
||||
int type;
|
||||
/* specifies the type of data: */
|
||||
#define TSP_UNDEF 0 /* undefined */
|
||||
#define TSP_TSP 1 /* symmetric TSP */
|
||||
#define TSP_ATSP 2 /* asymmetric TSP */
|
||||
#define TSP_TOUR 3 /* collection of tours */
|
||||
char *comment;
|
||||
/* additional comments (usually the name of the contributor or
|
||||
creator of the problem instance is given here) */
|
||||
int dimension;
|
||||
/* for a TSP or ATSP, the dimension is the number of its nodes
|
||||
for a TOUR it is the dimension of the corresponding problem */
|
||||
int edge_weight_type;
|
||||
/* specifies how the edge weights (or distances) are given: */
|
||||
#define TSP_UNDEF 0 /* undefined */
|
||||
#define TSP_EXPLICIT 1 /* listed explicitly */
|
||||
#define TSP_EUC_2D 2 /* Eucl. distances in 2-D */
|
||||
#define TSP_CEIL_2D 3 /* Eucl. distances in 2-D rounded up */
|
||||
#define TSP_GEO 4 /* geographical distances */
|
||||
#define TSP_ATT 5 /* special distance function */
|
||||
int edge_weight_format;
|
||||
/* describes the format of the edge weights if they are given
|
||||
explicitly: */
|
||||
#define TSP_UNDEF 0 /* undefined */
|
||||
#define TSP_FUNCTION 1 /* given by a function */
|
||||
#define TSP_FULL_MATRIX 2 /* given by a full matrix */
|
||||
#define TSP_UPPER_ROW 3 /* upper triangulat matrix (row-wise
|
||||
without diagonal entries) */
|
||||
#define TSP_LOWER_DIAG_ROW 4 /* lower triangular matrix (row-wise
|
||||
including diagonal entries) */
|
||||
int display_data_type;
|
||||
/* specifies how a graphical display of the nodes can be
|
||||
obtained: */
|
||||
#define TSP_UNDEF 0 /* undefined */
|
||||
#define TSP_COORD_DISPLAY 1 /* display is generated from the node
|
||||
coordinates */
|
||||
#define TSP_TWOD_DISPLAY 2 /* explicit coordinates in 2-D are
|
||||
given */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* data part */
|
||||
/* NODE_COORD_SECTION: */
|
||||
double *node_x_coord; /* double node_x_coord[1+dimension]; */
|
||||
double *node_y_coord; /* double node_y_coord[1+dimension]; */
|
||||
/* DISPLAY_DATA_SECTION: */
|
||||
double *dply_x_coord; /* double dply_x_coord[1+dimension]; */
|
||||
double *dply_y_coord; /* double dply_y_coord[1+dimension]; */
|
||||
/* TOUR_SECTION: */
|
||||
int *tour; /* int tour[1+dimension]; */
|
||||
/* EDGE_WEIGHT_SECTION: */
|
||||
int *edge_weight; /* int edge_weight[1+dimension*dimension]; */
|
||||
};
|
||||
|
||||
TSP *tsp_read_data(char *fname);
|
||||
/* read TSP instance data */
|
||||
|
||||
void tsp_free_data(TSP *tsp);
|
||||
/* free TSP instance data */
|
||||
|
||||
int tsp_distance(TSP *tsp, int i, int j);
|
||||
/* compute distance between two nodes */
|
||||
|
||||
#endif
|
||||
|
||||
/* eof */
|
||||
/* glptsp.h */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
-- Copyright (C) 2000, 2001, 2002, 2003 Andrew Makhorin, Department
|
||||
-- for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
|
||||
-- All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
|
||||
--
|
||||
-- This file is a part of GLPK (GNU Linear Programming Kit).
|
||||
--
|
||||
-- GLPK is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 2, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
|
||||
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
-- License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with GLPK; see the file COPYING. If not, write to the Free
|
||||
-- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
-- 02111-1307, USA.
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _GLPTSP_H
|
||||
#define _GLPTSP_H
|
||||
|
||||
#define tsp_read_data glp_tsp_read_data
|
||||
#define tsp_free_data glp_tsp_free_data
|
||||
#define tsp_distance glp_tsp_distance
|
||||
|
||||
typedef struct TSP TSP;
|
||||
|
||||
struct TSP
|
||||
{ /* TSP (or related problem) instance in the format described in
|
||||
the report: G.Reinelt, TSPLIB 95 */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* the specification part */
|
||||
char *name;
|
||||
/* identifies the data file */
|
||||
int type;
|
||||
/* specifies the type of data: */
|
||||
#define TSP_UNDEF 0 /* undefined */
|
||||
#define TSP_TSP 1 /* symmetric TSP */
|
||||
#define TSP_ATSP 2 /* asymmetric TSP */
|
||||
#define TSP_TOUR 3 /* collection of tours */
|
||||
char *comment;
|
||||
/* additional comments (usually the name of the contributor or
|
||||
creator of the problem instance is given here) */
|
||||
int dimension;
|
||||
/* for a TSP or ATSP, the dimension is the number of its nodes
|
||||
for a TOUR it is the dimension of the corresponding problem */
|
||||
int edge_weight_type;
|
||||
/* specifies how the edge weights (or distances) are given: */
|
||||
#define TSP_UNDEF 0 /* undefined */
|
||||
#define TSP_EXPLICIT 1 /* listed explicitly */
|
||||
#define TSP_EUC_2D 2 /* Eucl. distances in 2-D */
|
||||
#define TSP_CEIL_2D 3 /* Eucl. distances in 2-D rounded up */
|
||||
#define TSP_GEO 4 /* geographical distances */
|
||||
#define TSP_ATT 5 /* special distance function */
|
||||
int edge_weight_format;
|
||||
/* describes the format of the edge weights if they are given
|
||||
explicitly: */
|
||||
#define TSP_UNDEF 0 /* undefined */
|
||||
#define TSP_FUNCTION 1 /* given by a function */
|
||||
#define TSP_FULL_MATRIX 2 /* given by a full matrix */
|
||||
#define TSP_UPPER_ROW 3 /* upper triangulat matrix (row-wise
|
||||
without diagonal entries) */
|
||||
#define TSP_LOWER_DIAG_ROW 4 /* lower triangular matrix (row-wise
|
||||
including diagonal entries) */
|
||||
int display_data_type;
|
||||
/* specifies how a graphical display of the nodes can be
|
||||
obtained: */
|
||||
#define TSP_UNDEF 0 /* undefined */
|
||||
#define TSP_COORD_DISPLAY 1 /* display is generated from the node
|
||||
coordinates */
|
||||
#define TSP_TWOD_DISPLAY 2 /* explicit coordinates in 2-D are
|
||||
given */
|
||||
/*--------------------------------------------------------------*/
|
||||
/* data part */
|
||||
/* NODE_COORD_SECTION: */
|
||||
double *node_x_coord; /* double node_x_coord[1+dimension]; */
|
||||
double *node_y_coord; /* double node_y_coord[1+dimension]; */
|
||||
/* DISPLAY_DATA_SECTION: */
|
||||
double *dply_x_coord; /* double dply_x_coord[1+dimension]; */
|
||||
double *dply_y_coord; /* double dply_y_coord[1+dimension]; */
|
||||
/* TOUR_SECTION: */
|
||||
int *tour; /* int tour[1+dimension]; */
|
||||
/* EDGE_WEIGHT_SECTION: */
|
||||
int *edge_weight; /* int edge_weight[1+dimension*dimension]; */
|
||||
};
|
||||
|
||||
TSP *tsp_read_data(char *fname);
|
||||
/* read TSP instance data */
|
||||
|
||||
void tsp_free_data(TSP *tsp);
|
||||
/* free TSP instance data */
|
||||
|
||||
int tsp_distance(TSP *tsp, int i, int j);
|
||||
/* compute distance between two nodes */
|
||||
|
||||
#endif
|
||||
|
||||
/* eof */
|
||||
@@ -0,0 +1,272 @@
|
||||
set(GOBLIN_SOURCES
|
||||
abstractBalanced.cpp
|
||||
abstractBigraph.cpp
|
||||
abstractDigraph.cpp
|
||||
abstractGraph.cpp
|
||||
abstractMixedGraph.cpp
|
||||
abstractSubgraph.cpp
|
||||
attributePool.cpp
|
||||
auxiliaryNetwork.cpp
|
||||
balancedDigraph.cpp
|
||||
balancedToBalanced.cpp
|
||||
basicHeap.cpp
|
||||
bigraphToDigraph.cpp
|
||||
binaryHeap.cpp
|
||||
branchMIP.cpp
|
||||
branchScheme.cpp
|
||||
canvasBuilder.cpp
|
||||
complement.cpp
|
||||
denseBigraph.cpp
|
||||
denseDigraph.cpp
|
||||
denseGraph.cpp
|
||||
denseRepresentation.cpp
|
||||
dictionary.cpp
|
||||
digraphToDigraph.cpp
|
||||
disjointFamily.cpp
|
||||
doxygen.cpp
|
||||
dynamicQueue.cpp
|
||||
dynamicStack.cpp
|
||||
exportToDot.cpp
|
||||
exportToTk.cpp
|
||||
exportToXFig.cpp
|
||||
fibonacciHeap.cpp
|
||||
fileExport.cpp
|
||||
fileImport.cpp
|
||||
globals.cpp
|
||||
goblinController.cpp
|
||||
graphDisplayProxy.cpp
|
||||
graphRepresentation.cpp
|
||||
graphToBalanced.cpp
|
||||
hashTable.cpp
|
||||
ilpCompose.cpp
|
||||
ilpWrapper.cpp
|
||||
incrementalGeometry.cpp
|
||||
indexSet.cpp
|
||||
itAuxiliaryNetwork.cpp
|
||||
itGraph.cpp
|
||||
itSurfaceGraph.cpp
|
||||
layoutForceDirected.cpp
|
||||
layoutKandinsky.cpp
|
||||
layoutLayered.cpp
|
||||
layoutOrthogonal.cpp
|
||||
libConvert.cpp
|
||||
libImport.cpp
|
||||
libLayout.cpp
|
||||
libPerfect.cpp
|
||||
libPlanarity.cpp
|
||||
listOfAuthors.cpp
|
||||
listOfModules.cpp
|
||||
listOfReferences.cpp
|
||||
listOfTimers.cpp
|
||||
lpBasis.cpp
|
||||
lpRepresentation.cpp
|
||||
lpSolver.cpp
|
||||
managedObject.cpp
|
||||
matrix.cpp
|
||||
mixedGraph.cpp
|
||||
moduleGuard.cpp
|
||||
movingLineModel.cpp
|
||||
nestedFamily.cpp
|
||||
networkSimplex.cpp
|
||||
orthogonalGrid.cpp
|
||||
poolTables.cpp
|
||||
segment.cpp
|
||||
seriesParallel.cpp
|
||||
shrinkingNetwork.cpp
|
||||
solveAsyTSP.cpp
|
||||
solveColour.cpp
|
||||
solveComponents.cpp
|
||||
solveMCBalFlow.cpp
|
||||
solveMCFlow.cpp
|
||||
solveMatching.cpp
|
||||
solveMaxBalFlow.cpp
|
||||
solveMaxCut.cpp
|
||||
solveMaxFlow.cpp
|
||||
solveMinCut.cpp
|
||||
solveMinTree.cpp
|
||||
solvePlanarity.cpp
|
||||
solvePostman.cpp
|
||||
solveSPTree.cpp
|
||||
solveStable.cpp
|
||||
solveSteiner.cpp
|
||||
solveSymmTSP.cpp
|
||||
solveTJoin.cpp
|
||||
solveTreePkg.cpp
|
||||
sparseBigraph.cpp
|
||||
sparseDigraph.cpp
|
||||
sparseGraph.cpp
|
||||
sparseRepresentation.cpp
|
||||
staticQueue.cpp
|
||||
staticStack.cpp
|
||||
stripeDissectionModel.cpp
|
||||
subgraph.cpp
|
||||
surfaceGraph.cpp
|
||||
timers.cpp
|
||||
treeView.cpp
|
||||
)
|
||||
|
||||
file(GLOB GOBLIN_HEADERS *.h)
|
||||
|
||||
include_directories(
|
||||
../../../include
|
||||
)
|
||||
|
||||
add_definitions(
|
||||
-DON_DLL_EXPORTS
|
||||
)
|
||||
|
||||
if(MSVC)
|
||||
add_definitions(
|
||||
-DUNICODE
|
||||
)
|
||||
|
||||
endif(MSVC)
|
||||
|
||||
add_library(goblin SHARED ${GOBLIN_SOURCES})
|
||||
|
||||
target_link_libraries(goblin ${GOBLIN_LINKLIBRARIES})
|
||||
|
||||
set_property(TARGET goblin PROPERTY LINK_INTERFACE_LIBRARIES "")
|
||||
|
||||
install(TARGETS goblin
|
||||
RUNTIME DESTINATION bin
|
||||
LIBRARY DESTINATION lib
|
||||
)
|
||||
|
||||
install(FILES ${GOBLIN_HEADERS} DESTINATION include)
|
||||
set(GOBLIN_SOURCES
|
||||
abstractBalanced.cpp
|
||||
abstractBigraph.cpp
|
||||
abstractDigraph.cpp
|
||||
abstractGraph.cpp
|
||||
abstractMixedGraph.cpp
|
||||
abstractSubgraph.cpp
|
||||
attributePool.cpp
|
||||
auxiliaryNetwork.cpp
|
||||
balancedDigraph.cpp
|
||||
balancedToBalanced.cpp
|
||||
basicHeap.cpp
|
||||
bigraphToDigraph.cpp
|
||||
binaryHeap.cpp
|
||||
branchMIP.cpp
|
||||
branchScheme.cpp
|
||||
canvasBuilder.cpp
|
||||
complement.cpp
|
||||
denseBigraph.cpp
|
||||
denseDigraph.cpp
|
||||
denseGraph.cpp
|
||||
denseRepresentation.cpp
|
||||
dictionary.cpp
|
||||
digraphToDigraph.cpp
|
||||
disjointFamily.cpp
|
||||
doxygen.cpp
|
||||
dynamicQueue.cpp
|
||||
dynamicStack.cpp
|
||||
exportToDot.cpp
|
||||
exportToTk.cpp
|
||||
exportToXFig.cpp
|
||||
fibonacciHeap.cpp
|
||||
fileExport.cpp
|
||||
fileImport.cpp
|
||||
globals.cpp
|
||||
goblinController.cpp
|
||||
graphDisplayProxy.cpp
|
||||
graphRepresentation.cpp
|
||||
graphToBalanced.cpp
|
||||
hashTable.cpp
|
||||
ilpCompose.cpp
|
||||
ilpWrapper.cpp
|
||||
incrementalGeometry.cpp
|
||||
indexSet.cpp
|
||||
itAuxiliaryNetwork.cpp
|
||||
itGraph.cpp
|
||||
itSurfaceGraph.cpp
|
||||
layoutForceDirected.cpp
|
||||
layoutKandinsky.cpp
|
||||
layoutLayered.cpp
|
||||
layoutOrthogonal.cpp
|
||||
libConvert.cpp
|
||||
libImport.cpp
|
||||
libLayout.cpp
|
||||
libPerfect.cpp
|
||||
libPlanarity.cpp
|
||||
listOfAuthors.cpp
|
||||
listOfModules.cpp
|
||||
listOfReferences.cpp
|
||||
listOfTimers.cpp
|
||||
lpBasis.cpp
|
||||
lpRepresentation.cpp
|
||||
lpSolver.cpp
|
||||
managedObject.cpp
|
||||
matrix.cpp
|
||||
mixedGraph.cpp
|
||||
moduleGuard.cpp
|
||||
movingLineModel.cpp
|
||||
nestedFamily.cpp
|
||||
networkSimplex.cpp
|
||||
orthogonalGrid.cpp
|
||||
poolTables.cpp
|
||||
segment.cpp
|
||||
seriesParallel.cpp
|
||||
shrinkingNetwork.cpp
|
||||
solveAsyTSP.cpp
|
||||
solveColour.cpp
|
||||
solveComponents.cpp
|
||||
solveMCBalFlow.cpp
|
||||
solveMCFlow.cpp
|
||||
solveMatching.cpp
|
||||
solveMaxBalFlow.cpp
|
||||
solveMaxCut.cpp
|
||||
solveMaxFlow.cpp
|
||||
solveMinCut.cpp
|
||||
solveMinTree.cpp
|
||||
solvePlanarity.cpp
|
||||
solvePostman.cpp
|
||||
solveSPTree.cpp
|
||||
solveStable.cpp
|
||||
solveSteiner.cpp
|
||||
solveSymmTSP.cpp
|
||||
solveTJoin.cpp
|
||||
solveTreePkg.cpp
|
||||
sparseBigraph.cpp
|
||||
sparseDigraph.cpp
|
||||
sparseGraph.cpp
|
||||
sparseRepresentation.cpp
|
||||
staticQueue.cpp
|
||||
staticStack.cpp
|
||||
stripeDissectionModel.cpp
|
||||
subgraph.cpp
|
||||
surfaceGraph.cpp
|
||||
timers.cpp
|
||||
treeView.cpp
|
||||
)
|
||||
|
||||
file(GLOB GOBLIN_HEADERS *.h)
|
||||
|
||||
include_directories(
|
||||
../../../include
|
||||
)
|
||||
|
||||
add_definitions(
|
||||
-DON_DLL_EXPORTS
|
||||
)
|
||||
|
||||
if(MSVC)
|
||||
add_definitions(
|
||||
-DUNICODE
|
||||
)
|
||||
|
||||
endif(MSVC)
|
||||
|
||||
add_library(goblin SHARED ${GOBLIN_SOURCES})
|
||||
|
||||
target_link_libraries(goblin ${GOBLIN_LINKLIBRARIES})
|
||||
|
||||
set_property(TARGET goblin PROPERTY LINK_INTERFACE_LIBRARIES "")
|
||||
|
||||
install(TARGETS goblin
|
||||
RUNTIME DESTINATION bin
|
||||
LIBRARY DESTINATION lib
|
||||
)
|
||||
|
||||
install(FILES ${GOBLIN_HEADERS} DESTINATION include)
|
||||
@@ -0,0 +1,418 @@
|
||||
|
||||
lib_LTLIBRARIES = libgoblin.la
|
||||
noinst_LTLIBRARIES = libgoblin_nil.la
|
||||
|
||||
GOBLIN_INC = \
|
||||
abstractBalanced.h \
|
||||
abstractBigraph.h \
|
||||
abstractDigraph.h \
|
||||
abstractGraph.h \
|
||||
abstractMixedGraph.h \
|
||||
abstractSubgraph.h \
|
||||
attribute.h \
|
||||
attributePool.h \
|
||||
auxiliaryNetwork.h \
|
||||
balancedDigraph.h \
|
||||
balancedToBalanced.h \
|
||||
basicHeap.h \
|
||||
bigraphToDigraph.h \
|
||||
binaryHeap.h \
|
||||
branchAsyTSP.h \
|
||||
branchColour.h \
|
||||
branchMIP.h \
|
||||
branchMaxCut.h \
|
||||
branchScheme.h \
|
||||
branchStable.h \
|
||||
branchSymmTSP.h \
|
||||
canvasBuilder.h \
|
||||
complement.h \
|
||||
configuration.h \
|
||||
denseBigraph.h \
|
||||
denseDigraph.h \
|
||||
denseGraph.h \
|
||||
denseInclude.h \
|
||||
denseRepresentation.h \
|
||||
dictionary.h \
|
||||
digraphToDigraph.h \
|
||||
disjointFamily.h \
|
||||
dynamicQueue.h \
|
||||
dynamicStack.h \
|
||||
exportToDot.h \
|
||||
exportToTk.h \
|
||||
exportToXFig.h \
|
||||
fibonacciHeap.h \
|
||||
fileExport.h \
|
||||
fileImport.h \
|
||||
globals.h \
|
||||
glpkWrapper.h \
|
||||
goblin.h \
|
||||
goblinController.h \
|
||||
goblinQueue.h \
|
||||
gosh.h \
|
||||
graphDisplayProxy.h \
|
||||
graphInclude.h \
|
||||
graphRepresentation.h \
|
||||
graphToBalanced.h \
|
||||
hashTable.h \
|
||||
ilpWrapper.h \
|
||||
incrementalGeometry.h \
|
||||
indexSet.h \
|
||||
investigator.h \
|
||||
lpSolver.h \
|
||||
managedObject.h \
|
||||
matrix.h \
|
||||
messenger.h \
|
||||
mixedGraph.h \
|
||||
moduleGuard.h \
|
||||
movingLineModel.h \
|
||||
nestedFamily.h \
|
||||
networkSimplex.h \
|
||||
orthogonalGrid.h \
|
||||
segment.h \
|
||||
sequentialQueue.h \
|
||||
sequentialStack.h \
|
||||
shrinkingNetwork.h \
|
||||
sparseBigraph.h \
|
||||
sparseDigraph.h \
|
||||
sparseGraph.h \
|
||||
sparseInclude.h \
|
||||
sparseRepresentation.h \
|
||||
staticQueue.h \
|
||||
staticStack.h \
|
||||
stripeDissectionModel.h \
|
||||
subgraph.h \
|
||||
surfaceGraph.h \
|
||||
switchBaseTypes.h \
|
||||
timers.h \
|
||||
treeView.h \
|
||||
version.h
|
||||
|
||||
|
||||
GOBLIN_SRC = \
|
||||
abstractBalanced.cpp \
|
||||
abstractBigraph.cpp \
|
||||
abstractDigraph.cpp \
|
||||
abstractGraph.cpp \
|
||||
abstractMixedGraph.cpp \
|
||||
abstractSubgraph.cpp \
|
||||
attributePool.cpp \
|
||||
auxiliaryNetwork.cpp \
|
||||
balancedDigraph.cpp \
|
||||
balancedToBalanced.cpp \
|
||||
basicHeap.cpp \
|
||||
bigraphToDigraph.cpp \
|
||||
binaryHeap.cpp \
|
||||
branchMIP.cpp \
|
||||
branchScheme.cpp \
|
||||
canvasBuilder.cpp \
|
||||
complement.cpp \
|
||||
denseBigraph.cpp \
|
||||
denseDigraph.cpp \
|
||||
denseGraph.cpp \
|
||||
denseRepresentation.cpp \
|
||||
dictionary.cpp \
|
||||
digraphToDigraph.cpp \
|
||||
disjointFamily.cpp \
|
||||
doxygen.cpp \
|
||||
dynamicQueue.cpp \
|
||||
dynamicStack.cpp \
|
||||
exportToDot.cpp \
|
||||
exportToTk.cpp \
|
||||
exportToXFig.cpp \
|
||||
fibonacciHeap.cpp \
|
||||
fileExport.cpp \
|
||||
fileImport.cpp \
|
||||
globals.cpp \
|
||||
goblinController.cpp \
|
||||
graphDisplayProxy.cpp \
|
||||
graphRepresentation.cpp \
|
||||
graphToBalanced.cpp \
|
||||
hashTable.cpp \
|
||||
ilpCompose.cpp \
|
||||
ilpWrapper.cpp \
|
||||
incrementalGeometry.cpp \
|
||||
indexSet.cpp \
|
||||
itAuxiliaryNetwork.cpp \
|
||||
itGraph.cpp \
|
||||
itSurfaceGraph.cpp \
|
||||
layoutForceDirected.cpp \
|
||||
layoutKandinsky.cpp \
|
||||
layoutLayered.cpp \
|
||||
layoutOrthogonal.cpp \
|
||||
libConvert.cpp \
|
||||
libImport.cpp \
|
||||
libLayout.cpp \
|
||||
libPerfect.cpp \
|
||||
libPlanarity.cpp \
|
||||
listOfAuthors.cpp \
|
||||
listOfModules.cpp \
|
||||
listOfReferences.cpp \
|
||||
listOfTimers.cpp \
|
||||
lpBasis.cpp \
|
||||
lpRepresentation.cpp \
|
||||
lpSolver.cpp \
|
||||
managedObject.cpp \
|
||||
matrix.cpp \
|
||||
mixedGraph.cpp \
|
||||
moduleGuard.cpp \
|
||||
movingLineModel.cpp \
|
||||
nestedFamily.cpp \
|
||||
networkSimplex.cpp \
|
||||
orthogonalGrid.cpp \
|
||||
poolTables.cpp \
|
||||
segment.cpp \
|
||||
seriesParallel.cpp \
|
||||
shrinkingNetwork.cpp \
|
||||
solveAsyTSP.cpp \
|
||||
solveColour.cpp \
|
||||
solveComponents.cpp \
|
||||
solveMCBalFlow.cpp \
|
||||
solveMCFlow.cpp \
|
||||
solveMatching.cpp \
|
||||
solveMaxBalFlow.cpp \
|
||||
solveMaxCut.cpp \
|
||||
solveMaxFlow.cpp \
|
||||
solveMinCut.cpp \
|
||||
solveMinTree.cpp \
|
||||
solvePlanarity.cpp \
|
||||
solvePostman.cpp \
|
||||
solveSPTree.cpp \
|
||||
solveStable.cpp \
|
||||
solveSteiner.cpp \
|
||||
solveSymmTSP.cpp \
|
||||
solveTJoin.cpp \
|
||||
solveTreePkg.cpp \
|
||||
sparseBigraph.cpp \
|
||||
sparseDigraph.cpp \
|
||||
sparseGraph.cpp \
|
||||
sparseRepresentation.cpp \
|
||||
staticQueue.cpp \
|
||||
staticStack.cpp \
|
||||
stripeDissectionModel.cpp \
|
||||
subgraph.cpp \
|
||||
surfaceGraph.cpp \
|
||||
timers.cpp \
|
||||
treeView.cpp
|
||||
|
||||
goblinincludedir = $(includedir)/goblin
|
||||
goblininclude_HEADERS = $(GOBLIN_INC)
|
||||
|
||||
libgoblin_nil_la_SOURCES = $(GOBLIN_SRC)
|
||||
|
||||
libgoblin_la_SOURCES =
|
||||
libgoblin_la_LIBADD = libgoblin_nil.la
|
||||
|
||||
EXTRA_DIST = \
|
||||
CMakeLists.txt
|
||||
|
||||
include $(top_srcdir)/misc/Makefile.defs
|
||||
|
||||
|
||||
lib_LTLIBRARIES = libgoblin.la
|
||||
noinst_LTLIBRARIES = libgoblin_nil.la
|
||||
|
||||
GOBLIN_INC = \
|
||||
abstractBalanced.h \
|
||||
abstractBigraph.h \
|
||||
abstractDigraph.h \
|
||||
abstractGraph.h \
|
||||
abstractMixedGraph.h \
|
||||
abstractSubgraph.h \
|
||||
attribute.h \
|
||||
attributePool.h \
|
||||
auxiliaryNetwork.h \
|
||||
balancedDigraph.h \
|
||||
balancedToBalanced.h \
|
||||
basicHeap.h \
|
||||
bigraphToDigraph.h \
|
||||
binaryHeap.h \
|
||||
branchAsyTSP.h \
|
||||
branchColour.h \
|
||||
branchMIP.h \
|
||||
branchMaxCut.h \
|
||||
branchScheme.h \
|
||||
branchStable.h \
|
||||
branchSymmTSP.h \
|
||||
canvasBuilder.h \
|
||||
complement.h \
|
||||
configuration.h \
|
||||
denseBigraph.h \
|
||||
denseDigraph.h \
|
||||
denseGraph.h \
|
||||
denseInclude.h \
|
||||
denseRepresentation.h \
|
||||
dictionary.h \
|
||||
digraphToDigraph.h \
|
||||
disjointFamily.h \
|
||||
dynamicQueue.h \
|
||||
dynamicStack.h \
|
||||
exportToDot.h \
|
||||
exportToTk.h \
|
||||
exportToXFig.h \
|
||||
fibonacciHeap.h \
|
||||
fileExport.h \
|
||||
fileImport.h \
|
||||
globals.h \
|
||||
glpkWrapper.h \
|
||||
goblin.h \
|
||||
goblinController.h \
|
||||
goblinQueue.h \
|
||||
gosh.h \
|
||||
graphDisplayProxy.h \
|
||||
graphInclude.h \
|
||||
graphRepresentation.h \
|
||||
graphToBalanced.h \
|
||||
hashTable.h \
|
||||
ilpWrapper.h \
|
||||
incrementalGeometry.h \
|
||||
indexSet.h \
|
||||
investigator.h \
|
||||
lpSolver.h \
|
||||
managedObject.h \
|
||||
matrix.h \
|
||||
messenger.h \
|
||||
mixedGraph.h \
|
||||
moduleGuard.h \
|
||||
movingLineModel.h \
|
||||
nestedFamily.h \
|
||||
networkSimplex.h \
|
||||
orthogonalGrid.h \
|
||||
segment.h \
|
||||
sequentialQueue.h \
|
||||
sequentialStack.h \
|
||||
shrinkingNetwork.h \
|
||||
sparseBigraph.h \
|
||||
sparseDigraph.h \
|
||||
sparseGraph.h \
|
||||
sparseInclude.h \
|
||||
sparseRepresentation.h \
|
||||
staticQueue.h \
|
||||
staticStack.h \
|
||||
stripeDissectionModel.h \
|
||||
subgraph.h \
|
||||
surfaceGraph.h \
|
||||
switchBaseTypes.h \
|
||||
timers.h \
|
||||
treeView.h \
|
||||
version.h
|
||||
|
||||
|
||||
GOBLIN_SRC = \
|
||||
abstractBalanced.cpp \
|
||||
abstractBigraph.cpp \
|
||||
abstractDigraph.cpp \
|
||||
abstractGraph.cpp \
|
||||
abstractMixedGraph.cpp \
|
||||
abstractSubgraph.cpp \
|
||||
attributePool.cpp \
|
||||
auxiliaryNetwork.cpp \
|
||||
balancedDigraph.cpp \
|
||||
balancedToBalanced.cpp \
|
||||
basicHeap.cpp \
|
||||
bigraphToDigraph.cpp \
|
||||
binaryHeap.cpp \
|
||||
branchMIP.cpp \
|
||||
branchScheme.cpp \
|
||||
canvasBuilder.cpp \
|
||||
complement.cpp \
|
||||
denseBigraph.cpp \
|
||||
denseDigraph.cpp \
|
||||
denseGraph.cpp \
|
||||
denseRepresentation.cpp \
|
||||
dictionary.cpp \
|
||||
digraphToDigraph.cpp \
|
||||
disjointFamily.cpp \
|
||||
doxygen.cpp \
|
||||
dynamicQueue.cpp \
|
||||
dynamicStack.cpp \
|
||||
exportToDot.cpp \
|
||||
exportToTk.cpp \
|
||||
exportToXFig.cpp \
|
||||
fibonacciHeap.cpp \
|
||||
fileExport.cpp \
|
||||
fileImport.cpp \
|
||||
globals.cpp \
|
||||
goblinController.cpp \
|
||||
graphDisplayProxy.cpp \
|
||||
graphRepresentation.cpp \
|
||||
graphToBalanced.cpp \
|
||||
hashTable.cpp \
|
||||
ilpCompose.cpp \
|
||||
ilpWrapper.cpp \
|
||||
incrementalGeometry.cpp \
|
||||
indexSet.cpp \
|
||||
itAuxiliaryNetwork.cpp \
|
||||
itGraph.cpp \
|
||||
itSurfaceGraph.cpp \
|
||||
layoutForceDirected.cpp \
|
||||
layoutKandinsky.cpp \
|
||||
layoutLayered.cpp \
|
||||
layoutOrthogonal.cpp \
|
||||
libConvert.cpp \
|
||||
libImport.cpp \
|
||||
libLayout.cpp \
|
||||
libPerfect.cpp \
|
||||
libPlanarity.cpp \
|
||||
listOfAuthors.cpp \
|
||||
listOfModules.cpp \
|
||||
listOfReferences.cpp \
|
||||
listOfTimers.cpp \
|
||||
lpBasis.cpp \
|
||||
lpRepresentation.cpp \
|
||||
lpSolver.cpp \
|
||||
managedObject.cpp \
|
||||
matrix.cpp \
|
||||
mixedGraph.cpp \
|
||||
moduleGuard.cpp \
|
||||
movingLineModel.cpp \
|
||||
nestedFamily.cpp \
|
||||
networkSimplex.cpp \
|
||||
orthogonalGrid.cpp \
|
||||
poolTables.cpp \
|
||||
segment.cpp \
|
||||
seriesParallel.cpp \
|
||||
shrinkingNetwork.cpp \
|
||||
solveAsyTSP.cpp \
|
||||
solveColour.cpp \
|
||||
solveComponents.cpp \
|
||||
solveMCBalFlow.cpp \
|
||||
solveMCFlow.cpp \
|
||||
solveMatching.cpp \
|
||||
solveMaxBalFlow.cpp \
|
||||
solveMaxCut.cpp \
|
||||
solveMaxFlow.cpp \
|
||||
solveMinCut.cpp \
|
||||
solveMinTree.cpp \
|
||||
solvePlanarity.cpp \
|
||||
solvePostman.cpp \
|
||||
solveSPTree.cpp \
|
||||
solveStable.cpp \
|
||||
solveSteiner.cpp \
|
||||
solveSymmTSP.cpp \
|
||||
solveTJoin.cpp \
|
||||
solveTreePkg.cpp \
|
||||
sparseBigraph.cpp \
|
||||
sparseDigraph.cpp \
|
||||
sparseGraph.cpp \
|
||||
sparseRepresentation.cpp \
|
||||
staticQueue.cpp \
|
||||
staticStack.cpp \
|
||||
stripeDissectionModel.cpp \
|
||||
subgraph.cpp \
|
||||
surfaceGraph.cpp \
|
||||
timers.cpp \
|
||||
treeView.cpp
|
||||
|
||||
goblinincludedir = $(includedir)/goblin
|
||||
goblininclude_HEADERS = $(GOBLIN_INC)
|
||||
|
||||
libgoblin_nil_la_SOURCES = $(GOBLIN_SRC)
|
||||
|
||||
libgoblin_la_SOURCES =
|
||||
libgoblin_la_LIBADD = libgoblin_nil.la
|
||||
|
||||
EXTRA_DIST = \
|
||||
CMakeLists.txt
|
||||
|
||||
include $(top_srcdir)/misc/Makefile.defs
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,238 @@
|
||||
|
||||
// This file forms part of the GOBLIN C++ Class Library.
|
||||
//
|
||||
// Initially written by Christian Fremuth-Paeger, February 1999
|
||||
//
|
||||
// Copying, compiling, distribution and modification
|
||||
// of this source code is permitted only in accordance
|
||||
// with the GOBLIN general licence information.
|
||||
|
||||
/// \file abstractBalanced.h
|
||||
/// \brief #abstractBalancedFNW class interface
|
||||
|
||||
#ifndef _ABSTRACT_BALANCED_H_
|
||||
#define _ABSTRACT_BALANCED_H_
|
||||
|
||||
#include "abstractDigraph.h"
|
||||
|
||||
|
||||
/// \brief The base class for all kinds of balanced (skew-symmetric) digraph objects
|
||||
|
||||
class abstractBalancedFNW : public abstractDiGraph
|
||||
{
|
||||
friend class balancedToBalanced;
|
||||
protected:
|
||||
|
||||
TNode n1; ///< Number of outer nodes
|
||||
TArc* Q; ///< An array for encoding of odd cycles
|
||||
TArc* prop; ///< An array of node props
|
||||
TArc* petal; ///< An array of node petals
|
||||
TNode* base; ///< An array of blossom bases
|
||||
|
||||
public:
|
||||
|
||||
abstractBalancedFNW(TNode _n1=0,TArc _m1=0) throw();
|
||||
virtual ~abstractBalancedFNW() throw();
|
||||
|
||||
unsigned long Allocated() const throw();
|
||||
|
||||
bool IsBalanced() const throw() {return true;};
|
||||
|
||||
virtual void Symmetrize() throw() = 0;
|
||||
virtual void Relax() throw() = 0;
|
||||
|
||||
TNode N1() const throw() {return n1;};
|
||||
|
||||
TNode ComplNode(TNode v) throw(ERRange);
|
||||
TArc ComplArc(TArc a) throw(ERRange);
|
||||
|
||||
// *************************************************************** //
|
||||
// Management of Odd Cycles //
|
||||
// *************************************************************** //
|
||||
|
||||
void InitCycles() throw();
|
||||
void ReleaseCycles() throw();
|
||||
|
||||
// *************************************************************** //
|
||||
// Management of Blossoms and Blossom Bases //
|
||||
// *************************************************************** //
|
||||
|
||||
void InitBlossoms() throw();
|
||||
void ReleaseBlossoms() throw();
|
||||
TNode Base(TNode v) throw(ERRange);
|
||||
TNode Pred(TNode v) throw(ERRange);
|
||||
void Bud(TNode v) throw(ERRange);
|
||||
void Shrink(TNode u,TNode v) throw(ERRange);
|
||||
|
||||
void InitPartition() throw() {InitBlossoms();};
|
||||
void ReleasePartition() throw() {ReleaseBlossoms();};
|
||||
void Merge(TNode u,TNode v) throw(ERRange) {Shrink(u,v);};
|
||||
TNode Find(TNode v) throw(ERRange) {return Base(v);};
|
||||
|
||||
// *************************************************************** //
|
||||
// Management of Props //
|
||||
// *************************************************************** //
|
||||
|
||||
void InitProps() throw();
|
||||
void ReleaseProps() throw();
|
||||
|
||||
// *************************************************************** //
|
||||
// Management of Petals //
|
||||
// *************************************************************** //
|
||||
|
||||
void InitPetals() throw();
|
||||
void ReleasePetals() throw();
|
||||
|
||||
TFloat FindBalCap(TArc*,TNode u,TNode v) throw(ERRange,ERRejected);
|
||||
virtual void BalPush(TArc a,TFloat lambda) throw(ERRange,ERRejected) = 0;
|
||||
virtual TFloat BalFlow(TArc a) const throw(ERRange,ERRejected) = 0;
|
||||
virtual TFloat BalCap(TArc a) const throw(ERRange,ERRejected);
|
||||
void BalAugment(TArc*,TNode,TNode,TFloat) throw(ERRange,ERRejected);
|
||||
|
||||
void CancelEven() throw();
|
||||
void MakeIntegral(TArc*,TNode,TNode) throw(ERRange);
|
||||
|
||||
TFloat MaxBalFlow(TNode s) throw(ERRange);
|
||||
TFloat Anstee(TNode s) throw(ERRange);
|
||||
virtual TFloat CancelOdd() throw();
|
||||
TFloat MicaliVazirani(TNode s,TNode t=NoNode) throw(ERRange);
|
||||
|
||||
TFloat BNSAndAugment(TNode s) throw(ERRange);
|
||||
TFloat BalancedScaling(TNode s) throw(ERRange);
|
||||
bool BNS(TNode s,TNode t=NoNode) throw(ERRange,ERRejected);
|
||||
void Expand(TNode* dist,TArc*,TNode,TNode) throw(ERRange);
|
||||
void CoExpand(TNode* dist,TArc*,TNode,TNode) throw(ERRange);
|
||||
|
||||
bool BNSKocayStone(TNode s,TNode t=NoNode) throw(ERRange);
|
||||
bool BNSKamedaMunro(TNode s,TNode t=NoNode) throw(ERRange);
|
||||
bool BNSHeuristicsBF(TNode s,TNode t=NoNode) throw(ERRange);
|
||||
bool BNSMicaliVazirani(TNode s,TNode t=NoNode) throw(ERRange);
|
||||
|
||||
TFloat MinCBalFlow(TNode s) throw(ERRange,ERRejected);
|
||||
TFloat PrimalDual(TNode s) throw(ERRange,ERRejected);
|
||||
TFloat EnhancedPD(TNode s) throw(ERRange,ERRejected);
|
||||
TFloat CancelPD() throw();
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
// This file forms part of the GOBLIN C++ Class Library.
|
||||
//
|
||||
// Initially written by Christian Fremuth-Paeger, February 1999
|
||||
//
|
||||
// Copying, compiling, distribution and modification
|
||||
// of this source code is permitted only in accordance
|
||||
// with the GOBLIN general licence information.
|
||||
|
||||
/// \file abstractBalanced.h
|
||||
/// \brief #abstractBalancedFNW class interface
|
||||
|
||||
#ifndef _ABSTRACT_BALANCED_H_
|
||||
#define _ABSTRACT_BALANCED_H_
|
||||
|
||||
#include "abstractDigraph.h"
|
||||
|
||||
|
||||
/// \brief The base class for all kinds of balanced (skew-symmetric) digraph objects
|
||||
|
||||
class abstractBalancedFNW : public abstractDiGraph
|
||||
{
|
||||
friend class balancedToBalanced;
|
||||
protected:
|
||||
|
||||
TNode n1; ///< Number of outer nodes
|
||||
TArc* Q; ///< An array for encoding of odd cycles
|
||||
TArc* prop; ///< An array of node props
|
||||
TArc* petal; ///< An array of node petals
|
||||
TNode* base; ///< An array of blossom bases
|
||||
|
||||
public:
|
||||
|
||||
abstractBalancedFNW(TNode _n1=0,TArc _m1=0) throw();
|
||||
virtual ~abstractBalancedFNW() throw();
|
||||
|
||||
unsigned long Allocated() const throw();
|
||||
|
||||
bool IsBalanced() const throw() {return true;};
|
||||
|
||||
virtual void Symmetrize() throw() = 0;
|
||||
virtual void Relax() throw() = 0;
|
||||
|
||||
TNode N1() const throw() {return n1;};
|
||||
|
||||
TNode ComplNode(TNode v) throw(ERRange);
|
||||
TArc ComplArc(TArc a) throw(ERRange);
|
||||
|
||||
// *************************************************************** //
|
||||
// Management of Odd Cycles //
|
||||
// *************************************************************** //
|
||||
|
||||
void InitCycles() throw();
|
||||
void ReleaseCycles() throw();
|
||||
|
||||
// *************************************************************** //
|
||||
// Management of Blossoms and Blossom Bases //
|
||||
// *************************************************************** //
|
||||
|
||||
void InitBlossoms() throw();
|
||||
void ReleaseBlossoms() throw();
|
||||
TNode Base(TNode v) throw(ERRange);
|
||||
TNode Pred(TNode v) throw(ERRange);
|
||||
void Bud(TNode v) throw(ERRange);
|
||||
void Shrink(TNode u,TNode v) throw(ERRange);
|
||||
|
||||
void InitPartition() throw() {InitBlossoms();};
|
||||
void ReleasePartition() throw() {ReleaseBlossoms();};
|
||||
void Merge(TNode u,TNode v) throw(ERRange) {Shrink(u,v);};
|
||||
TNode Find(TNode v) throw(ERRange) {return Base(v);};
|
||||
|
||||
// *************************************************************** //
|
||||
// Management of Props //
|
||||
// *************************************************************** //
|
||||
|
||||
void InitProps() throw();
|
||||
void ReleaseProps() throw();
|
||||
|
||||
// *************************************************************** //
|
||||
// Management of Petals //
|
||||
// *************************************************************** //
|
||||
|
||||
void InitPetals() throw();
|
||||
void ReleasePetals() throw();
|
||||
|
||||
TFloat FindBalCap(TArc*,TNode u,TNode v) throw(ERRange,ERRejected);
|
||||
virtual void BalPush(TArc a,TFloat lambda) throw(ERRange,ERRejected) = 0;
|
||||
virtual TFloat BalFlow(TArc a) const throw(ERRange,ERRejected) = 0;
|
||||
virtual TFloat BalCap(TArc a) const throw(ERRange,ERRejected);
|
||||
void BalAugment(TArc*,TNode,TNode,TFloat) throw(ERRange,ERRejected);
|
||||
|
||||
void CancelEven() throw();
|
||||
void MakeIntegral(TArc*,TNode,TNode) throw(ERRange);
|
||||
|
||||
TFloat MaxBalFlow(TNode s) throw(ERRange);
|
||||
TFloat Anstee(TNode s) throw(ERRange);
|
||||
virtual TFloat CancelOdd() throw();
|
||||
TFloat MicaliVazirani(TNode s,TNode t=NoNode) throw(ERRange);
|
||||
|
||||
TFloat BNSAndAugment(TNode s) throw(ERRange);
|
||||
TFloat BalancedScaling(TNode s) throw(ERRange);
|
||||
bool BNS(TNode s,TNode t=NoNode) throw(ERRange,ERRejected);
|
||||
void Expand(TNode* dist,TArc*,TNode,TNode) throw(ERRange);
|
||||
void CoExpand(TNode* dist,TArc*,TNode,TNode) throw(ERRange);
|
||||
|
||||
bool BNSKocayStone(TNode s,TNode t=NoNode) throw(ERRange);
|
||||
bool BNSKamedaMunro(TNode s,TNode t=NoNode) throw(ERRange);
|
||||
bool BNSHeuristicsBF(TNode s,TNode t=NoNode) throw(ERRange);
|
||||
bool BNSMicaliVazirani(TNode s,TNode t=NoNode) throw(ERRange);
|
||||
|
||||
TFloat MinCBalFlow(TNode s) throw(ERRange,ERRejected);
|
||||
TFloat PrimalDual(TNode s) throw(ERRange,ERRejected);
|
||||
TFloat EnhancedPD(TNode s) throw(ERRange,ERRejected);
|
||||
TFloat CancelPD() throw();
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,346 @@
|
||||
|
||||
// This file forms part of the GOBLIN C++ Class Library.
|
||||
//
|
||||
// Initially written by Christian Fremuth-Paeger, December 1998
|
||||
//
|
||||
// Copying, compiling, distribution and modification
|
||||
// of this source code is permitted only in accordance
|
||||
// with the GOBLIN general licence information.
|
||||
|
||||
/// \file abstractBigraph.cpp
|
||||
/// \brief #abstractBiGraph partial class implementation
|
||||
|
||||
#include "abstractBigraph.h"
|
||||
|
||||
|
||||
abstractBiGraph::abstractBiGraph(TNode _n1,TNode _n2,TArc _m) throw(ERRange) :
|
||||
abstractGraph(_n1+_n2,_m), n1(_n1), n2(_n2)
|
||||
{
|
||||
CheckLimits();
|
||||
|
||||
LogEntry(LOG_MEM,"...Abstract bigraph object allocated");
|
||||
}
|
||||
|
||||
|
||||
abstractBiGraph::~abstractBiGraph() throw()
|
||||
{
|
||||
LogEntry(LOG_MEM,"...Abstract bigraph object disallocated");
|
||||
}
|
||||
|
||||
|
||||
unsigned long abstractBiGraph::Allocated() const throw()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool abstractBiGraph::IsBipartite() const throw()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void abstractBiGraph::CheckLimits() throw(ERRange)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
abstractMixedGraph::CheckLimits();
|
||||
|
||||
if (2*n1>=CT.MaxNode())
|
||||
{
|
||||
InternalError("CheckLimits","Number of left-hand nodes is out of range");
|
||||
}
|
||||
|
||||
if (2*n2>=CT.MaxNode())
|
||||
{
|
||||
InternalError("CheckLimits","Number of right-hand nodes is out of range");
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void abstractBiGraph::RandomArcs(TArc _m) throw(ERRejected)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (m+_m>=CT.MaxArc() || (!CT.randParallels && m+_m>TArc(n1*n2)))
|
||||
Error(ERR_REJECTED,"RandomArcs","Number of arcs is out of range");
|
||||
|
||||
#endif
|
||||
|
||||
if (CT.logMan && _m>0)
|
||||
{
|
||||
sprintf(CT.logBuffer,"Generating %lu edges...",static_cast<unsigned long>(_m));
|
||||
LogEntry(LOG_MAN,CT.logBuffer);
|
||||
}
|
||||
|
||||
for (TArc i=0;i<_m;)
|
||||
{
|
||||
TNode u = (TNode)CT.Rand(n1);
|
||||
TNode v = n1+(TNode)CT.Rand(n2);
|
||||
|
||||
TArc a = (!CT.randParallels && m>0) ? Adjacency(u,v) : NoArc;
|
||||
|
||||
if (a==NoArc)
|
||||
{
|
||||
ReleaseInvestigators();
|
||||
InsertArc(u,v);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void abstractBiGraph::ReadNNodes(goblinImport& F) throw(ERParse)
|
||||
{
|
||||
TNode *nodes = F.GetTNodeTuple(3);
|
||||
n = nodes[0];
|
||||
n1 = nodes[1];
|
||||
ni = nodes[2];
|
||||
n2 = n-n1;
|
||||
delete[] nodes;
|
||||
}
|
||||
|
||||
|
||||
leftHandNodes::leftHandNodes(const abstractBiGraph& _G) throw() :
|
||||
managedObject(_G.Context()),indexSet<TNode>(_G.N(),_G.Context()), G(_G)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
leftHandNodes::~leftHandNodes() throw()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
unsigned long leftHandNodes::Size() const throw()
|
||||
{
|
||||
return sizeof(leftHandNodes) + managedObject::Allocated();
|
||||
}
|
||||
|
||||
|
||||
bool leftHandNodes::IsMember(const TNode i) const throw(ERRange)
|
||||
{
|
||||
return (i<G.N1());
|
||||
}
|
||||
|
||||
|
||||
TNode leftHandNodes::First() const throw()
|
||||
{
|
||||
if (G.N1()>0) return 0; else return G.N();
|
||||
}
|
||||
|
||||
|
||||
TNode leftHandNodes::Successor(const TNode i) const throw(ERRange)
|
||||
{
|
||||
if (i<G.N1()-1) return i+1; else return G.N();
|
||||
}
|
||||
|
||||
|
||||
rightHandNodes::rightHandNodes(const abstractBiGraph& _G) throw() :
|
||||
managedObject(_G.Context()),indexSet<TNode>(_G.N(),_G.Context()), G(_G)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
rightHandNodes::~rightHandNodes() throw()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
unsigned long rightHandNodes::Size() const throw()
|
||||
{
|
||||
return sizeof(rightHandNodes) + managedObject::Allocated();
|
||||
}
|
||||
|
||||
|
||||
bool rightHandNodes::IsMember(const TNode i) const throw(ERRange)
|
||||
{
|
||||
return (i>=G.N1() && i<G.N());
|
||||
}
|
||||
|
||||
|
||||
TNode rightHandNodes::First() const throw()
|
||||
{
|
||||
if (G.N2()>0) return G.N1(); else return G.N();
|
||||
}
|
||||
|
||||
|
||||
TNode rightHandNodes::Successor(const TNode i) const throw(ERRange)
|
||||
{
|
||||
if (i<G.N()-1) return i+1; else return G.N();
|
||||
}
|
||||
|
||||
// This file forms part of the GOBLIN C++ Class Library.
|
||||
//
|
||||
// Initially written by Christian Fremuth-Paeger, December 1998
|
||||
//
|
||||
// Copying, compiling, distribution and modification
|
||||
// of this source code is permitted only in accordance
|
||||
// with the GOBLIN general licence information.
|
||||
|
||||
/// \file abstractBigraph.cpp
|
||||
/// \brief #abstractBiGraph partial class implementation
|
||||
|
||||
#include "abstractBigraph.h"
|
||||
|
||||
|
||||
abstractBiGraph::abstractBiGraph(TNode _n1,TNode _n2,TArc _m) throw(ERRange) :
|
||||
abstractGraph(_n1+_n2,_m), n1(_n1), n2(_n2)
|
||||
{
|
||||
CheckLimits();
|
||||
|
||||
LogEntry(LOG_MEM,"...Abstract bigraph object allocated");
|
||||
}
|
||||
|
||||
|
||||
abstractBiGraph::~abstractBiGraph() throw()
|
||||
{
|
||||
LogEntry(LOG_MEM,"...Abstract bigraph object disallocated");
|
||||
}
|
||||
|
||||
|
||||
unsigned long abstractBiGraph::Allocated() const throw()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool abstractBiGraph::IsBipartite() const throw()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void abstractBiGraph::CheckLimits() throw(ERRange)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
abstractMixedGraph::CheckLimits();
|
||||
|
||||
if (2*n1>=CT.MaxNode())
|
||||
{
|
||||
InternalError("CheckLimits","Number of left-hand nodes is out of range");
|
||||
}
|
||||
|
||||
if (2*n2>=CT.MaxNode())
|
||||
{
|
||||
InternalError("CheckLimits","Number of right-hand nodes is out of range");
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void abstractBiGraph::RandomArcs(TArc _m) throw(ERRejected)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (m+_m>=CT.MaxArc() || (!CT.randParallels && m+_m>TArc(n1*n2)))
|
||||
Error(ERR_REJECTED,"RandomArcs","Number of arcs is out of range");
|
||||
|
||||
#endif
|
||||
|
||||
if (CT.logMan && _m>0)
|
||||
{
|
||||
sprintf(CT.logBuffer,"Generating %lu edges...",static_cast<unsigned long>(_m));
|
||||
LogEntry(LOG_MAN,CT.logBuffer);
|
||||
}
|
||||
|
||||
for (TArc i=0;i<_m;)
|
||||
{
|
||||
TNode u = (TNode)CT.Rand(n1);
|
||||
TNode v = n1+(TNode)CT.Rand(n2);
|
||||
|
||||
TArc a = (!CT.randParallels && m>0) ? Adjacency(u,v) : NoArc;
|
||||
|
||||
if (a==NoArc)
|
||||
{
|
||||
ReleaseInvestigators();
|
||||
InsertArc(u,v);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void abstractBiGraph::ReadNNodes(goblinImport& F) throw(ERParse)
|
||||
{
|
||||
TNode *nodes = F.GetTNodeTuple(3);
|
||||
n = nodes[0];
|
||||
n1 = nodes[1];
|
||||
ni = nodes[2];
|
||||
n2 = n-n1;
|
||||
delete[] nodes;
|
||||
}
|
||||
|
||||
|
||||
leftHandNodes::leftHandNodes(const abstractBiGraph& _G) throw() :
|
||||
managedObject(_G.Context()),indexSet<TNode>(_G.N(),_G.Context()), G(_G)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
leftHandNodes::~leftHandNodes() throw()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
unsigned long leftHandNodes::Size() const throw()
|
||||
{
|
||||
return sizeof(leftHandNodes) + managedObject::Allocated();
|
||||
}
|
||||
|
||||
|
||||
bool leftHandNodes::IsMember(const TNode i) const throw(ERRange)
|
||||
{
|
||||
return (i<G.N1());
|
||||
}
|
||||
|
||||
|
||||
TNode leftHandNodes::First() const throw()
|
||||
{
|
||||
if (G.N1()>0) return 0; else return G.N();
|
||||
}
|
||||
|
||||
|
||||
TNode leftHandNodes::Successor(const TNode i) const throw(ERRange)
|
||||
{
|
||||
if (i<G.N1()-1) return i+1; else return G.N();
|
||||
}
|
||||
|
||||
|
||||
rightHandNodes::rightHandNodes(const abstractBiGraph& _G) throw() :
|
||||
managedObject(_G.Context()),indexSet<TNode>(_G.N(),_G.Context()), G(_G)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
rightHandNodes::~rightHandNodes() throw()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
unsigned long rightHandNodes::Size() const throw()
|
||||
{
|
||||
return sizeof(rightHandNodes) + managedObject::Allocated();
|
||||
}
|
||||
|
||||
|
||||
bool rightHandNodes::IsMember(const TNode i) const throw(ERRange)
|
||||
{
|
||||
return (i>=G.N1() && i<G.N());
|
||||
}
|
||||
|
||||
|
||||
TNode rightHandNodes::First() const throw()
|
||||
{
|
||||
if (G.N2()>0) return G.N1(); else return G.N();
|
||||
}
|
||||
|
||||
|
||||
TNode rightHandNodes::Successor(const TNode i) const throw(ERRange)
|
||||
{
|
||||
if (i<G.N()-1) return i+1; else return G.N();
|
||||
}
|
||||
@@ -0,0 +1,324 @@
|
||||
|
||||
// This file forms part of the GOBLIN C++ Class Library.
|
||||
//
|
||||
// Initially written by Christian Fremuth-Paeger, December 1998
|
||||
//
|
||||
// Copying, compiling, distribution and modification
|
||||
// of this source code is permitted only in accordance
|
||||
// with the GOBLIN general licence information.
|
||||
|
||||
/// \file abstractBigraph.h
|
||||
/// \brief #abstractBiGraph class interface
|
||||
|
||||
#ifndef _ABSTRACT_BIGRAPH_H_
|
||||
#define _ABSTRACT_BIGRAPH_H_
|
||||
|
||||
#include "abstractGraph.h"
|
||||
|
||||
|
||||
/// \brief The base class for all kinds of bipartite graph objects
|
||||
|
||||
class abstractBiGraph : public abstractGraph
|
||||
{
|
||||
protected:
|
||||
|
||||
TNode n1; ///< Number of left-hand nodes
|
||||
TNode n2; ///< Number of right-hand nodes
|
||||
|
||||
public:
|
||||
|
||||
abstractBiGraph(TNode _n1=0,TNode _n2=0,TArc _m=0) throw(ERRange);
|
||||
virtual ~abstractBiGraph() throw();
|
||||
|
||||
unsigned long Allocated() const throw();
|
||||
void CheckLimits() throw(ERRange);
|
||||
|
||||
/// \addtogroup classifications
|
||||
/// @{
|
||||
|
||||
bool IsBipartite() const throw();
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
/// \addtogroup objectDimensions
|
||||
/// @{
|
||||
|
||||
/// \brief Query the number of left-hand graph nodes
|
||||
///
|
||||
/// \return The number of left-hand graph nodes
|
||||
inline TNode N1() const throw();
|
||||
|
||||
/// \brief Query the number of right-hand graph nodes
|
||||
///
|
||||
/// \return The number of right-hand graph nodes
|
||||
inline TNode N2() const throw();
|
||||
|
||||
/// @}
|
||||
|
||||
void RandomArcs(TArc _m) throw(ERRejected);
|
||||
|
||||
virtual void ReadNNodes(goblinImport& F) throw(ERParse);
|
||||
|
||||
bool MaximumAssignment() throw();
|
||||
bool MaximumAssignment(TCap cDeg) throw();
|
||||
bool MaximumAssignment(TCap *pLower,TCap *pDeg = NULL) throw();
|
||||
|
||||
bool MinCAssignment() throw();
|
||||
bool MinCAssignment(TCap cDeg) throw();
|
||||
bool MinCAssignment(TCap *pLower,TCap *pDeg = NULL) throw();
|
||||
|
||||
private:
|
||||
|
||||
bool PMHeuristicsCandidates() throw();
|
||||
|
||||
public:
|
||||
|
||||
bool MaximumMatching() throw()
|
||||
{return MaximumAssignment();};
|
||||
bool MaximumMatching(TCap cDeg) throw()
|
||||
{return MaximumAssignment(cDeg);};
|
||||
bool MaximumMatching(TCap *pLower,TCap *pDeg = NULL) throw()
|
||||
{return MaximumAssignment(pLower,pDeg);};
|
||||
|
||||
bool MinCMatching() throw()
|
||||
{return MinCAssignment();};
|
||||
bool MinCMatching(TCap cDeg) throw()
|
||||
{return MinCAssignment(cDeg);};
|
||||
bool MinCMatching(TCap *pLower,TCap *pDeg = NULL) throw()
|
||||
{return MinCAssignment(pLower,pDeg);};
|
||||
|
||||
TNode StableSet() throw();
|
||||
TNode NodeColouring(TNode k = NoNode) throw();
|
||||
|
||||
};
|
||||
|
||||
|
||||
inline TNode abstractBiGraph::N1() const throw()
|
||||
{
|
||||
return n1;
|
||||
}
|
||||
|
||||
|
||||
inline TNode abstractBiGraph::N2() const throw()
|
||||
{
|
||||
return n2;
|
||||
}
|
||||
|
||||
|
||||
/// \addtogroup groupIndexSets
|
||||
/// @{
|
||||
|
||||
/// \brief Index sets representing all left-hand nodes of a bipartite graph
|
||||
///
|
||||
/// Objects specify all bigraph nodes 0,1,..,n1-1
|
||||
|
||||
class leftHandNodes : public virtual indexSet<TNode>
|
||||
{
|
||||
private:
|
||||
|
||||
const abstractBiGraph& G;
|
||||
|
||||
public:
|
||||
|
||||
leftHandNodes(const abstractBiGraph& _G) throw();
|
||||
~leftHandNodes() throw();
|
||||
|
||||
unsigned long Size() const throw();
|
||||
|
||||
bool IsMember(const TNode i) const throw(ERRange);
|
||||
TNode First() const throw();
|
||||
TNode Successor(const TNode i) const throw(ERRange);
|
||||
|
||||
};
|
||||
|
||||
|
||||
/// \brief Index sets representing all right-hand nodes of a bipartite graph
|
||||
///
|
||||
/// Objects specify all bigraph nodes n1,n1+1,..,n-1
|
||||
|
||||
class rightHandNodes : public virtual indexSet<TNode>
|
||||
{
|
||||
private:
|
||||
|
||||
const abstractBiGraph& G;
|
||||
|
||||
public:
|
||||
|
||||
rightHandNodes(const abstractBiGraph& _G) throw();
|
||||
~rightHandNodes() throw();
|
||||
|
||||
unsigned long Size() const throw();
|
||||
|
||||
bool IsMember(const TNode i) const throw(ERRange);
|
||||
TNode First() const throw();
|
||||
TNode Successor(const TNode i) const throw(ERRange);
|
||||
|
||||
};
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
// This file forms part of the GOBLIN C++ Class Library.
|
||||
//
|
||||
// Initially written by Christian Fremuth-Paeger, December 1998
|
||||
//
|
||||
// Copying, compiling, distribution and modification
|
||||
// of this source code is permitted only in accordance
|
||||
// with the GOBLIN general licence information.
|
||||
|
||||
/// \file abstractBigraph.h
|
||||
/// \brief #abstractBiGraph class interface
|
||||
|
||||
#ifndef _ABSTRACT_BIGRAPH_H_
|
||||
#define _ABSTRACT_BIGRAPH_H_
|
||||
|
||||
#include "abstractGraph.h"
|
||||
|
||||
|
||||
/// \brief The base class for all kinds of bipartite graph objects
|
||||
|
||||
class abstractBiGraph : public abstractGraph
|
||||
{
|
||||
protected:
|
||||
|
||||
TNode n1; ///< Number of left-hand nodes
|
||||
TNode n2; ///< Number of right-hand nodes
|
||||
|
||||
public:
|
||||
|
||||
abstractBiGraph(TNode _n1=0,TNode _n2=0,TArc _m=0) throw(ERRange);
|
||||
virtual ~abstractBiGraph() throw();
|
||||
|
||||
unsigned long Allocated() const throw();
|
||||
void CheckLimits() throw(ERRange);
|
||||
|
||||
/// \addtogroup classifications
|
||||
/// @{
|
||||
|
||||
bool IsBipartite() const throw();
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
/// \addtogroup objectDimensions
|
||||
/// @{
|
||||
|
||||
/// \brief Query the number of left-hand graph nodes
|
||||
///
|
||||
/// \return The number of left-hand graph nodes
|
||||
inline TNode N1() const throw();
|
||||
|
||||
/// \brief Query the number of right-hand graph nodes
|
||||
///
|
||||
/// \return The number of right-hand graph nodes
|
||||
inline TNode N2() const throw();
|
||||
|
||||
/// @}
|
||||
|
||||
void RandomArcs(TArc _m) throw(ERRejected);
|
||||
|
||||
virtual void ReadNNodes(goblinImport& F) throw(ERParse);
|
||||
|
||||
bool MaximumAssignment() throw();
|
||||
bool MaximumAssignment(TCap cDeg) throw();
|
||||
bool MaximumAssignment(TCap *pLower,TCap *pDeg = NULL) throw();
|
||||
|
||||
bool MinCAssignment() throw();
|
||||
bool MinCAssignment(TCap cDeg) throw();
|
||||
bool MinCAssignment(TCap *pLower,TCap *pDeg = NULL) throw();
|
||||
|
||||
private:
|
||||
|
||||
bool PMHeuristicsCandidates() throw();
|
||||
|
||||
public:
|
||||
|
||||
bool MaximumMatching() throw()
|
||||
{return MaximumAssignment();};
|
||||
bool MaximumMatching(TCap cDeg) throw()
|
||||
{return MaximumAssignment(cDeg);};
|
||||
bool MaximumMatching(TCap *pLower,TCap *pDeg = NULL) throw()
|
||||
{return MaximumAssignment(pLower,pDeg);};
|
||||
|
||||
bool MinCMatching() throw()
|
||||
{return MinCAssignment();};
|
||||
bool MinCMatching(TCap cDeg) throw()
|
||||
{return MinCAssignment(cDeg);};
|
||||
bool MinCMatching(TCap *pLower,TCap *pDeg = NULL) throw()
|
||||
{return MinCAssignment(pLower,pDeg);};
|
||||
|
||||
TNode StableSet() throw();
|
||||
TNode NodeColouring(TNode k = NoNode) throw();
|
||||
|
||||
};
|
||||
|
||||
|
||||
inline TNode abstractBiGraph::N1() const throw()
|
||||
{
|
||||
return n1;
|
||||
}
|
||||
|
||||
|
||||
inline TNode abstractBiGraph::N2() const throw()
|
||||
{
|
||||
return n2;
|
||||
}
|
||||
|
||||
|
||||
/// \addtogroup groupIndexSets
|
||||
/// @{
|
||||
|
||||
/// \brief Index sets representing all left-hand nodes of a bipartite graph
|
||||
///
|
||||
/// Objects specify all bigraph nodes 0,1,..,n1-1
|
||||
|
||||
class leftHandNodes : public virtual indexSet<TNode>
|
||||
{
|
||||
private:
|
||||
|
||||
const abstractBiGraph& G;
|
||||
|
||||
public:
|
||||
|
||||
leftHandNodes(const abstractBiGraph& _G) throw();
|
||||
~leftHandNodes() throw();
|
||||
|
||||
unsigned long Size() const throw();
|
||||
|
||||
bool IsMember(const TNode i) const throw(ERRange);
|
||||
TNode First() const throw();
|
||||
TNode Successor(const TNode i) const throw(ERRange);
|
||||
|
||||
};
|
||||
|
||||
|
||||
/// \brief Index sets representing all right-hand nodes of a bipartite graph
|
||||
///
|
||||
/// Objects specify all bigraph nodes n1,n1+1,..,n-1
|
||||
|
||||
class rightHandNodes : public virtual indexSet<TNode>
|
||||
{
|
||||
private:
|
||||
|
||||
const abstractBiGraph& G;
|
||||
|
||||
public:
|
||||
|
||||
rightHandNodes(const abstractBiGraph& _G) throw();
|
||||
~rightHandNodes() throw();
|
||||
|
||||
unsigned long Size() const throw();
|
||||
|
||||
bool IsMember(const TNode i) const throw(ERRange);
|
||||
TNode First() const throw();
|
||||
TNode Successor(const TNode i) const throw(ERRange);
|
||||
|
||||
};
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,700 @@
|
||||
|
||||
// This file forms part of the GOBLIN C++ Class Library.
|
||||
//
|
||||
// Initially written by Christian Fremuth-Paeger, December 1998
|
||||
//
|
||||
// Copying, compiling, distribution and modification
|
||||
// of this source code is permitted only in accordance
|
||||
// with the GOBLIN general licence information.
|
||||
|
||||
/// \file abstractDigraph.cpp
|
||||
/// \brief #abstractDiGraph partial class implementation
|
||||
|
||||
#include "abstractDigraph.h"
|
||||
|
||||
|
||||
abstractDiGraph::abstractDiGraph(TNode _n,TArc _m) throw() :
|
||||
abstractMixedGraph(_n,_m)
|
||||
{
|
||||
LogEntry(LOG_MEM,"...Abstract digraph allocated");
|
||||
}
|
||||
|
||||
|
||||
abstractDiGraph::~abstractDiGraph() throw()
|
||||
{
|
||||
LogEntry(LOG_MEM,"...Abstract digraph disallocated");
|
||||
}
|
||||
|
||||
|
||||
unsigned long abstractDiGraph::Allocated() const throw()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
TFloat abstractDiGraph::Flow(TArc a) const throw(ERRange)
|
||||
{
|
||||
return Sub(a);
|
||||
}
|
||||
|
||||
|
||||
void abstractDiGraph::Push(TArc a,TFloat Lambda) throw(ERRange,ERRejected)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (a>=2*m) NoSuchArc("Push",a);
|
||||
|
||||
#endif
|
||||
|
||||
// This looks like cycling code since the default implementation of
|
||||
// SetSubRelative() also calls Push(). But note that represented graphs
|
||||
// reimplement SetSubRelative(), and all problem reimplement Push().
|
||||
// So, no recurrency occurs for concrete objects.
|
||||
|
||||
SetSubRelative(a, (a&1) ? -Lambda : Lambda);
|
||||
}
|
||||
|
||||
|
||||
void abstractDiGraph::Augment(TArc* pred,TNode u,TNode v,TFloat Lambda)
|
||||
throw(ERRange,ERRejected)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (u>=n) NoSuchNode("Augment",u);
|
||||
|
||||
if (v>=n) NoSuchNode("Augment",v);
|
||||
|
||||
if (Lambda<=0) Error(ERR_REJECTED,"Augment","Amount should be positive");
|
||||
|
||||
if (!pred) Error(ERR_REJECTED,"Augment","Missing predecessor labels");
|
||||
|
||||
TNode PathLength = 0;
|
||||
|
||||
#endif
|
||||
|
||||
TNode w = v;
|
||||
|
||||
#if defined(_LOGGING_)
|
||||
|
||||
THandle LH = NoHandle;
|
||||
|
||||
if (CT.logMeth>1)
|
||||
{
|
||||
sprintf(CT.logBuffer,"Augmenting by %g units of flow...",
|
||||
static_cast<double>(Lambda));
|
||||
LogEntry(LOG_METH2,CT.logBuffer);
|
||||
LogEntry(LOG_METH2,"Path in reverse order:");
|
||||
OpenFold();
|
||||
sprintf(CT.logBuffer,"(%lu",static_cast<unsigned long>(w));
|
||||
LH = LogStart(LOG_METH2,CT.logBuffer);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
do
|
||||
{
|
||||
TArc a = pred[w];
|
||||
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (PathLength>=n || a==NoArc)
|
||||
{
|
||||
InternalError("Augment","Missing start node");
|
||||
}
|
||||
|
||||
PathLength++;
|
||||
|
||||
#endif
|
||||
|
||||
Push(a,Lambda);
|
||||
pred[w] = NoArc;
|
||||
w = StartNode(a);
|
||||
|
||||
#if defined(_LOGGING_)
|
||||
|
||||
if (CT.logMeth>1)
|
||||
{
|
||||
sprintf(CT.logBuffer,"[%lu]%lu",
|
||||
static_cast<unsigned long>(a),static_cast<unsigned long>(w));
|
||||
LogAppend(LH,CT.logBuffer);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
while (w!=u);
|
||||
|
||||
#if defined(_LOGGING_)
|
||||
|
||||
if (CT.logMeth>1)
|
||||
{
|
||||
LogEnd(LH,")");
|
||||
CloseFold();
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
TFloat abstractDiGraph::FindCap(TArc* pred,TNode u,TNode v) throw(ERRange,ERRejected)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (u>=n) NoSuchNode("FindCap",u);
|
||||
|
||||
if (v>=n) NoSuchNode("FindCap",v);
|
||||
|
||||
if (!pred) Error(ERR_REJECTED,"FindCap","Missing predecessor labels");
|
||||
|
||||
TNode PathLength = 0;
|
||||
|
||||
#endif
|
||||
|
||||
TNode w = v;
|
||||
TFloat Lambda = InfFloat;
|
||||
|
||||
do
|
||||
{
|
||||
TArc a = pred[w];
|
||||
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (PathLength>=n || a==NoArc)
|
||||
{
|
||||
InternalError("FindCap","Missing start node");
|
||||
}
|
||||
|
||||
PathLength++;
|
||||
|
||||
#endif
|
||||
|
||||
if (ResCap(a)<Lambda) Lambda = ResCap(a);
|
||||
|
||||
w = StartNode(a);
|
||||
}
|
||||
while (w!=u);
|
||||
|
||||
return Lambda;
|
||||
}
|
||||
|
||||
|
||||
void abstractDiGraph::AdjustDivergence(TArc a,TFloat Lambda)
|
||||
throw(ERRange,ERRejected)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (a>=2*m) NoSuchArc("AdjustDivergence",a);
|
||||
|
||||
if (Lambda<0)
|
||||
Error(ERR_REJECTED,"AdjustDivergence","Amount should be non-negative");
|
||||
|
||||
#endif
|
||||
|
||||
TNode u = StartNode(a);
|
||||
TNode v = EndNode(a);
|
||||
|
||||
if (sDegIn!=NULL)
|
||||
{
|
||||
if (a&1)
|
||||
{
|
||||
sDegIn[u] -= Lambda;
|
||||
sDegOut[v] -= Lambda;
|
||||
}
|
||||
else
|
||||
{
|
||||
sDegOut[u] += Lambda;
|
||||
sDegIn[v] += Lambda;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TFloat abstractDiGraph::FlowValue(TNode s,TNode t) throw(ERRange,ERCheck)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (s>=n) NoSuchNode("FlowValue",s);
|
||||
|
||||
if (t>=n) NoSuchNode("FlowValue",t);
|
||||
|
||||
#endif
|
||||
|
||||
LogEntry(LOG_METH,"Checking the flow labels...");
|
||||
|
||||
for (TNode v=0;v<n;v++)
|
||||
{
|
||||
if (Divergence(v)!=Demand(v) && !(v==s || v==t))
|
||||
Error(ERR_CHECK,"FlowValue","Not a legal st-flow");
|
||||
}
|
||||
|
||||
if (CT.logRes)
|
||||
{
|
||||
sprintf(CT.logBuffer,"...Flow value: %g",Divergence(t));
|
||||
LogEntry(LOG_RES,CT.logBuffer);
|
||||
}
|
||||
|
||||
return Divergence(t);
|
||||
}
|
||||
|
||||
|
||||
bool abstractDiGraph::Compatible() throw()
|
||||
{
|
||||
LogEntry(LOG_METH,"Checking reduced length labels...");
|
||||
|
||||
TFloat* potential = GetPotentials();
|
||||
|
||||
for (TArc a=0;a<2*m;a++)
|
||||
{
|
||||
if (ResCap(a)>0 && RedLength(potential,a)<-CT.epsilon)
|
||||
{
|
||||
LogEntry(LOG_RES,"...solutions are not compatible");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
LogEntry(LOG_RES,"...solutions are compatible");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
TFloat abstractDiGraph::MCF_DualObjective() throw()
|
||||
{
|
||||
TFloat ret = 0;
|
||||
TFloat* potential = GetPotentials();
|
||||
|
||||
for (TNode v=0;v<n && potential;v++)
|
||||
{
|
||||
ret += Demand(v)*potential[v];
|
||||
}
|
||||
|
||||
for (TArc a=0;a<m;a++)
|
||||
{
|
||||
TFloat thisLength = RedLength(potential,2*a);
|
||||
|
||||
if (thisLength>0) ret += LCap(2*a)*thisLength;
|
||||
if (thisLength<0) ret += UCap(2*a)*thisLength;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
supersaturatedNodes::supersaturatedNodes(const abstractDiGraph& _G,TCap _delta) throw() :
|
||||
managedObject(_G.Context()),indexSet<TNode>(_G.N(),_G.Context()),G(_G),delta(_delta)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
supersaturatedNodes::~supersaturatedNodes() throw()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
unsigned long supersaturatedNodes::Size() const throw()
|
||||
{
|
||||
return sizeof(supersaturatedNodes) + managedObject::Allocated();
|
||||
}
|
||||
|
||||
|
||||
bool supersaturatedNodes::IsMember(const TNode i) const throw(ERRange)
|
||||
{
|
||||
return (const_cast<abstractDiGraph&>(G).Divergence(i)-G.Demand(i) > delta);
|
||||
}
|
||||
|
||||
|
||||
deficientNodes::deficientNodes(const abstractDiGraph& _G,TCap _delta) throw() :
|
||||
managedObject(_G.Context()),indexSet<TNode>(_G.N(),_G.Context()),G(_G),delta(_delta)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
deficientNodes::~deficientNodes() throw()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
unsigned long deficientNodes::Size() const throw()
|
||||
{
|
||||
return sizeof(deficientNodes) + managedObject::Allocated();
|
||||
}
|
||||
|
||||
|
||||
bool deficientNodes::IsMember(const TNode i) const throw(ERRange)
|
||||
{
|
||||
return (const_cast<abstractDiGraph&>(G).Divergence(i)-G.Demand(i) < -delta);
|
||||
}
|
||||
|
||||
|
||||
residualArcs::residualArcs(const abstractMixedGraph& _G,TCap _delta) throw() :
|
||||
managedObject(_G.Context()),indexSet<TArc>(2*_G.M(),_G.Context()),
|
||||
G(_G),delta(_delta)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
residualArcs::~residualArcs() throw()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
unsigned long residualArcs::Size() const throw()
|
||||
{
|
||||
return sizeof(residualArcs) + managedObject::Allocated();
|
||||
}
|
||||
|
||||
|
||||
bool residualArcs::IsMember(const TArc i) const throw(ERRange)
|
||||
{
|
||||
return ( G.Blocking(i|1) && G.ResCap(i)>delta)
|
||||
|| (!G.Blocking(i|1) && G.UCap(i)>delta);
|
||||
}
|
||||
|
||||
// This file forms part of the GOBLIN C++ Class Library.
|
||||
//
|
||||
// Initially written by Christian Fremuth-Paeger, December 1998
|
||||
//
|
||||
// Copying, compiling, distribution and modification
|
||||
// of this source code is permitted only in accordance
|
||||
// with the GOBLIN general licence information.
|
||||
|
||||
/// \file abstractDigraph.cpp
|
||||
/// \brief #abstractDiGraph partial class implementation
|
||||
|
||||
#include "abstractDigraph.h"
|
||||
|
||||
|
||||
abstractDiGraph::abstractDiGraph(TNode _n,TArc _m) throw() :
|
||||
abstractMixedGraph(_n,_m)
|
||||
{
|
||||
LogEntry(LOG_MEM,"...Abstract digraph allocated");
|
||||
}
|
||||
|
||||
|
||||
abstractDiGraph::~abstractDiGraph() throw()
|
||||
{
|
||||
LogEntry(LOG_MEM,"...Abstract digraph disallocated");
|
||||
}
|
||||
|
||||
|
||||
unsigned long abstractDiGraph::Allocated() const throw()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
TFloat abstractDiGraph::Flow(TArc a) const throw(ERRange)
|
||||
{
|
||||
return Sub(a);
|
||||
}
|
||||
|
||||
|
||||
void abstractDiGraph::Push(TArc a,TFloat Lambda) throw(ERRange,ERRejected)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (a>=2*m) NoSuchArc("Push",a);
|
||||
|
||||
#endif
|
||||
|
||||
// This looks like cycling code since the default implementation of
|
||||
// SetSubRelative() also calls Push(). But note that represented graphs
|
||||
// reimplement SetSubRelative(), and all problem reimplement Push().
|
||||
// So, no recurrency occurs for concrete objects.
|
||||
|
||||
SetSubRelative(a, (a&1) ? -Lambda : Lambda);
|
||||
}
|
||||
|
||||
|
||||
void abstractDiGraph::Augment(TArc* pred,TNode u,TNode v,TFloat Lambda)
|
||||
throw(ERRange,ERRejected)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (u>=n) NoSuchNode("Augment",u);
|
||||
|
||||
if (v>=n) NoSuchNode("Augment",v);
|
||||
|
||||
if (Lambda<=0) Error(ERR_REJECTED,"Augment","Amount should be positive");
|
||||
|
||||
if (!pred) Error(ERR_REJECTED,"Augment","Missing predecessor labels");
|
||||
|
||||
TNode PathLength = 0;
|
||||
|
||||
#endif
|
||||
|
||||
TNode w = v;
|
||||
|
||||
#if defined(_LOGGING_)
|
||||
|
||||
THandle LH = NoHandle;
|
||||
|
||||
if (CT.logMeth>1)
|
||||
{
|
||||
sprintf(CT.logBuffer,"Augmenting by %g units of flow...",
|
||||
static_cast<double>(Lambda));
|
||||
LogEntry(LOG_METH2,CT.logBuffer);
|
||||
LogEntry(LOG_METH2,"Path in reverse order:");
|
||||
OpenFold();
|
||||
sprintf(CT.logBuffer,"(%lu",static_cast<unsigned long>(w));
|
||||
LH = LogStart(LOG_METH2,CT.logBuffer);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
do
|
||||
{
|
||||
TArc a = pred[w];
|
||||
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (PathLength>=n || a==NoArc)
|
||||
{
|
||||
InternalError("Augment","Missing start node");
|
||||
}
|
||||
|
||||
PathLength++;
|
||||
|
||||
#endif
|
||||
|
||||
Push(a,Lambda);
|
||||
pred[w] = NoArc;
|
||||
w = StartNode(a);
|
||||
|
||||
#if defined(_LOGGING_)
|
||||
|
||||
if (CT.logMeth>1)
|
||||
{
|
||||
sprintf(CT.logBuffer,"[%lu]%lu",
|
||||
static_cast<unsigned long>(a),static_cast<unsigned long>(w));
|
||||
LogAppend(LH,CT.logBuffer);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
while (w!=u);
|
||||
|
||||
#if defined(_LOGGING_)
|
||||
|
||||
if (CT.logMeth>1)
|
||||
{
|
||||
LogEnd(LH,")");
|
||||
CloseFold();
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
TFloat abstractDiGraph::FindCap(TArc* pred,TNode u,TNode v) throw(ERRange,ERRejected)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (u>=n) NoSuchNode("FindCap",u);
|
||||
|
||||
if (v>=n) NoSuchNode("FindCap",v);
|
||||
|
||||
if (!pred) Error(ERR_REJECTED,"FindCap","Missing predecessor labels");
|
||||
|
||||
TNode PathLength = 0;
|
||||
|
||||
#endif
|
||||
|
||||
TNode w = v;
|
||||
TFloat Lambda = InfFloat;
|
||||
|
||||
do
|
||||
{
|
||||
TArc a = pred[w];
|
||||
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (PathLength>=n || a==NoArc)
|
||||
{
|
||||
InternalError("FindCap","Missing start node");
|
||||
}
|
||||
|
||||
PathLength++;
|
||||
|
||||
#endif
|
||||
|
||||
if (ResCap(a)<Lambda) Lambda = ResCap(a);
|
||||
|
||||
w = StartNode(a);
|
||||
}
|
||||
while (w!=u);
|
||||
|
||||
return Lambda;
|
||||
}
|
||||
|
||||
|
||||
void abstractDiGraph::AdjustDivergence(TArc a,TFloat Lambda)
|
||||
throw(ERRange,ERRejected)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (a>=2*m) NoSuchArc("AdjustDivergence",a);
|
||||
|
||||
if (Lambda<0)
|
||||
Error(ERR_REJECTED,"AdjustDivergence","Amount should be non-negative");
|
||||
|
||||
#endif
|
||||
|
||||
TNode u = StartNode(a);
|
||||
TNode v = EndNode(a);
|
||||
|
||||
if (sDegIn!=NULL)
|
||||
{
|
||||
if (a&1)
|
||||
{
|
||||
sDegIn[u] -= Lambda;
|
||||
sDegOut[v] -= Lambda;
|
||||
}
|
||||
else
|
||||
{
|
||||
sDegOut[u] += Lambda;
|
||||
sDegIn[v] += Lambda;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TFloat abstractDiGraph::FlowValue(TNode s,TNode t) throw(ERRange,ERCheck)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (s>=n) NoSuchNode("FlowValue",s);
|
||||
|
||||
if (t>=n) NoSuchNode("FlowValue",t);
|
||||
|
||||
#endif
|
||||
|
||||
LogEntry(LOG_METH,"Checking the flow labels...");
|
||||
|
||||
for (TNode v=0;v<n;v++)
|
||||
{
|
||||
if (Divergence(v)!=Demand(v) && !(v==s || v==t))
|
||||
Error(ERR_CHECK,"FlowValue","Not a legal st-flow");
|
||||
}
|
||||
|
||||
if (CT.logRes)
|
||||
{
|
||||
sprintf(CT.logBuffer,"...Flow value: %g",Divergence(t));
|
||||
LogEntry(LOG_RES,CT.logBuffer);
|
||||
}
|
||||
|
||||
return Divergence(t);
|
||||
}
|
||||
|
||||
|
||||
bool abstractDiGraph::Compatible() throw()
|
||||
{
|
||||
LogEntry(LOG_METH,"Checking reduced length labels...");
|
||||
|
||||
TFloat* potential = GetPotentials();
|
||||
|
||||
for (TArc a=0;a<2*m;a++)
|
||||
{
|
||||
if (ResCap(a)>0 && RedLength(potential,a)<-CT.epsilon)
|
||||
{
|
||||
LogEntry(LOG_RES,"...solutions are not compatible");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
LogEntry(LOG_RES,"...solutions are compatible");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
TFloat abstractDiGraph::MCF_DualObjective() throw()
|
||||
{
|
||||
TFloat ret = 0;
|
||||
TFloat* potential = GetPotentials();
|
||||
|
||||
for (TNode v=0;v<n && potential;v++)
|
||||
{
|
||||
ret += Demand(v)*potential[v];
|
||||
}
|
||||
|
||||
for (TArc a=0;a<m;a++)
|
||||
{
|
||||
TFloat thisLength = RedLength(potential,2*a);
|
||||
|
||||
if (thisLength>0) ret += LCap(2*a)*thisLength;
|
||||
if (thisLength<0) ret += UCap(2*a)*thisLength;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
supersaturatedNodes::supersaturatedNodes(const abstractDiGraph& _G,TCap _delta) throw() :
|
||||
managedObject(_G.Context()),indexSet<TNode>(_G.N(),_G.Context()),G(_G),delta(_delta)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
supersaturatedNodes::~supersaturatedNodes() throw()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
unsigned long supersaturatedNodes::Size() const throw()
|
||||
{
|
||||
return sizeof(supersaturatedNodes) + managedObject::Allocated();
|
||||
}
|
||||
|
||||
|
||||
bool supersaturatedNodes::IsMember(const TNode i) const throw(ERRange)
|
||||
{
|
||||
return (const_cast<abstractDiGraph&>(G).Divergence(i)-G.Demand(i) > delta);
|
||||
}
|
||||
|
||||
|
||||
deficientNodes::deficientNodes(const abstractDiGraph& _G,TCap _delta) throw() :
|
||||
managedObject(_G.Context()),indexSet<TNode>(_G.N(),_G.Context()),G(_G),delta(_delta)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
deficientNodes::~deficientNodes() throw()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
unsigned long deficientNodes::Size() const throw()
|
||||
{
|
||||
return sizeof(deficientNodes) + managedObject::Allocated();
|
||||
}
|
||||
|
||||
|
||||
bool deficientNodes::IsMember(const TNode i) const throw(ERRange)
|
||||
{
|
||||
return (const_cast<abstractDiGraph&>(G).Divergence(i)-G.Demand(i) < -delta);
|
||||
}
|
||||
|
||||
|
||||
residualArcs::residualArcs(const abstractMixedGraph& _G,TCap _delta) throw() :
|
||||
managedObject(_G.Context()),indexSet<TArc>(2*_G.M(),_G.Context()),
|
||||
G(_G),delta(_delta)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
residualArcs::~residualArcs() throw()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
unsigned long residualArcs::Size() const throw()
|
||||
{
|
||||
return sizeof(residualArcs) + managedObject::Allocated();
|
||||
}
|
||||
|
||||
|
||||
bool residualArcs::IsMember(const TArc i) const throw(ERRange)
|
||||
{
|
||||
return ( G.Blocking(i|1) && G.ResCap(i)>delta)
|
||||
|| (!G.Blocking(i|1) && G.UCap(i)>delta);
|
||||
}
|
||||
@@ -0,0 +1,628 @@
|
||||
|
||||
// This file forms part of the GOBLIN C++ Class Library.
|
||||
//
|
||||
// Initially written by Christian Fremuth-Paeger, December 1998
|
||||
//
|
||||
// Copying, compiling, distribution and modification
|
||||
// of this source code is permitted only in accordance
|
||||
// with the GOBLIN general licence information.
|
||||
|
||||
/// \file abstractDigraph.h
|
||||
/// \brief #abstractDiGraph class interface
|
||||
|
||||
#ifndef _ABSTRACT_DIGRAPH_H_
|
||||
#define _ABSTRACT_DIGRAPH_H_
|
||||
|
||||
#include "abstractMixedGraph.h"
|
||||
|
||||
|
||||
/// \brief The base class for all kinds of directed graph objects
|
||||
|
||||
class abstractDiGraph : public abstractMixedGraph
|
||||
{
|
||||
friend class abstractMixedGraph; // For the max-flow methods
|
||||
|
||||
public:
|
||||
|
||||
abstractDiGraph(TNode _n=0,TArc _m=0) throw();
|
||||
virtual ~abstractDiGraph() throw();
|
||||
|
||||
unsigned long Allocated() const throw();
|
||||
|
||||
bool IsDirected() const throw()
|
||||
{
|
||||
return true;
|
||||
};
|
||||
|
||||
TFloat NodeCap(TNode v) throw(ERRange)
|
||||
{
|
||||
if (DegIn(v)<DegOut(v)) return DegIn(v); else return DegOut(v);
|
||||
};
|
||||
|
||||
|
||||
/// \addtogroup flowLowLevel
|
||||
/// @{
|
||||
|
||||
/// \brief Return a flow value
|
||||
///
|
||||
/// \param a An arc index
|
||||
/// \return The flow on this arc (the subgraph multiplicity)
|
||||
virtual TFloat Flow(TArc a) const throw(ERRange);
|
||||
|
||||
/// \brief Increase or decrease the flow value of the arc a by an amount Lambda
|
||||
///
|
||||
/// \param a An arc index
|
||||
/// \param lambda An amount of flow
|
||||
virtual void Push(TArc a,TFloat lambda) throw(ERRange,ERRejected);
|
||||
|
||||
/// \brief Update the degree labels after a push operation
|
||||
///
|
||||
/// \param a An arc index
|
||||
/// \param lambda An amount of flow
|
||||
void AdjustDivergence(TArc a,TFloat lambda) throw(ERRange,ERRejected);
|
||||
|
||||
/// \brief Compute the residual path capacity
|
||||
///
|
||||
/// \param pred[] An array of predecessor arcs assigned with the graph nodes
|
||||
/// \param source The path start node
|
||||
/// \param target The path end node
|
||||
/// \return The minimal residual capacity on the described path
|
||||
TFloat FindCap(TArc* pred,TNode source,TNode target) throw(ERRange,ERRejected);
|
||||
|
||||
/// \brief Augment along a given path
|
||||
///
|
||||
/// \param pred[] An array of predecessor arcs assigned with the graph nodes
|
||||
/// \param source The path start node
|
||||
/// \param target The path end node
|
||||
/// \param lambda An amount of flow
|
||||
void Augment(TArc* pred,TNode source,TNode target,TFloat lambda) throw(ERRange,ERRejected);
|
||||
|
||||
/// \brief Checks wether the flow labels define an st-flow and, if so, returns the flow value
|
||||
///
|
||||
/// \param source The path start node
|
||||
/// \param target The path end node
|
||||
/// \return The flow value, that is the divergence at the target node
|
||||
TFloat FlowValue(TNode source,TNode target) throw(ERRange,ERCheck);
|
||||
|
||||
/// \brief Complementary slackness optimality test
|
||||
///
|
||||
/// \retval true Both the flow and the node potentials are optimal
|
||||
///
|
||||
/// Checks wether the flow labels and the node potentials satisfy the
|
||||
/// complementary slackness conditions, that is, for every arc, either
|
||||
/// the residual capacity is zero, or the reduced length is non-negative.
|
||||
///
|
||||
/// This procedure does not verify that the flow is feasible!
|
||||
bool Compatible() throw();
|
||||
|
||||
/// \brief Computes a min-cost flow "dual" objective value from the node potentials
|
||||
///
|
||||
/// \return The dual objective value
|
||||
///
|
||||
/// This applies to arbitrary node potentials and gives a lower bound on the minimal flow objective
|
||||
TFloat MCF_DualObjective() throw();
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
/// \addtogroup treePacking
|
||||
/// @{
|
||||
|
||||
/// \brief Determine a maximum arborescence packing
|
||||
///
|
||||
/// \param root The root node index in the range [0,1,..,n-1]
|
||||
///
|
||||
/// If the arc capacity bounds are all one, this determines a maximum number
|
||||
/// of disjoint spanning arborescences rooted at r, and this number matches
|
||||
/// the minimum cut capacity returned by StrongEdgeConnectivity(r).
|
||||
///
|
||||
/// In the general setting with non-trivial arc capacities, the constructed
|
||||
/// arborescences are not edge disjoint and hence cannot be completely saved
|
||||
/// to the edge colours. The particular spanning trees can be obtained either
|
||||
/// by the predecessor labels of the trace objects (set traceLevel>=3), or by
|
||||
/// calling TreePKGInit() and TreePKGStripTree() directly (and then using the
|
||||
/// predecessor trees of the manipulated digraph).
|
||||
TCap TreePacking(TNode root) throw(ERRange);
|
||||
|
||||
/// \brief Generate a digraph copy to be manipulated during the tree packing
|
||||
/// \brief method and determine the total tree multiplicity
|
||||
///
|
||||
/// \param totalMulti The multiplicity of all arborescences to be determined
|
||||
/// \param root The root node index in range [0,1,..,n-1]
|
||||
/// \return Pointer to a digraph to be manipulated by TreePKGStripTree()
|
||||
abstractDiGraph* TreePKGInit(TCap* totalMulti,TNode root) throw();
|
||||
|
||||
/// \brief Reduce the arc capacities in the digraph copy according to the
|
||||
/// \brief current arborescence and construct another arborescence if one exists
|
||||
///
|
||||
/// \param G Pointer to the digraph to be manipulated
|
||||
/// \param multi The remaining multiplicity
|
||||
/// \param root The root node index in range [0,1,..,n-1]
|
||||
/// \return The capacity of the newly found arborescence
|
||||
TCap TreePKGStripTree(abstractDiGraph* G,TCap* multi,TNode root) throw(ERRange);
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
/// \addtogroup minimumMeanCycle
|
||||
/// @{
|
||||
|
||||
/// \brief Compute a minimum mean length value cycle
|
||||
///
|
||||
/// \param EligibleArcs The set of eligible arcs
|
||||
/// \param meanValue A pointer to where the mean length value is written
|
||||
/// \return The index of a node on the found cycle or NoNode
|
||||
///
|
||||
/// This determines a cycle such that mean length value of the traversed
|
||||
/// arcs is minimal, exports this cycle by the predecessor labels. If the
|
||||
/// digraph is acyclic, NoNode is returned.
|
||||
TNode MinimumMeanCycle(const indexSet<TArc>& EligibleArcs,TFloat* meanValue) throw();
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
/// \addtogroup groupDirectedAcyclic
|
||||
/// @{
|
||||
|
||||
/// \brief Determine a topological numbering
|
||||
///
|
||||
/// \return A node on a directed cycle, or NoNode if the graph is a DAG
|
||||
///
|
||||
/// The ordinal numbers are provided by the node colour register
|
||||
TNode TopSort() throw();
|
||||
|
||||
/// \brief Determine a critical path
|
||||
///
|
||||
/// \return The end node of the critical path, or NoNode if the graph is not a DAG
|
||||
TNode CriticalPath() throw();
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
/// \addtogroup maximumFlow
|
||||
/// @{
|
||||
|
||||
private:
|
||||
|
||||
TFloat MXF_EdmondsKarp(TNode,TNode) throw(ERRange);
|
||||
TFloat MXF_CapacityScaling(TNode,TNode) throw(ERRange);
|
||||
TFloat MXF_PushRelabel(TMethMXF,TNode,TNode) throw(ERRange);
|
||||
TFloat MXF_Dinic(TNode,TNode) throw(ERRange);
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
/// \addtogroup groupMinCut
|
||||
/// @{
|
||||
|
||||
private:
|
||||
|
||||
TCap MCC_HaoOrlin(TMethMCC method,TNode r) throw(ERRange);
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
/// \addtogroup minCostFlow
|
||||
/// @{
|
||||
|
||||
private:
|
||||
|
||||
TFloat MCF_BusackerGowen(TNode,TNode) throw(ERRejected);
|
||||
TFloat MCF_EdmondsKarp(TNode,TNode) throw(ERRejected);
|
||||
|
||||
TFloat MCF_CycleCanceling() throw();
|
||||
TFloat MCF_MinMeanCycleCanceling() throw();
|
||||
TFloat MCF_CostScaling(TMethMCF) throw();
|
||||
TFloat MCF_NWSimplex() throw();
|
||||
TFloat MCF_CapacityScaling(bool = true) throw(ERRejected);
|
||||
TFloat MCF_ShortestAugmentingPath() throw(ERRejected)
|
||||
{return MCF_CapacityScaling(false);};
|
||||
|
||||
void MCF_NWSimplexCancelFree() throw();
|
||||
void MCF_NWSimplexStrongTree() throw();
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
/// \addtogroup eulerPostman
|
||||
/// @{
|
||||
|
||||
public:
|
||||
|
||||
// Documented in the class abstractMixedGraph
|
||||
void ChinesePostman(bool adjustUCap) throw(ERRejected);
|
||||
|
||||
/// @}
|
||||
|
||||
};
|
||||
|
||||
|
||||
/// \addtogroup groupIndexSets
|
||||
/// @{
|
||||
|
||||
/// \brief Index sets representing all supersaturated nodes
|
||||
///
|
||||
/// Objects specify all graph nodes with Divergence() > Demand() + delta
|
||||
/// where the latter is the capacity scaling parameter
|
||||
|
||||
class supersaturatedNodes : public virtual indexSet<TNode>
|
||||
{
|
||||
private:
|
||||
|
||||
const abstractDiGraph& G;
|
||||
const TCap delta;
|
||||
|
||||
public:
|
||||
|
||||
supersaturatedNodes(const abstractDiGraph& _G,TCap _delta) throw();
|
||||
~supersaturatedNodes() throw();
|
||||
|
||||
unsigned long Size() const throw();
|
||||
|
||||
bool IsMember(const TNode i) const throw(ERRange);
|
||||
|
||||
};
|
||||
|
||||
|
||||
/// \brief Index sets representing all deficient nodes
|
||||
///
|
||||
/// Objects specify all graph nodes with Divergence() < Demand() - delta
|
||||
/// where the latter is the capacity scaling parameter
|
||||
|
||||
class deficientNodes : public virtual indexSet<TNode>
|
||||
{
|
||||
private:
|
||||
|
||||
const abstractDiGraph& G;
|
||||
const TCap delta;
|
||||
|
||||
public:
|
||||
|
||||
deficientNodes(const abstractDiGraph& _G,TCap _delta) throw();
|
||||
~deficientNodes() throw();
|
||||
|
||||
unsigned long Size() const throw();
|
||||
|
||||
bool IsMember(const TNode i) const throw(ERRange);
|
||||
|
||||
};
|
||||
|
||||
|
||||
/// \brief Index sets representing residual arcs
|
||||
|
||||
class residualArcs : public indexSet<TArc>
|
||||
{
|
||||
private:
|
||||
|
||||
const abstractMixedGraph& G;
|
||||
TCap delta;
|
||||
|
||||
public:
|
||||
|
||||
residualArcs(const abstractMixedGraph& _G,TCap _delta=0.0) throw();
|
||||
~residualArcs() throw();
|
||||
|
||||
unsigned long Size() const throw();
|
||||
|
||||
bool IsMember(const TArc i) const throw(ERRange);
|
||||
|
||||
};
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
// This file forms part of the GOBLIN C++ Class Library.
|
||||
//
|
||||
// Initially written by Christian Fremuth-Paeger, December 1998
|
||||
//
|
||||
// Copying, compiling, distribution and modification
|
||||
// of this source code is permitted only in accordance
|
||||
// with the GOBLIN general licence information.
|
||||
|
||||
/// \file abstractDigraph.h
|
||||
/// \brief #abstractDiGraph class interface
|
||||
|
||||
#ifndef _ABSTRACT_DIGRAPH_H_
|
||||
#define _ABSTRACT_DIGRAPH_H_
|
||||
|
||||
#include "abstractMixedGraph.h"
|
||||
|
||||
|
||||
/// \brief The base class for all kinds of directed graph objects
|
||||
|
||||
class abstractDiGraph : public abstractMixedGraph
|
||||
{
|
||||
friend class abstractMixedGraph; // For the max-flow methods
|
||||
|
||||
public:
|
||||
|
||||
abstractDiGraph(TNode _n=0,TArc _m=0) throw();
|
||||
virtual ~abstractDiGraph() throw();
|
||||
|
||||
unsigned long Allocated() const throw();
|
||||
|
||||
bool IsDirected() const throw()
|
||||
{
|
||||
return true;
|
||||
};
|
||||
|
||||
TFloat NodeCap(TNode v) throw(ERRange)
|
||||
{
|
||||
if (DegIn(v)<DegOut(v)) return DegIn(v); else return DegOut(v);
|
||||
};
|
||||
|
||||
|
||||
/// \addtogroup flowLowLevel
|
||||
/// @{
|
||||
|
||||
/// \brief Return a flow value
|
||||
///
|
||||
/// \param a An arc index
|
||||
/// \return The flow on this arc (the subgraph multiplicity)
|
||||
virtual TFloat Flow(TArc a) const throw(ERRange);
|
||||
|
||||
/// \brief Increase or decrease the flow value of the arc a by an amount Lambda
|
||||
///
|
||||
/// \param a An arc index
|
||||
/// \param lambda An amount of flow
|
||||
virtual void Push(TArc a,TFloat lambda) throw(ERRange,ERRejected);
|
||||
|
||||
/// \brief Update the degree labels after a push operation
|
||||
///
|
||||
/// \param a An arc index
|
||||
/// \param lambda An amount of flow
|
||||
void AdjustDivergence(TArc a,TFloat lambda) throw(ERRange,ERRejected);
|
||||
|
||||
/// \brief Compute the residual path capacity
|
||||
///
|
||||
/// \param pred[] An array of predecessor arcs assigned with the graph nodes
|
||||
/// \param source The path start node
|
||||
/// \param target The path end node
|
||||
/// \return The minimal residual capacity on the described path
|
||||
TFloat FindCap(TArc* pred,TNode source,TNode target) throw(ERRange,ERRejected);
|
||||
|
||||
/// \brief Augment along a given path
|
||||
///
|
||||
/// \param pred[] An array of predecessor arcs assigned with the graph nodes
|
||||
/// \param source The path start node
|
||||
/// \param target The path end node
|
||||
/// \param lambda An amount of flow
|
||||
void Augment(TArc* pred,TNode source,TNode target,TFloat lambda) throw(ERRange,ERRejected);
|
||||
|
||||
/// \brief Checks wether the flow labels define an st-flow and, if so, returns the flow value
|
||||
///
|
||||
/// \param source The path start node
|
||||
/// \param target The path end node
|
||||
/// \return The flow value, that is the divergence at the target node
|
||||
TFloat FlowValue(TNode source,TNode target) throw(ERRange,ERCheck);
|
||||
|
||||
/// \brief Complementary slackness optimality test
|
||||
///
|
||||
/// \retval true Both the flow and the node potentials are optimal
|
||||
///
|
||||
/// Checks wether the flow labels and the node potentials satisfy the
|
||||
/// complementary slackness conditions, that is, for every arc, either
|
||||
/// the residual capacity is zero, or the reduced length is non-negative.
|
||||
///
|
||||
/// This procedure does not verify that the flow is feasible!
|
||||
bool Compatible() throw();
|
||||
|
||||
/// \brief Computes a min-cost flow "dual" objective value from the node potentials
|
||||
///
|
||||
/// \return The dual objective value
|
||||
///
|
||||
/// This applies to arbitrary node potentials and gives a lower bound on the minimal flow objective
|
||||
TFloat MCF_DualObjective() throw();
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
/// \addtogroup treePacking
|
||||
/// @{
|
||||
|
||||
/// \brief Determine a maximum arborescence packing
|
||||
///
|
||||
/// \param root The root node index in the range [0,1,..,n-1]
|
||||
///
|
||||
/// If the arc capacity bounds are all one, this determines a maximum number
|
||||
/// of disjoint spanning arborescences rooted at r, and this number matches
|
||||
/// the minimum cut capacity returned by StrongEdgeConnectivity(r).
|
||||
///
|
||||
/// In the general setting with non-trivial arc capacities, the constructed
|
||||
/// arborescences are not edge disjoint and hence cannot be completely saved
|
||||
/// to the edge colours. The particular spanning trees can be obtained either
|
||||
/// by the predecessor labels of the trace objects (set traceLevel>=3), or by
|
||||
/// calling TreePKGInit() and TreePKGStripTree() directly (and then using the
|
||||
/// predecessor trees of the manipulated digraph).
|
||||
TCap TreePacking(TNode root) throw(ERRange);
|
||||
|
||||
/// \brief Generate a digraph copy to be manipulated during the tree packing
|
||||
/// \brief method and determine the total tree multiplicity
|
||||
///
|
||||
/// \param totalMulti The multiplicity of all arborescences to be determined
|
||||
/// \param root The root node index in range [0,1,..,n-1]
|
||||
/// \return Pointer to a digraph to be manipulated by TreePKGStripTree()
|
||||
abstractDiGraph* TreePKGInit(TCap* totalMulti,TNode root) throw();
|
||||
|
||||
/// \brief Reduce the arc capacities in the digraph copy according to the
|
||||
/// \brief current arborescence and construct another arborescence if one exists
|
||||
///
|
||||
/// \param G Pointer to the digraph to be manipulated
|
||||
/// \param multi The remaining multiplicity
|
||||
/// \param root The root node index in range [0,1,..,n-1]
|
||||
/// \return The capacity of the newly found arborescence
|
||||
TCap TreePKGStripTree(abstractDiGraph* G,TCap* multi,TNode root) throw(ERRange);
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
/// \addtogroup minimumMeanCycle
|
||||
/// @{
|
||||
|
||||
/// \brief Compute a minimum mean length value cycle
|
||||
///
|
||||
/// \param EligibleArcs The set of eligible arcs
|
||||
/// \param meanValue A pointer to where the mean length value is written
|
||||
/// \return The index of a node on the found cycle or NoNode
|
||||
///
|
||||
/// This determines a cycle such that mean length value of the traversed
|
||||
/// arcs is minimal, exports this cycle by the predecessor labels. If the
|
||||
/// digraph is acyclic, NoNode is returned.
|
||||
TNode MinimumMeanCycle(const indexSet<TArc>& EligibleArcs,TFloat* meanValue) throw();
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
/// \addtogroup groupDirectedAcyclic
|
||||
/// @{
|
||||
|
||||
/// \brief Determine a topological numbering
|
||||
///
|
||||
/// \return A node on a directed cycle, or NoNode if the graph is a DAG
|
||||
///
|
||||
/// The ordinal numbers are provided by the node colour register
|
||||
TNode TopSort() throw();
|
||||
|
||||
/// \brief Determine a critical path
|
||||
///
|
||||
/// \return The end node of the critical path, or NoNode if the graph is not a DAG
|
||||
TNode CriticalPath() throw();
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
/// \addtogroup maximumFlow
|
||||
/// @{
|
||||
|
||||
private:
|
||||
|
||||
TFloat MXF_EdmondsKarp(TNode,TNode) throw(ERRange);
|
||||
TFloat MXF_CapacityScaling(TNode,TNode) throw(ERRange);
|
||||
TFloat MXF_PushRelabel(TMethMXF,TNode,TNode) throw(ERRange);
|
||||
TFloat MXF_Dinic(TNode,TNode) throw(ERRange);
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
/// \addtogroup groupMinCut
|
||||
/// @{
|
||||
|
||||
private:
|
||||
|
||||
TCap MCC_HaoOrlin(TMethMCC method,TNode r) throw(ERRange);
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
/// \addtogroup minCostFlow
|
||||
/// @{
|
||||
|
||||
private:
|
||||
|
||||
TFloat MCF_BusackerGowen(TNode,TNode) throw(ERRejected);
|
||||
TFloat MCF_EdmondsKarp(TNode,TNode) throw(ERRejected);
|
||||
|
||||
TFloat MCF_CycleCanceling() throw();
|
||||
TFloat MCF_MinMeanCycleCanceling() throw();
|
||||
TFloat MCF_CostScaling(TMethMCF) throw();
|
||||
TFloat MCF_NWSimplex() throw();
|
||||
TFloat MCF_CapacityScaling(bool = true) throw(ERRejected);
|
||||
TFloat MCF_ShortestAugmentingPath() throw(ERRejected)
|
||||
{return MCF_CapacityScaling(false);};
|
||||
|
||||
void MCF_NWSimplexCancelFree() throw();
|
||||
void MCF_NWSimplexStrongTree() throw();
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
/// \addtogroup eulerPostman
|
||||
/// @{
|
||||
|
||||
public:
|
||||
|
||||
// Documented in the class abstractMixedGraph
|
||||
void ChinesePostman(bool adjustUCap) throw(ERRejected);
|
||||
|
||||
/// @}
|
||||
|
||||
};
|
||||
|
||||
|
||||
/// \addtogroup groupIndexSets
|
||||
/// @{
|
||||
|
||||
/// \brief Index sets representing all supersaturated nodes
|
||||
///
|
||||
/// Objects specify all graph nodes with Divergence() > Demand() + delta
|
||||
/// where the latter is the capacity scaling parameter
|
||||
|
||||
class supersaturatedNodes : public virtual indexSet<TNode>
|
||||
{
|
||||
private:
|
||||
|
||||
const abstractDiGraph& G;
|
||||
const TCap delta;
|
||||
|
||||
public:
|
||||
|
||||
supersaturatedNodes(const abstractDiGraph& _G,TCap _delta) throw();
|
||||
~supersaturatedNodes() throw();
|
||||
|
||||
unsigned long Size() const throw();
|
||||
|
||||
bool IsMember(const TNode i) const throw(ERRange);
|
||||
|
||||
};
|
||||
|
||||
|
||||
/// \brief Index sets representing all deficient nodes
|
||||
///
|
||||
/// Objects specify all graph nodes with Divergence() < Demand() - delta
|
||||
/// where the latter is the capacity scaling parameter
|
||||
|
||||
class deficientNodes : public virtual indexSet<TNode>
|
||||
{
|
||||
private:
|
||||
|
||||
const abstractDiGraph& G;
|
||||
const TCap delta;
|
||||
|
||||
public:
|
||||
|
||||
deficientNodes(const abstractDiGraph& _G,TCap _delta) throw();
|
||||
~deficientNodes() throw();
|
||||
|
||||
unsigned long Size() const throw();
|
||||
|
||||
bool IsMember(const TNode i) const throw(ERRange);
|
||||
|
||||
};
|
||||
|
||||
|
||||
/// \brief Index sets representing residual arcs
|
||||
|
||||
class residualArcs : public indexSet<TArc>
|
||||
{
|
||||
private:
|
||||
|
||||
const abstractMixedGraph& G;
|
||||
TCap delta;
|
||||
|
||||
public:
|
||||
|
||||
residualArcs(const abstractMixedGraph& _G,TCap _delta=0.0) throw();
|
||||
~residualArcs() throw();
|
||||
|
||||
unsigned long Size() const throw();
|
||||
|
||||
bool IsMember(const TArc i) const throw(ERRange);
|
||||
|
||||
};
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,76 @@
|
||||
|
||||
// This file forms part of the GOBLIN C++ Class Library.
|
||||
//
|
||||
// Initially written by Christian Fremuth-Paeger, December 1998
|
||||
//
|
||||
// Copying, compiling, distribution and modification
|
||||
// of this source code is permitted only in accordance
|
||||
// with the GOBLIN general licence information.
|
||||
|
||||
/// \file abstractGraph.cpp
|
||||
/// \brief #abstractGraph partial class implementation
|
||||
|
||||
#include "abstractGraph.h"
|
||||
|
||||
|
||||
abstractGraph::abstractGraph(TNode _n,TArc _m) throw() :
|
||||
abstractMixedGraph(_n,_m)
|
||||
{
|
||||
LogEntry(LOG_MEM,"...Abstract graph object allocated");
|
||||
}
|
||||
|
||||
|
||||
abstractGraph::~abstractGraph() throw()
|
||||
{
|
||||
LogEntry(LOG_MEM,"...Abstract graph object disallocated");
|
||||
}
|
||||
|
||||
|
||||
unsigned long abstractGraph::Allocated() const throw()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool abstractGraph::IsUndirected() const throw()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// This file forms part of the GOBLIN C++ Class Library.
|
||||
//
|
||||
// Initially written by Christian Fremuth-Paeger, December 1998
|
||||
//
|
||||
// Copying, compiling, distribution and modification
|
||||
// of this source code is permitted only in accordance
|
||||
// with the GOBLIN general licence information.
|
||||
|
||||
/// \file abstractGraph.cpp
|
||||
/// \brief #abstractGraph partial class implementation
|
||||
|
||||
#include "abstractGraph.h"
|
||||
|
||||
|
||||
abstractGraph::abstractGraph(TNode _n,TArc _m) throw() :
|
||||
abstractMixedGraph(_n,_m)
|
||||
{
|
||||
LogEntry(LOG_MEM,"...Abstract graph object allocated");
|
||||
}
|
||||
|
||||
|
||||
abstractGraph::~abstractGraph() throw()
|
||||
{
|
||||
LogEntry(LOG_MEM,"...Abstract graph object disallocated");
|
||||
}
|
||||
|
||||
|
||||
unsigned long abstractGraph::Allocated() const throw()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool abstractGraph::IsUndirected() const throw()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,580 @@
|
||||
|
||||
// This file forms part of the GOBLIN C++ Class Library.
|
||||
//
|
||||
// Initially written by Christian Fremuth-Paeger, December 1998
|
||||
//
|
||||
// Copying, compiling, distribution and modification
|
||||
// of this source code is permitted only in accordance
|
||||
// with the GOBLIN general licence information.
|
||||
|
||||
/// \file abstractGraph.h
|
||||
/// \brief #abstractGraph class interface
|
||||
|
||||
#ifndef _ABSTRACT_GRAPH_H_
|
||||
#define _ABSTRACT_GRAPH_H_
|
||||
|
||||
#include "abstractMixedGraph.h"
|
||||
|
||||
|
||||
/// \brief The base class for all kinds of undirected graph objects
|
||||
|
||||
class abstractGraph : public abstractMixedGraph
|
||||
{
|
||||
friend class abstractMixedGraph;
|
||||
friend class branchSymmTSP;
|
||||
|
||||
public:
|
||||
|
||||
abstractGraph(TNode _n=0,TArc _m=0) throw();
|
||||
virtual ~abstractGraph() throw();
|
||||
|
||||
unsigned long Allocated() const throw();
|
||||
|
||||
|
||||
/// \addtogroup classifications
|
||||
/// @{
|
||||
|
||||
bool IsUndirected() const throw();
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
|
||||
/// \addtogroup steiner
|
||||
/// @{
|
||||
|
||||
protected:
|
||||
|
||||
/// \brief Compute a Steiner tree by the Mehlhorn heuristic
|
||||
///
|
||||
/// \param Terminals An index set of terminal nodes in the range [0,1,..,n]
|
||||
/// \param root A node in the range [0,1,..,n]
|
||||
/// \return The length of the found Steiner tree
|
||||
///
|
||||
/// This uses a discrete Voronoi diagram which is obtained by simultaneous
|
||||
/// search for shortest path trees from all terminal nodes. The found partial
|
||||
/// trees are shrunk, and on the resulting graph a minimum spanning tree is
|
||||
/// computed. This tree maps back to a Steiner tree in the original graph.
|
||||
///
|
||||
/// The procedure requires non-negative edge length. It is 1-approximative,
|
||||
/// that is, the constructed tree is twice as long as an optimal Steiner tree
|
||||
/// in the worst case.
|
||||
TFloat STT_Heuristic(const indexSet<TNode>& Terminals,TNode root) throw(ERRange);
|
||||
|
||||
// Documented in the class abstractMixedGraph
|
||||
TFloat STT_Enumerate(const indexSet<TNode>& Terminals,TNode root) throw(ERRange);
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
/// \addtogroup tsp
|
||||
/// @{
|
||||
|
||||
protected:
|
||||
|
||||
// Documented in the class abstractMixedGraph
|
||||
virtual TFloat TSP_Heuristic(THeurTSP method,TNode root) throw(ERRange,ERRejected);
|
||||
|
||||
/// \brief Compute a tour by the Christofides Heuristic
|
||||
///
|
||||
/// \param r The tree root node or NoNode
|
||||
/// \return The length of the constructed tour
|
||||
///
|
||||
/// This works similar as TSP_HeuristicTree() in the sense that a spanning
|
||||
/// tree is extended to an Eulerian graph. Here, a minimum 1-matching of
|
||||
/// the nodes with odd degree in the tree are added. From the resulting graph,
|
||||
/// an arbitrary Eulerian walk is determined. This is reduced to a Hamiltonian
|
||||
/// cycle by travelling around the Eulerian walk and skipping all nodes which
|
||||
/// have already been visited.
|
||||
///
|
||||
/// The procedure is intended for metric undirected graphs, and then is
|
||||
/// 1/2-approximative, that is, the constructed tour is 3/2 times as long as an
|
||||
/// optimal tour in the worst case. The procedure works for all other kinds
|
||||
/// of complete graphs, but does not produce good tours in the general setting.
|
||||
///
|
||||
/// If no root node is specified, the procedure is repeated for all possible
|
||||
/// root nodes.
|
||||
///
|
||||
/// If CT.methLocal==LOCAL_OPTIMIZE, TSP_LocalSearch() is called for postprocessing.
|
||||
TFloat TSP_HeuristicChristofides(TNode r=NoNode) throw(ERRange);
|
||||
|
||||
/// \brief Refine a given tour by a 2 arc exchange step
|
||||
///
|
||||
/// \param pred An array of predecessor arcs, describing an Hamiltonian cycle
|
||||
/// \param limit The treshold for the acceptable change of tour length
|
||||
/// \retval true If the tour has been changed
|
||||
///
|
||||
/// This takes a given tour and searches for a pair of edges a1=uv, a2=xy which
|
||||
/// can be profitably replaced by the edges ux and vy. At most one replacement
|
||||
/// is done!
|
||||
bool TSP_2Exchange(TArc* pred,TFloat limit=0) throw(ERRejected);
|
||||
|
||||
// Documented in the class abstractMixedGraph
|
||||
TFloat TSP_SubOpt1Tree(TRelaxTSP method,TNode root,TFloat& bestUpper,
|
||||
bool branchAndBound) throw(ERRange);
|
||||
|
||||
// Documented in the class abstractMixedGraph
|
||||
TFloat TSP_BranchAndBound(TRelaxTSP method,int nCandidates,
|
||||
TNode root,TFloat upperBound) throw();
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
/// \addtogroup matching
|
||||
/// @{
|
||||
|
||||
public:
|
||||
|
||||
/// \brief Determine a maximum b-matching or f-factor
|
||||
///
|
||||
/// \retval true A perfect matching has been found
|
||||
///
|
||||
/// The desired node degrees are defined implicitly by the Demand() values.
|
||||
virtual bool MaximumMatching() throw();
|
||||
|
||||
/// \brief Determine a maximum k-factor
|
||||
///
|
||||
/// \param cDeg The desired constant node degree
|
||||
/// \retval true A perfect matching has been found
|
||||
virtual bool MaximumMatching(TCap cDeg) throw();
|
||||
|
||||
/// \brief Determine a minimum defect (b,c)-matching
|
||||
///
|
||||
/// \param pLower A pointer to an array of lower degree bounds
|
||||
/// \param pDeg A pointer to an array of upper degree bounds or NULL
|
||||
/// \retval true A perfect matching has been found
|
||||
virtual bool MaximumMatching(TCap *pLower,TCap *pDeg = NULL) throw();
|
||||
|
||||
/// \brief Determine a minimum-cost perfect b-matching or f-factor
|
||||
///
|
||||
/// \retval true A perfect matching has been found
|
||||
///
|
||||
/// The desired node degrees are defined implicitly by the Demand() values.
|
||||
/// Other than the overloaded methods which take explicit degree information,
|
||||
/// this allows for the candidate graph heuristic if the graph is dense and
|
||||
/// if methCandidates >= 0.
|
||||
///
|
||||
virtual bool MinCMatching() throw();
|
||||
|
||||
/// \brief Determine a minimum-cost perfect k-factor
|
||||
///
|
||||
/// \param cDeg The desired constant node degree
|
||||
/// \retval true A perfect matching has been found
|
||||
virtual bool MinCMatching(TCap cDeg) throw();
|
||||
|
||||
/// \brief Determine a minimum-cost perfect (b,c)-matching
|
||||
///
|
||||
/// \param pLower A pointer to an array of lower degree bounds
|
||||
/// \param pDeg A pointer to an array of upper degree bounds or NULL
|
||||
/// \retval true A perfect matching has been found
|
||||
virtual bool MinCMatching(TCap *pLower,TCap *pDeg = NULL) throw();
|
||||
|
||||
private:
|
||||
|
||||
/// \brief Determine a minimum-cost perfect (b,c)-matching by a candidate heuristic
|
||||
///
|
||||
/// \retval true A perfect matching has been found
|
||||
///
|
||||
/// This calls PMHeuristicsRandom() several times and takes the join of the
|
||||
/// found matchings as a candidate graph. If methSolve = 0, an optimal matching
|
||||
/// of the candidate graph is provided. Otherwise, a min-cost flow on the
|
||||
/// candidate graph is used as the starting solution on the entire graph.
|
||||
bool PMHeuristicsCandidates() throw();
|
||||
|
||||
protected:
|
||||
|
||||
/// \brief Determine a minimum-cost perfect (b,c)-matching by a random heuristic
|
||||
///
|
||||
/// \return The weight of the constructed matching
|
||||
///
|
||||
/// This step-by-step chooses random nodes and add adjacent arcs increasing
|
||||
/// by their lenght.
|
||||
TFloat PMHeuristicsRandom() throw();
|
||||
|
||||
public:
|
||||
|
||||
/// \brief Provide a minimum length edge cover by the edge colour register
|
||||
///
|
||||
/// \return The total edge length
|
||||
TFloat MinCEdgeCover() throw(ERRejected);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
/// \brief Compute a T-join for a given node set T
|
||||
///
|
||||
/// \param Terminals A set of terminal nodes. Must have even cardinality
|
||||
///
|
||||
/// This is the working procedure for all kinds of T-join solvers.
|
||||
/// It requires non-negative edge lengths.
|
||||
void ComputeTJoin(const indexSet<TNode>& Terminals) throw(ERRejected);
|
||||
|
||||
public:
|
||||
|
||||
/// \brief Compute a T-join for a given node set T
|
||||
///
|
||||
/// \param Terminals A set of terminal nodes. Must have even cardinality
|
||||
///
|
||||
/// Other than ComputeTJoin(), this can deal with negative length arcs.
|
||||
void MinCTJoin(const indexSet<TNode>& Terminals) throw();
|
||||
|
||||
/// \brief Compute a shortest path connecting a given node pair
|
||||
///
|
||||
/// \param s The start node of the path to be generated
|
||||
/// \param t The end node of the path to be generated
|
||||
/// \retval true A shortest st-path has been found
|
||||
///
|
||||
/// Other than general shortest path methods applied to undirected graphs,
|
||||
/// this can deal with negative length arcs. The found path is provided by
|
||||
/// the subgraph labels.
|
||||
bool SPX_TJoin(TNode s,TNode t) throw(ERRange);
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
/// \addtogroup eulerPostman
|
||||
/// @{
|
||||
|
||||
public:
|
||||
|
||||
// Documented in the class abstractMixedGraph
|
||||
void ChinesePostman(bool adjustUCap) throw(ERRejected);
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
/// \addtogroup maxCut
|
||||
/// @{
|
||||
|
||||
protected:
|
||||
|
||||
/// \brief Approximate maximum weight edge cut
|
||||
///
|
||||
/// \param method A #TMethMaxCut value specifying the applied method
|
||||
/// \param s A left-hand node index or NoNode
|
||||
/// \param t A right-hand node index or NoNode
|
||||
/// \return The weight of the constructed edge cut
|
||||
///
|
||||
/// Depending on methMaxCut, this either calls MXC_HeuristicGRASP(),
|
||||
/// MXC_HeuristicTree() or MXC_DualTJoin().
|
||||
TFloat MXC_Heuristic(TMethMaxCut method,TNode s = NoNode,TNode t = NoNode)
|
||||
throw(ERRange,ERRejected);
|
||||
|
||||
/// \brief Approximate maximum weight edge cut by using a maximum spanning tree
|
||||
///
|
||||
/// \param s A left-hand node index or NoNode
|
||||
/// \param t A right-hand node index or NoNode
|
||||
/// \return The weight of the constructed edge cut
|
||||
///
|
||||
/// This sets the bipartition according to a maximum weight spanning tree
|
||||
/// and the root node s. In particular, the graph must be connected.
|
||||
/// If methLocal==LOCAL_OPTIMIZE, MXC_LocalSearch() is called for postprocessing.
|
||||
TFloat MXC_HeuristicTree(TNode s = NoNode,TNode t = NoNode) throw(ERRange,ERRejected);
|
||||
|
||||
/// \brief Exact solution of the undirected planar maximum weight edge cut problem
|
||||
///
|
||||
/// \param s A left-hand node index or NoNode
|
||||
/// \return The weight of the constructed edge cut
|
||||
///
|
||||
/// This determines a T-join in the undirected dual graph.
|
||||
///
|
||||
/// The procedure is restricted to non-negative edge lengths!
|
||||
TFloat MXC_DualTJoin(TNode s = NoNode) throw(ERRange,ERRejected);
|
||||
|
||||
/// @}
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
// This file forms part of the GOBLIN C++ Class Library.
|
||||
//
|
||||
// Initially written by Christian Fremuth-Paeger, December 1998
|
||||
//
|
||||
// Copying, compiling, distribution and modification
|
||||
// of this source code is permitted only in accordance
|
||||
// with the GOBLIN general licence information.
|
||||
|
||||
/// \file abstractGraph.h
|
||||
/// \brief #abstractGraph class interface
|
||||
|
||||
#ifndef _ABSTRACT_GRAPH_H_
|
||||
#define _ABSTRACT_GRAPH_H_
|
||||
|
||||
#include "abstractMixedGraph.h"
|
||||
|
||||
|
||||
/// \brief The base class for all kinds of undirected graph objects
|
||||
|
||||
class abstractGraph : public abstractMixedGraph
|
||||
{
|
||||
friend class abstractMixedGraph;
|
||||
friend class branchSymmTSP;
|
||||
|
||||
public:
|
||||
|
||||
abstractGraph(TNode _n=0,TArc _m=0) throw();
|
||||
virtual ~abstractGraph() throw();
|
||||
|
||||
unsigned long Allocated() const throw();
|
||||
|
||||
|
||||
/// \addtogroup classifications
|
||||
/// @{
|
||||
|
||||
bool IsUndirected() const throw();
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
|
||||
/// \addtogroup steiner
|
||||
/// @{
|
||||
|
||||
protected:
|
||||
|
||||
/// \brief Compute a Steiner tree by the Mehlhorn heuristic
|
||||
///
|
||||
/// \param Terminals An index set of terminal nodes in the range [0,1,..,n]
|
||||
/// \param root A node in the range [0,1,..,n]
|
||||
/// \return The length of the found Steiner tree
|
||||
///
|
||||
/// This uses a discrete Voronoi diagram which is obtained by simultaneous
|
||||
/// search for shortest path trees from all terminal nodes. The found partial
|
||||
/// trees are shrunk, and on the resulting graph a minimum spanning tree is
|
||||
/// computed. This tree maps back to a Steiner tree in the original graph.
|
||||
///
|
||||
/// The procedure requires non-negative edge length. It is 1-approximative,
|
||||
/// that is, the constructed tree is twice as long as an optimal Steiner tree
|
||||
/// in the worst case.
|
||||
TFloat STT_Heuristic(const indexSet<TNode>& Terminals,TNode root) throw(ERRange);
|
||||
|
||||
// Documented in the class abstractMixedGraph
|
||||
TFloat STT_Enumerate(const indexSet<TNode>& Terminals,TNode root) throw(ERRange);
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
/// \addtogroup tsp
|
||||
/// @{
|
||||
|
||||
protected:
|
||||
|
||||
// Documented in the class abstractMixedGraph
|
||||
virtual TFloat TSP_Heuristic(THeurTSP method,TNode root) throw(ERRange,ERRejected);
|
||||
|
||||
/// \brief Compute a tour by the Christofides Heuristic
|
||||
///
|
||||
/// \param r The tree root node or NoNode
|
||||
/// \return The length of the constructed tour
|
||||
///
|
||||
/// This works similar as TSP_HeuristicTree() in the sense that a spanning
|
||||
/// tree is extended to an Eulerian graph. Here, a minimum 1-matching of
|
||||
/// the nodes with odd degree in the tree are added. From the resulting graph,
|
||||
/// an arbitrary Eulerian walk is determined. This is reduced to a Hamiltonian
|
||||
/// cycle by travelling around the Eulerian walk and skipping all nodes which
|
||||
/// have already been visited.
|
||||
///
|
||||
/// The procedure is intended for metric undirected graphs, and then is
|
||||
/// 1/2-approximative, that is, the constructed tour is 3/2 times as long as an
|
||||
/// optimal tour in the worst case. The procedure works for all other kinds
|
||||
/// of complete graphs, but does not produce good tours in the general setting.
|
||||
///
|
||||
/// If no root node is specified, the procedure is repeated for all possible
|
||||
/// root nodes.
|
||||
///
|
||||
/// If CT.methLocal==LOCAL_OPTIMIZE, TSP_LocalSearch() is called for postprocessing.
|
||||
TFloat TSP_HeuristicChristofides(TNode r=NoNode) throw(ERRange);
|
||||
|
||||
/// \brief Refine a given tour by a 2 arc exchange step
|
||||
///
|
||||
/// \param pred An array of predecessor arcs, describing an Hamiltonian cycle
|
||||
/// \param limit The treshold for the acceptable change of tour length
|
||||
/// \retval true If the tour has been changed
|
||||
///
|
||||
/// This takes a given tour and searches for a pair of edges a1=uv, a2=xy which
|
||||
/// can be profitably replaced by the edges ux and vy. At most one replacement
|
||||
/// is done!
|
||||
bool TSP_2Exchange(TArc* pred,TFloat limit=0) throw(ERRejected);
|
||||
|
||||
// Documented in the class abstractMixedGraph
|
||||
TFloat TSP_SubOpt1Tree(TRelaxTSP method,TNode root,TFloat& bestUpper,
|
||||
bool branchAndBound) throw(ERRange);
|
||||
|
||||
// Documented in the class abstractMixedGraph
|
||||
TFloat TSP_BranchAndBound(TRelaxTSP method,int nCandidates,
|
||||
TNode root,TFloat upperBound) throw();
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
/// \addtogroup matching
|
||||
/// @{
|
||||
|
||||
public:
|
||||
|
||||
/// \brief Determine a maximum b-matching or f-factor
|
||||
///
|
||||
/// \retval true A perfect matching has been found
|
||||
///
|
||||
/// The desired node degrees are defined implicitly by the Demand() values.
|
||||
virtual bool MaximumMatching() throw();
|
||||
|
||||
/// \brief Determine a maximum k-factor
|
||||
///
|
||||
/// \param cDeg The desired constant node degree
|
||||
/// \retval true A perfect matching has been found
|
||||
virtual bool MaximumMatching(TCap cDeg) throw();
|
||||
|
||||
/// \brief Determine a minimum defect (b,c)-matching
|
||||
///
|
||||
/// \param pLower A pointer to an array of lower degree bounds
|
||||
/// \param pDeg A pointer to an array of upper degree bounds or NULL
|
||||
/// \retval true A perfect matching has been found
|
||||
virtual bool MaximumMatching(TCap *pLower,TCap *pDeg = NULL) throw();
|
||||
|
||||
/// \brief Determine a minimum-cost perfect b-matching or f-factor
|
||||
///
|
||||
/// \retval true A perfect matching has been found
|
||||
///
|
||||
/// The desired node degrees are defined implicitly by the Demand() values.
|
||||
/// Other than the overloaded methods which take explicit degree information,
|
||||
/// this allows for the candidate graph heuristic if the graph is dense and
|
||||
/// if methCandidates >= 0.
|
||||
///
|
||||
virtual bool MinCMatching() throw();
|
||||
|
||||
/// \brief Determine a minimum-cost perfect k-factor
|
||||
///
|
||||
/// \param cDeg The desired constant node degree
|
||||
/// \retval true A perfect matching has been found
|
||||
virtual bool MinCMatching(TCap cDeg) throw();
|
||||
|
||||
/// \brief Determine a minimum-cost perfect (b,c)-matching
|
||||
///
|
||||
/// \param pLower A pointer to an array of lower degree bounds
|
||||
/// \param pDeg A pointer to an array of upper degree bounds or NULL
|
||||
/// \retval true A perfect matching has been found
|
||||
virtual bool MinCMatching(TCap *pLower,TCap *pDeg = NULL) throw();
|
||||
|
||||
private:
|
||||
|
||||
/// \brief Determine a minimum-cost perfect (b,c)-matching by a candidate heuristic
|
||||
///
|
||||
/// \retval true A perfect matching has been found
|
||||
///
|
||||
/// This calls PMHeuristicsRandom() several times and takes the join of the
|
||||
/// found matchings as a candidate graph. If methSolve = 0, an optimal matching
|
||||
/// of the candidate graph is provided. Otherwise, a min-cost flow on the
|
||||
/// candidate graph is used as the starting solution on the entire graph.
|
||||
bool PMHeuristicsCandidates() throw();
|
||||
|
||||
protected:
|
||||
|
||||
/// \brief Determine a minimum-cost perfect (b,c)-matching by a random heuristic
|
||||
///
|
||||
/// \return The weight of the constructed matching
|
||||
///
|
||||
/// This step-by-step chooses random nodes and add adjacent arcs increasing
|
||||
/// by their lenght.
|
||||
TFloat PMHeuristicsRandom() throw();
|
||||
|
||||
public:
|
||||
|
||||
/// \brief Provide a minimum length edge cover by the edge colour register
|
||||
///
|
||||
/// \return The total edge length
|
||||
TFloat MinCEdgeCover() throw(ERRejected);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
/// \brief Compute a T-join for a given node set T
|
||||
///
|
||||
/// \param Terminals A set of terminal nodes. Must have even cardinality
|
||||
///
|
||||
/// This is the working procedure for all kinds of T-join solvers.
|
||||
/// It requires non-negative edge lengths.
|
||||
void ComputeTJoin(const indexSet<TNode>& Terminals) throw(ERRejected);
|
||||
|
||||
public:
|
||||
|
||||
/// \brief Compute a T-join for a given node set T
|
||||
///
|
||||
/// \param Terminals A set of terminal nodes. Must have even cardinality
|
||||
///
|
||||
/// Other than ComputeTJoin(), this can deal with negative length arcs.
|
||||
void MinCTJoin(const indexSet<TNode>& Terminals) throw();
|
||||
|
||||
/// \brief Compute a shortest path connecting a given node pair
|
||||
///
|
||||
/// \param s The start node of the path to be generated
|
||||
/// \param t The end node of the path to be generated
|
||||
/// \retval true A shortest st-path has been found
|
||||
///
|
||||
/// Other than general shortest path methods applied to undirected graphs,
|
||||
/// this can deal with negative length arcs. The found path is provided by
|
||||
/// the subgraph labels.
|
||||
bool SPX_TJoin(TNode s,TNode t) throw(ERRange);
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
/// \addtogroup eulerPostman
|
||||
/// @{
|
||||
|
||||
public:
|
||||
|
||||
// Documented in the class abstractMixedGraph
|
||||
void ChinesePostman(bool adjustUCap) throw(ERRejected);
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
/// \addtogroup maxCut
|
||||
/// @{
|
||||
|
||||
protected:
|
||||
|
||||
/// \brief Approximate maximum weight edge cut
|
||||
///
|
||||
/// \param method A #TMethMaxCut value specifying the applied method
|
||||
/// \param s A left-hand node index or NoNode
|
||||
/// \param t A right-hand node index or NoNode
|
||||
/// \return The weight of the constructed edge cut
|
||||
///
|
||||
/// Depending on methMaxCut, this either calls MXC_HeuristicGRASP(),
|
||||
/// MXC_HeuristicTree() or MXC_DualTJoin().
|
||||
TFloat MXC_Heuristic(TMethMaxCut method,TNode s = NoNode,TNode t = NoNode)
|
||||
throw(ERRange,ERRejected);
|
||||
|
||||
/// \brief Approximate maximum weight edge cut by using a maximum spanning tree
|
||||
///
|
||||
/// \param s A left-hand node index or NoNode
|
||||
/// \param t A right-hand node index or NoNode
|
||||
/// \return The weight of the constructed edge cut
|
||||
///
|
||||
/// This sets the bipartition according to a maximum weight spanning tree
|
||||
/// and the root node s. In particular, the graph must be connected.
|
||||
/// If methLocal==LOCAL_OPTIMIZE, MXC_LocalSearch() is called for postprocessing.
|
||||
TFloat MXC_HeuristicTree(TNode s = NoNode,TNode t = NoNode) throw(ERRange,ERRejected);
|
||||
|
||||
/// \brief Exact solution of the undirected planar maximum weight edge cut problem
|
||||
///
|
||||
/// \param s A left-hand node index or NoNode
|
||||
/// \return The weight of the constructed edge cut
|
||||
///
|
||||
/// This determines a T-join in the undirected dual graph.
|
||||
///
|
||||
/// The procedure is restricted to non-negative edge lengths!
|
||||
TFloat MXC_DualTJoin(TNode s = NoNode) throw(ERRange,ERRejected);
|
||||
|
||||
/// @}
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,102 @@
|
||||
|
||||
//provisorische Implementierung zum Schreiben von abstractSubgraph in Datei
|
||||
|
||||
#include "abstractSubgraph.h"
|
||||
|
||||
|
||||
sparseGraph *abstractSubgraph::CreateGraphObject() const throw()
|
||||
{
|
||||
sparseGraph *G = new sparseGraph(this->SourceGraph()->N(),CT);
|
||||
graphRepresentation* GR = G->Representation();
|
||||
|
||||
for (TArc a=0; a<SourceGraph()->M()*2; a++)
|
||||
{
|
||||
if (this->HasArc(a))
|
||||
G->InsertArc(StartNode(a),EndNode(a));
|
||||
}
|
||||
|
||||
for (TDim i=0;i<SourceGraph()->Dim();i++)
|
||||
{
|
||||
for (TNode v=0;v<SourceGraph()->N(); v++)
|
||||
{
|
||||
GR -> SetC(v,i,SourceGraph()->C(v,i));
|
||||
}
|
||||
}
|
||||
|
||||
return G;
|
||||
}
|
||||
|
||||
|
||||
void abstractSubgraph::Write(const char* fileName) const throw(ERFile)
|
||||
{
|
||||
abstractMixedGraph* G = CreateGraphObject();
|
||||
G -> Write(fileName);
|
||||
delete G;
|
||||
}
|
||||
|
||||
|
||||
TArc abstractSubgraph::Reverse(TArc a) const throw(ERRange)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
//if (a>=2*m) NoSuchArc("Reverse",a);
|
||||
#endif
|
||||
|
||||
return a^1;
|
||||
}
|
||||
|
||||
|
||||
unsigned long abstractSubgraph::Allocated() const throw()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
//provisorische Implementierung zum Schreiben von abstractSubgraph in Datei
|
||||
|
||||
#include "abstractSubgraph.h"
|
||||
|
||||
|
||||
sparseGraph *abstractSubgraph::CreateGraphObject() const throw()
|
||||
{
|
||||
sparseGraph *G = new sparseGraph(this->SourceGraph()->N(),CT);
|
||||
graphRepresentation* GR = G->Representation();
|
||||
|
||||
for (TArc a=0; a<SourceGraph()->M()*2; a++)
|
||||
{
|
||||
if (this->HasArc(a))
|
||||
G->InsertArc(StartNode(a),EndNode(a));
|
||||
}
|
||||
|
||||
for (TDim i=0;i<SourceGraph()->Dim();i++)
|
||||
{
|
||||
for (TNode v=0;v<SourceGraph()->N(); v++)
|
||||
{
|
||||
GR -> SetC(v,i,SourceGraph()->C(v,i));
|
||||
}
|
||||
}
|
||||
|
||||
return G;
|
||||
}
|
||||
|
||||
|
||||
void abstractSubgraph::Write(const char* fileName) const throw(ERFile)
|
||||
{
|
||||
abstractMixedGraph* G = CreateGraphObject();
|
||||
G -> Write(fileName);
|
||||
delete G;
|
||||
}
|
||||
|
||||
|
||||
TArc abstractSubgraph::Reverse(TArc a) const throw(ERRange)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
//if (a>=2*m) NoSuchArc("Reverse",a);
|
||||
#endif
|
||||
|
||||
return a^1;
|
||||
}
|
||||
|
||||
|
||||
unsigned long abstractSubgraph::Allocated() const throw()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,220 @@
|
||||
|
||||
/*
|
||||
** This file forms part of the GOBLIN C++ Class Library.
|
||||
**
|
||||
** Written by Birk Eisermann, August 2003.
|
||||
**
|
||||
** Copying, compiling, distribution and modification
|
||||
** of this source code is permitted only in accordance
|
||||
** with the GOBLIN general licence information.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _ABSTRACT_SUBGRAPH_H_
|
||||
#define _ABSTRACT_SUBGRAPH_H_
|
||||
|
||||
//vorerst zusätzlich:
|
||||
#include "sparseGraph.h"
|
||||
|
||||
/*!
|
||||
* \brief Dieses Interface repr�entiert einen Teilgraph.
|
||||
*
|
||||
* Ein Teilgraph enthält jeweils eine Teilmenge von Knoten und Kanten aus
|
||||
* dem Ursprungsgraph getSourceGraph().
|
||||
*
|
||||
* Momentan kann mit der Methode createGraphObject() ein graph-Objekt (das
|
||||
* ja indirekt von abstractMixedGraph abgeleitet ist) erzeugt werden, welches
|
||||
* alle Knoten des SourceGraph und alle Kanten des Teilgraphen enthält.
|
||||
*/
|
||||
class abstractSubgraph : public virtual managedObject
|
||||
{
|
||||
|
||||
public:
|
||||
//New methods in this class
|
||||
/*! \brief getSourceGraph returns a reference to the original %graph.
|
||||
*
|
||||
* The returned reference doesn't have to be deleted!
|
||||
* Deletion will be made automatically.*/
|
||||
virtual const abstractMixedGraph* SourceGraph() const throw() = 0;
|
||||
|
||||
/*!
|
||||
* \brief returns a reference to a %graph: SourceGraph without this %graph
|
||||
*
|
||||
* The returned reference doesn't have to be deleted!
|
||||
* Deletion will be made automatical.
|
||||
*
|
||||
* If SourceGraph G:= (V,E) and %subgraph H:= (V1,E1) and V1 is part of
|
||||
* V and E1 is part of E, then the returned graph I:= (V2,E2) is
|
||||
* defined as follows:
|
||||
* - V2 := "V without V1"
|
||||
* - E2 := all edges which are incident in V2
|
||||
* that means all edges which are between a vertex of V1 and one of V2
|
||||
* are not either in E1 nor in E2.
|
||||
*
|
||||
* => the "WithoutGraph" of I is the original graph H.
|
||||
*/
|
||||
/* + represent vertices; _,= represent edges.
|
||||
* the =-edges belong to no graph
|
||||
* |--without graph(V2)------------|----subgraph (V1)----|
|
||||
* | __ + == + __ __ + |
|
||||
* | + __ | __ + __ |
|
||||
* | + == + + |
|
||||
* |-----------------------source graph (V)--------------|
|
||||
*/
|
||||
virtual const abstractSubgraph* ComplementarySubgraph() const throw() = 0;
|
||||
//!tests, if node is on this %subgraph
|
||||
virtual bool HasNode(TNode node) const throw(ERRange) = 0;
|
||||
|
||||
/*!
|
||||
* \brief adds an arc (from sourcegraph) to the %subgraph.
|
||||
*
|
||||
* If one of the nodes StartNode(a) or EndNode(a) isn't on the subgraph, it
|
||||
* will be automatical be added.
|
||||
* \param a an arc of the SourceGraph
|
||||
* \exception ERRange, ERRejected ??? Check this!
|
||||
*/
|
||||
virtual void AddArc(TArc a) throw(ERRange,ERRejected) = 0;
|
||||
virtual TArc AddArc(TNode u,TNode v) throw(ERRange,ERRejected) = 0;
|
||||
virtual void AddNode(TNode u) throw(ERRange,ERRejected) = 0;
|
||||
/*!
|
||||
* \brief deletes an arc from the %subgraph.
|
||||
*
|
||||
* The nodes StartNode(a) and EndNode(a) will remain on the subgraph.
|
||||
* \param a an arc of the SourceGraph
|
||||
* \exception ERRange, ERRejected ??? Check this!
|
||||
*/
|
||||
virtual void OmitArc(TArc a) throw(ERRange,ERRejected) = 0;
|
||||
virtual void OmitArc(TNode u,TNode v) throw(ERRange,ERRejected) = 0;
|
||||
virtual void OmitNode(TNode u) throw(ERRange,ERRejected) = 0;
|
||||
|
||||
virtual void OmitIsolatedNodes() throw() = 0;
|
||||
|
||||
//provisorisch:
|
||||
virtual sparseGraph* CreateGraphObject() const throw();
|
||||
virtual void Write(const char* fileName) const throw(ERFile);
|
||||
|
||||
|
||||
//overwrite following methods of abstractMixedGraph_Int
|
||||
virtual TNode StartNode(TArc) const throw(ERRange) = 0;
|
||||
virtual TNode EndNode(TArc) const throw(ERRange) = 0;
|
||||
virtual bool HasArc(TArc a) const throw(ERRange) = 0;
|
||||
virtual TNode N() const throw() = 0; //!<returns the number of vertices
|
||||
virtual TArc M() const throw() = 0; //!<returns the number of edges
|
||||
virtual unsigned long Allocated() const throw();
|
||||
|
||||
virtual TArc Reverse(TArc a) const throw(ERRange);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
** This file forms part of the GOBLIN C++ Class Library.
|
||||
**
|
||||
** Written by Birk Eisermann, August 2003.
|
||||
**
|
||||
** Copying, compiling, distribution and modification
|
||||
** of this source code is permitted only in accordance
|
||||
** with the GOBLIN general licence information.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _ABSTRACT_SUBGRAPH_H_
|
||||
#define _ABSTRACT_SUBGRAPH_H_
|
||||
|
||||
//vorerst zusätzlich:
|
||||
#include "sparseGraph.h"
|
||||
|
||||
/*!
|
||||
* \brief Dieses Interface repr�entiert einen Teilgraph.
|
||||
*
|
||||
* Ein Teilgraph enthält jeweils eine Teilmenge von Knoten und Kanten aus
|
||||
* dem Ursprungsgraph getSourceGraph().
|
||||
*
|
||||
* Momentan kann mit der Methode createGraphObject() ein graph-Objekt (das
|
||||
* ja indirekt von abstractMixedGraph abgeleitet ist) erzeugt werden, welches
|
||||
* alle Knoten des SourceGraph und alle Kanten des Teilgraphen enthält.
|
||||
*/
|
||||
class abstractSubgraph : public virtual managedObject
|
||||
{
|
||||
|
||||
public:
|
||||
//New methods in this class
|
||||
/*! \brief getSourceGraph returns a reference to the original %graph.
|
||||
*
|
||||
* The returned reference doesn't have to be deleted!
|
||||
* Deletion will be made automatically.*/
|
||||
virtual const abstractMixedGraph* SourceGraph() const throw() = 0;
|
||||
|
||||
/*!
|
||||
* \brief returns a reference to a %graph: SourceGraph without this %graph
|
||||
*
|
||||
* The returned reference doesn't have to be deleted!
|
||||
* Deletion will be made automatical.
|
||||
*
|
||||
* If SourceGraph G:= (V,E) and %subgraph H:= (V1,E1) and V1 is part of
|
||||
* V and E1 is part of E, then the returned graph I:= (V2,E2) is
|
||||
* defined as follows:
|
||||
* - V2 := "V without V1"
|
||||
* - E2 := all edges which are incident in V2
|
||||
* that means all edges which are between a vertex of V1 and one of V2
|
||||
* are not either in E1 nor in E2.
|
||||
*
|
||||
* => the "WithoutGraph" of I is the original graph H.
|
||||
*/
|
||||
/* + represent vertices; _,= represent edges.
|
||||
* the =-edges belong to no graph
|
||||
* |--without graph(V2)------------|----subgraph (V1)----|
|
||||
* | __ + == + __ __ + |
|
||||
* | + __ | __ + __ |
|
||||
* | + == + + |
|
||||
* |-----------------------source graph (V)--------------|
|
||||
*/
|
||||
virtual const abstractSubgraph* ComplementarySubgraph() const throw() = 0;
|
||||
//!tests, if node is on this %subgraph
|
||||
virtual bool HasNode(TNode node) const throw(ERRange) = 0;
|
||||
|
||||
/*!
|
||||
* \brief adds an arc (from sourcegraph) to the %subgraph.
|
||||
*
|
||||
* If one of the nodes StartNode(a) or EndNode(a) isn't on the subgraph, it
|
||||
* will be automatical be added.
|
||||
* \param a an arc of the SourceGraph
|
||||
* \exception ERRange, ERRejected ??? Check this!
|
||||
*/
|
||||
virtual void AddArc(TArc a) throw(ERRange,ERRejected) = 0;
|
||||
virtual TArc AddArc(TNode u,TNode v) throw(ERRange,ERRejected) = 0;
|
||||
virtual void AddNode(TNode u) throw(ERRange,ERRejected) = 0;
|
||||
/*!
|
||||
* \brief deletes an arc from the %subgraph.
|
||||
*
|
||||
* The nodes StartNode(a) and EndNode(a) will remain on the subgraph.
|
||||
* \param a an arc of the SourceGraph
|
||||
* \exception ERRange, ERRejected ??? Check this!
|
||||
*/
|
||||
virtual void OmitArc(TArc a) throw(ERRange,ERRejected) = 0;
|
||||
virtual void OmitArc(TNode u,TNode v) throw(ERRange,ERRejected) = 0;
|
||||
virtual void OmitNode(TNode u) throw(ERRange,ERRejected) = 0;
|
||||
|
||||
virtual void OmitIsolatedNodes() throw() = 0;
|
||||
|
||||
//provisorisch:
|
||||
virtual sparseGraph* CreateGraphObject() const throw();
|
||||
virtual void Write(const char* fileName) const throw(ERFile);
|
||||
|
||||
|
||||
//overwrite following methods of abstractMixedGraph_Int
|
||||
virtual TNode StartNode(TArc) const throw(ERRange) = 0;
|
||||
virtual TNode EndNode(TArc) const throw(ERRange) = 0;
|
||||
virtual bool HasArc(TArc a) const throw(ERRange) = 0;
|
||||
virtual TNode N() const throw() = 0; //!<returns the number of vertices
|
||||
virtual TArc M() const throw() = 0; //!<returns the number of edges
|
||||
virtual unsigned long Allocated() const throw();
|
||||
|
||||
virtual TArc Reverse(TArc a) const throw(ERRange);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,972 @@
|
||||
|
||||
// This file forms part of the GOBLIN C++ Class Library.
|
||||
//
|
||||
// Initially written by Birk Eisermann, August 2005
|
||||
//
|
||||
// Copying, compiling, distribution and modification
|
||||
// of this source code is permitted only in accordance
|
||||
// with the GOBLIN general licence information.
|
||||
|
||||
/// \file attributePool.h
|
||||
/// \brief #attributePool class interface and templates
|
||||
|
||||
#ifndef _ATTRIBUTE_POOL_H_
|
||||
#define _ATTRIBUTE_POOL_H_
|
||||
|
||||
#include <list>
|
||||
|
||||
#include "attribute.h"
|
||||
#include "fileImport.h"
|
||||
#include "fileExport.h"
|
||||
|
||||
|
||||
/// \addtogroup groupAttributes
|
||||
/// @{
|
||||
|
||||
/// \brief A class for graph attribute management
|
||||
///
|
||||
/// The objects of this class are containers for #attribute objects.
|
||||
/// The potentially contained attributes are specified by a #TPoolTable[]
|
||||
/// array and a matching enum type.
|
||||
///
|
||||
/// Attribute pools manage the following:
|
||||
/// - Lookup and initialization of attribute values
|
||||
/// - Memory savings by support for constant attribute values
|
||||
/// - File import [export] from [to] tree like formats
|
||||
/// - Automatic shrinking and expansion when the graph is manipulated
|
||||
|
||||
class attributePool
|
||||
{
|
||||
public:
|
||||
|
||||
/// \brief Specifies how many indices are represented by embedded attributes
|
||||
enum TAttributeType {
|
||||
ATTR_FULL_RANK = 0, ///< \brief All referenced attributes have full rank
|
||||
ATTR_ALLOW_NULL = 1, ///< \brief Referenced attributes have either full or zero rank
|
||||
ATTR_REQ_SINGLETON = 2 ///< \brief Referenced attributes have either full rank or rank 1
|
||||
};
|
||||
|
||||
protected:
|
||||
|
||||
const TPoolTable* table;
|
||||
const unsigned short dim;
|
||||
list<attributeBase*> attributes;
|
||||
list<TPoolEnum> tokens;
|
||||
const TAttributeType poolType;
|
||||
|
||||
/// \brief Lookup for the specified attribute
|
||||
attributeBase* FindAttribute(TPoolEnum token) const throw();
|
||||
|
||||
public:
|
||||
|
||||
/// \brief Construct an attribute pool
|
||||
/// \param _table A pool table
|
||||
/// \param _dim The number of records in this table
|
||||
/// \param _poolType Specifies if zero size attributes are allowed
|
||||
attributePool(const TPoolTable* _table,TPoolEnum _dim,TAttributeType _poolType) throw();
|
||||
|
||||
/// \brief Copy constructor
|
||||
attributePool(const attributePool& P) throw();
|
||||
|
||||
/// \brief Destruct an attribute pool
|
||||
~attributePool() throw();
|
||||
|
||||
size_t Size() const throw() {return 0;};
|
||||
|
||||
/// \brief Delete all attributes from this pool
|
||||
void Flush() throw();
|
||||
|
||||
/// \brief Read pool data as a part of the graph object file representation
|
||||
TPoolEnum ReadAttribute(goblinRootObject&,goblinImport& F) throw();
|
||||
|
||||
/// \brief Read pool data as a part of the graph object file representation
|
||||
void ReadPool(goblinRootObject& F,goblinImport&) throw();
|
||||
|
||||
/// \brief Read a string attribute as a part of the graph object file representation
|
||||
bool ReadStringAttribute(goblinImport& F,TPoolEnum token) throw(ERParse);
|
||||
|
||||
/// \brief Write an attribute to s file
|
||||
void WriteAttribute(const goblinRootObject&,goblinExport& F,TPoolEnum token,attributeBase* _attribute=NULL) const throw();
|
||||
|
||||
/// \brief Write all pool data to file
|
||||
void WritePool(const goblinRootObject&,goblinExport& F,const char*) const throw();
|
||||
|
||||
/// \brief Copy all attributes into a specified attribute pool
|
||||
///
|
||||
/// But only those attribute which are not associated with graph nodes,
|
||||
/// layout nodes or graph arcs.
|
||||
void ExportAttributes(attributePool& P) const throw();
|
||||
|
||||
/// \brief Copy an attribute into this attribute pool
|
||||
template <typename T> void ImportAttribute(attribute<T>& A,TPoolEnum token) throw();
|
||||
|
||||
/// \brief Assign an attribute with a given sequence of values
|
||||
template <typename T> attribute<T>* ImportArray(TPoolEnum token,const T* _value,size_t size) throw();
|
||||
|
||||
/// \brief Allocate a new attribute and add it to the pool
|
||||
/// \param X The data object to which the attributes belong
|
||||
/// \param _token The index of the attribute in the pool table
|
||||
/// \param attributeType Specifies the attribute rank
|
||||
/// \param _value_ptr Either NULL or a pointer to the default value
|
||||
///
|
||||
/// Other than the #InitAttribute() and #RawAttribute() methods which
|
||||
/// result in full rank attributes, this operation supports constant attributes
|
||||
template <typename T> attribute<T>* MakeAttribute(
|
||||
goblinRootObject& X,TPoolEnum _token,TAttributeType attributeType,void* _value_ptr = NULL) throw();
|
||||
|
||||
/// \brief Remove an attribute from the pool and deallocate it
|
||||
void ReleaseAttribute(TPoolEnum token) throw();
|
||||
|
||||
/// \brief Direct access to an attribute in this pool
|
||||
template <typename T> attribute<T>* GetAttribute(TPoolEnum token) const throw();
|
||||
|
||||
/// \brief Export the vector encapsulated into a pool attribute
|
||||
template <typename T> vector<T>* GetVector(TPoolEnum token) const throw();
|
||||
|
||||
/// \brief Export the array encapsulated into a pool attribute
|
||||
template <typename T> T* GetArray(TPoolEnum token) const throw();
|
||||
|
||||
/// \brief Obtain a full rank attribute, initialized with a default value
|
||||
template <typename T> attribute<T>* InitAttribute(goblinRootObject& X,TPoolEnum token,T _value) throw();
|
||||
|
||||
/// \brief Obtain a full rank vector, initialized with a default value
|
||||
template <typename T> vector<T>* InitVector(goblinRootObject& X,TPoolEnum token,T _value) throw();
|
||||
|
||||
/// \brief Obtain a full rank array, initialized with a default value
|
||||
template <typename T> T* InitArray(goblinRootObject& X,TPoolEnum token,T _value) throw();
|
||||
|
||||
/// \brief Obtain a full rank attribute without initialization
|
||||
template <typename T> attribute<T>* RawAttribute(goblinRootObject& X,TPoolEnum token) throw();
|
||||
|
||||
/// \brief Obtain a full rank vector without initialization
|
||||
template <typename T> vector<T>* RawVector(goblinRootObject& X,TPoolEnum token) throw();
|
||||
|
||||
/// \brief Obtain a full rank array without initialization
|
||||
template <typename T> T* RawArray(goblinRootObject& X,TPoolEnum token) throw();
|
||||
|
||||
/// \brief Set the capacity of all attributes of the specified type
|
||||
void ReserveItems(TArrayDim attributeType,TIndex capacity) throw(ERRange);
|
||||
|
||||
/// \brief Add numItems to all attributes of the specified type
|
||||
void AppendItems(TArrayDim attributeType,TIndex numItems) throw();
|
||||
|
||||
/// \brief Delete numItems from all attributes of the specified type
|
||||
void EraseItems(TArrayDim attributeType,TIndex numItems) throw(ERRange);
|
||||
|
||||
/// \brief Swap the specified items in all attributes of the specified type
|
||||
void SwapItems(TArrayDim attributeType,TIndex i1,TIndex i2) throw(ERRange);
|
||||
|
||||
/// \brief Return the attribute value for a given index
|
||||
template <typename T> T GetValue(TPoolEnum token,TIndex i,T _default) const throw();
|
||||
|
||||
/// \brief Return the default attribute value
|
||||
template <typename T> T DefaultValue(TPoolEnum token,T _default) const throw();
|
||||
|
||||
/// \brief Return the minimum attribute value
|
||||
template <typename T> T MinValue(TPoolEnum token,T _default) const throw();
|
||||
|
||||
/// \brief Return the maximum attribute value
|
||||
template <typename T> T MaxValue(TPoolEnum token,T _default) const throw();
|
||||
|
||||
/// \brief Return an index at which the minimum attribute value is achieved
|
||||
template <typename T> TIndex MinIndex(TPoolEnum token) const throw();
|
||||
|
||||
/// \brief Return an index at which the maximum attribute value is achieved
|
||||
template <typename T> TIndex MaxIndex(TPoolEnum token) const throw();
|
||||
|
||||
/// \brief Check if attribute values coincide for all indices
|
||||
template <typename T> bool IsConstant(TPoolEnum token) const throw();
|
||||
|
||||
};
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
template <typename T>
|
||||
attribute<T>* attributePool::MakeAttribute(goblinRootObject& X,TPoolEnum _token,
|
||||
TAttributeType attributeType,void* _value_ptr) throw()
|
||||
{
|
||||
// Handle synonymous tokens
|
||||
_token = TPoolEnum(table[_token].primaryIndex);
|
||||
|
||||
attribute<T>* pAttribute = GetAttribute<T>(_token);
|
||||
|
||||
if (!_value_ptr) _value_ptr = DefaultValueAsVoidPtr(table[_token].arrayType);
|
||||
|
||||
if (pAttribute)
|
||||
{
|
||||
if (attributeType==ATTR_ALLOW_NULL)
|
||||
{
|
||||
if (pAttribute->Size()>0)
|
||||
{
|
||||
pAttribute -> EraseItems(pAttribute->Size());
|
||||
pAttribute -> SetCapacity(0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t size = X.SizeInfo(table[_token].arrayDim,SIZE_ACTUAL);
|
||||
size_t capacity = X.SizeInfo(table[_token].arrayDim,SIZE_RESERVED);
|
||||
|
||||
if (attributeType==ATTR_REQ_SINGLETON && size==0)
|
||||
{
|
||||
if (pAttribute->Size()>1)
|
||||
{
|
||||
pAttribute -> EraseItems(pAttribute->Size()-1);
|
||||
pAttribute -> SetCapacity(1);
|
||||
}
|
||||
else if (pAttribute->Size()==0)
|
||||
{
|
||||
pAttribute -> IncreaseSize(1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pAttribute->Size()<size)
|
||||
{
|
||||
pAttribute -> SetCapacity(capacity);
|
||||
pAttribute -> IncreaseSize(size);
|
||||
}
|
||||
else if (pAttribute->Size()>size)
|
||||
{
|
||||
pAttribute -> EraseItems(pAttribute->Size()-size);
|
||||
pAttribute -> SetCapacity(capacity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pAttribute -> SetDefaultValue(*reinterpret_cast<T*>(_value_ptr));
|
||||
|
||||
return pAttribute;
|
||||
}
|
||||
|
||||
if (attributeType==ATTR_ALLOW_NULL)
|
||||
{
|
||||
pAttribute = new attribute<T>(0,*reinterpret_cast<T*>(_value_ptr));
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t size = X.SizeInfo(table[_token].arrayDim,SIZE_ACTUAL);
|
||||
size_t capacity = X.SizeInfo(table[_token].arrayDim,SIZE_RESERVED);
|
||||
|
||||
if (capacity==0)
|
||||
{
|
||||
if (attributeType==ATTR_FULL_RANK)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
// attributeType==ATTR_REQ_SINGLETON
|
||||
capacity = size = 1;
|
||||
}
|
||||
}
|
||||
|
||||
pAttribute = new attribute<T>(size,*reinterpret_cast<T*>(_value_ptr));
|
||||
pAttribute -> SetCapacity(capacity);
|
||||
}
|
||||
|
||||
attributes.insert(attributes.begin(),pAttribute);
|
||||
tokens.insert(tokens.begin(),(unsigned short)_token);
|
||||
|
||||
return pAttribute;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
attribute<T>* attributePool::ImportArray(TPoolEnum token,const T* _value,size_t size)
|
||||
throw()
|
||||
{
|
||||
attribute<T>* pAttribute = GetAttribute<T>(token);
|
||||
|
||||
if (!pAttribute)
|
||||
{
|
||||
pAttribute = new attribute<T>(0,*reinterpret_cast<T*>(
|
||||
DefaultValueAsVoidPtr(table[token].arrayType)));
|
||||
|
||||
attributes.insert(attributes.begin(),pAttribute);
|
||||
tokens.insert(tokens.begin(),(unsigned short)token);
|
||||
}
|
||||
|
||||
size_t oldSize = pAttribute->Size();
|
||||
|
||||
if (size>oldSize)
|
||||
{
|
||||
pAttribute -> IncreaseSize(size);
|
||||
}
|
||||
|
||||
memcpy(pAttribute->GetArray(),_value,sizeof(T)*size);
|
||||
|
||||
return pAttribute;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
attribute<T>* attributePool::GetAttribute(TPoolEnum token) const throw()
|
||||
{
|
||||
attributeBase* _attribute = FindAttribute(token);
|
||||
|
||||
if (!_attribute) return NULL;
|
||||
|
||||
return static_cast<attribute<T>*>(_attribute);
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
vector<T>* attributePool::GetVector(TPoolEnum token) const throw()
|
||||
{
|
||||
attributeBase* _attribute = FindAttribute(token);
|
||||
|
||||
if (!_attribute) return NULL;
|
||||
|
||||
return static_cast<attribute<T>*>(_attribute)->GetVector();
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
T* attributePool::GetArray(TPoolEnum token) const throw()
|
||||
{
|
||||
if (poolType==ATTR_ALLOW_NULL) return NULL;
|
||||
|
||||
attributeBase* _attributeBase = FindAttribute(token);
|
||||
|
||||
if (!_attributeBase) return NULL;
|
||||
|
||||
attribute<T>* _attribute = static_cast<attribute<T>*>(_attributeBase);
|
||||
|
||||
if (_attribute->Size()==0) return NULL;
|
||||
|
||||
return _attribute->GetArray();
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
attribute<T>* attributePool::InitAttribute(goblinRootObject& X,TPoolEnum token,T _value) throw()
|
||||
{
|
||||
attribute<T>* _attribute = GetAttribute<T>(token);
|
||||
|
||||
if (!_attribute)
|
||||
{
|
||||
return MakeAttribute<T>(X,token,ATTR_FULL_RANK,
|
||||
reinterpret_cast<void*>(&_value));
|
||||
}
|
||||
|
||||
_attribute -> Assign(_value);
|
||||
|
||||
return _attribute;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
vector<T>* attributePool::InitVector(goblinRootObject& X,TPoolEnum token,T _value) throw()
|
||||
{
|
||||
return InitAttribute(X,token,_value)->GetVector();
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
T* attributePool::InitArray(goblinRootObject& X,TPoolEnum token,T _value) throw()
|
||||
{
|
||||
vector<T>* _vector = InitVector(X,token,_value);
|
||||
|
||||
if (_vector->size()==0) return NULL;
|
||||
|
||||
return &((*_vector)[0]);
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
attribute<T>* attributePool::RawAttribute(goblinRootObject& X,TPoolEnum token) throw()
|
||||
{
|
||||
if (poolType==ATTR_FULL_RANK)
|
||||
{
|
||||
attribute<T>* _attribute = GetAttribute<T>(token);
|
||||
|
||||
if (_attribute) return _attribute;
|
||||
}
|
||||
|
||||
return MakeAttribute<T>(X,token,ATTR_FULL_RANK);
|
||||
}
|
||||
|
||||
|
||||
template <typename T> vector<T>* attributePool::RawVector(goblinRootObject& X,TPoolEnum token) throw()
|
||||
{
|
||||
return RawAttribute<T>(X,token)->GetVector();
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
T* attributePool::RawArray(goblinRootObject& X,TPoolEnum token) throw()
|
||||
{
|
||||
attribute<T>* _attribute = RawAttribute<T>(X,token);
|
||||
|
||||
if (_attribute->Size()==0) return NULL;
|
||||
|
||||
return _attribute->GetArray();
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
T attributePool::GetValue(TPoolEnum token,TIndex i,T _default) const throw()
|
||||
{
|
||||
attribute<T>* _attribute = GetAttribute<T>(token);
|
||||
|
||||
if (_attribute) return _attribute->GetValue(i);
|
||||
|
||||
return _default;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
T attributePool::DefaultValue(TPoolEnum token,T _default) const throw()
|
||||
{
|
||||
attribute<T>* _attribute = GetAttribute<T>(token);
|
||||
|
||||
if (_attribute) return _attribute->DefaultValue();
|
||||
|
||||
return _default;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
T attributePool::MinValue(TPoolEnum token,T _default) const throw()
|
||||
{
|
||||
attribute<T>* _attribute = GetAttribute<T>(token);
|
||||
|
||||
if (_attribute) return _attribute->MinValue();
|
||||
|
||||
return _default;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
T attributePool::MaxValue(TPoolEnum token,T _default) const throw()
|
||||
{
|
||||
attribute<T>* _attribute = GetAttribute<T>(token);
|
||||
|
||||
if (_attribute) return _attribute->MaxValue();
|
||||
|
||||
return _default;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
TIndex attributePool::MinIndex(TPoolEnum token) const throw()
|
||||
{
|
||||
attribute<T>* _attribute = GetAttribute<T>(token);
|
||||
|
||||
if (_attribute) return _attribute->MinIndex();
|
||||
|
||||
return NoIndex;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
TIndex attributePool::MaxIndex(TPoolEnum token) const throw()
|
||||
{
|
||||
attribute<T>* _attribute = GetAttribute<T>(token);
|
||||
|
||||
if (_attribute) return _attribute->MaxIndex();
|
||||
|
||||
return NoIndex;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
bool attributePool::IsConstant(TPoolEnum token) const throw()
|
||||
{
|
||||
attribute<T>* _attribute = GetAttribute<T>(token);
|
||||
|
||||
if (_attribute) return _attribute->IsConstant();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
// This file forms part of the GOBLIN C++ Class Library.
|
||||
//
|
||||
// Initially written by Birk Eisermann, August 2005
|
||||
//
|
||||
// Copying, compiling, distribution and modification
|
||||
// of this source code is permitted only in accordance
|
||||
// with the GOBLIN general licence information.
|
||||
|
||||
/// \file attributePool.h
|
||||
/// \brief #attributePool class interface and templates
|
||||
|
||||
#ifndef _ATTRIBUTE_POOL_H_
|
||||
#define _ATTRIBUTE_POOL_H_
|
||||
|
||||
#include <list>
|
||||
|
||||
#include "attribute.h"
|
||||
#include "fileImport.h"
|
||||
#include "fileExport.h"
|
||||
|
||||
|
||||
/// \addtogroup groupAttributes
|
||||
/// @{
|
||||
|
||||
/// \brief A class for graph attribute management
|
||||
///
|
||||
/// The objects of this class are containers for #attribute objects.
|
||||
/// The potentially contained attributes are specified by a #TPoolTable[]
|
||||
/// array and a matching enum type.
|
||||
///
|
||||
/// Attribute pools manage the following:
|
||||
/// - Lookup and initialization of attribute values
|
||||
/// - Memory savings by support for constant attribute values
|
||||
/// - File import [export] from [to] tree like formats
|
||||
/// - Automatic shrinking and expansion when the graph is manipulated
|
||||
|
||||
class attributePool
|
||||
{
|
||||
public:
|
||||
|
||||
/// \brief Specifies how many indices are represented by embedded attributes
|
||||
enum TAttributeType {
|
||||
ATTR_FULL_RANK = 0, ///< \brief All referenced attributes have full rank
|
||||
ATTR_ALLOW_NULL = 1, ///< \brief Referenced attributes have either full or zero rank
|
||||
ATTR_REQ_SINGLETON = 2 ///< \brief Referenced attributes have either full rank or rank 1
|
||||
};
|
||||
|
||||
protected:
|
||||
|
||||
const TPoolTable* table;
|
||||
const unsigned short dim;
|
||||
list<attributeBase*> attributes;
|
||||
list<TPoolEnum> tokens;
|
||||
const TAttributeType poolType;
|
||||
|
||||
/// \brief Lookup for the specified attribute
|
||||
attributeBase* FindAttribute(TPoolEnum token) const throw();
|
||||
|
||||
public:
|
||||
|
||||
/// \brief Construct an attribute pool
|
||||
/// \param _table A pool table
|
||||
/// \param _dim The number of records in this table
|
||||
/// \param _poolType Specifies if zero size attributes are allowed
|
||||
attributePool(const TPoolTable* _table,TPoolEnum _dim,TAttributeType _poolType) throw();
|
||||
|
||||
/// \brief Copy constructor
|
||||
attributePool(const attributePool& P) throw();
|
||||
|
||||
/// \brief Destruct an attribute pool
|
||||
~attributePool() throw();
|
||||
|
||||
size_t Size() const throw() {return 0;};
|
||||
|
||||
/// \brief Delete all attributes from this pool
|
||||
void Flush() throw();
|
||||
|
||||
/// \brief Read pool data as a part of the graph object file representation
|
||||
TPoolEnum ReadAttribute(goblinRootObject&,goblinImport& F) throw();
|
||||
|
||||
/// \brief Read pool data as a part of the graph object file representation
|
||||
void ReadPool(goblinRootObject& F,goblinImport&) throw();
|
||||
|
||||
/// \brief Read a string attribute as a part of the graph object file representation
|
||||
bool ReadStringAttribute(goblinImport& F,TPoolEnum token) throw(ERParse);
|
||||
|
||||
/// \brief Write an attribute to s file
|
||||
void WriteAttribute(const goblinRootObject&,goblinExport& F,TPoolEnum token,attributeBase* _attribute=NULL) const throw();
|
||||
|
||||
/// \brief Write all pool data to file
|
||||
void WritePool(const goblinRootObject&,goblinExport& F,const char*) const throw();
|
||||
|
||||
/// \brief Copy all attributes into a specified attribute pool
|
||||
///
|
||||
/// But only those attribute which are not associated with graph nodes,
|
||||
/// layout nodes or graph arcs.
|
||||
void ExportAttributes(attributePool& P) const throw();
|
||||
|
||||
/// \brief Copy an attribute into this attribute pool
|
||||
template <typename T> void ImportAttribute(attribute<T>& A,TPoolEnum token) throw();
|
||||
|
||||
/// \brief Assign an attribute with a given sequence of values
|
||||
template <typename T> attribute<T>* ImportArray(TPoolEnum token,const T* _value,size_t size) throw();
|
||||
|
||||
/// \brief Allocate a new attribute and add it to the pool
|
||||
/// \param X The data object to which the attributes belong
|
||||
/// \param _token The index of the attribute in the pool table
|
||||
/// \param attributeType Specifies the attribute rank
|
||||
/// \param _value_ptr Either NULL or a pointer to the default value
|
||||
///
|
||||
/// Other than the #InitAttribute() and #RawAttribute() methods which
|
||||
/// result in full rank attributes, this operation supports constant attributes
|
||||
template <typename T> attribute<T>* MakeAttribute(
|
||||
goblinRootObject& X,TPoolEnum _token,TAttributeType attributeType,void* _value_ptr = NULL) throw();
|
||||
|
||||
/// \brief Remove an attribute from the pool and deallocate it
|
||||
void ReleaseAttribute(TPoolEnum token) throw();
|
||||
|
||||
/// \brief Direct access to an attribute in this pool
|
||||
template <typename T> attribute<T>* GetAttribute(TPoolEnum token) const throw();
|
||||
|
||||
/// \brief Export the vector encapsulated into a pool attribute
|
||||
template <typename T> vector<T>* GetVector(TPoolEnum token) const throw();
|
||||
|
||||
/// \brief Export the array encapsulated into a pool attribute
|
||||
template <typename T> T* GetArray(TPoolEnum token) const throw();
|
||||
|
||||
/// \brief Obtain a full rank attribute, initialized with a default value
|
||||
template <typename T> attribute<T>* InitAttribute(goblinRootObject& X,TPoolEnum token,T _value) throw();
|
||||
|
||||
/// \brief Obtain a full rank vector, initialized with a default value
|
||||
template <typename T> vector<T>* InitVector(goblinRootObject& X,TPoolEnum token,T _value) throw();
|
||||
|
||||
/// \brief Obtain a full rank array, initialized with a default value
|
||||
template <typename T> T* InitArray(goblinRootObject& X,TPoolEnum token,T _value) throw();
|
||||
|
||||
/// \brief Obtain a full rank attribute without initialization
|
||||
template <typename T> attribute<T>* RawAttribute(goblinRootObject& X,TPoolEnum token) throw();
|
||||
|
||||
/// \brief Obtain a full rank vector without initialization
|
||||
template <typename T> vector<T>* RawVector(goblinRootObject& X,TPoolEnum token) throw();
|
||||
|
||||
/// \brief Obtain a full rank array without initialization
|
||||
template <typename T> T* RawArray(goblinRootObject& X,TPoolEnum token) throw();
|
||||
|
||||
/// \brief Set the capacity of all attributes of the specified type
|
||||
void ReserveItems(TArrayDim attributeType,TIndex capacity) throw(ERRange);
|
||||
|
||||
/// \brief Add numItems to all attributes of the specified type
|
||||
void AppendItems(TArrayDim attributeType,TIndex numItems) throw();
|
||||
|
||||
/// \brief Delete numItems from all attributes of the specified type
|
||||
void EraseItems(TArrayDim attributeType,TIndex numItems) throw(ERRange);
|
||||
|
||||
/// \brief Swap the specified items in all attributes of the specified type
|
||||
void SwapItems(TArrayDim attributeType,TIndex i1,TIndex i2) throw(ERRange);
|
||||
|
||||
/// \brief Return the attribute value for a given index
|
||||
template <typename T> T GetValue(TPoolEnum token,TIndex i,T _default) const throw();
|
||||
|
||||
/// \brief Return the default attribute value
|
||||
template <typename T> T DefaultValue(TPoolEnum token,T _default) const throw();
|
||||
|
||||
/// \brief Return the minimum attribute value
|
||||
template <typename T> T MinValue(TPoolEnum token,T _default) const throw();
|
||||
|
||||
/// \brief Return the maximum attribute value
|
||||
template <typename T> T MaxValue(TPoolEnum token,T _default) const throw();
|
||||
|
||||
/// \brief Return an index at which the minimum attribute value is achieved
|
||||
template <typename T> TIndex MinIndex(TPoolEnum token) const throw();
|
||||
|
||||
/// \brief Return an index at which the maximum attribute value is achieved
|
||||
template <typename T> TIndex MaxIndex(TPoolEnum token) const throw();
|
||||
|
||||
/// \brief Check if attribute values coincide for all indices
|
||||
template <typename T> bool IsConstant(TPoolEnum token) const throw();
|
||||
|
||||
};
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
template <typename T>
|
||||
attribute<T>* attributePool::MakeAttribute(goblinRootObject& X,TPoolEnum _token,
|
||||
TAttributeType attributeType,void* _value_ptr) throw()
|
||||
{
|
||||
// Handle synonymous tokens
|
||||
_token = TPoolEnum(table[_token].primaryIndex);
|
||||
|
||||
attribute<T>* pAttribute = GetAttribute<T>(_token);
|
||||
|
||||
if (!_value_ptr) _value_ptr = DefaultValueAsVoidPtr(table[_token].arrayType);
|
||||
|
||||
if (pAttribute)
|
||||
{
|
||||
if (attributeType==ATTR_ALLOW_NULL)
|
||||
{
|
||||
if (pAttribute->Size()>0)
|
||||
{
|
||||
pAttribute -> EraseItems(pAttribute->Size());
|
||||
pAttribute -> SetCapacity(0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t size = X.SizeInfo(table[_token].arrayDim,SIZE_ACTUAL);
|
||||
size_t capacity = X.SizeInfo(table[_token].arrayDim,SIZE_RESERVED);
|
||||
|
||||
if (attributeType==ATTR_REQ_SINGLETON && size==0)
|
||||
{
|
||||
if (pAttribute->Size()>1)
|
||||
{
|
||||
pAttribute -> EraseItems(pAttribute->Size()-1);
|
||||
pAttribute -> SetCapacity(1);
|
||||
}
|
||||
else if (pAttribute->Size()==0)
|
||||
{
|
||||
pAttribute -> IncreaseSize(1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pAttribute->Size()<size)
|
||||
{
|
||||
pAttribute -> SetCapacity(capacity);
|
||||
pAttribute -> IncreaseSize(size);
|
||||
}
|
||||
else if (pAttribute->Size()>size)
|
||||
{
|
||||
pAttribute -> EraseItems(pAttribute->Size()-size);
|
||||
pAttribute -> SetCapacity(capacity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pAttribute -> SetDefaultValue(*reinterpret_cast<T*>(_value_ptr));
|
||||
|
||||
return pAttribute;
|
||||
}
|
||||
|
||||
if (attributeType==ATTR_ALLOW_NULL)
|
||||
{
|
||||
pAttribute = new attribute<T>(0,*reinterpret_cast<T*>(_value_ptr));
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t size = X.SizeInfo(table[_token].arrayDim,SIZE_ACTUAL);
|
||||
size_t capacity = X.SizeInfo(table[_token].arrayDim,SIZE_RESERVED);
|
||||
|
||||
if (capacity==0)
|
||||
{
|
||||
if (attributeType==ATTR_FULL_RANK)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
// attributeType==ATTR_REQ_SINGLETON
|
||||
capacity = size = 1;
|
||||
}
|
||||
}
|
||||
|
||||
pAttribute = new attribute<T>(size,*reinterpret_cast<T*>(_value_ptr));
|
||||
pAttribute -> SetCapacity(capacity);
|
||||
}
|
||||
|
||||
attributes.insert(attributes.begin(),pAttribute);
|
||||
tokens.insert(tokens.begin(),(unsigned short)_token);
|
||||
|
||||
return pAttribute;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
attribute<T>* attributePool::ImportArray(TPoolEnum token,const T* _value,size_t size)
|
||||
throw()
|
||||
{
|
||||
attribute<T>* pAttribute = GetAttribute<T>(token);
|
||||
|
||||
if (!pAttribute)
|
||||
{
|
||||
pAttribute = new attribute<T>(0,*reinterpret_cast<T*>(
|
||||
DefaultValueAsVoidPtr(table[token].arrayType)));
|
||||
|
||||
attributes.insert(attributes.begin(),pAttribute);
|
||||
tokens.insert(tokens.begin(),(unsigned short)token);
|
||||
}
|
||||
|
||||
size_t oldSize = pAttribute->Size();
|
||||
|
||||
if (size>oldSize)
|
||||
{
|
||||
pAttribute -> IncreaseSize(size);
|
||||
}
|
||||
|
||||
memcpy(pAttribute->GetArray(),_value,sizeof(T)*size);
|
||||
|
||||
return pAttribute;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
attribute<T>* attributePool::GetAttribute(TPoolEnum token) const throw()
|
||||
{
|
||||
attributeBase* _attribute = FindAttribute(token);
|
||||
|
||||
if (!_attribute) return NULL;
|
||||
|
||||
return static_cast<attribute<T>*>(_attribute);
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
vector<T>* attributePool::GetVector(TPoolEnum token) const throw()
|
||||
{
|
||||
attributeBase* _attribute = FindAttribute(token);
|
||||
|
||||
if (!_attribute) return NULL;
|
||||
|
||||
return static_cast<attribute<T>*>(_attribute)->GetVector();
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
T* attributePool::GetArray(TPoolEnum token) const throw()
|
||||
{
|
||||
if (poolType==ATTR_ALLOW_NULL) return NULL;
|
||||
|
||||
attributeBase* _attributeBase = FindAttribute(token);
|
||||
|
||||
if (!_attributeBase) return NULL;
|
||||
|
||||
attribute<T>* _attribute = static_cast<attribute<T>*>(_attributeBase);
|
||||
|
||||
if (_attribute->Size()==0) return NULL;
|
||||
|
||||
return _attribute->GetArray();
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
attribute<T>* attributePool::InitAttribute(goblinRootObject& X,TPoolEnum token,T _value) throw()
|
||||
{
|
||||
attribute<T>* _attribute = GetAttribute<T>(token);
|
||||
|
||||
if (!_attribute)
|
||||
{
|
||||
return MakeAttribute<T>(X,token,ATTR_FULL_RANK,
|
||||
reinterpret_cast<void*>(&_value));
|
||||
}
|
||||
|
||||
_attribute -> Assign(_value);
|
||||
|
||||
return _attribute;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
vector<T>* attributePool::InitVector(goblinRootObject& X,TPoolEnum token,T _value) throw()
|
||||
{
|
||||
return InitAttribute(X,token,_value)->GetVector();
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
T* attributePool::InitArray(goblinRootObject& X,TPoolEnum token,T _value) throw()
|
||||
{
|
||||
vector<T>* _vector = InitVector(X,token,_value);
|
||||
|
||||
if (_vector->size()==0) return NULL;
|
||||
|
||||
return &((*_vector)[0]);
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
attribute<T>* attributePool::RawAttribute(goblinRootObject& X,TPoolEnum token) throw()
|
||||
{
|
||||
if (poolType==ATTR_FULL_RANK)
|
||||
{
|
||||
attribute<T>* _attribute = GetAttribute<T>(token);
|
||||
|
||||
if (_attribute) return _attribute;
|
||||
}
|
||||
|
||||
return MakeAttribute<T>(X,token,ATTR_FULL_RANK);
|
||||
}
|
||||
|
||||
|
||||
template <typename T> vector<T>* attributePool::RawVector(goblinRootObject& X,TPoolEnum token) throw()
|
||||
{
|
||||
return RawAttribute<T>(X,token)->GetVector();
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
T* attributePool::RawArray(goblinRootObject& X,TPoolEnum token) throw()
|
||||
{
|
||||
attribute<T>* _attribute = RawAttribute<T>(X,token);
|
||||
|
||||
if (_attribute->Size()==0) return NULL;
|
||||
|
||||
return _attribute->GetArray();
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
T attributePool::GetValue(TPoolEnum token,TIndex i,T _default) const throw()
|
||||
{
|
||||
attribute<T>* _attribute = GetAttribute<T>(token);
|
||||
|
||||
if (_attribute) return _attribute->GetValue(i);
|
||||
|
||||
return _default;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
T attributePool::DefaultValue(TPoolEnum token,T _default) const throw()
|
||||
{
|
||||
attribute<T>* _attribute = GetAttribute<T>(token);
|
||||
|
||||
if (_attribute) return _attribute->DefaultValue();
|
||||
|
||||
return _default;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
T attributePool::MinValue(TPoolEnum token,T _default) const throw()
|
||||
{
|
||||
attribute<T>* _attribute = GetAttribute<T>(token);
|
||||
|
||||
if (_attribute) return _attribute->MinValue();
|
||||
|
||||
return _default;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
T attributePool::MaxValue(TPoolEnum token,T _default) const throw()
|
||||
{
|
||||
attribute<T>* _attribute = GetAttribute<T>(token);
|
||||
|
||||
if (_attribute) return _attribute->MaxValue();
|
||||
|
||||
return _default;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
TIndex attributePool::MinIndex(TPoolEnum token) const throw()
|
||||
{
|
||||
attribute<T>* _attribute = GetAttribute<T>(token);
|
||||
|
||||
if (_attribute) return _attribute->MinIndex();
|
||||
|
||||
return NoIndex;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
TIndex attributePool::MaxIndex(TPoolEnum token) const throw()
|
||||
{
|
||||
attribute<T>* _attribute = GetAttribute<T>(token);
|
||||
|
||||
if (_attribute) return _attribute->MaxIndex();
|
||||
|
||||
return NoIndex;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
bool attributePool::IsConstant(TPoolEnum token) const throw()
|
||||
{
|
||||
attribute<T>* _attribute = GetAttribute<T>(token);
|
||||
|
||||
if (_attribute) return _attribute->IsConstant();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,850 @@
|
||||
|
||||
// This file forms part of the GOBLIN C++ Class Library.
|
||||
//
|
||||
// Initially written by Christian Fremuth-Paeger, January 1999
|
||||
//
|
||||
// Copying, compiling, distribution and modification
|
||||
// of this source code is permitted only in accordance
|
||||
// with the GOBLIN general licence information.
|
||||
|
||||
/// \file auxiliaryNetwork.cpp
|
||||
/// \brief #layeredAuxNetwork class implementation
|
||||
|
||||
#include "auxiliaryNetwork.h"
|
||||
|
||||
|
||||
layeredAuxNetwork::layeredAuxNetwork(abstractDiGraph& _G,TNode _s) throw() :
|
||||
managedObject(_G.Context()),
|
||||
abstractDiGraph(_G.N(),_G.M()),
|
||||
G(_G), s(_s), pred(_G.GetPredecessors())
|
||||
{
|
||||
G.MakeRef();
|
||||
blocked = new staticQueue<TNode>(n,CT);
|
||||
|
||||
outDegree = new TArc[n];
|
||||
successor = new TArc*[n];
|
||||
inDegree = new TArc[n];
|
||||
currentDegree = new TArc[n];
|
||||
prop = new TArc*[n];
|
||||
|
||||
for (TNode i=0;i<n;i++)
|
||||
{
|
||||
outDegree[i] = 0;
|
||||
inDegree[i] = 0;
|
||||
successor[i] = NULL;
|
||||
prop[i] = NULL;
|
||||
}
|
||||
|
||||
I = new iLayeredAuxNetwork(*this);
|
||||
|
||||
if (!pred) pred = G.InitPredecessors();
|
||||
|
||||
Phase = 1;
|
||||
align = "";
|
||||
|
||||
SetLayoutParameter(TokLayoutNodeLabelFormat,"#1");
|
||||
SetLayoutParameter(TokLayoutArcLabelFormat,"#2");
|
||||
|
||||
LogEntry(LOG_MEM,"Layered auxiliary network instanciated...");
|
||||
}
|
||||
|
||||
|
||||
void layeredAuxNetwork::Init() throw()
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (Phase!=1) Error(ERR_REJECTED,"Init","Inapplicable in phase 2");
|
||||
|
||||
#endif
|
||||
|
||||
for (TNode i=0;i<n;i++)
|
||||
{
|
||||
outDegree[i] = 0;
|
||||
inDegree[i] = 0;
|
||||
delete[] successor[i];
|
||||
successor[i] = NULL;
|
||||
delete[] prop[i];
|
||||
prop[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
layeredAuxNetwork::~layeredAuxNetwork() throw()
|
||||
{
|
||||
for (TNode i=0;i<n;i++)
|
||||
{
|
||||
delete[] successor[i];
|
||||
delete[] prop[i];
|
||||
}
|
||||
|
||||
delete[] outDegree;
|
||||
delete[] successor;
|
||||
delete[] inDegree;
|
||||
delete[] currentDegree;
|
||||
delete[] prop;
|
||||
delete blocked;
|
||||
delete I;
|
||||
|
||||
G.ReleaseRef();
|
||||
|
||||
LogEntry(LOG_MEM,"...Layered auxiliary network disallocated");
|
||||
}
|
||||
|
||||
|
||||
unsigned long layeredAuxNetwork::Size() const throw()
|
||||
{
|
||||
return
|
||||
sizeof(layeredAuxNetwork)
|
||||
+ managedObject::Allocated()
|
||||
+ abstractMixedGraph::Allocated()
|
||||
+ abstractDiGraph::Allocated()
|
||||
+ layeredAuxNetwork::Allocated();
|
||||
}
|
||||
|
||||
|
||||
unsigned long layeredAuxNetwork::Allocated() const throw()
|
||||
{
|
||||
unsigned long tmpSize
|
||||
= 3*n*sizeof(TArc) // outDegree[],inDegree[],currentDegree[]
|
||||
+ 2*n*sizeof(TArc*); // prop[],successor[]
|
||||
|
||||
for (TNode i=0;i<n;i++) // prop[][],successor[][]
|
||||
tmpSize += (outDegree[i]+inDegree[i])*sizeof(TArc);
|
||||
|
||||
return tmpSize;
|
||||
}
|
||||
|
||||
|
||||
investigator *layeredAuxNetwork::NewInvestigator() const throw()
|
||||
{
|
||||
return new iLayeredAuxNetwork(*this);
|
||||
}
|
||||
|
||||
|
||||
TNode layeredAuxNetwork::StartNode(TArc a) const throw(ERRange)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (a>=2*m) NoSuchArc("StartNode",a);
|
||||
|
||||
#endif
|
||||
|
||||
return G.StartNode(a);
|
||||
}
|
||||
|
||||
|
||||
TNode layeredAuxNetwork::EndNode(TArc a) const throw(ERRange)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (a>=2*m) NoSuchArc("EndNode",a);
|
||||
|
||||
#endif
|
||||
|
||||
return G.EndNode(a);
|
||||
}
|
||||
|
||||
|
||||
TArc layeredAuxNetwork::First(TNode v) const throw(ERRange,ERRejected)
|
||||
{
|
||||
Error(ERR_REJECTED,"First","Not implemented");
|
||||
throw ERRejected();
|
||||
}
|
||||
|
||||
|
||||
TArc layeredAuxNetwork::Right(TArc a,TNode u) const throw(ERRange,ERRejected)
|
||||
{
|
||||
Error(ERR_REJECTED,"Right","Not implemented");
|
||||
throw ERRejected();
|
||||
}
|
||||
|
||||
|
||||
TCap layeredAuxNetwork::UCap(TArc a) const throw(ERRange)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (a>=2*m) NoSuchArc("UCap",a);
|
||||
|
||||
#endif
|
||||
|
||||
if (!Blocking(2*(a>>1))) return (TCap)G.ResCap(2*(a>>1));
|
||||
if (!Blocking(2*(a>>1)+1)) return (TCap)G.ResCap(2*(a>>1)+1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool layeredAuxNetwork::Blocking(TArc a) const throw(ERRange)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (a>=2*m) NoSuchArc("Blocking",a);
|
||||
|
||||
#endif
|
||||
|
||||
return
|
||||
G.ResCap(a)==0
|
||||
|| Blocked(G.StartNode(a))
|
||||
|| G.Dist(G.StartNode(a))!=G.Dist(G.EndNode(a))-1;
|
||||
}
|
||||
|
||||
|
||||
char layeredAuxNetwork::Orientation(TArc a) throw(ERRange)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (a>=2*m) NoSuchArc("Orientation",a);
|
||||
|
||||
#endif
|
||||
|
||||
if (!Blocking(2*(a>>1))) return 1;
|
||||
if (!Blocking(2*(a>>1)+1)) return 2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
TFloat layeredAuxNetwork::Dist(TNode v) throw(ERRange)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (v>=n) NoSuchNode("Dist",v);
|
||||
|
||||
#endif
|
||||
|
||||
return G.Dist(v);
|
||||
}
|
||||
|
||||
|
||||
void layeredAuxNetwork::Phase1() throw(ERRejected)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (Phase==1) Error(ERR_REJECTED,"Phase1","Already in phase 1");
|
||||
|
||||
#endif
|
||||
|
||||
Phase = 1;
|
||||
}
|
||||
|
||||
|
||||
void layeredAuxNetwork::InsertProp(TArc a) throw(ERRange,ERRejected)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (a>=2*m) NoSuchArc("InsertProp",a);
|
||||
|
||||
if (Phase==2) Error(ERR_REJECTED,"InsertProp","Inapplicable in phase 2");
|
||||
|
||||
#endif
|
||||
|
||||
TNode u = EndNode(a);
|
||||
TNode v = StartNode(a);
|
||||
|
||||
inDegree[u]++;
|
||||
prop[u] = (TArc*)GoblinRealloc(prop[u],sizeof(TArc)*(int)inDegree[u]);
|
||||
prop[u][inDegree[u]-1] = a;
|
||||
|
||||
outDegree[v]++;
|
||||
successor[v] = (TArc*)GoblinRealloc(successor[v],sizeof(TArc)*(int)outDegree[v]);
|
||||
successor[v][outDegree[v]-1] = a;
|
||||
}
|
||||
|
||||
|
||||
void layeredAuxNetwork::Phase2() throw(ERRejected)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (Phase==2) Error(ERR_REJECTED,"Phase2","Already in phase 2");
|
||||
|
||||
#endif
|
||||
|
||||
for (TNode i=0;i<n;i++) currentDegree[i] = inDegree[i];
|
||||
|
||||
I -> Reset();
|
||||
Phase = 2;
|
||||
}
|
||||
|
||||
|
||||
bool layeredAuxNetwork::Blocked(TNode v) const throw(ERRange)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (v>=n) NoSuchNode("Blocked",v);
|
||||
|
||||
#endif
|
||||
|
||||
if (v==s) return false;
|
||||
else return (currentDegree[v]==0);
|
||||
}
|
||||
|
||||
|
||||
TFloat layeredAuxNetwork::FindPath(TNode t) throw(ERRange,ERRejected)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (t>=n) NoSuchNode("FindPath",t);
|
||||
|
||||
if (Phase==1) Error(ERR_REJECTED,"FindPath","Inapplicable in phase 1");
|
||||
|
||||
#endif
|
||||
|
||||
TNode v = t;
|
||||
TFloat Lambda = InfFloat;
|
||||
|
||||
#if defined(_LOGGING_)
|
||||
|
||||
THandle LH = NoHandle;
|
||||
|
||||
if (CT.logMeth>1)
|
||||
{
|
||||
sprintf(CT.logBuffer,"Augmenting by path (%lu",static_cast<unsigned long>(v));
|
||||
LH = LogStart(LOG_METH2,CT.logBuffer);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
while (v!=s)
|
||||
{
|
||||
TArc a = I->Peek(v);
|
||||
TNode u = StartNode(a);
|
||||
|
||||
while (Blocked(u) || G.ResCap(a)==0)
|
||||
{
|
||||
I -> Read(v);
|
||||
a = I->Peek(v);
|
||||
u = StartNode(a);
|
||||
}
|
||||
|
||||
pred[v] = a;
|
||||
v = u;
|
||||
|
||||
if (G.ResCap(a)<Lambda) Lambda = G.ResCap(a);
|
||||
|
||||
#if defined(_LOGGING_)
|
||||
|
||||
if (CT.logMeth>1)
|
||||
{
|
||||
sprintf(CT.logBuffer,",%lu",static_cast<unsigned long>(v));
|
||||
LogAppend(LH,CT.logBuffer);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(_LOGGING_)
|
||||
|
||||
if (CT.logMeth>1) LogEnd(LH,")");
|
||||
|
||||
#endif
|
||||
|
||||
if (Lambda<=0) InternalError("FindPath","Path has no residual capacity");
|
||||
|
||||
return Lambda;
|
||||
}
|
||||
|
||||
|
||||
void layeredAuxNetwork::TopErasure(TArc a) throw(ERRange,ERRejected)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (a>=2*m) NoSuchArc("TopErasure",a);
|
||||
|
||||
if (Phase==1) Error(ERR_REJECTED,"TopErasure","Inapplicable in phase 1");
|
||||
|
||||
#endif
|
||||
|
||||
TNode x = EndNode(a);
|
||||
I -> Read(x);
|
||||
|
||||
currentDegree[x]--;
|
||||
|
||||
#if defined(_LOGGING_)
|
||||
|
||||
if (CT.logMeth>1)
|
||||
{
|
||||
sprintf(CT.logBuffer,"Node %lu has indegree %lu",
|
||||
static_cast<unsigned long>(x),
|
||||
static_cast<unsigned long>(currentDegree[x]));
|
||||
LogEntry(LOG_METH2,CT.logBuffer);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if (currentDegree[x]==0)
|
||||
{
|
||||
blocked -> Insert(x);
|
||||
while (!(blocked -> Empty()))
|
||||
{
|
||||
x = blocked->Delete();
|
||||
|
||||
#if defined(_LOGGING_)
|
||||
|
||||
if (CT.logMeth>1)
|
||||
{
|
||||
sprintf(CT.logBuffer,"Deleting node %lu...",
|
||||
static_cast<unsigned long>(x));
|
||||
LogEntry(LOG_METH2,CT.logBuffer);
|
||||
OpenFold();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
for (TArc i=0;i<outDegree[x];i++)
|
||||
{
|
||||
TArc aa = successor[x][i];
|
||||
TNode y = EndNode(aa);
|
||||
|
||||
if (G.ResCap(aa)>0)
|
||||
{
|
||||
currentDegree[y]--;
|
||||
|
||||
#if defined(_LOGGING_)
|
||||
|
||||
if (CT.logMeth>1)
|
||||
{
|
||||
sprintf(CT.logBuffer,"Node %lu has indegree %lu",
|
||||
static_cast<unsigned long>(y),
|
||||
static_cast<unsigned long>(currentDegree[y]));
|
||||
LogEntry(LOG_METH2,CT.logBuffer);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if (currentDegree[y]==0) blocked -> Insert(y);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(_LOGGING_)
|
||||
|
||||
if (CT.logMeth>1) CloseFold();
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This file forms part of the GOBLIN C++ Class Library.
|
||||
//
|
||||
// Initially written by Christian Fremuth-Paeger, January 1999
|
||||
//
|
||||
// Copying, compiling, distribution and modification
|
||||
// of this source code is permitted only in accordance
|
||||
// with the GOBLIN general licence information.
|
||||
|
||||
/// \file auxiliaryNetwork.cpp
|
||||
/// \brief #layeredAuxNetwork class implementation
|
||||
|
||||
#include "auxiliaryNetwork.h"
|
||||
|
||||
|
||||
layeredAuxNetwork::layeredAuxNetwork(abstractDiGraph& _G,TNode _s) throw() :
|
||||
managedObject(_G.Context()),
|
||||
abstractDiGraph(_G.N(),_G.M()),
|
||||
G(_G), s(_s), pred(_G.GetPredecessors())
|
||||
{
|
||||
G.MakeRef();
|
||||
blocked = new staticQueue<TNode>(n,CT);
|
||||
|
||||
outDegree = new TArc[n];
|
||||
successor = new TArc*[n];
|
||||
inDegree = new TArc[n];
|
||||
currentDegree = new TArc[n];
|
||||
prop = new TArc*[n];
|
||||
|
||||
for (TNode i=0;i<n;i++)
|
||||
{
|
||||
outDegree[i] = 0;
|
||||
inDegree[i] = 0;
|
||||
successor[i] = NULL;
|
||||
prop[i] = NULL;
|
||||
}
|
||||
|
||||
I = new iLayeredAuxNetwork(*this);
|
||||
|
||||
if (!pred) pred = G.InitPredecessors();
|
||||
|
||||
Phase = 1;
|
||||
align = "";
|
||||
|
||||
SetLayoutParameter(TokLayoutNodeLabelFormat,"#1");
|
||||
SetLayoutParameter(TokLayoutArcLabelFormat,"#2");
|
||||
|
||||
LogEntry(LOG_MEM,"Layered auxiliary network instanciated...");
|
||||
}
|
||||
|
||||
|
||||
void layeredAuxNetwork::Init() throw()
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (Phase!=1) Error(ERR_REJECTED,"Init","Inapplicable in phase 2");
|
||||
|
||||
#endif
|
||||
|
||||
for (TNode i=0;i<n;i++)
|
||||
{
|
||||
outDegree[i] = 0;
|
||||
inDegree[i] = 0;
|
||||
delete[] successor[i];
|
||||
successor[i] = NULL;
|
||||
delete[] prop[i];
|
||||
prop[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
layeredAuxNetwork::~layeredAuxNetwork() throw()
|
||||
{
|
||||
for (TNode i=0;i<n;i++)
|
||||
{
|
||||
delete[] successor[i];
|
||||
delete[] prop[i];
|
||||
}
|
||||
|
||||
delete[] outDegree;
|
||||
delete[] successor;
|
||||
delete[] inDegree;
|
||||
delete[] currentDegree;
|
||||
delete[] prop;
|
||||
delete blocked;
|
||||
delete I;
|
||||
|
||||
G.ReleaseRef();
|
||||
|
||||
LogEntry(LOG_MEM,"...Layered auxiliary network disallocated");
|
||||
}
|
||||
|
||||
|
||||
unsigned long layeredAuxNetwork::Size() const throw()
|
||||
{
|
||||
return
|
||||
sizeof(layeredAuxNetwork)
|
||||
+ managedObject::Allocated()
|
||||
+ abstractMixedGraph::Allocated()
|
||||
+ abstractDiGraph::Allocated()
|
||||
+ layeredAuxNetwork::Allocated();
|
||||
}
|
||||
|
||||
|
||||
unsigned long layeredAuxNetwork::Allocated() const throw()
|
||||
{
|
||||
unsigned long tmpSize
|
||||
= 3*n*sizeof(TArc) // outDegree[],inDegree[],currentDegree[]
|
||||
+ 2*n*sizeof(TArc*); // prop[],successor[]
|
||||
|
||||
for (TNode i=0;i<n;i++) // prop[][],successor[][]
|
||||
tmpSize += (outDegree[i]+inDegree[i])*sizeof(TArc);
|
||||
|
||||
return tmpSize;
|
||||
}
|
||||
|
||||
|
||||
investigator *layeredAuxNetwork::NewInvestigator() const throw()
|
||||
{
|
||||
return new iLayeredAuxNetwork(*this);
|
||||
}
|
||||
|
||||
|
||||
TNode layeredAuxNetwork::StartNode(TArc a) const throw(ERRange)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (a>=2*m) NoSuchArc("StartNode",a);
|
||||
|
||||
#endif
|
||||
|
||||
return G.StartNode(a);
|
||||
}
|
||||
|
||||
|
||||
TNode layeredAuxNetwork::EndNode(TArc a) const throw(ERRange)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (a>=2*m) NoSuchArc("EndNode",a);
|
||||
|
||||
#endif
|
||||
|
||||
return G.EndNode(a);
|
||||
}
|
||||
|
||||
|
||||
TArc layeredAuxNetwork::First(TNode v) const throw(ERRange,ERRejected)
|
||||
{
|
||||
Error(ERR_REJECTED,"First","Not implemented");
|
||||
throw ERRejected();
|
||||
}
|
||||
|
||||
|
||||
TArc layeredAuxNetwork::Right(TArc a,TNode u) const throw(ERRange,ERRejected)
|
||||
{
|
||||
Error(ERR_REJECTED,"Right","Not implemented");
|
||||
throw ERRejected();
|
||||
}
|
||||
|
||||
|
||||
TCap layeredAuxNetwork::UCap(TArc a) const throw(ERRange)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (a>=2*m) NoSuchArc("UCap",a);
|
||||
|
||||
#endif
|
||||
|
||||
if (!Blocking(2*(a>>1))) return (TCap)G.ResCap(2*(a>>1));
|
||||
if (!Blocking(2*(a>>1)+1)) return (TCap)G.ResCap(2*(a>>1)+1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool layeredAuxNetwork::Blocking(TArc a) const throw(ERRange)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (a>=2*m) NoSuchArc("Blocking",a);
|
||||
|
||||
#endif
|
||||
|
||||
return
|
||||
G.ResCap(a)==0
|
||||
|| Blocked(G.StartNode(a))
|
||||
|| G.Dist(G.StartNode(a))!=G.Dist(G.EndNode(a))-1;
|
||||
}
|
||||
|
||||
|
||||
char layeredAuxNetwork::Orientation(TArc a) throw(ERRange)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (a>=2*m) NoSuchArc("Orientation",a);
|
||||
|
||||
#endif
|
||||
|
||||
if (!Blocking(2*(a>>1))) return 1;
|
||||
if (!Blocking(2*(a>>1)+1)) return 2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
TFloat layeredAuxNetwork::Dist(TNode v) throw(ERRange)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (v>=n) NoSuchNode("Dist",v);
|
||||
|
||||
#endif
|
||||
|
||||
return G.Dist(v);
|
||||
}
|
||||
|
||||
|
||||
void layeredAuxNetwork::Phase1() throw(ERRejected)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (Phase==1) Error(ERR_REJECTED,"Phase1","Already in phase 1");
|
||||
|
||||
#endif
|
||||
|
||||
Phase = 1;
|
||||
}
|
||||
|
||||
|
||||
void layeredAuxNetwork::InsertProp(TArc a) throw(ERRange,ERRejected)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (a>=2*m) NoSuchArc("InsertProp",a);
|
||||
|
||||
if (Phase==2) Error(ERR_REJECTED,"InsertProp","Inapplicable in phase 2");
|
||||
|
||||
#endif
|
||||
|
||||
TNode u = EndNode(a);
|
||||
TNode v = StartNode(a);
|
||||
|
||||
inDegree[u]++;
|
||||
prop[u] = (TArc*)GoblinRealloc(prop[u],sizeof(TArc)*(int)inDegree[u]);
|
||||
prop[u][inDegree[u]-1] = a;
|
||||
|
||||
outDegree[v]++;
|
||||
successor[v] = (TArc*)GoblinRealloc(successor[v],sizeof(TArc)*(int)outDegree[v]);
|
||||
successor[v][outDegree[v]-1] = a;
|
||||
}
|
||||
|
||||
|
||||
void layeredAuxNetwork::Phase2() throw(ERRejected)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (Phase==2) Error(ERR_REJECTED,"Phase2","Already in phase 2");
|
||||
|
||||
#endif
|
||||
|
||||
for (TNode i=0;i<n;i++) currentDegree[i] = inDegree[i];
|
||||
|
||||
I -> Reset();
|
||||
Phase = 2;
|
||||
}
|
||||
|
||||
|
||||
bool layeredAuxNetwork::Blocked(TNode v) const throw(ERRange)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (v>=n) NoSuchNode("Blocked",v);
|
||||
|
||||
#endif
|
||||
|
||||
if (v==s) return false;
|
||||
else return (currentDegree[v]==0);
|
||||
}
|
||||
|
||||
|
||||
TFloat layeredAuxNetwork::FindPath(TNode t) throw(ERRange,ERRejected)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (t>=n) NoSuchNode("FindPath",t);
|
||||
|
||||
if (Phase==1) Error(ERR_REJECTED,"FindPath","Inapplicable in phase 1");
|
||||
|
||||
#endif
|
||||
|
||||
TNode v = t;
|
||||
TFloat Lambda = InfFloat;
|
||||
|
||||
#if defined(_LOGGING_)
|
||||
|
||||
THandle LH = NoHandle;
|
||||
|
||||
if (CT.logMeth>1)
|
||||
{
|
||||
sprintf(CT.logBuffer,"Augmenting by path (%lu",static_cast<unsigned long>(v));
|
||||
LH = LogStart(LOG_METH2,CT.logBuffer);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
while (v!=s)
|
||||
{
|
||||
TArc a = I->Peek(v);
|
||||
TNode u = StartNode(a);
|
||||
|
||||
while (Blocked(u) || G.ResCap(a)==0)
|
||||
{
|
||||
I -> Read(v);
|
||||
a = I->Peek(v);
|
||||
u = StartNode(a);
|
||||
}
|
||||
|
||||
pred[v] = a;
|
||||
v = u;
|
||||
|
||||
if (G.ResCap(a)<Lambda) Lambda = G.ResCap(a);
|
||||
|
||||
#if defined(_LOGGING_)
|
||||
|
||||
if (CT.logMeth>1)
|
||||
{
|
||||
sprintf(CT.logBuffer,",%lu",static_cast<unsigned long>(v));
|
||||
LogAppend(LH,CT.logBuffer);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(_LOGGING_)
|
||||
|
||||
if (CT.logMeth>1) LogEnd(LH,")");
|
||||
|
||||
#endif
|
||||
|
||||
if (Lambda<=0) InternalError("FindPath","Path has no residual capacity");
|
||||
|
||||
return Lambda;
|
||||
}
|
||||
|
||||
|
||||
void layeredAuxNetwork::TopErasure(TArc a) throw(ERRange,ERRejected)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (a>=2*m) NoSuchArc("TopErasure",a);
|
||||
|
||||
if (Phase==1) Error(ERR_REJECTED,"TopErasure","Inapplicable in phase 1");
|
||||
|
||||
#endif
|
||||
|
||||
TNode x = EndNode(a);
|
||||
I -> Read(x);
|
||||
|
||||
currentDegree[x]--;
|
||||
|
||||
#if defined(_LOGGING_)
|
||||
|
||||
if (CT.logMeth>1)
|
||||
{
|
||||
sprintf(CT.logBuffer,"Node %lu has indegree %lu",
|
||||
static_cast<unsigned long>(x),
|
||||
static_cast<unsigned long>(currentDegree[x]));
|
||||
LogEntry(LOG_METH2,CT.logBuffer);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if (currentDegree[x]==0)
|
||||
{
|
||||
blocked -> Insert(x);
|
||||
while (!(blocked -> Empty()))
|
||||
{
|
||||
x = blocked->Delete();
|
||||
|
||||
#if defined(_LOGGING_)
|
||||
|
||||
if (CT.logMeth>1)
|
||||
{
|
||||
sprintf(CT.logBuffer,"Deleting node %lu...",
|
||||
static_cast<unsigned long>(x));
|
||||
LogEntry(LOG_METH2,CT.logBuffer);
|
||||
OpenFold();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
for (TArc i=0;i<outDegree[x];i++)
|
||||
{
|
||||
TArc aa = successor[x][i];
|
||||
TNode y = EndNode(aa);
|
||||
|
||||
if (G.ResCap(aa)>0)
|
||||
{
|
||||
currentDegree[y]--;
|
||||
|
||||
#if defined(_LOGGING_)
|
||||
|
||||
if (CT.logMeth>1)
|
||||
{
|
||||
sprintf(CT.logBuffer,"Node %lu has indegree %lu",
|
||||
static_cast<unsigned long>(y),
|
||||
static_cast<unsigned long>(currentDegree[y]));
|
||||
LogEntry(LOG_METH2,CT.logBuffer);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if (currentDegree[y]==0) blocked -> Insert(y);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(_LOGGING_)
|
||||
|
||||
if (CT.logMeth>1) CloseFold();
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,278 @@
|
||||
|
||||
// This file forms part of the GOBLIN C++ Class Library.
|
||||
//
|
||||
// Initially written by Christian Fremuth-Paeger, January 1999
|
||||
//
|
||||
// Copying, compiling, distribution and modification
|
||||
// of this source code is permitted only in accordance
|
||||
// with the GOBLIN general licence information.
|
||||
|
||||
/// \file auxiliaryNetwork.h
|
||||
/// \brief #layeredAuxNetwork class interface
|
||||
|
||||
|
||||
#if !defined(_AUXILIARY_NETWORK_H_)
|
||||
|
||||
#define _AUXILIARY_NETWORK_H_
|
||||
|
||||
#include "abstractDigraph.h"
|
||||
#include "staticQueue.h"
|
||||
|
||||
|
||||
/// \addtogroup maximumFlow
|
||||
/// @{
|
||||
|
||||
/// \brief A class for supporting supporting network flow methods which use layered augmentation
|
||||
///
|
||||
/// An auxiliary network is a sparely represented DAG and defined relative to
|
||||
/// a flow network G (a digraph with fixed arc capacities) and a pair of
|
||||
/// nodes s, t for which a flow has to be maximized (t is not specified
|
||||
/// in the constructor, but only in augmenation phases).
|
||||
///
|
||||
/// The incidence structure of the auxiliary network is manipulated in phases.
|
||||
/// In the odd phases, incidences are generated for the arcs which occur on a
|
||||
/// shortest residual path. In the even phases (the augmentation phases),
|
||||
/// arcs are deleted when no further residual capacity is available.
|
||||
|
||||
class layeredAuxNetwork : public abstractDiGraph
|
||||
{
|
||||
friend class iLayeredAuxNetwork;
|
||||
|
||||
protected:
|
||||
|
||||
abstractDiGraph& G;
|
||||
TNode s;
|
||||
TArc* pred;
|
||||
|
||||
investigator* I;
|
||||
char Phase;
|
||||
char* align;
|
||||
|
||||
TArc* outDegree;
|
||||
TArc** successor;
|
||||
TArc* inDegree;
|
||||
TArc* currentDegree;
|
||||
TArc** prop;
|
||||
|
||||
staticQueue<TNode>* blocked;
|
||||
|
||||
public:
|
||||
|
||||
layeredAuxNetwork(abstractDiGraph &GC,TNode ss) throw();
|
||||
~layeredAuxNetwork() throw();
|
||||
|
||||
unsigned long Size() const throw();
|
||||
unsigned long Allocated() const throw();
|
||||
investigator* NewInvestigator() const throw();
|
||||
|
||||
|
||||
TNode StartNode(TArc a) const throw(ERRange);
|
||||
TNode EndNode(TArc a) const throw(ERRange);
|
||||
|
||||
TArc First(TNode v) const throw(ERRange,ERRejected);
|
||||
TArc Right(TArc a,TNode v) const throw(ERRange,ERRejected);
|
||||
|
||||
TCap UCap(TArc a) const throw(ERRange);
|
||||
bool CUCap() const throw() {return G.CUCap();};
|
||||
bool Blocking(TArc a) const throw(ERRange);
|
||||
char Orientation(TArc a) throw(ERRange);
|
||||
bool COrientation() throw() {return false;};
|
||||
void WriteIncidences(goblinExport* F) throw()
|
||||
{G.WriteIncidences(F);};
|
||||
TFloat Dist(TNode v) throw(ERRange);
|
||||
|
||||
TFloat Length(TArc a) const throw() {return 1;};
|
||||
bool CLength() const throw() {return true;};
|
||||
|
||||
TFloat C(TNode v,char i) const throw(ERRange) {return G.C(v,i);};
|
||||
TFloat CMax(char i) const throw(ERRange) {return G.CMax(i);};
|
||||
TDim Dim() const throw() {return G.Dim();};
|
||||
bool HiddenNode(TNode v) const throw(ERRange) {return G.HiddenNode(v);};
|
||||
|
||||
|
||||
void Phase1() throw(ERRejected);
|
||||
void Init() throw();
|
||||
void InsertProp(TArc a) throw(ERRange,ERRejected);
|
||||
|
||||
void Phase2() throw(ERRejected);
|
||||
bool Blocked(TNode v) const throw(ERRange);
|
||||
TFloat FindPath(TNode t) throw(ERRange,ERRejected);
|
||||
void TopErasure(TArc a) throw(ERRange,ERRejected);
|
||||
|
||||
TFloat Sub(TArc a) const throw() {return 0;};
|
||||
|
||||
};
|
||||
|
||||
|
||||
/// \brief Investigators for #layeredAuxNetwork objects
|
||||
|
||||
class iLayeredAuxNetwork : public investigator
|
||||
{
|
||||
private:
|
||||
|
||||
const layeredAuxNetwork &G;
|
||||
TNode n;
|
||||
|
||||
TArc* currentIndex;
|
||||
|
||||
public:
|
||||
|
||||
iLayeredAuxNetwork(const layeredAuxNetwork &GC) throw();
|
||||
~iLayeredAuxNetwork() throw();
|
||||
|
||||
unsigned long Size() const throw();
|
||||
unsigned long Allocated() const throw();
|
||||
|
||||
void Reset() throw();
|
||||
void Reset(TNode v) throw(ERRange);
|
||||
TArc Read(TNode v) throw(ERRange,ERRejected);
|
||||
TArc Peek(TNode v) throw(ERRange,ERRejected);
|
||||
bool Active(TNode v) const throw(ERRange);
|
||||
void Skip(TNode v) throw(ERRange,ERRejected);
|
||||
|
||||
};
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
// This file forms part of the GOBLIN C++ Class Library.
|
||||
//
|
||||
// Initially written by Christian Fremuth-Paeger, January 1999
|
||||
//
|
||||
// Copying, compiling, distribution and modification
|
||||
// of this source code is permitted only in accordance
|
||||
// with the GOBLIN general licence information.
|
||||
|
||||
/// \file auxiliaryNetwork.h
|
||||
/// \brief #layeredAuxNetwork class interface
|
||||
|
||||
|
||||
#if !defined(_AUXILIARY_NETWORK_H_)
|
||||
|
||||
#define _AUXILIARY_NETWORK_H_
|
||||
|
||||
#include "abstractDigraph.h"
|
||||
#include "staticQueue.h"
|
||||
|
||||
|
||||
/// \addtogroup maximumFlow
|
||||
/// @{
|
||||
|
||||
/// \brief A class for supporting supporting network flow methods which use layered augmentation
|
||||
///
|
||||
/// An auxiliary network is a sparely represented DAG and defined relative to
|
||||
/// a flow network G (a digraph with fixed arc capacities) and a pair of
|
||||
/// nodes s, t for which a flow has to be maximized (t is not specified
|
||||
/// in the constructor, but only in augmenation phases).
|
||||
///
|
||||
/// The incidence structure of the auxiliary network is manipulated in phases.
|
||||
/// In the odd phases, incidences are generated for the arcs which occur on a
|
||||
/// shortest residual path. In the even phases (the augmentation phases),
|
||||
/// arcs are deleted when no further residual capacity is available.
|
||||
|
||||
class layeredAuxNetwork : public abstractDiGraph
|
||||
{
|
||||
friend class iLayeredAuxNetwork;
|
||||
|
||||
protected:
|
||||
|
||||
abstractDiGraph& G;
|
||||
TNode s;
|
||||
TArc* pred;
|
||||
|
||||
investigator* I;
|
||||
char Phase;
|
||||
char* align;
|
||||
|
||||
TArc* outDegree;
|
||||
TArc** successor;
|
||||
TArc* inDegree;
|
||||
TArc* currentDegree;
|
||||
TArc** prop;
|
||||
|
||||
staticQueue<TNode>* blocked;
|
||||
|
||||
public:
|
||||
|
||||
layeredAuxNetwork(abstractDiGraph &GC,TNode ss) throw();
|
||||
~layeredAuxNetwork() throw();
|
||||
|
||||
unsigned long Size() const throw();
|
||||
unsigned long Allocated() const throw();
|
||||
investigator* NewInvestigator() const throw();
|
||||
|
||||
|
||||
TNode StartNode(TArc a) const throw(ERRange);
|
||||
TNode EndNode(TArc a) const throw(ERRange);
|
||||
|
||||
TArc First(TNode v) const throw(ERRange,ERRejected);
|
||||
TArc Right(TArc a,TNode v) const throw(ERRange,ERRejected);
|
||||
|
||||
TCap UCap(TArc a) const throw(ERRange);
|
||||
bool CUCap() const throw() {return G.CUCap();};
|
||||
bool Blocking(TArc a) const throw(ERRange);
|
||||
char Orientation(TArc a) throw(ERRange);
|
||||
bool COrientation() throw() {return false;};
|
||||
void WriteIncidences(goblinExport* F) throw()
|
||||
{G.WriteIncidences(F);};
|
||||
TFloat Dist(TNode v) throw(ERRange);
|
||||
|
||||
TFloat Length(TArc a) const throw() {return 1;};
|
||||
bool CLength() const throw() {return true;};
|
||||
|
||||
TFloat C(TNode v,char i) const throw(ERRange) {return G.C(v,i);};
|
||||
TFloat CMax(char i) const throw(ERRange) {return G.CMax(i);};
|
||||
TDim Dim() const throw() {return G.Dim();};
|
||||
bool HiddenNode(TNode v) const throw(ERRange) {return G.HiddenNode(v);};
|
||||
|
||||
|
||||
void Phase1() throw(ERRejected);
|
||||
void Init() throw();
|
||||
void InsertProp(TArc a) throw(ERRange,ERRejected);
|
||||
|
||||
void Phase2() throw(ERRejected);
|
||||
bool Blocked(TNode v) const throw(ERRange);
|
||||
TFloat FindPath(TNode t) throw(ERRange,ERRejected);
|
||||
void TopErasure(TArc a) throw(ERRange,ERRejected);
|
||||
|
||||
TFloat Sub(TArc a) const throw() {return 0;};
|
||||
|
||||
};
|
||||
|
||||
|
||||
/// \brief Investigators for #layeredAuxNetwork objects
|
||||
|
||||
class iLayeredAuxNetwork : public investigator
|
||||
{
|
||||
private:
|
||||
|
||||
const layeredAuxNetwork &G;
|
||||
TNode n;
|
||||
|
||||
TArc* currentIndex;
|
||||
|
||||
public:
|
||||
|
||||
iLayeredAuxNetwork(const layeredAuxNetwork &GC) throw();
|
||||
~iLayeredAuxNetwork() throw();
|
||||
|
||||
unsigned long Size() const throw();
|
||||
unsigned long Allocated() const throw();
|
||||
|
||||
void Reset() throw();
|
||||
void Reset(TNode v) throw(ERRange);
|
||||
TArc Read(TNode v) throw(ERRange,ERRejected);
|
||||
TArc Peek(TNode v) throw(ERRange,ERRejected);
|
||||
bool Active(TNode v) const throw(ERRange);
|
||||
void Skip(TNode v) throw(ERRange,ERRejected);
|
||||
|
||||
};
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,430 @@
|
||||
|
||||
// This file forms part of the GOBLIN C++ Class Library.
|
||||
//
|
||||
// Initially written by Christian Fremuth-Paeger, January 2000
|
||||
//
|
||||
// Copying, compiling, distribution and modification
|
||||
// of this source code is permitted only in accordance
|
||||
// with the GOBLIN general licence information.
|
||||
|
||||
/// \file balancedDigraph.cpp
|
||||
/// \brief #balancedFNW class implementation
|
||||
|
||||
#include "balancedDigraph.h"
|
||||
|
||||
|
||||
balancedFNW::balancedFNW(TNode _n1,goblinController& _CT) throw() :
|
||||
managedObject(_CT),
|
||||
abstractBalancedFNW(_n1,TArc(0)),
|
||||
X(static_cast<const balancedFNW&>(*this))
|
||||
{
|
||||
X.SetCOrientation(1);
|
||||
X.NewSubgraph();
|
||||
|
||||
LogEntry(LOG_MEM,"...Balanced flow network instanciated");
|
||||
}
|
||||
|
||||
|
||||
balancedFNW::balancedFNW(const char* fileName,goblinController& _CT)
|
||||
throw(ERFile,ERParse) :
|
||||
managedObject(_CT),
|
||||
abstractBalancedFNW(TNode(0),TArc(0)),
|
||||
X(static_cast<const balancedFNW&>(*this))
|
||||
{
|
||||
#if defined(_TIMERS_)
|
||||
|
||||
CT.globalTimer[TimerIO] -> Enable();
|
||||
|
||||
#endif
|
||||
|
||||
LogEntry(LOG_IO,"Loading balanced flow network...");
|
||||
if (!CT.logIO && CT.logMem)
|
||||
LogEntry(LOG_MEM,"Loading balanced flow network...");
|
||||
|
||||
goblinImport F(fileName,CT);
|
||||
|
||||
CT.sourceNodeInFile = CT.targetNodeInFile = CT.rootNodeInFile = NoNode;
|
||||
|
||||
F.Scan("balanced_fnw");
|
||||
ReadAllData(F);
|
||||
|
||||
n1 = n>>1;
|
||||
|
||||
SetSourceNode((CT.sourceNodeInFile<n) ? CT.sourceNodeInFile : NoNode);
|
||||
SetTargetNode((CT.targetNodeInFile<n) ? CT.targetNodeInFile : NoNode);
|
||||
SetRootNode ((CT.rootNodeInFile <n) ? CT.rootNodeInFile : NoNode);
|
||||
|
||||
X.SetCOrientation(1);
|
||||
|
||||
int l = strlen(fileName)-4;
|
||||
char* tmpLabel = new char[l+1];
|
||||
memcpy(tmpLabel,fileName,l);
|
||||
tmpLabel[l] = 0;
|
||||
SetLabel(tmpLabel);
|
||||
delete[] tmpLabel;
|
||||
|
||||
CT.SetMaster(Handle());
|
||||
|
||||
#if defined(_TIMERS_)
|
||||
|
||||
CT.globalTimer[TimerIO] -> Disable();
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
unsigned long balancedFNW::Size() const throw()
|
||||
{
|
||||
return
|
||||
sizeof(balancedFNW)
|
||||
+ managedObject::Allocated()
|
||||
+ abstractMixedGraph::Allocated()
|
||||
+ abstractDiGraph::Allocated()
|
||||
+ abstractBalancedFNW::Allocated();
|
||||
}
|
||||
|
||||
|
||||
unsigned long balancedFNW::Allocated() const throw()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
TFloat balancedFNW::Length(TArc a) const throw(ERRange)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (a>=2*m) NoSuchArc("Length",a);
|
||||
|
||||
#endif
|
||||
|
||||
if (X.CLength()) return X.MaxLength();
|
||||
|
||||
return X.Length(a);
|
||||
}
|
||||
|
||||
|
||||
void balancedFNW::Symmetrize() throw()
|
||||
{
|
||||
LogEntry(LOG_MAN,"Symmetrising flow...");
|
||||
|
||||
TArc m0 = m>>1;
|
||||
for (TArc a=0;a<m0;a++)
|
||||
{
|
||||
TFloat Lambda = (Flow(4*a+2)-Flow(4*a))/2;
|
||||
if (Lambda>0)
|
||||
{
|
||||
Push(4*a,Lambda);
|
||||
Push(4*a+3,Lambda);
|
||||
}
|
||||
else
|
||||
{
|
||||
Push(4*a+1,-Lambda);
|
||||
Push(4*a+2,-Lambda);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void balancedFNW::Relax() throw()
|
||||
{
|
||||
LogEntry(LOG_MAN,"Relaxing symmetry...");
|
||||
}
|
||||
|
||||
|
||||
balancedFNW::~balancedFNW() throw()
|
||||
{
|
||||
LogEntry(LOG_MEM,"...Balanced flow network disallocated");
|
||||
|
||||
if (CT.traceLevel==2) Display();
|
||||
}
|
||||
|
||||
|
||||
splitGraph::splitGraph(const abstractDiGraph &G) throw() :
|
||||
managedObject(G.Context()),
|
||||
balancedFNW(G.N()+1)
|
||||
{
|
||||
LogEntry(LOG_MAN,"Generating split graph...");
|
||||
|
||||
X.SetCapacity(2*G.N()+2,2*G.M()+2*G.N(),2*G.N()+4);
|
||||
ImportLayoutData(G);
|
||||
|
||||
if (G.Dim()>=2)
|
||||
{
|
||||
TFloat nodeSpacing = 0.0;
|
||||
GetLayoutParameter(TokLayoutNodeSpacing,nodeSpacing);
|
||||
|
||||
TFloat xMin = 0.0;
|
||||
TFloat xMax = 0.0;
|
||||
TFloat yMin = 0.0;
|
||||
TFloat yMax = 0.0;
|
||||
|
||||
G.Layout_GetBoundingInterval(0,xMin,xMax);
|
||||
G.Layout_GetBoundingInterval(1,yMin,yMax);
|
||||
|
||||
for (TNode v=0;v<G.N();v++)
|
||||
{
|
||||
// First copy is displayed as the original
|
||||
X.SetC(2*v,0,G.C(v,0));
|
||||
X.SetC(2*v,1,G.C(v,1));
|
||||
|
||||
// Second copy is rotated about 180 degrees
|
||||
X.SetC(2*v+1,0,xMax+xMin-G.C(v,0));
|
||||
X.SetC(2*v+1,1,2*yMax -G.C(v,1));
|
||||
}
|
||||
|
||||
X.SetC(2*G.N(),0,xMax);
|
||||
X.SetC(2*G.N(),1,yMax);
|
||||
X.SetC(2*G.N()+1,0,xMin);
|
||||
X.SetC(2*G.N()+1,1,yMax);
|
||||
|
||||
X.Layout_SetBoundingInterval(0,xMin-nodeSpacing,xMax+nodeSpacing);
|
||||
X.Layout_SetBoundingInterval(1,yMin,2*yMax-yMin);
|
||||
}
|
||||
|
||||
for (TArc a=0;a<G.M();++a)
|
||||
{
|
||||
TNode u = G.StartNode(2*a);
|
||||
TNode v = G.EndNode(2*a);
|
||||
InsertArc(2*u,2*v,G.UCap(2*a),G.Length(2*a),G.LCap(2*a));
|
||||
}
|
||||
|
||||
TCap totalSupply = 0;
|
||||
TCap totalDemand = 0;
|
||||
|
||||
for (TNode v=0;v<G.N();++v)
|
||||
{
|
||||
TCap thisDemand = G.Demand(v);
|
||||
|
||||
if (thisDemand<0)
|
||||
{
|
||||
InsertArc(n-1,2*v,-thisDemand,0);
|
||||
totalSupply += -thisDemand;
|
||||
}
|
||||
else if (thisDemand>0)
|
||||
{
|
||||
InsertArc(2*v,n-2,thisDemand,0);
|
||||
totalDemand += thisDemand;
|
||||
}
|
||||
}
|
||||
|
||||
X.SetDemand(n-1,-totalSupply-totalDemand);
|
||||
X.SetDemand(n-2,totalSupply+totalDemand);
|
||||
|
||||
X.SetCapacity(N(),M(),L());
|
||||
}
|
||||
|
||||
// This file forms part of the GOBLIN C++ Class Library.
|
||||
//
|
||||
// Initially written by Christian Fremuth-Paeger, January 2000
|
||||
//
|
||||
// Copying, compiling, distribution and modification
|
||||
// of this source code is permitted only in accordance
|
||||
// with the GOBLIN general licence information.
|
||||
|
||||
/// \file balancedDigraph.cpp
|
||||
/// \brief #balancedFNW class implementation
|
||||
|
||||
#include "balancedDigraph.h"
|
||||
|
||||
|
||||
balancedFNW::balancedFNW(TNode _n1,goblinController& _CT) throw() :
|
||||
managedObject(_CT),
|
||||
abstractBalancedFNW(_n1,TArc(0)),
|
||||
X(static_cast<const balancedFNW&>(*this))
|
||||
{
|
||||
X.SetCOrientation(1);
|
||||
X.NewSubgraph();
|
||||
|
||||
LogEntry(LOG_MEM,"...Balanced flow network instanciated");
|
||||
}
|
||||
|
||||
|
||||
balancedFNW::balancedFNW(const char* fileName,goblinController& _CT)
|
||||
throw(ERFile,ERParse) :
|
||||
managedObject(_CT),
|
||||
abstractBalancedFNW(TNode(0),TArc(0)),
|
||||
X(static_cast<const balancedFNW&>(*this))
|
||||
{
|
||||
#if defined(_TIMERS_)
|
||||
|
||||
CT.globalTimer[TimerIO] -> Enable();
|
||||
|
||||
#endif
|
||||
|
||||
LogEntry(LOG_IO,"Loading balanced flow network...");
|
||||
if (!CT.logIO && CT.logMem)
|
||||
LogEntry(LOG_MEM,"Loading balanced flow network...");
|
||||
|
||||
goblinImport F(fileName,CT);
|
||||
|
||||
CT.sourceNodeInFile = CT.targetNodeInFile = CT.rootNodeInFile = NoNode;
|
||||
|
||||
F.Scan("balanced_fnw");
|
||||
ReadAllData(F);
|
||||
|
||||
n1 = n>>1;
|
||||
|
||||
SetSourceNode((CT.sourceNodeInFile<n) ? CT.sourceNodeInFile : NoNode);
|
||||
SetTargetNode((CT.targetNodeInFile<n) ? CT.targetNodeInFile : NoNode);
|
||||
SetRootNode ((CT.rootNodeInFile <n) ? CT.rootNodeInFile : NoNode);
|
||||
|
||||
X.SetCOrientation(1);
|
||||
|
||||
int l = strlen(fileName)-4;
|
||||
char* tmpLabel = new char[l+1];
|
||||
memcpy(tmpLabel,fileName,l);
|
||||
tmpLabel[l] = 0;
|
||||
SetLabel(tmpLabel);
|
||||
delete[] tmpLabel;
|
||||
|
||||
CT.SetMaster(Handle());
|
||||
|
||||
#if defined(_TIMERS_)
|
||||
|
||||
CT.globalTimer[TimerIO] -> Disable();
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
unsigned long balancedFNW::Size() const throw()
|
||||
{
|
||||
return
|
||||
sizeof(balancedFNW)
|
||||
+ managedObject::Allocated()
|
||||
+ abstractMixedGraph::Allocated()
|
||||
+ abstractDiGraph::Allocated()
|
||||
+ abstractBalancedFNW::Allocated();
|
||||
}
|
||||
|
||||
|
||||
unsigned long balancedFNW::Allocated() const throw()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
TFloat balancedFNW::Length(TArc a) const throw(ERRange)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (a>=2*m) NoSuchArc("Length",a);
|
||||
|
||||
#endif
|
||||
|
||||
if (X.CLength()) return X.MaxLength();
|
||||
|
||||
return X.Length(a);
|
||||
}
|
||||
|
||||
|
||||
void balancedFNW::Symmetrize() throw()
|
||||
{
|
||||
LogEntry(LOG_MAN,"Symmetrising flow...");
|
||||
|
||||
TArc m0 = m>>1;
|
||||
for (TArc a=0;a<m0;a++)
|
||||
{
|
||||
TFloat Lambda = (Flow(4*a+2)-Flow(4*a))/2;
|
||||
if (Lambda>0)
|
||||
{
|
||||
Push(4*a,Lambda);
|
||||
Push(4*a+3,Lambda);
|
||||
}
|
||||
else
|
||||
{
|
||||
Push(4*a+1,-Lambda);
|
||||
Push(4*a+2,-Lambda);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void balancedFNW::Relax() throw()
|
||||
{
|
||||
LogEntry(LOG_MAN,"Relaxing symmetry...");
|
||||
}
|
||||
|
||||
|
||||
balancedFNW::~balancedFNW() throw()
|
||||
{
|
||||
LogEntry(LOG_MEM,"...Balanced flow network disallocated");
|
||||
|
||||
if (CT.traceLevel==2) Display();
|
||||
}
|
||||
|
||||
|
||||
splitGraph::splitGraph(const abstractDiGraph &G) throw() :
|
||||
managedObject(G.Context()),
|
||||
balancedFNW(G.N()+1)
|
||||
{
|
||||
LogEntry(LOG_MAN,"Generating split graph...");
|
||||
|
||||
X.SetCapacity(2*G.N()+2,2*G.M()+2*G.N(),2*G.N()+4);
|
||||
ImportLayoutData(G);
|
||||
|
||||
if (G.Dim()>=2)
|
||||
{
|
||||
TFloat nodeSpacing = 0.0;
|
||||
GetLayoutParameter(TokLayoutNodeSpacing,nodeSpacing);
|
||||
|
||||
TFloat xMin = 0.0;
|
||||
TFloat xMax = 0.0;
|
||||
TFloat yMin = 0.0;
|
||||
TFloat yMax = 0.0;
|
||||
|
||||
G.Layout_GetBoundingInterval(0,xMin,xMax);
|
||||
G.Layout_GetBoundingInterval(1,yMin,yMax);
|
||||
|
||||
for (TNode v=0;v<G.N();v++)
|
||||
{
|
||||
// First copy is displayed as the original
|
||||
X.SetC(2*v,0,G.C(v,0));
|
||||
X.SetC(2*v,1,G.C(v,1));
|
||||
|
||||
// Second copy is rotated about 180 degrees
|
||||
X.SetC(2*v+1,0,xMax+xMin-G.C(v,0));
|
||||
X.SetC(2*v+1,1,2*yMax -G.C(v,1));
|
||||
}
|
||||
|
||||
X.SetC(2*G.N(),0,xMax);
|
||||
X.SetC(2*G.N(),1,yMax);
|
||||
X.SetC(2*G.N()+1,0,xMin);
|
||||
X.SetC(2*G.N()+1,1,yMax);
|
||||
|
||||
X.Layout_SetBoundingInterval(0,xMin-nodeSpacing,xMax+nodeSpacing);
|
||||
X.Layout_SetBoundingInterval(1,yMin,2*yMax-yMin);
|
||||
}
|
||||
|
||||
for (TArc a=0;a<G.M();++a)
|
||||
{
|
||||
TNode u = G.StartNode(2*a);
|
||||
TNode v = G.EndNode(2*a);
|
||||
InsertArc(2*u,2*v,G.UCap(2*a),G.Length(2*a),G.LCap(2*a));
|
||||
}
|
||||
|
||||
TCap totalSupply = 0;
|
||||
TCap totalDemand = 0;
|
||||
|
||||
for (TNode v=0;v<G.N();++v)
|
||||
{
|
||||
TCap thisDemand = G.Demand(v);
|
||||
|
||||
if (thisDemand<0)
|
||||
{
|
||||
InsertArc(n-1,2*v,-thisDemand,0);
|
||||
totalSupply += -thisDemand;
|
||||
}
|
||||
else if (thisDemand>0)
|
||||
{
|
||||
InsertArc(2*v,n-2,thisDemand,0);
|
||||
totalDemand += thisDemand;
|
||||
}
|
||||
}
|
||||
|
||||
X.SetDemand(n-1,-totalSupply-totalDemand);
|
||||
X.SetDemand(n-2,totalSupply+totalDemand);
|
||||
|
||||
X.SetCapacity(N(),M(),L());
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
|
||||
// This file forms part of the GOBLIN C++ Class Library.
|
||||
//
|
||||
// Initially written by Christian Fremuth-Paeger, January 2000
|
||||
//
|
||||
// Copying, compiling, distribution and modification
|
||||
// of this source code is permitted only in accordance
|
||||
// with the GOBLIN general licence information.
|
||||
|
||||
/// \file balancedDigraph.h
|
||||
/// \brief #balancedFNW and #splitGraph class interfaces
|
||||
|
||||
#ifndef _BALANCED_DIGRAPH_H_
|
||||
#define _BALANCED_DIGRAPH_H_
|
||||
|
||||
#include "abstractBalanced.h"
|
||||
#include "sparseRepresentation.h"
|
||||
|
||||
|
||||
/// \brief Balanced (skew-symmetric) directed graphs represented with incidence lists
|
||||
|
||||
class balancedFNW : public abstractBalancedFNW
|
||||
{
|
||||
friend class sparseRepresentation;
|
||||
|
||||
protected:
|
||||
|
||||
sparseRepresentation X;
|
||||
|
||||
public:
|
||||
|
||||
/// \brief Default constructor for balanced digraphs
|
||||
///
|
||||
/// \param _n The initial number of nodes
|
||||
/// \param _CT The context to which this graph object is attached
|
||||
balancedFNW(TNode _n,goblinController& _CT=goblinDefaultContext) throw();
|
||||
|
||||
/// \brief File constructor for balanced digraphs
|
||||
///
|
||||
/// \param fileName The source file name
|
||||
/// \param _CT The context to which this graph object is attached
|
||||
balancedFNW(const char* fileName,goblinController& _CT=goblinDefaultContext)
|
||||
throw(ERFile,ERParse);
|
||||
|
||||
~balancedFNW() throw();
|
||||
|
||||
unsigned long Size() const throw();
|
||||
unsigned long Allocated() const throw();
|
||||
|
||||
void Symmetrize() throw();
|
||||
void Relax() throw();
|
||||
|
||||
#include <sparseInclude.h>
|
||||
|
||||
TFloat Length(TArc a) const throw(ERRange);
|
||||
TFloat BalFlow(TArc a) const throw(ERRange,ERRejected)
|
||||
{return X.Sub(a);};
|
||||
void BalPush(TArc a,TFloat lambda) throw(ERRange)
|
||||
{Push(a,lambda); Push(a^2,lambda);};
|
||||
|
||||
};
|
||||
|
||||
|
||||
/// \brief Balanced digraphs obtained by symmetrization of ordinary flow networks
|
||||
|
||||
class splitGraph : public balancedFNW
|
||||
{
|
||||
public:
|
||||
|
||||
splitGraph(const abstractDiGraph &G) throw();
|
||||
|
||||
TNode DefaultSourceNode() const throw() {return n-1;};
|
||||
TNode DefaultTargetNode() const throw() {return n-2;};
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
// This file forms part of the GOBLIN C++ Class Library.
|
||||
//
|
||||
// Initially written by Christian Fremuth-Paeger, January 2000
|
||||
//
|
||||
// Copying, compiling, distribution and modification
|
||||
// of this source code is permitted only in accordance
|
||||
// with the GOBLIN general licence information.
|
||||
|
||||
/// \file balancedDigraph.h
|
||||
/// \brief #balancedFNW and #splitGraph class interfaces
|
||||
|
||||
#ifndef _BALANCED_DIGRAPH_H_
|
||||
#define _BALANCED_DIGRAPH_H_
|
||||
|
||||
#include "abstractBalanced.h"
|
||||
#include "sparseRepresentation.h"
|
||||
|
||||
|
||||
/// \brief Balanced (skew-symmetric) directed graphs represented with incidence lists
|
||||
|
||||
class balancedFNW : public abstractBalancedFNW
|
||||
{
|
||||
friend class sparseRepresentation;
|
||||
|
||||
protected:
|
||||
|
||||
sparseRepresentation X;
|
||||
|
||||
public:
|
||||
|
||||
/// \brief Default constructor for balanced digraphs
|
||||
///
|
||||
/// \param _n The initial number of nodes
|
||||
/// \param _CT The context to which this graph object is attached
|
||||
balancedFNW(TNode _n,goblinController& _CT=goblinDefaultContext) throw();
|
||||
|
||||
/// \brief File constructor for balanced digraphs
|
||||
///
|
||||
/// \param fileName The source file name
|
||||
/// \param _CT The context to which this graph object is attached
|
||||
balancedFNW(const char* fileName,goblinController& _CT=goblinDefaultContext)
|
||||
throw(ERFile,ERParse);
|
||||
|
||||
~balancedFNW() throw();
|
||||
|
||||
unsigned long Size() const throw();
|
||||
unsigned long Allocated() const throw();
|
||||
|
||||
void Symmetrize() throw();
|
||||
void Relax() throw();
|
||||
|
||||
#include <sparseInclude.h>
|
||||
|
||||
TFloat Length(TArc a) const throw(ERRange);
|
||||
TFloat BalFlow(TArc a) const throw(ERRange,ERRejected)
|
||||
{return X.Sub(a);};
|
||||
void BalPush(TArc a,TFloat lambda) throw(ERRange)
|
||||
{Push(a,lambda); Push(a^2,lambda);};
|
||||
|
||||
};
|
||||
|
||||
|
||||
/// \brief Balanced digraphs obtained by symmetrization of ordinary flow networks
|
||||
|
||||
class splitGraph : public balancedFNW
|
||||
{
|
||||
public:
|
||||
|
||||
splitGraph(const abstractDiGraph &G) throw();
|
||||
|
||||
TNode DefaultSourceNode() const throw() {return n-1;};
|
||||
TNode DefaultTargetNode() const throw() {return n-2;};
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,206 @@
|
||||
|
||||
// This file forms part of the GOBLIN C++ Class Library.
|
||||
//
|
||||
// Initially written by Christian Fremuth-Paeger, May 2000
|
||||
//
|
||||
// Copying, compiling, distribution and modification
|
||||
// of this source code is permitted only in accordance
|
||||
// with the GOBLIN general licence information.
|
||||
|
||||
/// \file balancedToBalanced.h
|
||||
/// \brief #balancedToBalanced class interface
|
||||
|
||||
#ifndef _BALANCED_TO_BALANCED_H_
|
||||
#define _BALANCED_TO_BALANCED_H_
|
||||
|
||||
#include "abstractBalanced.h"
|
||||
|
||||
|
||||
/// \brief Balanced digraphs obtained as a simplification of balanced network flow problems
|
||||
///
|
||||
/// Any object in this class results from another balanced digraph and an according
|
||||
/// fixed balanced pseudo-flow. By that transformation, lower capacity bounds
|
||||
/// and node imbalances are eliminated. Circulation and b-flow problems map
|
||||
/// to single source / target flow problems. This is analogous to the #digraphToDigraph
|
||||
/// class for ordinary network flow probleme.
|
||||
|
||||
class balancedToBalanced : public abstractBalancedFNW
|
||||
{
|
||||
protected:
|
||||
|
||||
abstractBalancedFNW & G; ///< Original network
|
||||
|
||||
TNode n0; ///< Number of nodes in the original network
|
||||
TArc m0; ///< Number of arcs in the original network
|
||||
TNode k2; ///< Number of odd cycles
|
||||
TNode k1; ///< k1 == k2/2
|
||||
|
||||
TNode s1; ///< Source node, s1 == DefaultSourceNode()
|
||||
TNode t1; ///< Target node, t1 == DefaultTargetNode()
|
||||
TNode s2; ///< Additional source node
|
||||
TNode t2; ///< Additional target node
|
||||
TArc ret1; ///< Return arc with end nodes t1 and s1
|
||||
TArc ret2; ///< Return arc with end nodes t2 and s2
|
||||
TArc art1; ///< Artifical arc with end nodes s1 and t2
|
||||
TArc art2; ///< Artifical arc with end nodes s2 and t1
|
||||
|
||||
TFloat* flow; ///< Flow values on the artifical arcs
|
||||
TArc* artifical;
|
||||
// artifical[v] connects the original node v to s2 or t2.
|
||||
// Only partially defined, 2*k2 arcs in total.
|
||||
TNode * repr; ///< Canonical elements of the odd cycles
|
||||
|
||||
bool symm; ///< Is flow balanced?
|
||||
|
||||
public:
|
||||
|
||||
balancedToBalanced(abstractBalancedFNW &GC) throw();
|
||||
~balancedToBalanced() throw();
|
||||
|
||||
unsigned long Size() const throw();
|
||||
unsigned long Allocated() const throw();
|
||||
|
||||
bool Perfect() const throw();
|
||||
|
||||
void Relax() throw();
|
||||
void Symmetrize() throw();
|
||||
|
||||
TNode DefaultSourceNode() const throw() {return s1;};
|
||||
TNode DefaultTargetNode() const throw() {return t1;};
|
||||
|
||||
TNode StartNode(TArc a) const throw(ERRange);
|
||||
TNode EndNode(TArc a) const throw(ERRange);
|
||||
|
||||
TArc First(TNode v) const throw(ERRange);
|
||||
TArc Right(TArc a,TNode v) const throw(ERRange,ERRejected);
|
||||
|
||||
TCap Demand(TNode v) const throw(ERRange);
|
||||
bool CDemand() const throw() {return false;};
|
||||
TCap LCap(TArc a) const throw(ERRange);
|
||||
bool CLCap() const throw() {return G.CLCap() && (G.MaxLCap()==0);};
|
||||
TCap UCap(TArc a) const throw(ERRange);
|
||||
bool CUCap() const throw() {return false;};
|
||||
TFloat Length(TArc a) const throw(ERRange);
|
||||
bool CLength() const throw()
|
||||
{return G.CLength() && (G.MaxLength()==0);};
|
||||
bool Blocking(TArc a) const throw() {return a&1;};
|
||||
|
||||
TFloat C(TNode v,TDim i) const throw(ERRange);
|
||||
TFloat CMax(TDim i) const throw(ERRange);
|
||||
TDim Dim() const throw() {return G.Dim();};
|
||||
bool HiddenNode(TNode v) const throw(ERRange);
|
||||
|
||||
TFloat Flow(TArc a) const throw(ERRange);
|
||||
TFloat BalFlow(TArc a) const throw(ERRange,ERRejected);
|
||||
void Push(TArc a,TFloat lambda) throw(ERRange,ERRejected);
|
||||
void BalPush(TArc a,TFloat lambda) throw(ERRange,ERRejected);
|
||||
|
||||
TFloat Sub(TArc a) const throw(ERRange) {return BalFlow(a);};
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
// This file forms part of the GOBLIN C++ Class Library.
|
||||
//
|
||||
// Initially written by Christian Fremuth-Paeger, May 2000
|
||||
//
|
||||
// Copying, compiling, distribution and modification
|
||||
// of this source code is permitted only in accordance
|
||||
// with the GOBLIN general licence information.
|
||||
|
||||
/// \file balancedToBalanced.h
|
||||
/// \brief #balancedToBalanced class interface
|
||||
|
||||
#ifndef _BALANCED_TO_BALANCED_H_
|
||||
#define _BALANCED_TO_BALANCED_H_
|
||||
|
||||
#include "abstractBalanced.h"
|
||||
|
||||
|
||||
/// \brief Balanced digraphs obtained as a simplification of balanced network flow problems
|
||||
///
|
||||
/// Any object in this class results from another balanced digraph and an according
|
||||
/// fixed balanced pseudo-flow. By that transformation, lower capacity bounds
|
||||
/// and node imbalances are eliminated. Circulation and b-flow problems map
|
||||
/// to single source / target flow problems. This is analogous to the #digraphToDigraph
|
||||
/// class for ordinary network flow probleme.
|
||||
|
||||
class balancedToBalanced : public abstractBalancedFNW
|
||||
{
|
||||
protected:
|
||||
|
||||
abstractBalancedFNW & G; ///< Original network
|
||||
|
||||
TNode n0; ///< Number of nodes in the original network
|
||||
TArc m0; ///< Number of arcs in the original network
|
||||
TNode k2; ///< Number of odd cycles
|
||||
TNode k1; ///< k1 == k2/2
|
||||
|
||||
TNode s1; ///< Source node, s1 == DefaultSourceNode()
|
||||
TNode t1; ///< Target node, t1 == DefaultTargetNode()
|
||||
TNode s2; ///< Additional source node
|
||||
TNode t2; ///< Additional target node
|
||||
TArc ret1; ///< Return arc with end nodes t1 and s1
|
||||
TArc ret2; ///< Return arc with end nodes t2 and s2
|
||||
TArc art1; ///< Artifical arc with end nodes s1 and t2
|
||||
TArc art2; ///< Artifical arc with end nodes s2 and t1
|
||||
|
||||
TFloat* flow; ///< Flow values on the artifical arcs
|
||||
TArc* artifical;
|
||||
// artifical[v] connects the original node v to s2 or t2.
|
||||
// Only partially defined, 2*k2 arcs in total.
|
||||
TNode * repr; ///< Canonical elements of the odd cycles
|
||||
|
||||
bool symm; ///< Is flow balanced?
|
||||
|
||||
public:
|
||||
|
||||
balancedToBalanced(abstractBalancedFNW &GC) throw();
|
||||
~balancedToBalanced() throw();
|
||||
|
||||
unsigned long Size() const throw();
|
||||
unsigned long Allocated() const throw();
|
||||
|
||||
bool Perfect() const throw();
|
||||
|
||||
void Relax() throw();
|
||||
void Symmetrize() throw();
|
||||
|
||||
TNode DefaultSourceNode() const throw() {return s1;};
|
||||
TNode DefaultTargetNode() const throw() {return t1;};
|
||||
|
||||
TNode StartNode(TArc a) const throw(ERRange);
|
||||
TNode EndNode(TArc a) const throw(ERRange);
|
||||
|
||||
TArc First(TNode v) const throw(ERRange);
|
||||
TArc Right(TArc a,TNode v) const throw(ERRange,ERRejected);
|
||||
|
||||
TCap Demand(TNode v) const throw(ERRange);
|
||||
bool CDemand() const throw() {return false;};
|
||||
TCap LCap(TArc a) const throw(ERRange);
|
||||
bool CLCap() const throw() {return G.CLCap() && (G.MaxLCap()==0);};
|
||||
TCap UCap(TArc a) const throw(ERRange);
|
||||
bool CUCap() const throw() {return false;};
|
||||
TFloat Length(TArc a) const throw(ERRange);
|
||||
bool CLength() const throw()
|
||||
{return G.CLength() && (G.MaxLength()==0);};
|
||||
bool Blocking(TArc a) const throw() {return a&1;};
|
||||
|
||||
TFloat C(TNode v,TDim i) const throw(ERRange);
|
||||
TFloat CMax(TDim i) const throw(ERRange);
|
||||
TDim Dim() const throw() {return G.Dim();};
|
||||
bool HiddenNode(TNode v) const throw(ERRange);
|
||||
|
||||
TFloat Flow(TArc a) const throw(ERRange);
|
||||
TFloat BalFlow(TArc a) const throw(ERRange,ERRejected);
|
||||
void Push(TArc a,TFloat lambda) throw(ERRange,ERRejected);
|
||||
void BalPush(TArc a,TFloat lambda) throw(ERRange,ERRejected);
|
||||
|
||||
TFloat Sub(TArc a) const throw(ERRange) {return BalFlow(a);};
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,670 @@
|
||||
|
||||
// This file forms part of the GOBLIN C++ Class Library.
|
||||
//
|
||||
// Initially written by Christian Fremuth-Paeger, September 1998
|
||||
//
|
||||
// Copying, compiling, distribution and modification
|
||||
// of this source code is permitted only in accordance
|
||||
// with the GOBLIN general licence information.
|
||||
|
||||
/// \file basicHeap.cpp
|
||||
/// \brief #basicHeap class implementation
|
||||
|
||||
#include "basicHeap.h"
|
||||
|
||||
|
||||
template <class TItem,class TKey>
|
||||
basicHeap<TItem,TKey>::basicHeap(TItem nn,goblinController &thisContext)
|
||||
throw() : managedObject(thisContext)
|
||||
{
|
||||
#if defined(_TIMERS_)
|
||||
|
||||
this -> CT.globalTimer[TimerPrioQ] -> Enable();
|
||||
|
||||
#endif
|
||||
|
||||
n = nn;
|
||||
v = new TItem[n];
|
||||
key = new TKey[n];
|
||||
maxIndex = 0;
|
||||
|
||||
this -> LogEntry(LOG_MEM,"...Priority queue allocated");
|
||||
|
||||
#if defined(_TIMERS_)
|
||||
|
||||
this -> CT.globalTimer[TimerPrioQ] -> Disable();
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
template <class TItem,class TKey>
|
||||
void basicHeap<TItem,TKey>::Init() throw()
|
||||
{
|
||||
#if defined(_TIMERS_)
|
||||
|
||||
this -> CT.globalTimer[TimerPrioQ] -> Enable();
|
||||
|
||||
#endif
|
||||
|
||||
maxIndex = 0;
|
||||
|
||||
this -> LogEntry(LOG_MEM,"...Priority queue instanciated");
|
||||
|
||||
#if defined(_TIMERS_)
|
||||
|
||||
this -> CT.globalTimer[TimerPrioQ] -> Disable();
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
template <class TItem,class TKey>
|
||||
unsigned long basicHeap<TItem,TKey>::Size() const throw()
|
||||
{
|
||||
return
|
||||
sizeof(basicHeap<TItem,TKey>)
|
||||
+ managedObject::Allocated()
|
||||
+ basicHeap::Allocated();
|
||||
}
|
||||
|
||||
|
||||
template <class TItem,class TKey>
|
||||
unsigned long basicHeap<TItem,TKey>::Allocated() const throw()
|
||||
{
|
||||
return
|
||||
n*sizeof(TItem)
|
||||
+ n*sizeof(TKey);
|
||||
}
|
||||
|
||||
|
||||
template <class TItem,class TKey>
|
||||
char* basicHeap<TItem,TKey>::Display() const throw()
|
||||
{
|
||||
this -> LogEntry(MSG_TRACE,"Priority queue");
|
||||
|
||||
if (Empty()) this->LogEntry(MSG_TRACE2," ---");
|
||||
else
|
||||
{
|
||||
THandle LH = this->LogStart(MSG_TRACE2," ");
|
||||
|
||||
for (TItem i=0;i<maxIndex;i++)
|
||||
{
|
||||
sprintf(this->CT.logBuffer,"%lu[%g]",
|
||||
static_cast<unsigned long>(v[i]),key[v[i]]);
|
||||
this -> LogAppend(LH,this->CT.logBuffer);
|
||||
|
||||
if (i<maxIndex-1)
|
||||
{
|
||||
this -> LogAppend(LH,", ");
|
||||
|
||||
if (i%10==9)
|
||||
{
|
||||
this -> LogEnd(LH);
|
||||
LH = this->LogStart(MSG_TRACE2," ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this -> LogEnd(LH);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
template <class TItem,class TKey>
|
||||
basicHeap<TItem,TKey>::~basicHeap() throw()
|
||||
{
|
||||
#if defined(_TIMERS_)
|
||||
|
||||
this -> CT.globalTimer[TimerPrioQ] -> Enable();
|
||||
|
||||
#endif
|
||||
|
||||
delete[] v;
|
||||
delete[] key;
|
||||
|
||||
this -> LogEntry(LOG_MEM,"...Priority queue disallocated");
|
||||
|
||||
#if defined(_TIMERS_)
|
||||
|
||||
this -> CT.globalTimer[TimerPrioQ] -> Disable();
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
template <class TItem,class TKey>
|
||||
void basicHeap<TItem,TKey>::Insert(TItem w,TKey alpha) throw(ERRange,ERRejected)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (w>=n) NoSuchItem("Insert",w);
|
||||
|
||||
if (maxIndex>=n)
|
||||
this -> Error(ERR_REJECTED,"Insert","Buffer is full");
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(_TIMERS_)
|
||||
|
||||
this -> CT.globalTimer[TimerPrioQ] -> Enable();
|
||||
|
||||
#endif
|
||||
|
||||
TItem step = maxIndex;
|
||||
TItem j = 0;
|
||||
while (step>1)
|
||||
{
|
||||
TItem nextStep = step>>1;
|
||||
|
||||
if (key[v[j+nextStep]]>alpha)
|
||||
{
|
||||
j+=nextStep;
|
||||
step = step-nextStep;
|
||||
}
|
||||
else step = nextStep;
|
||||
}
|
||||
|
||||
if ((step>0) && (key[v[j]]>alpha)) j++;
|
||||
|
||||
memmove(v+j+1,v+j,(unsigned long)(maxIndex-j)*sizeof(TItem));
|
||||
v[j] = w;
|
||||
key[w] = alpha;
|
||||
maxIndex++;
|
||||
|
||||
#if defined(_TIMERS_)
|
||||
|
||||
this -> CT.globalTimer[TimerPrioQ] -> Disable();
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
template <class TItem,class TKey>
|
||||
void basicHeap<TItem,TKey>::Delete(TItem w) throw(ERRange,ERRejected)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (w>=n) NoSuchItem("Delete",w);
|
||||
|
||||
#endif
|
||||
|
||||
TKey alpha = key[w];
|
||||
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (alpha==InfFloat)
|
||||
{
|
||||
sprintf(this->CT.logBuffer,"Not a member: %lu",
|
||||
static_cast<unsigned long>(w));
|
||||
Error(ERR_REJECTED,"Delete",this->CT.logBuffer);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(_TIMERS_)
|
||||
|
||||
this -> CT.globalTimer[TimerPrioQ] -> Enable();
|
||||
|
||||
#endif
|
||||
|
||||
TItem step = maxIndex;
|
||||
TItem j = 0;
|
||||
|
||||
while (step>1)
|
||||
{
|
||||
TItem nextStep = step>>1;
|
||||
|
||||
if (key[v[j+nextStep]]>alpha)
|
||||
{
|
||||
j+=nextStep;
|
||||
step = step-nextStep;
|
||||
}
|
||||
else step = nextStep;
|
||||
}
|
||||
|
||||
while (v[j]!=w) j++;
|
||||
|
||||
memmove(v+j,v+j+1,(unsigned long)(maxIndex-j-1)*sizeof(TItem));
|
||||
key[w] = InfFloat;
|
||||
maxIndex--;
|
||||
|
||||
#if defined(_TIMERS_)
|
||||
|
||||
this -> CT.globalTimer[TimerPrioQ] -> Disable();
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
template <class TItem,class TKey>
|
||||
TKey basicHeap<TItem,TKey>::Key(TItem w) const throw(ERRange)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (w>=n) NoSuchItem("Key",w);
|
||||
|
||||
#endif
|
||||
|
||||
return key[w];
|
||||
}
|
||||
|
||||
|
||||
template <class TItem,class TKey>
|
||||
void basicHeap<TItem,TKey>::ChangeKey(TItem w,TKey alpha) throw(ERRange,ERRejected)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (w>=n) NoSuchItem("ChangeKey",w);
|
||||
|
||||
if (key[w]==InfFloat)
|
||||
{
|
||||
sprintf(this->CT.logBuffer,"Not a member: %lu",
|
||||
static_cast<unsigned long>(w));
|
||||
Error(ERR_REJECTED,"ChangeKey",this->CT.logBuffer);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(_TIMERS_)
|
||||
|
||||
this -> CT.globalTimer[TimerPrioQ] -> Enable();
|
||||
|
||||
#endif
|
||||
|
||||
Delete(w);
|
||||
Insert(w,alpha);
|
||||
|
||||
#if defined(_TIMERS_)
|
||||
|
||||
this -> CT.globalTimer[TimerPrioQ] -> Disable();
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
template <class TItem,class TKey>
|
||||
TItem basicHeap<TItem,TKey>::Delete() throw(ERRejected)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (Empty()) this -> Error(ERR_REJECTED,"Delete","Queue is empty");
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(_TIMERS_)
|
||||
|
||||
this -> CT.globalTimer[TimerPrioQ] -> Enable();
|
||||
|
||||
#endif
|
||||
|
||||
TItem w = v[--maxIndex];
|
||||
key[w] = InfFloat;
|
||||
|
||||
#if defined(_TIMERS_)
|
||||
|
||||
this -> CT.globalTimer[TimerPrioQ] -> Disable();
|
||||
|
||||
#endif
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
|
||||
template <class TItem,class TKey>
|
||||
TItem basicHeap<TItem,TKey>::Peek() const throw(ERRejected)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (Empty()) this -> Error(ERR_REJECTED,"Peek","Queue is empty");
|
||||
|
||||
#endif
|
||||
|
||||
return v[maxIndex-1];
|
||||
}
|
||||
|
||||
|
||||
template class basicHeap<TIndex,TFloat>;
|
||||
|
||||
#ifndef _BIG_NODES_
|
||||
|
||||
template class basicHeap<TNode,TFloat>;
|
||||
|
||||
#endif
|
||||
|
||||
// This file forms part of the GOBLIN C++ Class Library.
|
||||
//
|
||||
// Initially written by Christian Fremuth-Paeger, September 1998
|
||||
//
|
||||
// Copying, compiling, distribution and modification
|
||||
// of this source code is permitted only in accordance
|
||||
// with the GOBLIN general licence information.
|
||||
|
||||
/// \file basicHeap.cpp
|
||||
/// \brief #basicHeap class implementation
|
||||
|
||||
#include "basicHeap.h"
|
||||
|
||||
|
||||
template <class TItem,class TKey>
|
||||
basicHeap<TItem,TKey>::basicHeap(TItem nn,goblinController &thisContext)
|
||||
throw() : managedObject(thisContext)
|
||||
{
|
||||
#if defined(_TIMERS_)
|
||||
|
||||
this -> CT.globalTimer[TimerPrioQ] -> Enable();
|
||||
|
||||
#endif
|
||||
|
||||
n = nn;
|
||||
v = new TItem[n];
|
||||
key = new TKey[n];
|
||||
maxIndex = 0;
|
||||
|
||||
this -> LogEntry(LOG_MEM,"...Priority queue allocated");
|
||||
|
||||
#if defined(_TIMERS_)
|
||||
|
||||
this -> CT.globalTimer[TimerPrioQ] -> Disable();
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
template <class TItem,class TKey>
|
||||
void basicHeap<TItem,TKey>::Init() throw()
|
||||
{
|
||||
#if defined(_TIMERS_)
|
||||
|
||||
this -> CT.globalTimer[TimerPrioQ] -> Enable();
|
||||
|
||||
#endif
|
||||
|
||||
maxIndex = 0;
|
||||
|
||||
this -> LogEntry(LOG_MEM,"...Priority queue instanciated");
|
||||
|
||||
#if defined(_TIMERS_)
|
||||
|
||||
this -> CT.globalTimer[TimerPrioQ] -> Disable();
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
template <class TItem,class TKey>
|
||||
unsigned long basicHeap<TItem,TKey>::Size() const throw()
|
||||
{
|
||||
return
|
||||
sizeof(basicHeap<TItem,TKey>)
|
||||
+ managedObject::Allocated()
|
||||
+ basicHeap::Allocated();
|
||||
}
|
||||
|
||||
|
||||
template <class TItem,class TKey>
|
||||
unsigned long basicHeap<TItem,TKey>::Allocated() const throw()
|
||||
{
|
||||
return
|
||||
n*sizeof(TItem)
|
||||
+ n*sizeof(TKey);
|
||||
}
|
||||
|
||||
|
||||
template <class TItem,class TKey>
|
||||
char* basicHeap<TItem,TKey>::Display() const throw()
|
||||
{
|
||||
this -> LogEntry(MSG_TRACE,"Priority queue");
|
||||
|
||||
if (Empty()) this->LogEntry(MSG_TRACE2," ---");
|
||||
else
|
||||
{
|
||||
THandle LH = this->LogStart(MSG_TRACE2," ");
|
||||
|
||||
for (TItem i=0;i<maxIndex;i++)
|
||||
{
|
||||
sprintf(this->CT.logBuffer,"%lu[%g]",
|
||||
static_cast<unsigned long>(v[i]),key[v[i]]);
|
||||
this -> LogAppend(LH,this->CT.logBuffer);
|
||||
|
||||
if (i<maxIndex-1)
|
||||
{
|
||||
this -> LogAppend(LH,", ");
|
||||
|
||||
if (i%10==9)
|
||||
{
|
||||
this -> LogEnd(LH);
|
||||
LH = this->LogStart(MSG_TRACE2," ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this -> LogEnd(LH);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
template <class TItem,class TKey>
|
||||
basicHeap<TItem,TKey>::~basicHeap() throw()
|
||||
{
|
||||
#if defined(_TIMERS_)
|
||||
|
||||
this -> CT.globalTimer[TimerPrioQ] -> Enable();
|
||||
|
||||
#endif
|
||||
|
||||
delete[] v;
|
||||
delete[] key;
|
||||
|
||||
this -> LogEntry(LOG_MEM,"...Priority queue disallocated");
|
||||
|
||||
#if defined(_TIMERS_)
|
||||
|
||||
this -> CT.globalTimer[TimerPrioQ] -> Disable();
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
template <class TItem,class TKey>
|
||||
void basicHeap<TItem,TKey>::Insert(TItem w,TKey alpha) throw(ERRange,ERRejected)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (w>=n) NoSuchItem("Insert",w);
|
||||
|
||||
if (maxIndex>=n)
|
||||
this -> Error(ERR_REJECTED,"Insert","Buffer is full");
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(_TIMERS_)
|
||||
|
||||
this -> CT.globalTimer[TimerPrioQ] -> Enable();
|
||||
|
||||
#endif
|
||||
|
||||
TItem step = maxIndex;
|
||||
TItem j = 0;
|
||||
while (step>1)
|
||||
{
|
||||
TItem nextStep = step>>1;
|
||||
|
||||
if (key[v[j+nextStep]]>alpha)
|
||||
{
|
||||
j+=nextStep;
|
||||
step = step-nextStep;
|
||||
}
|
||||
else step = nextStep;
|
||||
}
|
||||
|
||||
if ((step>0) && (key[v[j]]>alpha)) j++;
|
||||
|
||||
memmove(v+j+1,v+j,(unsigned long)(maxIndex-j)*sizeof(TItem));
|
||||
v[j] = w;
|
||||
key[w] = alpha;
|
||||
maxIndex++;
|
||||
|
||||
#if defined(_TIMERS_)
|
||||
|
||||
this -> CT.globalTimer[TimerPrioQ] -> Disable();
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
template <class TItem,class TKey>
|
||||
void basicHeap<TItem,TKey>::Delete(TItem w) throw(ERRange,ERRejected)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (w>=n) NoSuchItem("Delete",w);
|
||||
|
||||
#endif
|
||||
|
||||
TKey alpha = key[w];
|
||||
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (alpha==InfFloat)
|
||||
{
|
||||
sprintf(this->CT.logBuffer,"Not a member: %lu",
|
||||
static_cast<unsigned long>(w));
|
||||
Error(ERR_REJECTED,"Delete",this->CT.logBuffer);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(_TIMERS_)
|
||||
|
||||
this -> CT.globalTimer[TimerPrioQ] -> Enable();
|
||||
|
||||
#endif
|
||||
|
||||
TItem step = maxIndex;
|
||||
TItem j = 0;
|
||||
|
||||
while (step>1)
|
||||
{
|
||||
TItem nextStep = step>>1;
|
||||
|
||||
if (key[v[j+nextStep]]>alpha)
|
||||
{
|
||||
j+=nextStep;
|
||||
step = step-nextStep;
|
||||
}
|
||||
else step = nextStep;
|
||||
}
|
||||
|
||||
while (v[j]!=w) j++;
|
||||
|
||||
memmove(v+j,v+j+1,(unsigned long)(maxIndex-j-1)*sizeof(TItem));
|
||||
key[w] = InfFloat;
|
||||
maxIndex--;
|
||||
|
||||
#if defined(_TIMERS_)
|
||||
|
||||
this -> CT.globalTimer[TimerPrioQ] -> Disable();
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
template <class TItem,class TKey>
|
||||
TKey basicHeap<TItem,TKey>::Key(TItem w) const throw(ERRange)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (w>=n) NoSuchItem("Key",w);
|
||||
|
||||
#endif
|
||||
|
||||
return key[w];
|
||||
}
|
||||
|
||||
|
||||
template <class TItem,class TKey>
|
||||
void basicHeap<TItem,TKey>::ChangeKey(TItem w,TKey alpha) throw(ERRange,ERRejected)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (w>=n) NoSuchItem("ChangeKey",w);
|
||||
|
||||
if (key[w]==InfFloat)
|
||||
{
|
||||
sprintf(this->CT.logBuffer,"Not a member: %lu",
|
||||
static_cast<unsigned long>(w));
|
||||
Error(ERR_REJECTED,"ChangeKey",this->CT.logBuffer);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(_TIMERS_)
|
||||
|
||||
this -> CT.globalTimer[TimerPrioQ] -> Enable();
|
||||
|
||||
#endif
|
||||
|
||||
Delete(w);
|
||||
Insert(w,alpha);
|
||||
|
||||
#if defined(_TIMERS_)
|
||||
|
||||
this -> CT.globalTimer[TimerPrioQ] -> Disable();
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
template <class TItem,class TKey>
|
||||
TItem basicHeap<TItem,TKey>::Delete() throw(ERRejected)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (Empty()) this -> Error(ERR_REJECTED,"Delete","Queue is empty");
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(_TIMERS_)
|
||||
|
||||
this -> CT.globalTimer[TimerPrioQ] -> Enable();
|
||||
|
||||
#endif
|
||||
|
||||
TItem w = v[--maxIndex];
|
||||
key[w] = InfFloat;
|
||||
|
||||
#if defined(_TIMERS_)
|
||||
|
||||
this -> CT.globalTimer[TimerPrioQ] -> Disable();
|
||||
|
||||
#endif
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
|
||||
template <class TItem,class TKey>
|
||||
TItem basicHeap<TItem,TKey>::Peek() const throw(ERRejected)
|
||||
{
|
||||
#if defined(_FAILSAVE_)
|
||||
|
||||
if (Empty()) this -> Error(ERR_REJECTED,"Peek","Queue is empty");
|
||||
|
||||
#endif
|
||||
|
||||
return v[maxIndex-1];
|
||||
}
|
||||
|
||||
|
||||
template class basicHeap<TIndex,TFloat>;
|
||||
|
||||
#ifndef _BIG_NODES_
|
||||
|
||||
template class basicHeap<TNode,TFloat>;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,114 @@
|
||||
|
||||
// This file forms part of the GOBLIN C++ Class Library.
|
||||
//
|
||||
// Initially written by Christian Fremuth-Paeger, September 1998
|
||||
//
|
||||
// Copying, compiling, distribution and modification
|
||||
// of this source code is permitted only in accordance
|
||||
// with the GOBLIN general licence information.
|
||||
|
||||
/// \file basicHeap.h
|
||||
/// \brief #basicHeap class interface
|
||||
|
||||
#ifndef _BASIC_HEAP_H_
|
||||
#define _BASIC_HEAP_H_
|
||||
|
||||
#include "goblinQueue.h"
|
||||
|
||||
|
||||
/// \addtogroup groupPriorityQueues
|
||||
/// @{
|
||||
|
||||
/// \brief Naive implementation of a priority queue
|
||||
|
||||
template <class TItem,class TKey>
|
||||
class basicHeap : public goblinQueue<TItem,TKey>
|
||||
{
|
||||
private:
|
||||
|
||||
TItem* v;
|
||||
TKey* key;
|
||||
TItem maxIndex;
|
||||
TItem n;
|
||||
|
||||
public:
|
||||
|
||||
basicHeap(TItem nn,goblinController &thisContext) throw();
|
||||
~basicHeap() throw();
|
||||
|
||||
void Init() throw();
|
||||
unsigned long Size() const throw();
|
||||
unsigned long Allocated() const throw();
|
||||
char* Display() const throw();
|
||||
|
||||
void Insert(TItem w,TKey alpha) throw(ERRange,ERRejected);
|
||||
void Delete(TItem w) throw(ERRange,ERRejected);
|
||||
TKey Key(TItem w) const throw(ERRange);
|
||||
void ChangeKey(TItem w,TKey alpha) throw(ERRange,ERRejected);
|
||||
TItem Delete() throw(ERRejected);
|
||||
TItem Peek() const throw(ERRejected);
|
||||
bool Empty() const throw() {return (maxIndex==0);};
|
||||
TItem Cardinality() const throw() {return maxIndex;};
|
||||
|
||||
};
|
||||
|
||||
/// @}
|
||||
|
||||
#endif
|
||||
|
||||
// This file forms part of the GOBLIN C++ Class Library.
|
||||
//
|
||||
// Initially written by Christian Fremuth-Paeger, September 1998
|
||||
//
|
||||
// Copying, compiling, distribution and modification
|
||||
// of this source code is permitted only in accordance
|
||||
// with the GOBLIN general licence information.
|
||||
|
||||
/// \file basicHeap.h
|
||||
/// \brief #basicHeap class interface
|
||||
|
||||
#ifndef _BASIC_HEAP_H_
|
||||
#define _BASIC_HEAP_H_
|
||||
|
||||
#include "goblinQueue.h"
|
||||
|
||||
|
||||
/// \addtogroup groupPriorityQueues
|
||||
/// @{
|
||||
|
||||
/// \brief Naive implementation of a priority queue
|
||||
|
||||
template <class TItem,class TKey>
|
||||
class basicHeap : public goblinQueue<TItem,TKey>
|
||||
{
|
||||
private:
|
||||
|
||||
TItem* v;
|
||||
TKey* key;
|
||||
TItem maxIndex;
|
||||
TItem n;
|
||||
|
||||
public:
|
||||
|
||||
basicHeap(TItem nn,goblinController &thisContext) throw();
|
||||
~basicHeap() throw();
|
||||
|
||||
void Init() throw();
|
||||
unsigned long Size() const throw();
|
||||
unsigned long Allocated() const throw();
|
||||
char* Display() const throw();
|
||||
|
||||
void Insert(TItem w,TKey alpha) throw(ERRange,ERRejected);
|
||||
void Delete(TItem w) throw(ERRange,ERRejected);
|
||||
TKey Key(TItem w) const throw(ERRange);
|
||||
void ChangeKey(TItem w,TKey alpha) throw(ERRange,ERRejected);
|
||||
TItem Delete() throw(ERRejected);
|
||||
TItem Peek() const throw(ERRejected);
|
||||
bool Empty() const throw() {return (maxIndex==0);};
|
||||
TItem Cardinality() const throw() {return maxIndex;};
|
||||
|
||||
};
|
||||
|
||||
/// @}
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,202 @@
|
||||
|
||||
// This file forms part of the GOBLIN C++ Class Library.
|
||||
//
|
||||
// Initially written by Christian Fremuth-Paeger, December 1998
|
||||
//
|
||||
// Copying, compiling, distribution and modification
|
||||
// of this source code is permitted only in accordance
|
||||
// with the GOBLIN general licence information.
|
||||
|
||||
/// \file bigraphToDigraph.h
|
||||
/// \brief #bigraphToDigraph class interface
|
||||
|
||||
#ifndef _BIGRAPH_TO_DIGRAPH_H_
|
||||
#define _BIGRAPH_TO_DIGRAPH_H_
|
||||
|
||||
#include "abstractDigraph.h"
|
||||
#include "abstractBigraph.h"
|
||||
|
||||
|
||||
/// \brief Network flow reduction of bipartite matching problems
|
||||
|
||||
class bigraphToDigraph : public abstractDiGraph
|
||||
{
|
||||
|
||||
protected:
|
||||
|
||||
abstractBiGraph &G; ///< The original graph
|
||||
|
||||
TNode n0; ///< Number of nodes in the original network
|
||||
TNode n1; ///< Number of outer nodes in the original network
|
||||
TNode n2; ///< Number of inner nodes in the original network
|
||||
TArc m0; ///< Number of arcs in the original network
|
||||
|
||||
TNode s1; ///< Source node, s1 == DefaultSourceNode()
|
||||
TNode t1; ///< Target node, t1 == DefaultTargetNode()
|
||||
TNode s2; ///< Additional source node
|
||||
TNode t2; ///< Additional target node
|
||||
TArc ret1; ///< Return arc with end nodes t1 and s1
|
||||
TArc ret2; ///< Return arc with end nodes t2 and s2
|
||||
TArc art1; ///< Artifical arc with end nodes s1 and t2
|
||||
TArc art2; ///< Artifical arc with end nodes s2 and t1
|
||||
|
||||
TFloat* dgl; ///< Array of node degrees in the original graph
|
||||
TCap ccap; ///< Node capacity constant
|
||||
TCap* cap; ///< Array of (upper-lower) node capacities
|
||||
TCap* lower; ///< Array of lower node capacities
|
||||
|
||||
TCap sumLower1; ///< sum of lower degree bounds on the outer nodes
|
||||
TCap sumLower2; ///< sum of lower degree bounds on the inner nodes
|
||||
TCap sumUpper; ///< sum of upper degree bounds
|
||||
|
||||
TFloat minLength; ///< Minimum edge length of the original graph
|
||||
|
||||
public:
|
||||
|
||||
bigraphToDigraph(abstractBiGraph &GC,TCap *pLower,TCap *pCap = NULL) throw();
|
||||
bigraphToDigraph(abstractBiGraph &GC,TCap cCap) throw();
|
||||
bigraphToDigraph(abstractBiGraph &GC) throw();
|
||||
~bigraphToDigraph() throw();
|
||||
|
||||
void Init() throw();
|
||||
void SetDegrees() throw();
|
||||
unsigned long Size() const throw();
|
||||
unsigned long Allocated() const throw();
|
||||
|
||||
bool Perfect() const throw();
|
||||
|
||||
TNode DefaultSourceNode() const throw() {return s1;};
|
||||
TNode DefaultTargetNode() const throw() {return t1;};
|
||||
|
||||
TNode StartNode(TArc a) const throw(ERRange);
|
||||
TNode EndNode(TArc a) const throw(ERRange);
|
||||
|
||||
TArc First(TNode v) const throw(ERRange);
|
||||
TArc Right(TArc a,TNode v) const throw(ERRange);
|
||||
|
||||
TCap Demand(TNode v) const throw(ERRange);
|
||||
bool CDemand() const throw() {return false;};
|
||||
TCap LCap(TArc a) const throw() {return 0;};
|
||||
bool CLCap() const throw() {return true;};
|
||||
TCap UCap(TArc a) const throw(ERRange);
|
||||
bool CUCap() const throw() {return false;};
|
||||
TFloat Length(TArc a) const throw(ERRange);
|
||||
bool CLength() const throw()
|
||||
{return G.CLength() & (G.MaxLength()==0);};
|
||||
bool Blocking(TArc a) const throw() {return a&1;};
|
||||
|
||||
TFloat C(TNode v,TDim i) const throw(ERRange);
|
||||
TFloat CMax(TDim i) const throw(ERRange);
|
||||
TDim Dim() const throw() {return G.Dim();};
|
||||
bool HiddenNode(TNode v) const throw(ERRange);
|
||||
|
||||
TFloat Flow(TArc a) const throw(ERRange);
|
||||
void Push(TArc a,TFloat lambda) throw(ERRange,ERRejected);
|
||||
|
||||
TFloat Sub(TArc a) const throw(ERRange) {return Flow(a);};
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
// This file forms part of the GOBLIN C++ Class Library.
|
||||
//
|
||||
// Initially written by Christian Fremuth-Paeger, December 1998
|
||||
//
|
||||
// Copying, compiling, distribution and modification
|
||||
// of this source code is permitted only in accordance
|
||||
// with the GOBLIN general licence information.
|
||||
|
||||
/// \file bigraphToDigraph.h
|
||||
/// \brief #bigraphToDigraph class interface
|
||||
|
||||
#ifndef _BIGRAPH_TO_DIGRAPH_H_
|
||||
#define _BIGRAPH_TO_DIGRAPH_H_
|
||||
|
||||
#include "abstractDigraph.h"
|
||||
#include "abstractBigraph.h"
|
||||
|
||||
|
||||
/// \brief Network flow reduction of bipartite matching problems
|
||||
|
||||
class bigraphToDigraph : public abstractDiGraph
|
||||
{
|
||||
|
||||
protected:
|
||||
|
||||
abstractBiGraph &G; ///< The original graph
|
||||
|
||||
TNode n0; ///< Number of nodes in the original network
|
||||
TNode n1; ///< Number of outer nodes in the original network
|
||||
TNode n2; ///< Number of inner nodes in the original network
|
||||
TArc m0; ///< Number of arcs in the original network
|
||||
|
||||
TNode s1; ///< Source node, s1 == DefaultSourceNode()
|
||||
TNode t1; ///< Target node, t1 == DefaultTargetNode()
|
||||
TNode s2; ///< Additional source node
|
||||
TNode t2; ///< Additional target node
|
||||
TArc ret1; ///< Return arc with end nodes t1 and s1
|
||||
TArc ret2; ///< Return arc with end nodes t2 and s2
|
||||
TArc art1; ///< Artifical arc with end nodes s1 and t2
|
||||
TArc art2; ///< Artifical arc with end nodes s2 and t1
|
||||
|
||||
TFloat* dgl; ///< Array of node degrees in the original graph
|
||||
TCap ccap; ///< Node capacity constant
|
||||
TCap* cap; ///< Array of (upper-lower) node capacities
|
||||
TCap* lower; ///< Array of lower node capacities
|
||||
|
||||
TCap sumLower1; ///< sum of lower degree bounds on the outer nodes
|
||||
TCap sumLower2; ///< sum of lower degree bounds on the inner nodes
|
||||
TCap sumUpper; ///< sum of upper degree bounds
|
||||
|
||||
TFloat minLength; ///< Minimum edge length of the original graph
|
||||
|
||||
public:
|
||||
|
||||
bigraphToDigraph(abstractBiGraph &GC,TCap *pLower,TCap *pCap = NULL) throw();
|
||||
bigraphToDigraph(abstractBiGraph &GC,TCap cCap) throw();
|
||||
bigraphToDigraph(abstractBiGraph &GC) throw();
|
||||
~bigraphToDigraph() throw();
|
||||
|
||||
void Init() throw();
|
||||
void SetDegrees() throw();
|
||||
unsigned long Size() const throw();
|
||||
unsigned long Allocated() const throw();
|
||||
|
||||
bool Perfect() const throw();
|
||||
|
||||
TNode DefaultSourceNode() const throw() {return s1;};
|
||||
TNode DefaultTargetNode() const throw() {return t1;};
|
||||
|
||||
TNode StartNode(TArc a) const throw(ERRange);
|
||||
TNode EndNode(TArc a) const throw(ERRange);
|
||||
|
||||
TArc First(TNode v) const throw(ERRange);
|
||||
TArc Right(TArc a,TNode v) const throw(ERRange);
|
||||
|
||||
TCap Demand(TNode v) const throw(ERRange);
|
||||
bool CDemand() const throw() {return false;};
|
||||
TCap LCap(TArc a) const throw() {return 0;};
|
||||
bool CLCap() const throw() {return true;};
|
||||
TCap UCap(TArc a) const throw(ERRange);
|
||||
bool CUCap() const throw() {return false;};
|
||||
TFloat Length(TArc a) const throw(ERRange);
|
||||
bool CLength() const throw()
|
||||
{return G.CLength() & (G.MaxLength()==0);};
|
||||
bool Blocking(TArc a) const throw() {return a&1;};
|
||||
|
||||
TFloat C(TNode v,TDim i) const throw(ERRange);
|
||||
TFloat CMax(TDim i) const throw(ERRange);
|
||||
TDim Dim() const throw() {return G.Dim();};
|
||||
bool HiddenNode(TNode v) const throw(ERRange);
|
||||
|
||||
TFloat Flow(TArc a) const throw(ERRange);
|
||||
void Push(TArc a,TFloat lambda) throw(ERRange,ERRejected);
|
||||
|
||||
TFloat Sub(TArc a) const throw(ERRange) {return Flow(a);};
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user