diff options
author | Pasha <pasha@member.fsf.org> | 2023-01-27 00:54:07 +0000 |
---|---|---|
committer | Pasha <pasha@member.fsf.org> | 2023-01-27 00:54:07 +0000 |
commit | ef800d4ffafdbde7d7a172ad73bd984b1695c138 (patch) | |
tree | 920cc189130f1e98f252283fce94851443641a6d /glpk-5.0/examples | |
parent | ec4ae3c2b5cb0e83fb667f14f832ea94f68ef075 (diff) | |
download | oneapi-ef800d4ffafdbde7d7a172ad73bd984b1695c138.tar.gz oneapi-ef800d4ffafdbde7d7a172ad73bd984b1695c138.tar.bz2 |
Diffstat (limited to 'glpk-5.0/examples')
165 files changed, 30350 insertions, 0 deletions
diff --git a/glpk-5.0/examples/INDEX b/glpk-5.0/examples/INDEX new file mode 100644 index 0000000..6b51bf2 --- /dev/null +++ b/glpk-5.0/examples/INDEX @@ -0,0 +1,69 @@ +alloy.mps Aluminium alloy blending +assign.mod Assignment problem +bpp.mod Bin packing problem +cal.mod Print an ASCII calendar of the given year +cf12a.mod Curve fitting problem +cf12b.mod Curve fitting problem +cflsq.mod Curve fitting problem by least squares +color.mod Graph coloring problem +cpp.mod Critical path problem +crypto.mod A crypto-arithmetic puzzle +dea.mod Data envelopment analysis (DEA) +diet.mod Stigler's nutrition model +dist.mod A product distribution model +egypt.mod A static model for fertilizer production +fctp.mod Fixed-charge transportation problem +food.mod Food manufacture model +food2.mod Food manufacture model +furnace.mps Electric-arc furnace steelmaking +gap.mod Generalized assignment problem +graceful.mod Graceful Tree Labeling Problem +graph.mod Graph visualization +hashi.mod A solver for the Japanese number-puzzle Hashiwokakero +huge.mod Arithmetic mean of a large number of integers +icecream.mps Ice cream blending +jssp.mod Job-shop scheduling problem +life_goe.mod Conway's Game of Life garden of eden checker +magic.mod Magic square +maxcut.mod Maximum cut problem +maxflow.mod Maximum flow problem +mfasp.mod Minimum feedback arc set problem +mfvsp.mod Minimum feedback vertex set problem +min01ks.mod Finding minimal equivalent 0-1 knapsack inequality +misp.mod Maximum independent set problem +money.mod A crypto-arithmetic puzzle +murtagh.mps Oil refinery model +mvcp.mod Minimum vertex cover problem +numbrix.mod Number placement puzzle +pbn/*.* Paint-by-numbers puzzle +pentomino.mod A geometric placement puzzle +plan.lp A simple LP problem (CPLEX LP format) +plan.mod A simple LP problem (MathProg format) +plan.mps A simple LP problem (MPS format) +planarity.mod Graph planarity testing +powpl25h.mod Power plant LP scheduler (25hrs for daylightsavings) +powplant.mod Power plant LP scheduler +prod.mod A multiperiod production model +qfit.mod Quadratic curve fitting solution +queens.mod A classic combinatorial optimization problem +sat.mod Satisfiability problem +shiftcov.mod Workforce shift coverage assignment problem +shikaku.mod A solver for the logic puzzle Shikaku +sorting.mod How to sort arrays in MathProg +spp.mod Shortest path problem +stigler.mod Original Stigler's 1939 diet problem +sudoku.mod Number placement puzzle +tas.mod Tail assignment problem +tiling.mod Rectifiable polyomino tilings generator +todd.mod A class of hard instances of 0-1 knapsack problems +toto.mod Covering code generator, especially for football pool + systems +train.mod A model of railroad passenger car allocation +transp.mod A transportation problem +trick.mod A transportation design problem +tsp.mod Traveling salesman problem +wolfra6d.lp Neumann CA grid emulator generator +wolfra6d.mod Neumann CA grid emulator generator +xyacfs.mod Extended yet another curve fitting solution +yacfs.mod Yet another curve fitting solution +zebra.mod Who owns the zebra? diff --git a/glpk-5.0/examples/Makefile.am b/glpk-5.0/examples/Makefile.am new file mode 100644 index 0000000..7fff136 --- /dev/null +++ b/glpk-5.0/examples/Makefile.am @@ -0,0 +1,15 @@ +## Process this file with automake to produce Makefile.in ## + +AM_CPPFLAGS = -I$(srcdir)/../src + +LDADD = ../src/libglpk.la + +bin_PROGRAMS = glpsol + +glpsol_SOURCES = glpsol.c + +check: glpsol$(EXEEXT) + ./glpsol$(EXEEXT) --version + ./glpsol$(EXEEXT) --mps $(srcdir)/murtagh.mps --max + +## eof ## diff --git a/glpk-5.0/examples/Makefile.in b/glpk-5.0/examples/Makefile.in new file mode 100644 index 0000000..efbf3d7 --- /dev/null +++ b/glpk-5.0/examples/Makefile.in @@ -0,0 +1,559 @@ +# Makefile.in generated by automake 1.12.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2012 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__make_dryrun = \ + { \ + am__dry=no; \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ + | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ + *) \ + for am__flg in $$MAKEFLAGS; do \ + case $$am__flg in \ + *=*|--*) ;; \ + *n*) am__dry=yes; break;; \ + esac; \ + done;; \ + esac; \ + test $$am__dry = yes; \ + } +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +bin_PROGRAMS = glpsol$(EXEEXT) +subdir = examples +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(top_srcdir)/depcomp +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__installdirs = "$(DESTDIR)$(bindir)" +PROGRAMS = $(bin_PROGRAMS) +am_glpsol_OBJECTS = glpsol.$(OBJEXT) +glpsol_OBJECTS = $(am_glpsol_OBJECTS) +glpsol_LDADD = $(LDADD) +glpsol_DEPENDENCIES = ../src/libglpk.la +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(glpsol_SOURCES) +DIST_SOURCES = $(glpsol_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NOUNDEFINED = @NOUNDEFINED@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AM_CPPFLAGS = -I$(srcdir)/../src +LDADD = ../src/libglpk.la +glpsol_SOURCES = glpsol.c +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu examples/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu examples/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p || test -f $$p1; \ + then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +glpsol$(EXEEXT): $(glpsol_OBJECTS) $(glpsol_DEPENDENCIES) $(EXTRA_glpsol_DEPENDENCIES) + @rm -f glpsol$(EXEEXT) + $(LINK) $(glpsol_OBJECTS) $(glpsol_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glpsol.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +cscopelist: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) +installdirs: + for dir in "$(DESTDIR)$(bindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-binPROGRAMS + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ + clean-generic clean-libtool cscopelist ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-binPROGRAMS install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-binPROGRAMS + + +check: glpsol$(EXEEXT) + ./glpsol$(EXEEXT) --version + ./glpsol$(EXEEXT) --mps $(srcdir)/murtagh.mps --max + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/glpk-5.0/examples/alloy.mps b/glpk-5.0/examples/alloy.mps new file mode 100644 index 0000000..9f774f1 --- /dev/null +++ b/glpk-5.0/examples/alloy.mps @@ -0,0 +1,282 @@ +*NAME: ALLOY +*ROWS: 22 +*COLUMNS: 20 +*NONZERO: 203 +*OPT SOLN: 2149.247891 +*SOURCE: Linear Programming--Aluminium Alloy Blending +* Data Processing Application. N.Y.: IBM Corp. +*APPLICATION: Aluminium Alloy Blending +*COMMENTS: fixed MPS format +* encoded by Andrew Makhorin <mao@gnu.org> +* +NAME ALLOY +ROWS + N COST $ Cost $ + G ZN $ Zinc Minimum lbs + L ZX $ Zinc Maximum lbs + G CN $ Copper Minimum lbs + L CX $ Copper Maximum lbs + G MN $ Magnesium Minimum lbs + L MX $ Magnesium Maximum lbs + G CHN $ Chromium Minimum lbs + L CHX $ Chromium Maximum lbs + G BN $ Beryllium Minimum lbs + L BX $ Beryllium Maximum lbs + L IX $ Iron Maximum lbs + L SX $ Silicon Maximum lbs + L MGX $ Manganese Maximum lbs + L NX $ Nickel Maximum lbs + L TX $ Titanium Maximum lbs + L LX $ Lead Maximum lbs + L TNX $ Tin Maximum lbs + L BIX $ Bismuth Maximum lbs + L GX $ General Impurities lbs + L SCX $ Scrap 1 Limit lbs + G FL $ Furnance Load lbs +COLUMNS +* Pure Aluminium 1 + A1 COST .28 + IX .0004 + SX .0005 + FL 1.0 +* Pure Aluminium 2 + A2 COST .26 + IX .0006 + SX .0006 + FL 1.0 +* Pure Aluminium 3 + A3 COST .25 + IX .0011 + SX .0007 + FL 1.0 +* Pure Aluminium 4 + A4 COST .23 + IX .0026 + SX .0012 + FL 1.0 +* Pure Copper + C COST .31 + CN 1.00 + CX 1.00 + FL 1.0 +* Pure Magnesium + M COST .38 + MN 1.00 + MX 1.00 + FL 1.0 +* Beryllium/Aluminium Alloy + B/A COST 3.60 + BN 0.0600 + BX 0.0600 + FL 1.0 +* Pure Zinc + Z COST .22 + ZN .95 + ZX .95 + FL 1.0 +* Chromium Aluminium Alloy + C/A COST .27 + CHN .0300 + CHX .0300 + FL 1.0 +* Scrap 1 + SC1 COST .21 + ZN .0009 + ZX .0009 + CN .0444 + CX .0444 + MN .0042 + MX .0042 + CHN .0001 + CHX .0001 + IX .0024 + SX .0101 + MGX .0079 + NX .0001 + TX .0004 + LX .0001 + TNX .0001 + GX .0001 + SCX 1.00 + FL 1.0 +* Scrap 2 + SC2 COST .20 + ZN .0012 + ZX .0012 + CN .0026 + CX .0026 + MN .0060 + MX .0060 + CHN .0018 + CHX .0018 + IX .0026 + SX .0106 + MGX .0003 + NX .0002 + TX .0004 + LX .0001 + TNX .0001 + GX .0002 + FL 1.0 +* Scrap 3 + SC3 COST .21 + ZN .0568 + ZX .0568 + CN .0152 + CX .0152 + MN .0248 + MX .0248 + CHN .0020 + CHX .0020 + IX .0016 + SX .0013 + MGX .0005 + TX .0004 + LX .0003 + TNX .0003 + FL 1.0 +* Scrap 4 + SC4 COST .20 + ZN .0563 + ZX .0563 + CN .0149 + CX .0149 + MN .0238 + MX .0238 + CHN .0019 + CHX .0019 + IX .0019 + SX .0011 + MGX .0004 + TX .0004 + LX .0003 + TNX .0003 + FL 1.0 +* Scrap 5 + SC5 COST .21 + ZN .0460 + ZX .0460 + CN .0071 + CX .0071 + MN .0343 + MX .0343 + CHN .0013 + CHX .0013 + IX .0017 + SX .0013 + MGX .0018 + TX .0002 + LX .0002 + TNX .0002 + FL 1.0 +* Scrap 6 + SC6 COST .20 + ZN .0455 + ZX .0455 + CN .0071 + CX .0071 + MN .0343 + MX .0343 + IX .0016 + SX .0011 + MGX .0017 + TX .0002 + LX .0002 + TNX .0002 + FL 1.0 +* Scrap 7 + SC7 COST .21 + ZN .0009 + ZX .0009 + CN .0447 + CX .0447 + MN .0143 + MX .0143 + IX .0026 + SX .0013 + MGX .0052 + TX .0003 + LX .0001 + TNX .0001 + FL 1.0 +* Scrap 8 + SC8 COST .20 + ZN .0006 + ZX .0006 + CN .0623 + CX .0623 + IX .0017 + SX .0010 + MGX .0025 + TX .0005 + LX .0001 + TNX .0001 + GX .0025 + FL 1.0 +* Scrap 9 + SC9 COST .21 + ZN .0009 + ZX .0009 + CN .0034 + CX .0034 + MN .0093 + MX .0093 + CHN .0019 + CHX .0019 + IX .0030 + SX .0062 + MGX .0002 + TX .0003 + BIX .0005 + FL 1.0 +* Scrap 10 + SC10 COST .20 + ZN .0008 + ZX .0008 + CN .0003 + CX .0003 + MN .0249 + MX .0249 + CHN .0016 + CHX .0016 + IX .0015 + SX .0011 + MGX .0002 + FL 1.0 +* Scrap 11 + SC11 COST .21 + ZN .0675 + ZX .0675 + CN .0195 + CX .0195 + MN .0265 + MX .0265 + CHN .0020 + CHX .0020 + IX .0014 + SX .0008 + MGX .0002 + FL 1.0 +RHS + ZN 555. + ZX 590. + CN 140.0 + CX 190.0 + MN 245.0 + MX 275.0 + CHN 19.0 + CHX 22.0 + BN 2.0 + BX 4.0 + IX 15.0 + SX 10.0 + MGX 3.0 + NX 2.0 + TX 2.0 + LX 2.0 + TNX 2.0 + BIX 8.0 + GX 8.0 + SCX 900.0 + FL 10000. +ENDATA diff --git a/glpk-5.0/examples/assign.mod b/glpk-5.0/examples/assign.mod new file mode 100644 index 0000000..6f700bb --- /dev/null +++ b/glpk-5.0/examples/assign.mod @@ -0,0 +1,77 @@ +/* ASSIGN, Assignment Problem */ + +/* Written in GNU MathProg by Andrew Makhorin <mao@gnu.org> */ + +/* The assignment problem is one of the fundamental combinatorial + optimization problems. + + In its most general form, the problem is as follows: + + There are a number of agents and a number of tasks. Any agent can be + assigned to perform any task, incurring some cost that may vary + depending on the agent-task assignment. It is required to perform all + tasks by assigning exactly one agent to each task in such a way that + the total cost of the assignment is minimized. + + (From Wikipedia, the free encyclopedia.) */ + +param m, integer, > 0; +/* number of agents */ + +param n, integer, > 0; +/* number of tasks */ + +set I := 1..m; +/* set of agents */ + +set J := 1..n; +/* set of tasks */ + +param c{i in I, j in J}, >= 0; +/* cost of allocating task j to agent i */ + +var x{i in I, j in J}, >= 0; +/* x[i,j] = 1 means task j is assigned to agent i + note that variables x[i,j] are binary, however, there is no need to + declare them so due to the totally unimodular constraint matrix */ + +s.t. phi{i in I}: sum{j in J} x[i,j] <= 1; +/* each agent can perform at most one task */ + +s.t. psi{j in J}: sum{i in I} x[i,j] = 1; +/* each task must be assigned exactly to one agent */ + +minimize obj: sum{i in I, j in J} c[i,j] * x[i,j]; +/* the objective is to find a cheapest assignment */ + +solve; + +printf "\n"; +printf "Agent Task Cost\n"; +printf{i in I} "%5d %5d %10g\n", i, sum{j in J} j * x[i,j], + sum{j in J} c[i,j] * x[i,j]; +printf "----------------------\n"; +printf " Total: %10g\n", sum{i in I, j in J} c[i,j] * x[i,j]; +printf "\n"; + +data; + +/* These data correspond to an example from [Christofides]. */ + +/* Optimal solution is 76 */ + +param m := 8; + +param n := 8; + +param c : 1 2 3 4 5 6 7 8 := + 1 13 21 20 12 8 26 22 11 + 2 12 36 25 41 40 11 4 8 + 3 35 32 13 36 26 21 13 37 + 4 34 54 7 8 12 22 11 40 + 5 21 6 45 18 24 34 12 48 + 6 42 19 39 15 14 16 28 46 + 7 16 34 38 3 34 40 22 24 + 8 26 20 5 17 45 31 37 43 ; + +end; diff --git a/glpk-5.0/examples/bpp.mod b/glpk-5.0/examples/bpp.mod new file mode 100644 index 0000000..8dd354e --- /dev/null +++ b/glpk-5.0/examples/bpp.mod @@ -0,0 +1,83 @@ +/* BPP, Bin Packing Problem */ + +/* Written in GNU MathProg by Andrew Makhorin <mao@gnu.org> */ + +/* Given a set of items I = {1,...,m} with weight w[i] > 0, the Bin + Packing Problem (BPP) is to pack the items into bins of capacity c + in such a way that the number of bins used is minimal. */ + +param m, integer, > 0; +/* number of items */ + +set I := 1..m; +/* set of items */ + +param w{i in 1..m}, > 0; +/* w[i] is weight of item i */ + +param c, > 0; +/* bin capacity */ + +/* We need to estimate an upper bound of the number of bins sufficient + to contain all items. The number of items m can be used, however, it + is not a good idea. To obtain a more suitable estimation an easy + heuristic is used: we put items into a bin while it is possible, and + if the bin is full, we use another bin. The number of bins used in + this way gives us a more appropriate estimation. */ + +param z{i in I, j in 1..m} := +/* z[i,j] = 1 if item i is in bin j, otherwise z[i,j] = 0 */ + + if i = 1 and j = 1 then 1 + /* put item 1 into bin 1 */ + + else if exists{jj in 1..j-1} z[i,jj] then 0 + /* if item i is already in some bin, do not put it into bin j */ + + else if sum{ii in 1..i-1} w[ii] * z[ii,j] + w[i] > c then 0 + /* if item i does not fit into bin j, do not put it into bin j */ + + else 1; + /* otherwise put item i into bin j */ + +check{i in I}: sum{j in 1..m} z[i,j] = 1; +/* each item must be exactly in one bin */ + +check{j in 1..m}: sum{i in I} w[i] * z[i,j] <= c; +/* no bin must be overflowed */ + +param n := sum{j in 1..m} if exists{i in I} z[i,j] then 1; +/* determine the number of bins used by the heuristic; obviously it is + an upper bound of the optimal solution */ + +display n; + +set J := 1..n; +/* set of bins */ + +var x{i in I, j in J}, binary; +/* x[i,j] = 1 means item i is in bin j */ + +var used{j in J}, binary; +/* used[j] = 1 means bin j contains at least one item */ + +s.t. one{i in I}: sum{j in J} x[i,j] = 1; +/* each item must be exactly in one bin */ + +s.t. lim{j in J}: sum{i in I} w[i] * x[i,j] <= c * used[j]; +/* if bin j is used, it must not be overflowed */ + +minimize obj: sum{j in J} used[j]; +/* objective is to minimize the number of bins used */ + +data; + +/* The optimal solution is 3 bins */ + +param m := 6; + +param w := 1 50, 2 60, 3 30, 4 70, 5 50, 6 40; + +param c := 100; + +end; diff --git a/glpk-5.0/examples/cal.mod b/glpk-5.0/examples/cal.mod new file mode 100644 index 0000000..2555182 --- /dev/null +++ b/glpk-5.0/examples/cal.mod @@ -0,0 +1,49 @@ +/* cal.mod - print an ASCII calendar of the given year */ + +/* Written in GNU MathProg by Andrew Makhorin <mao@gnu.org> */ + +param year, integer, >= 0001, <= 3999, default 2010; + +param first_day{m in 1..12}, integer, >= 0, <= 6, := + time2str(str2time(year & "-" & m & "-01", "%Y-%m-%d"), "%w"); + +param days_in_month{m in 1..12}, integer, >= 28, <= 31, := + (str2time(year + (if m < 12 then 0 else 1) & "-" & + (if m < 12 then m+1 else 1) & "-01", "%Y-%m-%d") - + str2time(year & "-" & m & "-01", "%Y-%m-%d")) / 86400; + +param foo{m in 1..12, k in 0..5, d in 0..6}, integer, := + 7 * k + d + 1 - first_day[m]; + +param cal{m in 1..12, k in 0..5, d in 0..6}, integer, := + if 1 <= foo[m,k,d] and foo[m,k,d] <= days_in_month[m] then + foo[m,k,d]; + +printf "\n"; +printf "%33s%04d\n", "", year; +printf "\n"; +for {t in 1..12 by 3} +{ for {m in t..t+2} + { printf "%7s%-14s", "", time2str(str2time(m, "%m"), "%B"); + printf{0..0: m < t+2} " "; + } + printf "\n"; + for {m in t..t+2} + { printf " S M Tu W Th F S"; + printf{0..0: m < t+2} " "; + } + printf "\n"; + for {k in 0..5} + { for {m in t..t+2} + { for {d in 0..6} + { printf{0..0: cal[m,k,d] = 0} " "; + printf{0..0: cal[m,k,d] != 0} " %2d", cal[m,k,d]; + } + printf{0..0: m < t+2} " "; + } + printf "\n"; + } +} +printf "\n"; + +end; diff --git a/glpk-5.0/examples/cf12a.mod b/glpk-5.0/examples/cf12a.mod new file mode 100644 index 0000000..61a76c0 --- /dev/null +++ b/glpk-5.0/examples/cf12a.mod @@ -0,0 +1,81 @@ +/* + + Curve fitting problem 12.11(a) H P Williams "Model Building in Mathematical Programming" + + Dr. H J Mackenzie + HARD software + hjm@hardsoftware.com + + 2006-01-05 + + */ + +# set of points + +set I; + +# independent variable + +param x {i in I}; + +# dependent variable + +param y {i in I}; + +# output input values + +printf {i in I} "x = %.1f; y = %.1f\n", x[i], y[i]; + +# define equation variables + +var a; + +var b; + +var u {i in I}, >= 0; + +var v {i in I}, >= 0; + +# define objective function + +minimize error: sum {i in I} u[i] + sum {i in I} v[i]; + +# define equation constraint + +s.t. equation {i in I} : b * x[i] + a + u[i] - v[i] = y[i]; + +solve; + +printf "y = %.4fx + %.4f\n", b, a; + +/* + * + * DATA section + * + */ + +data; + +param : I : x y := + 1 0 1 + 2 0.5 0.9 + 3 1 0.7 + 4 1.5 1.5 + 5 1.9 2 + 6 2.5 2.4 + 7 3 3.2 + 8 3.5 2 + 9 4 2.7 + 10 4.5 3.5 + 11 5 1 + 12 5.5 4 + 13 6 3.6 + 14 6.6 2.7 + 15 7 5.7 + 16 7.6 4.6 + 17 8.5 6 + 18 9 6.8 + 19 10 7.3 +; + +end; diff --git a/glpk-5.0/examples/cf12b.mod b/glpk-5.0/examples/cf12b.mod new file mode 100644 index 0000000..56f1ba1 --- /dev/null +++ b/glpk-5.0/examples/cf12b.mod @@ -0,0 +1,88 @@ +/* + + Curve fitting problem 12.11(b) H P Williams "Model Building in Mathematical Programming" + + Dr. H J Mackenzie + HARD software + hjm@hardsoftware.com + + 2006-01-23 + + */ + +# set of points + +set I; + +# independent variable + +param x {i in I}; + +# dependent variable + +param y {i in I}; + +# output input values + +printf {i in I} "x = %.1f; y = %.1f\n", x[i], y[i]; + +# define equation variables + +var a; + +var b; + +var u {i in I}, >= 0; + +var v {i in I}, >= 0; + +var z; + +# define objective function + +minimize deviation: z; + +# define equation constraint + +s.t. equation {i in I} : b * x[i] + a + u[i] - v[i] = y[i]; + +# define deviation constrains + +s.t. u_deviation {i in I} : z - u[i] >= 0; +s.t. v_deviation {i in I} : z - v[i] >= 0; + +solve; + +printf "y = %.4fx + %.4f Max deviation = %.4f\n", b, a, z; + +/* + * + * DATA section + * + */ + +data; + +param : I : x y := + 1 0 1 + 2 0.5 0.9 + 3 1 0.7 + 4 1.5 1.5 + 5 1.9 2 + 6 2.5 2.4 + 7 3 3.2 + 8 3.5 2 + 9 4 2.7 + 10 4.5 3.5 + 11 5 1 + 12 5.5 4 + 13 6 3.6 + 14 6.6 2.7 + 15 7 5.7 + 16 7.6 4.6 + 17 8.5 6 + 18 9 6.8 + 19 10 7.3 +; + +end; diff --git a/glpk-5.0/examples/cflsq.mod b/glpk-5.0/examples/cflsq.mod new file mode 100644 index 0000000..4af4d02 --- /dev/null +++ b/glpk-5.0/examples/cflsq.mod @@ -0,0 +1,51 @@ +/*Curve fitting problem by Least Squares + Nigel_Galloway@operamail.com + October 1st., 2007 +*/ +set Sample; +param Sx {z in Sample}; +param Sy {z in Sample}; + +var X; +var Y; +var Ex{z in Sample}; +var Ey{z in Sample}; + +/* sum of variances is zero for Sx*/ +variencesX{z in Sample}: X + Ex[z] = Sx[z]; +zumVariancesX: sum{z in Sample} Ex[z] = 0; +/* sum of variances is zero for Sy*/ +variencesY{z in Sample}: Y + Ey[z] = Sy[z]; +zumVariancesY: sum{z in Sample} Ey[z] = 0; + +solve; + +param b1 := (sum{z in Sample} Ex[z]*Ey[z])/(sum{z in Sample} Ex[z]*Ex[z]); +printf "\nbest linear fit is:\n\ty = %f %s %fx\n\n", Y-b1*X, if b1 < 0 then "-" else "+", abs(b1); + +data; + +param: +Sample: Sx Sy := + 1 0 1 + 2 0.5 0.9 + 3 1 0.7 + 4 1.5 1.5 + 5 1.9 2 + 6 2.5 2.4 + 7 3 3.2 + 8 3.5 2 + 9 4 2.7 + 10 4.5 3.5 + 11 5 1 + 12 5.5 4 + 13 6 3.6 + 14 6.6 2.7 + 15 7 5.7 + 16 7.6 4.6 + 17 8.5 6 + 18 9 6.8 + 19 10 7.3 +; + +end; diff --git a/glpk-5.0/examples/color.mod b/glpk-5.0/examples/color.mod new file mode 100644 index 0000000..9a279c3 --- /dev/null +++ b/glpk-5.0/examples/color.mod @@ -0,0 +1,113 @@ +/* COLOR, Graph Coloring Problem */ + +/* Written in GNU MathProg by Andrew Makhorin <mao@gnu.org> */ + +/* Given an undirected loopless graph G = (V, E), where V is a set of + nodes, E <= V x V is a set of arcs, the Graph Coloring Problem is to + find a mapping (coloring) F: V -> C, where C = {1, 2, ... } is a set + of colors whose cardinality is as small as possible, such that + F(i) != F(j) for every arc (i,j) in E, that is adjacent nodes must + be assigned different colors. */ + +param n, integer, >= 2; +/* number of nodes */ + +set V := {1..n}; +/* set of nodes */ + +set E, within V cross V; +/* set of arcs */ + +check{(i,j) in E}: i != j; +/* there must be no loops */ + +/* We need to estimate an upper bound of the number of colors |C|. + The number of nodes |V| can be used, however, for sparse graphs such + bound is not very good. To obtain a more suitable estimation we use + an easy "greedy" heuristic. Let nodes 1, ..., i-1 are already + assigned some colors. To assign a color to node i we see if there is + an existing color not used for coloring nodes adjacent to node i. If + so, we use this color, otherwise we introduce a new color. */ + +set EE := setof{(i,j) in E} (i,j) union setof{(i,j) in E} (j,i); +/* symmetrisized set of arcs */ + +param z{i in V, case in 0..1} := +/* z[i,0] = color index assigned to node i + z[i,1] = maximal color index used for nodes 1, 2, ..., i-1 which are + adjacent to node i */ +( if case = 0 then + ( /* compute z[i,0] */ + min{c in 1..z[i,1]} + ( if not exists{j in V: j < i and (i,j) in EE} z[j,0] = c then + c + else + z[i,1] + 1 + ) + ) + else + ( /* compute z[i,1] */ + if not exists{j in V: j < i} (i,j) in EE then + 1 + else + max{j in V: j < i and (i,j) in EE} z[j,0] + ) +); + +check{(i,j) in E}: z[i,0] != z[j,0]; +/* check that all adjacent nodes are assigned distinct colors */ + +param nc := max{i in V} z[i,0]; +/* number of colors used by the heuristic; obviously, it is an upper + bound of the optimal solution */ + +display nc; + +var x{i in V, c in 1..nc}, binary; +/* x[i,c] = 1 means that node i is assigned color c */ + +var u{c in 1..nc}, binary; +/* u[c] = 1 means that color c is used, i.e. assigned to some node */ + +s.t. map{i in V}: sum{c in 1..nc} x[i,c] = 1; +/* each node must be assigned exactly one color */ + +s.t. arc{(i,j) in E, c in 1..nc}: x[i,c] + x[j,c] <= u[c]; +/* adjacent nodes cannot be assigned the same color */ + +minimize obj: sum{c in 1..nc} u[c]; +/* objective is to minimize the number of colors used */ + +data; + +/* These data correspond to the instance myciel3.col from: + http://mat.gsia.cmu.edu/COLOR/instances.html */ + +/* The optimal solution is 4 */ + +param n := 11; + +set E := + 1 2 + 1 4 + 1 7 + 1 9 + 2 3 + 2 6 + 2 8 + 3 5 + 3 7 + 3 10 + 4 5 + 4 6 + 4 10 + 5 8 + 5 9 + 6 11 + 7 11 + 8 11 + 9 11 + 10 11 +; + +end; diff --git a/glpk-5.0/examples/cplex/README b/glpk-5.0/examples/cplex/README new file mode 100644 index 0000000..38bb8b4 --- /dev/null +++ b/glpk-5.0/examples/cplex/README @@ -0,0 +1,44 @@ +The program module in this subdirectory is a crude implementation of +CPLEX-like interface to GLPK API. It consists of two files: cplex.c and +cplex.h. + +NOTE that this module is NOT a clean room implementation of the CPLEX +callable library. It only implements a CPLEX-like interface to the GLPK +API routines, and its main purpose is to provide possibility to build +and run applications which normally use the CPLEX callable library. + +This module approximately corresponds to CPLEX 9.0. + +Currently this module can be used as a linear programming solver for +Concorde, the state-of-the-art computer code for solving the symmetric +traveling salesman problem (TSP) developed by David Applegate, Robert +Bixby, Vasek Chvatal, and William Cook. For details about Concorde see +its web page at http://www.tsp.gatech.edu/concorde.html. + +To build Concorde along with GLPK you need to do the following: + +1. Configure, build, and install GLPK. + +2. Download the Concorde tarball co031219.tgz (version Dec 19, 2003), + unpack and unarchive it. + +3. Copy files cplex.h and cplex.c to subdirectory concorde/LP/. + +4. Create file named lpglpk.c in subdirectory concorde/LP/. This file + must contain the following two lines: + + #include "cplex.c" + #include "lpcplex8.c" + +5. Configure Concorde in usual way (./configure) and then build it with + the following command: + + make CPPFLAGS=-I. LPSOLVER_INTERFACE=lpglpk.c LPSOLVER_LIB=-lglpk + + The Concorde executable can be found in subdirectory concorde/TSP/. + +Please note that currently this GLPK interface module does not support +some important features (namely, CPXgetijdiv, CPXmdleave, CPXpivotin, +CPXpivotout, and CPXstrongbranch), so large (more than 1000 nodes) TSP +instances cannot be solved in a reasonable time, and some instances may +cause abnormal termination of Concorde (if CPXgetijdiv is called). diff --git a/glpk-5.0/examples/cplex/concorde.txt b/glpk-5.0/examples/cplex/concorde.txt new file mode 100644 index 0000000..c6f7aec --- /dev/null +++ b/glpk-5.0/examples/cplex/concorde.txt @@ -0,0 +1,121 @@ +Solver: Concorde-03.12.19 (options used: -s 99) + http://www.tsp.gatech.edu/concorde.html +LP Solver: GLPK 4.34 (CPLEX-like interface module examples/cplex) +Computer: Intel Pentium 4 CPU 3GHz, 2GB of RAM +Platform: Cygwin 1.5.24 (Windows XP 5.1 Build 2600 Service Pack 4) +Compiler: GCC 3.4.4 (options used: -O2) +Test set: http://www.iwr.uni-heidelberg.de/groups/comopt/software/ + TSPLIB95/ + +Problem Solution B&B Time, s +--------- -------- --- ------- +a280 2579 1 3.09 +ali535 202339 1 21.88 +att48 10628 1 0.20 +att532 27686 7 74.31 +bayg29 1610 1 0.08 +bays29 2020 1 0.08 +berlin52 7542 1 0.11 +bier127 118282 1 0.62 +brazil58 25395 1 0.23 +brd14051 +brg180 1950 1 0.34 +burma14 3323 1 0.06 +ch130 6110 1 0.92 +ch150 6528 1 1.69 +d1291 +d15112 +d1655 +d18512 +d198 15780 3 4.92 +d2103 +d493 35002 5 123.89 +d657 48913 11 148.17 +dantzig42 699 1 0.08 +dsj1000 18660188 13 251.00 +eil101 (failed due to CPXgetijdiv) +eil51 426 1 0.17 +eil76 538 1 0.11 +fl1400 +fl1577 +fl3795 +fl417 11861 1 47.20 +fnl4461 +fri26 937 1 0.05 +gil262 2378 3 10.39 +gr120 6942 1 0.66 +gr137 69853 1 2.09 +gr17 2085 1 0.03 +gr202 40160 1 3.97 +gr21 2707 1 0.03 +gr229 134602 7 19.45 +gr24 1272 1 0.03 +gr431 171414 9 40.67 +gr48 5046 1 0.22 +gr666 294358 3 40.23 +gr96 55209 1 1.22 +hk48 11461 1 0.08 +kroA100 21282 1 0.41 +kroA150 26524 1 2.09 +kroA200 29368 1 2.44 +kroB100 22141 1 1.20 +kroB150 26130 1 1.66 +kroB200 29437 1 1.41 +kroC100 20749 1 0.42 +kroD100 21294 1 0.50 +kroE100 22068 1 0.94 +lin105 14379 1 0.23 +lin318 42029 1 4.28 +nrw1379 +p654 34643 1 17.08 +pa561 2763 15 370.70 +pcb1173 56892 11 370.30 +pcb3038 +pcb442 59778 13 35.86 +pla33810 +pla7397 +pla85900 +pr1002 259045 1 23.08 +pr107 44303 1 0.38 +pr124 59030 1 1.23 +pr136 96772 1 2.19 +pr144 58537 1 0.89 +pr152 73682 1 2.73 +pr226 80369 1 2.72 +pr2392 +pr264 49135 1 1.61 +pr299 48191 3 14.52 +pr439 107217 15 117.75 +pr76 108159 1 0.95 +rat195 2323 5 12.91 +rat575 6773 19 202.52 +rat783 8806 1 37.92 +rat99 1211 1 0.50 +rd100 7910 1 0.28 +rd400 15281 11 74.41 +rl11849 +rl1304 +rl1323 +rl1889 +rl5915 +rl5934 +si1032 92650 1 82.09 +si175 21407 3 8.97 +si535 48450 1 71.28 +st70 675 1 0.20 +swiss42 1273 1 0.06 +ts225 126643 1 21.25 +tsp225 3916 1 10.14 +u1060 224094 13 507.44 +u1432 +u159 42080 1 0.41 +u1817 +u2152 +u2319 +u574 36905 1 32.84 +u724 41910 19 238.42 +ulysses16 6859 1 0.19 +ulysses22 7013 1 0.47 +usa13509 +vm1084 239297 9 543.38 +vm1748 diff --git a/glpk-5.0/examples/cplex/cplex.c b/glpk-5.0/examples/cplex/cplex.c new file mode 100644 index 0000000..ffc2c99 --- /dev/null +++ b/glpk-5.0/examples/cplex/cplex.c @@ -0,0 +1,2127 @@ +/* cplex.c (CPLEX-like interface to GLPK API) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* Copyright (C) 2001-2013 Free Software Foundation, Inc. +* Written by Andrew Makhorin <mao@gnu.org>. +* +* 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 3 of the License, 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. If not, see <http://www.gnu.org/licenses/>. +***********************************************************************/ + +#include <ctype.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <glpk.h> +#include "cplex.h" + +struct CPXENV +{ /* environment block */ + CPXLP *list; + /* linked list of problem objects */ + int *intparam; /* int intparam[]; */ + /* integer control parameters */ + double *dblparam; /* double dblparam[]; */ + /* floating-point control parameters */ +}; + +struct CPXLP +{ /* problem object */ + CPXENV *env; + /* pointer to environment block */ + glp_prob *prob; + /* pointer to underlying GLPK problem object */ + int rflen; + /* length of the array rflag */ + char *rflag; /* char rflag[rflen]; */ + /* rflag[i], i = 0,...,nrows-1, is a flag of i-th row: */ +#define RF_NOT_RANGED 0 /* not ranged */ +#define RF_RANGED_POS 1 /* ranged, RHS = lower bound */ +#define RF_RANGED_NEG 2 /* ranged, RHS = upper bound */ + int stat; + /* solution status reported by CPXgetstat; zero means no solution + exists */ + int meth; + /* method indicator reported by CPXgetmethod */ + int iwlen; + /* length of the working array */ + int *iwork; /* int iwork[iwlen] */ + /* working array initialized by binary zeros */ + CPXLP *link; + /* pointer to another problem object */ +}; + +struct intparam +{ int which; + int defv; + int minv; + int maxv; +}; + +struct dblparam +{ int which; + double defv; + double minv; + double maxv; +}; + +struct errstring +{ int code; + const char *string; +}; + +#define BIGINT 2100000000 +#define BIGDBL 1e75 + +static const struct intparam intparam[] = +{ {CPX_PARAM_ADVIND, 0, 0, 2}, + {CPX_PARAM_AGGIND, -1, -1, BIGINT}, + {CPX_PARAM_DATACHECK, CPX_OFF, CPX_OFF, CPX_ON}, + {CPX_PARAM_DPRIIND, CPX_DPRIIND_AUTO, CPX_DPRIIND_AUTO, + CPX_DPRIIND_DEVEX}, + {CPX_PARAM_FASTMIP, CPX_OFF, CPX_OFF, CPX_ON}, /* ??? */ + {CPX_PARAM_ITLIM, BIGINT, 0, BIGINT}, + {CPX_PARAM_PERIND, CPX_OFF, CPX_OFF, CPX_ON}, + {CPX_PARAM_PPRIIND, CPX_PPRIIND_AUTO, CPX_PPRIIND_PARTIAL, + CPX_PPRIIND_FULL}, + {CPX_PARAM_PREIND, CPX_ON, CPX_OFF, CPX_ON}, + {CPX_PARAM_REINV, 0, 0, 10000}, + {CPX_PARAM_SCRIND, CPX_OFF, CPX_OFF, CPX_ON}, + {CPX_PARAM_SIMDISPLAY, 1, 0, 2}, +}; + +static const struct dblparam dblparam[] = +{ {CPX_PARAM_EPOPT, 1e-6, 1e-9, 1e-1}, + {CPX_PARAM_EPPER, 1e-6, 1e-8, BIGDBL}, + {CPX_PARAM_EPRHS, 1e-6, 1e-9, 1e-1}, + {CPX_PARAM_OBJLLIM, -BIGDBL, -BIGDBL, +BIGDBL}, + {CPX_PARAM_OBJULIM, +BIGDBL, -BIGDBL, +BIGDBL}, +}; + +static const struct errstring errstring[] = +{ {CPXERR_ARRAY_NOT_ASCENDING, "Array entry %d not ascending"}, + {CPXERR_BAD_ARGUMENT, "Invalid argument"}, + {CPXERR_BAD_CTYPE, "Invalid ctype entry %d"}, + {CPXERR_BAD_FILETYPE, "Invalid filetype"}, + {CPXERR_BAD_LUB, "Invalid bound change indicator entry %d"}, + {CPXERR_BAD_PARAM_NUM, "Invalid parameter number"}, + {CPXERR_BAD_SENSE, "Invalid sense entry %d"}, + {CPXERR_BAD_STATUS, "Invalid status entry %d for basis specificat" + "ion"}, + {CPXERR_COL_INDEX_RANGE, "Column index %d out of range"}, + {CPXERR_COUNT_RANGE, "Count entry %d negative or larger than allo" + "wed"}, + {CPXERR_DUP_ENTRY, "Duplicate entry"}, + {CPXERR_FAIL_OPEN_WRITE, "Could not open file '%s' for writing"}, + {CPXERR_INDEX_RANGE, "Index is outside range of valid values"}, + {CPXERR_NEGATIVE_SURPLUS, "Insufficient array length"}, + {CPXERR_NO_BASIC_SOLN, "No basic solution exists"}, + {CPXERR_NO_ENVIRONMENT, "No environment exists"}, + {CPXERR_NO_FILENAME, "File name not specified"}, + {CPXERR_NO_MEMORY, "Out of memory"}, + {CPXERR_NO_PROBLEM, "No problem exists"}, + {CPXERR_NO_SOLN, "No solution exists"}, + {CPXERR_NOT_FIXED, "Only fixed variables are pivoted out"}, + {CPXERR_NULL_NAME, "Null pointer %d in name array"}, + {CPXERR_NULL_POINTER, "Null pointer for required data"}, + {CPXERR_PARAM_TOO_BIG, "Parameter value too big"}, + {CPXERR_PARAM_TOO_SMALL, "Parameter value too small"}, + {CPXERR_ROW_INDEX_RANGE, "Row index %d out of range"}, +}; + +/**********************************************************************/ + +#define xassert glp_assert +#define xprintf glp_printf +#define xmalloc glp_malloc +#define xcalloc glp_calloc +#define xfree glp_free + +/**********************************************************************/ + +static int findintparam(int whichparam) +{ int k, card; + card = sizeof(intparam) / sizeof(struct intparam); + for (k = 0; k < card; k++) + if (intparam[k].which == whichparam) return k; + return -1; +} + +static int getintparam(CPXENV *env, int whichparam) +{ int k; + xassert(env != NULL); + k = findintparam(whichparam); + xassert(k >= 0); + return env->intparam[k]; +} + +static int finddblparam(int whichparam) +{ int k, card; + card = sizeof(dblparam) / sizeof(struct dblparam); + for (k = 0; k < card; k++) + if (dblparam[k].which == whichparam) return k; + return -1; +} + +static double getdblparam(CPXENV *env, int whichparam) +{ int k; + xassert(env != NULL); + k = finddblparam(whichparam); + xassert(k >= 0); + return env->dblparam[k]; +} + +static const char *finderrstring(int errcode) +{ int k, card; + card = sizeof(errstring) / sizeof(struct errstring); + for (k = 0; k < card; k++) + { if (errstring[k].code == errcode) + return errstring[k].string; + } + return NULL; +} + +static int error(CPXENV *env, int errcode, ...) +{ va_list arg; + char buffer[510]; + xassert(env != NULL); + if (getintparam(env, CPX_PARAM_SCRIND) == CPX_ON) + { xassert(CPXgeterrorstring(env, errcode, buffer) == buffer); + va_start(arg, errcode); + vprintf(buffer, arg); + va_end(arg); + } + return errcode; +} + +static int checkenv(CPXENV *env) +{ int errcode; + if (env == NULL) + errcode = CPXERR_NO_ENVIRONMENT; + else + errcode = 0; + return errcode; +} + +static checklp(CPXENV *env, CPXLP *lp) +{ int errcode; + errcode = checkenv(env); + if (errcode) goto done; + if (lp == NULL) + errcode = error(env, CPXERR_NO_PROBLEM); +done: return errcode; +} + +static void invalidate(CPXLP *lp) +{ lp->stat = 0; + lp->meth = CPX_ALG_NONE; + return; +} + +static void enlargerflag(CPXLP *lp) +{ int m; + xassert(lp != NULL); + m = glp_get_num_rows(lp->prob); + if (lp->rflen < m) + { int rflen = lp->rflen; + char *rflag = lp->rflag; + while (lp->rflen < m) + { lp->rflen += lp->rflen; + xassert(lp->rflen > 0); + } + lp->rflag = xcalloc(lp->rflen, sizeof(char)); + memcpy(lp->rflag, rflag, rflen); + xfree(rflag); + } + return; +} + +static void enlargeiwork(CPXLP *lp, int len) +{ xassert(len >= 0); + if (lp->iwlen < len) + { xfree(lp->iwork); + while (lp->iwlen < len) + { lp->iwlen += lp->iwlen; + xassert(lp->iwlen > 0); + } + lp->iwork = xcalloc(lp->iwlen, sizeof(int)); + memset(lp->iwork, 0, lp->iwlen * sizeof(int)); + } + return; +} + +/**********************************************************************/ + +int CPXaddcols(CPXENV *env, CPXLP *lp, int ccnt, int nzcnt, + const double obj[], const int cmatbeg[], const int cmatind[], + const double cmatval[], const double lb[], const double ub[], + char *colname[]) +{ int j, k, m, n, beg, end, type, errcode; + double lbnd, ubnd; + errcode = checklp(env, lp); + if (errcode) goto done; + if (ccnt < 0 || nzcnt < 0) + { errcode = error(env, CPXERR_BAD_ARGUMENT); + goto done; + } + if (ccnt > 0) + { if (cmatbeg == NULL || cmatind == NULL || cmatval == NULL) + { errcode = error(env, CPXERR_NULL_POINTER); + goto done; + } + } + m = glp_get_num_rows(lp->prob); + n = glp_get_num_cols(lp->prob); + enlargeiwork(lp, m); + for (j = 0; j < ccnt; j++) + { beg = cmatbeg[j]; + if (j > 0 && !(cmatbeg[j-1] <= beg)) + { errcode = error(env, CPXERR_ARRAY_NOT_ASCENDING, j); + goto done; + } + if (!(0 <= beg && beg <= nzcnt)) + { errcode = error(env, CPXERR_INDEX_RANGE); + goto done; + } + end = (j < ccnt-1 ? cmatbeg[j+1] : nzcnt); + for (k = beg; k < end; k++) + { if (!(0 <= cmatind[k] && cmatind[k] < m)) + { errcode = error(env, CPXERR_ROW_INDEX_RANGE, k); + goto done; + } + } + errcode = 0; + for (k = beg; k < end; k++) + { if (lp->iwork[cmatind[k]]) + { errcode = error(env, CPXERR_DUP_ENTRY); + break; + } + lp->iwork[cmatind[k]] = 1; + } + for (k = beg; k < end; k++) + lp->iwork[cmatind[k]] = 0; + if (errcode) goto done; + if (colname != NULL) + { if (colname[j] == NULL) + { errcode = error(env, CPXERR_NULL_NAME, j); + goto done; + } + } + } + errcode = 0; + invalidate(lp); + if (ccnt > 0) + glp_add_cols(lp->prob, ccnt); + for (j = 0; j < ccnt; j++) + { if (colname != NULL) + glp_set_col_name(lp->prob, n+j+1, colname[j]); + lbnd = (lb == NULL ? 0.0 : lb[j]); + ubnd = (ub == NULL ? +CPX_INFBOUND : ub[j]); + if (lbnd <= -CPX_INFBOUND && ubnd >= +CPX_INFBOUND) + type = GLP_FR; + else if (ubnd >= +CPX_INFBOUND) + type = GLP_LO; + else if (lbnd <= -CPX_INFBOUND) + type = GLP_UP; + else if (lbnd != ubnd) + type = GLP_DB; + else + type = GLP_FX; + glp_set_col_bnds(lp->prob, n+j+1, type, lbnd, ubnd); + if (obj != NULL) + glp_set_obj_coef(lp->prob, n+j+1, obj[j]); + beg = cmatbeg[j]; + end = (j < ccnt-1 ? cmatbeg[j+1] : nzcnt); + for (k = beg; k < end; k++) + lp->iwork[k-beg] = cmatind[k]+1; + glp_set_mat_col(lp->prob, n+j+1, end-beg, lp->iwork-1, + cmatval+beg-1); + for (k = beg; k < end; k++) + lp->iwork[k-beg] = 0; + } +done: return errcode; +} + +int CPXaddrows(CPXENV *env, CPXLP *lp, int ccnt, int rcnt, int nzcnt, + const double rhs[], const char sense[], const int rmatbeg[], + const int rmatind[], const double rmatval[], char *colname[], + char *rowname[]) +{ int i, j, k, m, n, beg, end, type, errcode; + double temp; + errcode = checklp(env, lp); + if (errcode) goto done; + if (ccnt < 0 || rcnt < 0 || nzcnt < 0) + { errcode = error(env, CPXERR_BAD_ARGUMENT); + goto done; + } + if (rcnt > 0) + { if (rmatbeg == NULL || rmatind == NULL || rmatval == NULL) + { errcode = error(env, CPXERR_NULL_POINTER); + goto done; + } + } + m = glp_get_num_rows(lp->prob); + n = glp_get_num_cols(lp->prob); + enlargeiwork(lp, n+ccnt); + for (i = 0; i < rcnt; i++) + { if (sense != NULL) + { if (!(sense[i] == 'L' || sense[i] == 'E' || + sense[i] == 'G' || sense[i] == 'R')) + { errcode = error(env, CPXERR_BAD_SENSE, i); + goto done; + } + } + beg = rmatbeg[i]; + if (i > 0 && !(rmatbeg[i-1] <= beg)) + { errcode = error(env, CPXERR_ARRAY_NOT_ASCENDING, i); + goto done; + } + if (!(0 <= beg && beg <= nzcnt)) + { errcode = error(env, CPXERR_INDEX_RANGE); + goto done; + } + end = (i < rcnt-1 ? rmatbeg[i+1] : nzcnt); + for (k = beg; k < end; k++) + { if (!(0 <= rmatind[k] && rmatind[k] < n+ccnt)) + { errcode = error(env, CPXERR_COL_INDEX_RANGE, k); + goto done; + } + } + errcode = 0; + for (k = beg; k < end; k++) + { if (lp->iwork[rmatind[k]]) + { errcode = error(env, CPXERR_DUP_ENTRY); + break; + } + lp->iwork[rmatind[k]] = 1; + } + for (k = beg; k < end; k++) + lp->iwork[rmatind[k]] = 0; + if (errcode) goto done; + if (rowname != NULL) + { if (rowname[i] == NULL) + { errcode = error(env, CPXERR_NULL_NAME, i); + goto done; + } + } + } + for (j = 0; j < ccnt; j++) + { if (colname != NULL) + { if (colname[j] == NULL) + { errcode = error(env, CPXERR_NULL_NAME, j); + goto done; + } + } + } + errcode = 0; + invalidate(lp); + if (rcnt > 0) + glp_add_rows(lp->prob, rcnt); + if (ccnt > 0) + glp_add_cols(lp->prob, ccnt); + enlargerflag(lp); + for (i = 0; i < rcnt; i++) + { if (rowname != NULL) + glp_set_row_name(lp->prob, m+i+1, rowname[i]); + temp = (rhs == NULL ? 0.0 : rhs[i]); + if (sense == NULL || sense[i] == 'E') + { lp->rflag[m+i] = RF_NOT_RANGED; + type = GLP_FX; + } + else if (sense[i] == 'L') + { lp->rflag[m+i] = RF_NOT_RANGED; + type = GLP_UP; + } + else if (sense[i] == 'G') + { lp->rflag[m+i] = RF_NOT_RANGED; + type = GLP_LO; + } + else if (sense[i] == 'R') + { lp->rflag[m+i] = RF_RANGED_POS; + type = GLP_FX; + } + else + xassert(sense != sense); + glp_set_row_bnds(lp->prob, m+i+1, type, temp, temp); + beg = rmatbeg[i]; + end = (i < rcnt-1 ? rmatbeg[i+1] : nzcnt); + for (k = beg; k < end; k++) + lp->iwork[k-beg] = rmatind[k]+1; + glp_set_mat_row(lp->prob, m+i+1, end-beg, lp->iwork-1, + rmatval+beg-1); + for (k = beg; k < end; k++) + lp->iwork[k-beg] = 0; + } + for (j = 0; j < ccnt; j++) + { if (colname != NULL) + glp_set_col_name(lp->prob, n+j+1, colname[j]); + glp_set_col_bnds(lp->prob, n+j+1, GLP_LO, 0.0, 0.0); + } +done: return errcode; +} + +int CPXbaropt(CPXENV *env, CPXLP *lp) +{ xassert(env == env); + xassert(lp == lp); + xprintf("CPXbaropt: not implemented yet\n"); + exit(EXIT_FAILURE); + return -1; +} + +int CPXbinvrow(CPXENV *env, CPXLP *lp, int i, double y[]) +{ xassert(env == env); + xassert(lp == lp); + xassert(i == i); + xassert(y == y); + xprintf("CPXbinvrow: not implemented yet\n"); + exit(EXIT_FAILURE); + return -1; +} + +int CPXchgbds(CPXENV *env, CPXLP *lp, int cnt, const int indices[], + const char lu[], const double bd[]) +{ int j, n, type, errcode; + double lbnd, ubnd; + errcode = checklp(env, lp); + if (errcode) goto done; + if (cnt < 0) + { errcode = error(env, CPXERR_BAD_ARGUMENT); + goto done; + } + if (cnt > 0) + { if (indices == NULL || lu == NULL || bd == NULL) + { errcode = error(env, CPXERR_NULL_POINTER); + goto done; + } + } + n = glp_get_num_cols(lp->prob); + for (j = 0; j < cnt; j++) + { if (!(0 <= indices[j] && indices[j] < n)) + { errcode = error(env, CPXERR_COL_INDEX_RANGE, j); + goto done; + } + if (!(lu[j] == 'L' || lu[j] == 'U' || lu[j] == 'B')) + { errcode = error(env, CPXERR_BAD_LUB, j); + goto done; + } + } + errcode = 0; + invalidate(lp); + for (j = 0; j < cnt; j++) + { type = glp_get_col_type(lp->prob, indices[j]+1); + lbnd = glp_get_col_lb(lp->prob, indices[j]+1); + ubnd = glp_get_col_ub(lp->prob, indices[j]+1); + if (type == GLP_FR || type == GLP_UP) + lbnd = -CPX_INFBOUND; + if (type == GLP_FR || type == GLP_LO) + ubnd = +CPX_INFBOUND; + if (lu[j] == 'L') + lbnd = bd[j]; + else if (lu[j] == 'U') + ubnd = bd[j]; + else if (lu[j] == 'B') + lbnd = ubnd = bd[j]; + else + xassert(lu != lu); + if (lbnd <= -CPX_INFBOUND && ubnd >= +CPX_INFBOUND) + type = GLP_FR; + else if (ubnd >= +CPX_INFBOUND) + type = GLP_LO; + else if (lbnd <= -CPX_INFBOUND) + type = GLP_UP; + else if (lbnd != ubnd) + type = GLP_DB; + else + type = GLP_FX; + glp_set_col_bnds(lp->prob, indices[j]+1, type, lbnd, ubnd); + } +done: return errcode; +} + +int CPXchgcoeflist(CPXENV *env, CPXLP *lp, int numcoefs, + const int rowlist[], const int collist[], const double vallist[]) +{ int i, j, k, m, n, rcnt, ccnt, len, ptr, errcode; + int *head, *next, *ind; + double *val; + errcode = checklp(env, lp); + if (errcode) goto done; + if (numcoefs < 0) + { errcode = error(env, CPXERR_BAD_ARGUMENT); + goto done; + } + if (numcoefs == 0) + { errcode = 0; + goto done; + } + if (rowlist == NULL || collist == NULL || vallist == NULL) + { errcode = error(env, CPXERR_NULL_POINTER); + goto done; + } + /* check triplets and determine the number of rows and columns + to be changed */ + m = glp_get_num_rows(lp->prob); + n = glp_get_num_cols(lp->prob); + enlargeiwork(lp, m); + enlargeiwork(lp, n); + rcnt = ccnt = 0; + for (k = 0; k < numcoefs; k++) + { i = rowlist[k]; + if (!(0 <= i && i < m)) + { errcode = error(env, CPXERR_ROW_INDEX_RANGE, i); + goto done; + } + if (!(lp->iwork[i] & 0x01)) + rcnt++, lp->iwork[i] |= 0x01; + j = collist[k]; + if (!(0 <= j && j < n)) + { errcode = error(env, CPXERR_COL_INDEX_RANGE, j); + goto done; + } + if (!(lp->iwork[j] & 0x02)) + ccnt++, lp->iwork[j] |= 0x02; + } + memset(lp->iwork, 0, m * sizeof(int)); + memset(lp->iwork, 0, n * sizeof(int)); + errcode = 0; + invalidate(lp); + if (rcnt <= ccnt) + { /* change the matrix by rows */ + /* build the linked list of triplets: + head[i] is a pointer to first triplet for row i + next[k] is a pointer to next triplet for the same row */ + head = xcalloc(m, sizeof(int)); + for (i = 0; i < m; i++) + head[i] = -1; + next = xcalloc(numcoefs, sizeof(int)); + for (k = 0; k < numcoefs; k++) + { i = rowlist[k]; + next[k] = head[i]; + head[i] = k; + } + /* check duplicate columns */ + for (i = 0; i < m; i++) + { for (k = head[i]; k >= 0; k = next[k]) + { j = collist[k]; + if (lp->iwork[j]) + { xfree(head); + xfree(next); + errcode = error(env, CPXERR_DUP_ENTRY); + goto done; + } + lp->iwork[j] = 1; + } + for (k = head[i]; k >= 0; k = next[k]) + lp->iwork[collist[k]] = 0; + } + /* perform operation */ + ind = xcalloc(1+n, sizeof(int)); + val = xcalloc(1+n, sizeof(double)); + for (i = 0; i < m; i++) + { if (head[i] < 0) continue; + len = glp_get_mat_row(lp->prob, i+1, ind, val); + for (ptr = 1; ptr <= len; ptr++) + { j = ind[ptr]-1; + xassert(lp->iwork[j] == 0); + lp->iwork[j] = ptr; + } + for (k = head[i]; k >= 0; k = next[k]) + { j = collist[k]; + if (lp->iwork[j] == 0) + lp->iwork[j] = ++len; + ptr = lp->iwork[j]; + ind[ptr] = j+1, val[ptr] = vallist[k]; + } + glp_set_mat_row(lp->prob, i+1, len, ind, val); + for (ptr = 1; ptr <= len; ptr++) + lp->iwork[ind[ptr]-1] = 0; + } + } + else + { /* change the matrix by columns */ + /* build the linked lists of triplets: + head[j] is a pointer to first triplet for column j + next[k] is a pointer to next triplet for the same column */ + head = xcalloc(n, sizeof(int)); + for (j = 0; j < n; j++) + head[j] = -1; + next = xcalloc(numcoefs, sizeof(int)); + for (k = 0; k < numcoefs; k++) + { j = collist[k]; + next[k] = head[j]; + head[j] = k; + } + /* check duplicate rows */ + for (j = 0; j < n; j++) + { for (k = head[j]; k >= 0; k = next[k]) + { i = rowlist[k]; + if (lp->iwork[i]) + { xfree(head); + xfree(next); + errcode = error(env, CPXERR_DUP_ENTRY); + goto done; + } + lp->iwork[i] = 1; + } + for (k = head[j]; k >= 0; k = next[k]) + lp->iwork[rowlist[k]] = 0; + } + /* perform operation */ + ind = xcalloc(1+m, sizeof(int)); + val = xcalloc(1+m, sizeof(double)); + for (j = 0; j < n; j++) + { if (head[j] < 0) continue; + len = glp_get_mat_col(lp->prob, j+1, ind, val); + for (ptr = 1; ptr <= len; ptr++) + { i = ind[ptr]-1; + xassert(lp->iwork[i] == 0); + lp->iwork[i] = ptr; + } + for (k = head[j]; k >= 0; k = next[k]) + { i = rowlist[k]; + if (lp->iwork[i] == 0) + lp->iwork[i] = ++len; + ptr = lp->iwork[i]; + ind[ptr] = i+1, val[ptr] = vallist[k]; + } + glp_set_mat_col(lp->prob, j+1, len, ind, val); + for (ptr = 1; ptr <= len; ptr++) + lp->iwork[ind[ptr]-1] = 0; + } + } + xfree(head); + xfree(next); + xfree(ind); + xfree(val); +done: return errcode; +} + +void CPXchgobjsen(CPXENV *env, CPXLP *lp, int maxormin) +{ int errcode; + errcode = checklp(env, lp); + if (errcode) goto done; + if (!(maxormin == CPX_MIN || maxormin == CPX_MAX)) + { errcode = error(env, CPXERR_BAD_ARGUMENT); + goto done; + } + errcode = 0; + invalidate(lp); + if (maxormin == CPX_MIN) + glp_set_obj_dir(lp->prob, GLP_MIN); + else + glp_set_obj_dir(lp->prob, GLP_MAX); +done: xassert(errcode == errcode); + return; +} + +int CPXchgsense(CPXENV *env, CPXLP *lp, int cnt, const int indices[], + const char sense[]) +{ int i, m, type, errcode; + double rhs; + errcode = checklp(env, lp); + if (errcode) goto done; + if (cnt < 0) + { errcode = error(env, CPXERR_BAD_ARGUMENT); + goto done; + } + if (cnt > 0 && (indices == NULL || sense == NULL)) + { errcode = error(env, CPXERR_NULL_POINTER); + goto done; + } + m = glp_get_num_rows(lp->prob); + for (i = 0; i < cnt; i++) + { if (!(0 <= indices[i] && indices[i] < m)) + { errcode = error(env, CPXERR_ROW_INDEX_RANGE, i); + goto done; + } + if (!(sense[i] == 'L' || sense[i] == 'E' || sense[i] == 'G' || + sense[i] == 'R')) + { errcode = error(env, CPXERR_BAD_SENSE, i); + goto done; + } + } + errcode = 0; + invalidate(lp); + for (i = 0; i < cnt; i++) + { type = glp_get_row_type(lp->prob, indices[i]+1); + if (lp->rflag[indices[i]] == RF_NOT_RANGED) + { if (type == GLP_LO || type == GLP_FX) + rhs = glp_get_row_lb(lp->prob, indices[i]+1); + else if (type == GLP_UP) + rhs = glp_get_row_ub(lp->prob, indices[i]+1); + else + xassert(type != type); + } + else if (lp->rflag[indices[i]] == RF_RANGED_POS) + { xassert(type == GLP_DB || type == GLP_FX); + rhs = glp_get_row_lb(lp->prob, indices[i]+1); + } + else if (lp->rflag[indices[i]] == RF_RANGED_NEG) + { xassert(type == GLP_DB); + rhs = glp_get_row_ub(lp->prob, indices[i]+1); + } + else + xassert(lp != lp); + if (sense[i] == 'L') + { lp->rflag[indices[i]] = RF_NOT_RANGED; + type = GLP_UP; + } + else if (sense[i] == 'E') + { lp->rflag[indices[i]] = RF_NOT_RANGED; + type = GLP_FX; + } + else if (sense[i] == 'G') + { lp->rflag[indices[i]] = RF_NOT_RANGED; + type = GLP_LO; + } + else if (sense[i] == 'R') + { lp->rflag[indices[i]] = RF_RANGED_POS; + type = GLP_FX; + } + else + xassert(sense != sense); + glp_set_row_bnds(lp->prob, indices[i]+1, type, rhs, rhs); + } +done: return errcode; +} + +int CPXcloseCPLEX(CPXENV **_env) +{ CPXENV *env; + CPXLP *lp; + int errcode; + if (_env == NULL) + { errcode = CPXERR_NULL_POINTER; + goto done; + } + env = *_env; + errcode = checkenv(env); + if (errcode) goto done; + while (env->list != NULL) + { lp = env->list; + errcode = CPXfreeprob(env, &lp); + xassert(!errcode); + } + xfree(env->intparam); + xfree(env->dblparam); + xfree(env); + *_env = NULL; + errcode = 0; +done: return errcode; +} + +int CPXcopybase(CPXENV *env, CPXLP *lp, const int cstat[], + const int rstat[]) +{ int i, j, m, n, stat, errcode; + errcode = checklp(env, lp); + if (errcode) goto done; + m = glp_get_num_rows(lp->prob); + n = glp_get_num_cols(lp->prob); + if (m > 0 && rstat == NULL || n > 0 && cstat == NULL) + { errcode = error(env, CPXERR_NULL_POINTER); + goto done; + } + for (i = 0; i < m; i++) + { if (!(rstat[i] == CPX_AT_LOWER || rstat[i] == CPX_BASIC || + rstat[i] == CPX_AT_UPPER)) + { errcode = error(env, CPXERR_BAD_STATUS, i); + goto done; + } + } + for (j = 0; j < n; j++) + { if (!(cstat[j] == CPX_AT_LOWER || cstat[j] == CPX_BASIC || + cstat[j] == CPX_AT_UPPER || cstat[j] == CPX_FREE_SUPER)) + { errcode = error(env, CPXERR_BAD_STATUS, j); + goto done; + } + } + errcode = 0; + invalidate(lp); + for (i = 0; i < m; i++) + { if (rstat[i] == CPX_AT_LOWER) + stat = GLP_NL; + else if (rstat[i] == CPX_BASIC) + stat = GLP_BS; + else if (rstat[i] == CPX_AT_UPPER) + stat = GLP_NU; + else + xassert(rstat != rstat); + glp_set_row_stat(lp->prob, i+1, stat); + } + for (j = 0; j < n; j++) + { if (cstat[j] == CPX_AT_LOWER) + stat = GLP_NL; + else if (cstat[j] == CPX_BASIC) + stat = GLP_BS; + else if (cstat[j] == CPX_AT_UPPER) + stat = GLP_NU; + else if (cstat[j] == CPX_FREE_SUPER) + stat = GLP_NF; + else + xassert(cstat != cstat); + glp_set_col_stat(lp->prob, j+1, stat); + } +done: return errcode; +} + +int CPXcopybasednorms(CPXENV *env, CPXLP *lp, const int cstat[], + const int rstat[], const double dnorm[]) +{ int errcode; + errcode = CPXcopybase(env, lp, cstat, rstat); + xassert(dnorm == dnorm); + return errcode; +} + +int CPXcopylp(CPXENV *env, CPXLP *lp, int numcols, int numrows, + int objsen, const double obj[], const double rhs[], + const char sense[], const int matbeg[], const int matcnt[], + const int matind[], const double matval[], const double lb[], + const double ub[], const double rngval[]) +{ int errcode; + errcode = CPXcopylpwnames(env, lp, numcols, numrows, objsen, obj, + rhs, sense, matbeg, matcnt, matind, matval, lb, ub, rngval, + NULL, NULL); + return errcode; +} + +int CPXcopylpwnames(CPXENV *env, CPXLP *lp, int numcols, int numrows, + int objsen, const double obj[], const double rhs[], + const char sense[], const int matbeg[], const int matcnt[], + const int matind[], const double matval[], const double lb[], + const double ub[], const double rngval[], char *colname[], + char *rowname[]) +{ int i, j, k, beg, end, type, errcode; + double lbnd, ubnd; + char name[255+1]; + errcode = checklp(env, lp); + if (errcode) goto done; + if (numcols < 0 || numrows < 0) + { errcode = error(env, CPXERR_BAD_ARGUMENT); + goto done; + } + if (!(objsen == CPX_MIN || objsen == CPX_MAX)) + { errcode = error(env, CPXERR_BAD_ARGUMENT); + goto done; + } + if (numcols > 0) + { if (matbeg == NULL || matcnt == NULL || matind == NULL || + matval == NULL) + { errcode = error(env, CPXERR_NULL_POINTER); + goto done; + } + } + for (i = 0; i < numrows; i++) + { if (sense != NULL) + { if (!(sense[i] == 'L' || sense[i] == 'E' || + sense[i] == 'G' || sense[i] == 'R')) + { errcode = error(env, CPXERR_BAD_SENSE, i); + goto done; + } + } + if (rowname != NULL) + { if (rowname[i] == NULL) + { errcode = error(env, CPXERR_NULL_NAME, i); + goto done; + } + } + } + enlargeiwork(lp, numrows); + for (j = 0; j < numcols; j++) + { beg = matbeg[j]; + if (j > 0 && !(matbeg[j-1] <= beg)) + { errcode = error(env, CPXERR_ARRAY_NOT_ASCENDING, j); + goto done; + } + if (beg < 0) + { errcode = error(env, CPXERR_INDEX_RANGE); + goto done; + } + end = beg + matcnt[j]; + if (!(beg <= end) || j < numcols-1 && !(end <= matbeg[j+1])) + { errcode = error(env, CPXERR_COUNT_RANGE, j); + goto done; + } + for (k = beg; k < end; k++) + { if (!(0 <= matind[k] && matind[k] < numrows)) + { errcode = error(env, CPXERR_ROW_INDEX_RANGE, k); + goto done; + } + } + errcode = 0; + for (k = beg; k < end; k++) + { if (lp->iwork[matind[k]]) + { errcode = error(env, CPXERR_DUP_ENTRY); + break; + } + lp->iwork[matind[k]] = 1; + } + for (k = beg; k < end; k++) + lp->iwork[matind[k]] = 0; + if (errcode) goto done; + if (colname != NULL) + { if (colname[j] != NULL) + { errcode = error(env, CPXERR_NULL_NAME, j); + goto done; + } + } + } + errcode = 0; + invalidate(lp); + if (glp_get_prob_name(lp->prob) == NULL) + name[0] = '\0'; + else + strcpy(name, glp_get_prob_name(lp->prob)); + glp_erase_prob(lp->prob); + glp_set_prob_name(lp->prob, name); + if (objsen == CPX_MIN) + glp_set_obj_dir(lp->prob, GLP_MIN); + else if (objsen == CPX_MAX) + glp_set_obj_dir(lp->prob, GLP_MAX); + else + xassert(objsen != objsen); + if (numrows > 0) + glp_add_rows(lp->prob, numrows); + enlargerflag(lp); + for (i = 0; i < numrows; i++) + { if (rowname != NULL) + glp_set_row_name(lp->prob, i+1, rowname[i]); + lbnd = ubnd = (rhs == NULL ? 0.0 : rhs[i]); + if (sense == NULL || sense[i] == 'E') + { lp->rflag[i] = RF_NOT_RANGED; + type = GLP_FX; + } + else if (sense[i] == 'L') + { lp->rflag[i] = RF_NOT_RANGED; + type = GLP_UP; + } + else if (sense[i] == 'G') + { lp->rflag[i] = RF_NOT_RANGED; + type = GLP_LO; + } + else if (sense[i] == 'R') + { if (rngval == NULL || rngval[i] == 0.0) + { lp->rflag[i] = RF_RANGED_POS; + type = GLP_FX; + } + else if (rngval[i] > 0.0) + { lp->rflag[i] = RF_RANGED_POS; + type = GLP_DB; + ubnd += rngval[i]; + } + else /* rngval[i] < 0.0 */ + { lp->rflag[i] = RF_RANGED_NEG; + type = GLP_DB; + lbnd += rngval[i]; + } + } + else + xassert(sense != sense); + glp_set_row_bnds(lp->prob, i+1, type, lbnd, ubnd); + } + if (numcols > 0) + glp_add_cols(lp->prob, numcols); + for (j = 0; j < numcols; j++) + { if (colname != NULL) + glp_set_col_name(lp->prob, j+1, colname[j]); + lbnd = (lb == NULL ? 0.0 : lb[j]); + ubnd = (ub == NULL ? +CPX_INFBOUND : ub[j]); + if (lbnd <= -CPX_INFBOUND && ubnd >= +CPX_INFBOUND) + type = GLP_FR; + else if (ubnd >= +CPX_INFBOUND) + type = GLP_LO; + else if (lbnd <= -CPX_INFBOUND) + type = GLP_UP; + else if (lbnd != ubnd) + type = GLP_DB; + else + type = GLP_FX; + glp_set_col_bnds(lp->prob, j+1, type, lbnd, ubnd); + if (obj != NULL) + glp_set_obj_coef(lp->prob, j+1, obj[j]); + beg = matbeg[j]; + end = beg + matcnt[j]; + for (k = beg; k < end; k++) + lp->iwork[k-beg] = matind[k]+1; + glp_set_mat_col(lp->prob, j+1, end-beg, lp->iwork-1, + matval+beg-1); + for (k = beg; k < end; k++) + lp->iwork[k-beg] = 0; + } +done: return errcode; +} + +CPXLP *CPXcreateprob(CPXENV *env, int *status, const char *probname) +{ CPXLP *lp = NULL; + int errcode; + errcode = checkenv(env); + if (errcode) goto done; + lp = xmalloc(sizeof(struct CPXLP)); + lp->env = env; + lp->prob = glp_create_prob(); + glp_set_prob_name(lp->prob, probname); + lp->rflen = 100; + lp->rflag = xcalloc(lp->rflen, sizeof(char)); + lp->iwlen = 100; + lp->iwork = xcalloc(lp->iwlen, sizeof(int)); + memset(lp->iwork, 0, lp->iwlen * sizeof(int)); + lp->link = env->list; + env->list = lp; + invalidate(lp); +done: if (status != NULL) *status = errcode; + return lp; +} + +int CPXdelcols(CPXENV *env, CPXLP *lp, int begin, int end) +{ int j, n, errcode; + errcode = checklp(env, lp); + if (errcode) goto done; + n = glp_get_num_cols(lp->prob); + if (!(0 <= begin && begin <= end && end < n)) + { errcode = error(env, CPXERR_INDEX_RANGE); + goto done; + } + errcode = 0; + invalidate(lp); + enlargeiwork(lp, end-begin+1); + for (j = begin; j <= end; j++) + lp->iwork[j-begin] = j+1; + glp_del_cols(lp->prob, end-begin+1, lp->iwork-1); + for (j = begin; j <= end; j++) + lp->iwork[j-begin] = 0; +done: return errcode; +} + +int CPXdelrows(CPXENV *env, CPXLP *lp, int begin, int end) +{ int i, m, errcode; + errcode = checklp(env, lp); + if (errcode) goto done; + m = glp_get_num_rows(lp->prob); + if (!(0 <= begin && begin <= end && end < m)) + { errcode = error(env, CPXERR_INDEX_RANGE); + goto done; + } + errcode = 0; + invalidate(lp); + enlargeiwork(lp, end-begin+1); + for (i = begin; i <= end; i++) + lp->iwork[i-begin] = i+1; + glp_del_rows(lp->prob, end-begin+1, lp->iwork-1); + for (i = begin; i <= end; i++) + lp->iwork[i-begin] = 0; + for (i = end+1; i < m; i++) + lp->rflag[i-(end-begin+1)] = lp->rflag[i]; +done: return errcode; +} + +int CPXdelsetcols(CPXENV *env, CPXLP *lp, int delstat[]) +{ xassert(env == env); + xassert(lp == lp); + xassert(delstat == delstat); + xprintf("CPXdelsetcols: not implemented yet\n"); + exit(EXIT_FAILURE); + return -1; +} + +int CPXdelsetrows(CPXENV *env, CPXLP *lp, int delstat[]) +{ int i, m, cnt, ind, errcode; + errcode = checklp(env, lp); + if (errcode) goto done; + m = glp_get_num_rows(lp->prob); + if (m > 0 && delstat == NULL) + { errcode = error(env, CPXERR_NULL_POINTER); + goto done; + } + errcode = 0; + invalidate(lp); + enlargeiwork(lp, m); + cnt = ind = 0; + for (i = 0; i < m; i++) + { if (delstat[i] == 1) + { delstat[i] = -1; + lp->iwork[cnt++] = i+1; + } + else + { delstat[i] = ind; + lp->rflag[ind++] = lp->rflag[i]; + } + } + if (cnt > 0) + glp_del_rows(lp->prob, cnt, lp->iwork-1); + for (i = 0; i < cnt; i++) + lp->iwork[i] = 0; +done: return errcode; +} + +int CPXdualopt(CPXENV *env, CPXLP *lp); + +int CPXfreeprob(CPXENV *env, CPXLP **_lp) +{ CPXLP *lp; + int errcode; + errcode = checkenv(env); + if (errcode) goto done; + if (_lp == NULL) + { errcode = error(env, CPXERR_NULL_POINTER); + goto done; + } + lp = *_lp; + errcode = checklp(env, lp); + if (errcode) goto done; + errcode = 0; + env = lp->env; + if (env->list == lp) + env->list = lp->link; + else + { CPXLP *pp; + for (pp = env->list; pp != NULL; pp = pp->link) + if (pp->link == lp) break; + xassert(pp != NULL); + pp->link = lp->link; + } + glp_delete_prob(lp->prob); + xfree(lp->rflag); + xfree(lp->iwork); + xfree(lp); + *_lp = NULL; +done: return errcode; +} + +int CPXgetbase(CPXENV *env, CPXLP *lp, int cstat[], int rstat[]) +{ int i, j, m, n, stat, errcode; + errcode = checklp(env, lp); + if (errcode) goto done; + if (!lp->stat) + { errcode = error(env, CPXERR_NO_SOLN); + goto done; + } + if (lp->meth == CPX_ALG_PRIMAL || lp->meth == CPX_ALG_DUAL) + ; + else + { errcode = error(env, CPXERR_NO_BASIC_SOLN); + goto done; + } + errcode = 0; + if (rstat != NULL) + { m = glp_get_num_rows(lp->prob); + for (i = 0; i < m; i++) + { stat = glp_get_row_stat(lp->prob, i+1); + if (stat == GLP_BS) + rstat[i] = CPX_BASIC; + else if (lp->rflag[i] == RF_NOT_RANGED || stat != GLP_NU) + rstat[i] = CPX_AT_LOWER; + else + rstat[i] = CPX_AT_UPPER; + } + } + if (cstat != NULL) + { n = glp_get_num_cols(lp->prob); + for (j = 0; j < n; j++) + { stat = glp_get_col_stat(lp->prob, j+1); + if (stat == GLP_BS) + cstat[j] = CPX_BASIC; + else if (stat == GLP_NU) + cstat[j] = CPX_AT_UPPER; + else if (stat == GLP_NF) + cstat[j] = CPX_FREE_SUPER; + else + cstat[j] = CPX_AT_LOWER; + } + } +done: return errcode; +} + +int CPXgetbasednorms(CPXENV *env, CPXLP *lp, int cstat[], int rstat[], + double dnorm[]) +{ int i, m, errcode; + errcode = CPXgetbase(env, lp, cstat, rstat); + if (errcode) goto done; + if (dnorm != NULL) + { m = glp_get_num_rows(lp->prob); + for (i = 0; i < m; i++) dnorm[i] = 1.0; + } +done: return errcode; +} + +int CPXgetbhead(CPXENV *env, CPXLP *lp, int head[], double x[]) +{ xassert(env == env); + xassert(lp == lp); + xassert(head == head); + xassert(x == x); + xprintf("CPXgetbhead: not implemented yet\n"); + exit(EXIT_FAILURE); + return -1; +} + +int CPXgetdblparam(CPXENV *env, int whichparam, double *value) +{ int k, errcode; + errcode = checkenv(env); + if (errcode) goto done; + k = finddblparam(whichparam); + if (k < 0) + { errcode = error(env, CPXERR_BAD_PARAM_NUM); + goto done; + } + errcode = 0; + if (value != NULL) + *value = env->dblparam[k]; +done: return errcode; +} + +int CPXgetdj(CPXENV *env, CPXLP *lp, double dj[], int begin, int end) +{ int j, n, errcode; + errcode = checklp(env, lp); + if (errcode) goto done; + n = glp_get_num_cols(lp->prob); + if (!(0 <= begin && begin <= end && end < n)) + { errcode = error(env, CPXERR_INDEX_RANGE); + goto done; + } + if (!lp->stat) + { errcode = error(env, CPXERR_NO_SOLN); + goto done; + } + errcode = 0; + if (lp->meth == CPX_ALG_PRIMAL || lp->meth == CPX_ALG_DUAL) + { if (dj != NULL) + { for (j = begin; j <= end; j++) + dj[j-begin] = glp_get_col_dual(lp->prob, j+1); + } + } + else + xassert(lp != lp); +done: return errcode; +} + +char *CPXgeterrorstring(CPXENV *env, int errcode, char *buffer) +{ const char *string; + xassert(env == env); + string = finderrstring(errcode); + if (string == NULL) + buffer = NULL; + else + sprintf(buffer, "CPLEX Error %5d: %s.\n", errcode, string); + return buffer; +} + +int CPXgetijdiv(CPXENV *env, CPXLP *lp, int *idiv, int *jdiv) +{ xassert(env == env); + xassert(lp == lp); + xassert(idiv == idiv); + xassert(jdiv == jdiv); + xprintf("CPXgetijdiv: not implemented yet\n"); + exit(EXIT_FAILURE); + return -1; +} + +int CPXgetintparam(CPXENV *env, int whichparam, int *value) +{ int k, errcode; + errcode = checkenv(env); + if (errcode) goto done; + k = findintparam(whichparam); + if (k < 0) + { errcode = error(env, CPXERR_BAD_PARAM_NUM); + goto done; + } + errcode = 0; + if (value != NULL) + *value = env->intparam[k]; +done: return errcode; +} + +int CPXgetlb(CPXENV *env, CPXLP *lp, double lb[], int begin, int end) +{ xassert(env == env); + xassert(lp == lp); + xassert(lb == lb); + xassert(begin == begin); + xassert(end == end); + xprintf("CPXgetlb: not implemented yet\n"); + exit(EXIT_FAILURE); + return -1; +} + +int CPXgetmethod(CPXENV *env, CPXLP *lp) +{ int method; + if (checklp(env, lp)) + method = CPX_ALG_NONE; + else + method = lp->meth; + return method; +} + +int CPXgetnumcols(CPXENV *env, CPXLP *lp) +{ int numcols; + if (checklp(env, lp)) + numcols = 0; + else + numcols = glp_get_num_cols(lp->prob); + return numcols; +} + +int CPXgetnumnz(CPXENV *env, CPXLP *lp) +{ int numnz; + if (checklp(env, lp)) + numnz = 0; + else + numnz = glp_get_num_nz(lp->prob); + return numnz; +} + +int CPXgetnumrows(CPXENV *env, CPXLP *lp) +{ int numrows; + if (checklp(env, lp)) + numrows = 0; + else + numrows = glp_get_num_rows(lp->prob); + return numrows; +} + +int CPXgetobjval(CPXENV *env, CPXLP *lp, double *objval) +{ int errcode; + errcode = checklp(env, lp); + if (errcode) goto done; + if (!lp->stat) + { errcode = error(env, CPXERR_NO_SOLN); + goto done; + } + errcode = 0; + if (lp->meth == CPX_ALG_PRIMAL || lp->meth == CPX_ALG_DUAL) + { if (objval != NULL) + *objval = glp_get_obj_val(lp->prob); + } + else + xassert(lp != lp); +done: return errcode; +} + +int CPXgetpi(CPXENV *env, CPXLP *lp, double pi[], int begin, int end) +{ int i, m, errcode; + errcode = checklp(env, lp); + if (errcode) goto done; + m = glp_get_num_rows(lp->prob); + if (!(0 <= begin && begin <= end && end < m)) + { errcode = error(env, CPXERR_INDEX_RANGE); + goto done; + } + if (!lp->stat) + { errcode = error(env, CPXERR_NO_SOLN); + goto done; + } + errcode = 0; + if (lp->meth == CPX_ALG_PRIMAL || lp->meth == CPX_ALG_DUAL) + { if (pi != NULL) + { for (i = begin; i <= end; i++) + pi[i-begin] = glp_get_row_dual(lp->prob, i+1); + } + } + else + xassert(lp != lp); +done: return errcode; +} + +int CPXgetsense(CPXENV *env, CPXLP *lp, char sense[], int begin, + int end) +{ xassert(env == env); + xassert(lp == lp); + xassert(sense == sense); + xassert(begin == begin); + xassert(end == end); + xprintf("CPXgetsense: not implemented yet\n"); + exit(EXIT_FAILURE); + return -1; +} + +int CPXgetslack(CPXENV *env, CPXLP *lp, double slack[], int begin, + int end) +{ int i, m, type, errcode; + double temp; + errcode = checklp(env, lp); + if (errcode) goto done; + m = glp_get_num_rows(lp->prob); + if (!(0 <= begin && begin <= end && end < m)) + { errcode = error(env, CPXERR_INDEX_RANGE); + goto done; + } + if (!lp->stat) + { errcode = error(env, CPXERR_NO_SOLN); + goto done; + } + errcode = 0; + if (lp->meth == CPX_ALG_PRIMAL || lp->meth == CPX_ALG_DUAL) + { if (slack != NULL) + { for (i = begin; i <= end; i++) + { type = glp_get_row_type(lp->prob, i+1); + temp = glp_get_row_prim(lp->prob, i+1); + if (lp->rflag[i] == RF_NOT_RANGED) + { if (type == GLP_LO || type == GLP_FX) + slack[i-begin] = + glp_get_row_lb(lp->prob, i+1) - temp; + else if (type == GLP_UP) + slack[i-begin] = + glp_get_row_ub(lp->prob, i+1) - temp; + else + xassert(type != type); + } + else if (lp->rflag[i] == RF_RANGED_POS) + { xassert(type == GLP_DB || type == GLP_FX); + slack[i-begin] = + temp - glp_get_row_lb(lp->prob, i+1); + } + else if (lp->rflag[i] == RF_RANGED_NEG) + { xassert(type == GLP_DB); + slack[i-begin] = + temp - glp_get_row_ub(lp->prob, i+1); + } + else + xassert(lp != lp); + } + } + } + else + xassert(lp != lp); +done: return errcode; +} + +int CPXgetstat(CPXENV *env, CPXLP *lp) +{ int stat; + if (checklp(env, lp)) + stat = 0; + else + stat = lp->stat; + return stat; +} + +int CPXgetub(CPXENV *env, CPXLP *lp, double ub[], int begin, int end) +{ xassert(env == env); + xassert(lp == lp); + xassert(ub == ub); + xassert(begin == begin); + xassert(end == end); + xprintf("CPXgetub: not implemented yet\n"); + exit(EXIT_FAILURE); + return -1; +} + +int CPXgetweight(CPXENV *env, CPXLP *lp, int rcnt, const int rmatbeg[], + const int rmatind[], const double rmatval[], double weight[], + int dpriind) +{ xassert(env == env); + xassert(lp == lp); + xassert(rcnt == rcnt); + xassert(rmatbeg == rmatbeg); + xassert(rmatind == rmatind); + xassert(rmatval == rmatval); + xassert(weight == weight); + xassert(dpriind == dpriind); + xprintf("CPXgetweight: not implemented yet\n"); + exit(EXIT_FAILURE); + return -1; +} + +int CPXgetx(CPXENV *env, CPXLP *lp, double x[], int begin, int end) +{ int j, n, errcode; + errcode = checklp(env, lp); + if (errcode) goto done; + n = glp_get_num_cols(lp->prob); + if (!(0 <= begin && begin <= end && end < n)) + { errcode = error(env, CPXERR_INDEX_RANGE); + goto done; + } + if (!lp->stat) + { errcode = error(env, CPXERR_NO_SOLN); + goto done; + } + errcode = 0; + if (lp->meth == CPX_ALG_PRIMAL || lp->meth == CPX_ALG_DUAL) + { if (x != NULL) + { for (j = begin; j <= end; j++) + x[j-begin] = glp_get_col_prim(lp->prob, j+1); + } + } + else + xassert(lp != lp); +done: return errcode; +} + +int CPXinfodblparam(CPXENV *env, int whichparam, double *defvalue, + double *minvalue, double *maxvalue) +{ int k, errcode; + errcode = checkenv(env); + if (errcode) goto done; + k = finddblparam(whichparam); + if (k < 0) + { errcode = error(env, CPXERR_BAD_PARAM_NUM); + goto done; + } + errcode = 0; + if (defvalue != NULL) + *defvalue = dblparam[k].defv; + if (minvalue != NULL) + *minvalue = dblparam[k].minv; + if (maxvalue != NULL) + *maxvalue = dblparam[k].maxv; +done: return errcode; +} + +int CPXinfointparam(CPXENV *env, int whichparam, int *defvalue, + int *minvalue, int *maxvalue) +{ int k, errcode; + errcode = checkenv(env); + if (errcode) goto done; + k = findintparam(whichparam); + if (k < 0) + { errcode = error(env, CPXERR_BAD_PARAM_NUM); + goto done; + } + errcode = 0; + if (defvalue != NULL) + *defvalue = intparam[k].defv; + if (minvalue != NULL) + *minvalue = intparam[k].minv; + if (maxvalue != NULL) + *maxvalue = intparam[k].maxv; +done: return errcode; +} + +int CPXmdleave(const CPXENV *env, CPXLP *lp, const int goodlist[], + int goodlen, double downratio[], double upratio[]) +{ int k; + xassert(env == env); + xassert(lp == lp); + xassert(goodlist == goodlist); + xassert(goodlen >= 0); + xassert(downratio != NULL); + xassert(upratio != NULL); + /* not implemented yet */ + for (k = 0; k < goodlen; k++) + downratio[k] = upratio[k] = 0.0; + return 0; +} + +int CPXnewcols(CPXENV *env, CPXLP *lp, int ccnt, const double obj[], + const double lb[], const double ub[], const char ctype[], + char *colname[]) +{ int j, n, kind, type, errcode; + double lbnd, ubnd; + errcode = checklp(env, lp); + if (errcode) goto done; + if (ccnt < 0) + { errcode = error(env, CPXERR_BAD_ARGUMENT); + goto done; + } + for (j = 0; j < ccnt; j++) + { if (ctype != NULL) + { if (!(ctype[j] == 'C' || ctype[j] == 'B' || + ctype[j] == 'I')) + { errcode = error(env, CPXERR_BAD_CTYPE, j); + goto done; + } + } + if (colname != NULL) + { if (colname[j] == NULL) + { errcode = error(env, CPXERR_NULL_NAME, j); + goto done; + } + } + } + errcode = 0; + invalidate(lp); + n = glp_get_num_cols(lp->prob); + if (ccnt > 0) + glp_add_cols(lp->prob, ccnt); + for (j = 0; j < ccnt; j++) + { if (colname != NULL) + glp_set_col_name(lp->prob, n+j+1, colname[j]); + if (obj != NULL) + glp_set_obj_coef(lp->prob, n+j+1, obj[j]); + lbnd = (lb == NULL ? 0.0 : lb[j]); + ubnd = (ub == NULL ? 0.0 : ub[j]); + if (lbnd <= -CPX_INFBOUND && ubnd >= +CPX_INFBOUND) + type = GLP_FR; + else if (ubnd >= +CPX_INFBOUND) + type = GLP_LO; + else if (lbnd <= -CPX_INFBOUND) + type = GLP_UP; + else if (lbnd != ubnd) + type = GLP_DB; + else + type = GLP_FX; + glp_set_col_bnds(lp->prob, n+j+1, type, lbnd, ubnd); + if (ctype != NULL) + { if (ctype[j] == 'C') + kind = GLP_CV; + else if (ctype[j] == 'B') + kind = GLP_BV; + else if (ctype[j] == 'I') + kind = GLP_IV; + else + xassert(ctype != ctype); + glp_set_col_kind(lp->prob, n+j+1, kind); + } + } +done: return errcode; +} + +int CPXnewrows(CPXENV *env, CPXLP *lp, int rcnt, const double rhs[], + const char sense[], const double rngval[], char *rowname[]) +{ int i, m, type, errcode; + double lbnd, ubnd; + errcode = checklp(env, lp); + if (errcode) goto done; + if (rcnt < 0) + { errcode = error(env, CPXERR_BAD_ARGUMENT); + goto done; + } + for (i = 0; i < rcnt; i++) + { if (sense != NULL) + { if (!(sense[i] == 'L' || sense[i] == 'E' || + sense[i] == 'G' || sense[i] == 'R')) + { errcode = error(env, CPXERR_BAD_SENSE, i); + goto done; + } + } + if (rowname != NULL) + { if (rowname[i] == NULL) + { errcode = error(env, CPXERR_NULL_NAME, i); + goto done; + } + } + } + errcode = 0; + invalidate(lp); + m = glp_get_num_rows(lp->prob); + if (rcnt > 0) + glp_add_rows(lp->prob, rcnt); + enlargerflag(lp); + for (i = 0; i < rcnt; i++) + { if (rowname != NULL) + glp_set_row_name(lp->prob, m+i+1, rowname[i]); + lbnd = ubnd = (rhs == NULL ? 0.0 : rhs[i]); + if (sense == NULL || sense[i] == 'E') + { lp->rflag[m+i] = RF_NOT_RANGED; + type = GLP_FX; + } + else if (sense[i] == 'L') + { lp->rflag[m+i] = RF_NOT_RANGED; + type = GLP_UP; + } + else if (sense[i] == 'G') + { lp->rflag[m+i] = RF_NOT_RANGED; + type = GLP_LO; + } + else if (sense[i] == 'R') + { if (rngval == NULL || rngval[i] == 0.0) + { lp->rflag[m+i] = RF_RANGED_POS; + type = GLP_FX; + } + else if (rngval[i] > 0.0) + { lp->rflag[m+i] = RF_RANGED_POS; + type = GLP_DB; + ubnd += rngval[i]; + } + else /* rngval[i] < 0.0 */ + { lp->rflag[m+i] = RF_RANGED_NEG; + type = GLP_DB; + lbnd += rngval[i]; + } + } + else + xassert(sense != sense); + glp_set_row_bnds(lp->prob, m+i+1, type, lbnd, ubnd); + } +done: return errcode; +} + +CPXENV *CPXopenCPLEX(int *status) +{ CPXENV *env; + int k, card; + env = xmalloc(sizeof(CPXENV)); + env->list = NULL; + card = sizeof(intparam) / sizeof(struct intparam); + env->intparam = xcalloc(card, sizeof(int)); + for (k = 0; k < card; k++) + env->intparam[k] = intparam[k].defv; + card = sizeof(dblparam) / sizeof(struct dblparam); + env->dblparam = xcalloc(card, sizeof(double)); + for (k = 0; k < card; k++) + env->dblparam[k] = dblparam[k].defv; + if (status != NULL) *status = 0; + return env; +} + +int CPXpivotin(CPXENV *env, CPXLP *lp, const int rlist[], int rlen) +{ int i, m, errcode; + errcode = checklp(env, lp); + if (errcode) goto done; + if (rlen < 0) + { errcode = error(env, CPXERR_BAD_ARGUMENT); + goto done; + } + if (rlen > 0 && rlist == NULL) + { errcode = error(env, CPXERR_NULL_POINTER); + goto done; + } + m = glp_get_num_rows(lp->prob); + for (i = 0; i < rlen; i++) + { if (!(0 <= rlist[i] && rlist[i] < m)) + { errcode = error(env, CPXERR_ROW_INDEX_RANGE, i); + goto done; + } + } + errcode = 0; + for (i = 0; i < rlen; i++) + { if (glp_get_row_type(lp->prob, rlist[i]+1) != GLP_FX) + { if (glp_get_row_stat(lp->prob, rlist[i]+1) != GLP_BS) + { /* not implemented yet */ + break; + } + } + } +done: return errcode; +} + +int CPXpivotout(CPXENV *env, CPXLP *lp, const int clist[], int clen) +{ int j, n, errcode; + errcode = checklp(env, lp); + if (errcode) goto done; + if (clen < 0) + { errcode = error(env, CPXERR_BAD_ARGUMENT); + goto done; + } + if (clen > 0 && clist == NULL) + { errcode = error(env, CPXERR_NULL_POINTER); + goto done; + } + n = glp_get_num_cols(lp->prob); + for (j = 0; j < clen; j++) + { if (!(0 <= clist[j] && clist[j] < n)) + { errcode = error(env, CPXERR_COL_INDEX_RANGE, j); + goto done; + } + if (glp_get_col_type(lp->prob, clist[j]+1) != GLP_FX) + { errcode = error(env, CPXERR_NOT_FIXED); + goto done; + } + } + errcode = 0; + for (j = 0; j < clen; j++) + { if (glp_get_col_stat(lp->prob, clist[j]+1) == GLP_BS) + { /* not implemented yet */ + break; + } + } +done: return errcode; +} + +int CPXprimopt(CPXENV *env, CPXLP *lp); + +int CPXsavwrite(CPXENV *env, CPXLP *lp, const char *filename) +{ xassert(env == env); + xassert(lp == lp); + xassert(filename == filename); + xprintf("CPXsavwrite: not implemented yet\n"); + exit(EXIT_FAILURE); + return -1; +} + +int CPXsetdblparam(CPXENV *env, int whichparam, double newvalue) +{ int k, errcode; + errcode = checkenv(env); + if (errcode) goto done; + k = finddblparam(whichparam); + if (k < 0) + { errcode = error(env, CPXERR_BAD_PARAM_NUM); + goto done; + } + if (newvalue < dblparam[k].minv) + { errcode = error(env, CPXERR_PARAM_TOO_SMALL); + goto done; + } + if (newvalue > dblparam[k].maxv) + { errcode = error(env, CPXERR_PARAM_TOO_BIG); + goto done; + } + errcode = 0; + env->dblparam[k] = newvalue; +done: return errcode; +} + +int CPXsetintparam(CPXENV *env, int whichparam, int newvalue) +{ int k, errcode; + errcode = checkenv(env); + if (errcode) goto done; + k = findintparam(whichparam); + if (k < 0) + { errcode = error(env, CPXERR_BAD_PARAM_NUM); + goto done; + } + if (newvalue < intparam[k].minv) + { errcode = error(env, CPXERR_PARAM_TOO_SMALL); + goto done; + } + if (newvalue > intparam[k].maxv) + { errcode = error(env, CPXERR_PARAM_TOO_BIG); + goto done; + } + errcode = 0; + env->intparam[k] = newvalue; +done: return errcode; +} + +int CPXsolninfo(CPXENV *env, CPXLP *lp, int *solnmethod, int *solntype, + int *pfeasind, int *dfeasind) +{ int type, pfeas, dfeas, errcode; + errcode = checklp(env, lp); + if (errcode) goto done; + errcode = 0; + if (!lp->stat) + type = CPX_NO_SOLN, pfeas = dfeas = 0; + else if (lp->meth == CPX_ALG_PRIMAL || lp->meth == CPX_ALG_DUAL) + { type = CPX_BASIC_SOLN; + pfeas = (glp_get_prim_stat(lp->prob) == GLP_FEAS); + dfeas = (glp_get_dual_stat(lp->prob) == GLP_FEAS); + } + else + xassert(lp != lp); + if (solnmethod != NULL) + *solnmethod = lp->meth; + if (solntype != NULL) + *solntype = type; + if (pfeasind != NULL) + *pfeasind = pfeas; + if (dfeasind != NULL) + *dfeasind = dfeas; +done: return errcode; +} + +int CPXsolution(CPXENV *env, CPXLP *lp, int *lpstat, double *objval, + double x[], double pi[], double slack[], double dj[]) +{ int m, n, errcode; + errcode = checklp(env, lp); + if (errcode) goto done; + if (!lp->stat) + { errcode = error(env, CPXERR_NO_SOLN); + goto done; + } + errcode = 0; + m = glp_get_num_rows(lp->prob); + n = glp_get_num_cols(lp->prob); + if (lp->meth == CPX_ALG_PRIMAL || lp->meth == CPX_ALG_DUAL) + { if (lpstat != NULL) + *lpstat = CPXgetstat(env, lp); + if (objval != NULL) + xassert(CPXgetobjval(env, lp, objval) == 0); + if (x != NULL) + xassert(CPXgetx(env, lp, x, 0, n-1) == 0); + if (pi != NULL) + xassert(CPXgetpi(env, lp, pi, 0, m-1) == 0); + if (slack != NULL) + xassert(CPXgetslack(env, lp, slack, 0, m-1) == 0); + if (dj != NULL) + xassert(CPXgetdj(env, lp, dj, 0, n-1) == 0); + } + else + xassert(lp != lp); +done: return errcode; +} + +int CPXstrongbranch(CPXENV *env, CPXLP *lp, const int goodlist[], + int goodlen, double downpen[], double uppen[], int itlim) +{ int k; + xassert(env == env); + xassert(lp == lp); + xassert(goodlist == goodlist); + xassert(goodlen >= 0); + xassert(downpen != NULL); + xassert(uppen != NULL); + xassert(itlim == itlim); + /* not implemented yet */ + for (k = 0; k < goodlen; k++) + downpen[k] = uppen[k] = 0.0; + return 0; +} + +static int xstrcasecmp(const char *s1, const char *s2) +{ int c1, c2; + for (;;) + { c1 = toupper((unsigned char)*s1++); + c2 = toupper((unsigned char)*s2++); + if (c1 == '\0' || c1 != c2) break; + } + return c1 - c2; +} + +static void getfiletype(const char *filename, char type[3+1]) +{ /* determine filetype from filename */ + int beg, end; + beg = end = strlen(filename); + while (beg > 0 && filename[beg-1] != '.' && end - beg < 3) + beg--; + if (beg > 0 && filename[beg-1] == '.' && + xstrcasecmp(&filename[beg], "gz") == 0) + { end = --beg; + while (beg > 0 && filename[beg-1] != '.' && end - beg < 3) + beg--; + } + if (beg > 0 && filename[beg-1] == '.') + { memcpy(type, &filename[beg], end - beg); + type[end - beg] = '\0'; + } + else + type[0] = '\0'; + return; +} + +int CPXwriteprob(CPXENV *env, CPXLP *lp, const char *filename, + const char *filetype) +{ glp_prob *copy; + int errcode; + char type[3+1]; + errcode = checklp(env, lp); + if (errcode) goto done; + if (filename == NULL) + { errcode = error(env, CPXERR_NO_FILENAME); + goto done; + } + if (filetype == NULL) + getfiletype(filename, type), filetype = type; + if (xstrcasecmp(filetype, "MPS") == 0) + { glp_term_out(GLP_OFF); + errcode = glp_write_mps(lp->prob, GLP_MPS_FILE, NULL, filename) + ; + glp_term_out(GLP_ON); + } + else if (xstrcasecmp(filetype, "LP") == 0) + { glp_term_out(GLP_OFF); + errcode = glp_write_lp(lp->prob, NULL, filename); + glp_term_out(GLP_ON); + } + else if (xstrcasecmp(filetype, "RMP") == 0 || + xstrcasecmp(filetype, "REW") == 0) + { copy = glp_create_prob(); + glp_copy_prob(copy, lp->prob, GLP_OFF); + glp_term_out(GLP_OFF); + errcode = glp_write_mps(copy, GLP_MPS_DECK, NULL, filename); + glp_term_out(GLP_ON); + glp_delete_prob(copy); + } + else if (xstrcasecmp(filetype, "RLP") == 0) + { copy = glp_create_prob(); + glp_copy_prob(copy, lp->prob, GLP_OFF); + glp_term_out(GLP_OFF); + errcode = glp_write_lp(copy, NULL, filename); + glp_term_out(GLP_ON); + glp_delete_prob(copy); + } + else + { errcode = error(env, CPXERR_BAD_FILETYPE); + goto done; + } + if (errcode) + errcode = error(env, CPXERR_FAIL_OPEN_WRITE, filename); +done: return errcode; +} + +/**********************************************************************/ + +static int solvelp(CPXENV *env, CPXLP *lp, int meth) +{ glp_smcp parm; + int errcode; + errcode = checklp(env, lp); + if (errcode) goto done; + errcode = 0; + invalidate(lp); + glp_init_smcp(&parm); + switch (meth) + { case CPX_ALG_PRIMAL: + parm.meth = GLP_PRIMAL; + break; + case CPX_ALG_DUAL: + parm.meth = GLP_DUAL; + break; + default: + xassert(meth != meth); + } + switch (getintparam(env, CPX_PARAM_SIMDISPLAY)) + { case 0: + parm.msg_lev = GLP_MSG_OFF; + break; + case 1: + parm.msg_lev = GLP_MSG_ALL; + break; + case 2: + parm.msg_lev = GLP_MSG_ALL; + parm.out_frq = 1; + break; + default: + xassert(env != env); + } + xassert(getdblparam == getdblparam); + switch (getintparam(env, CPX_PARAM_ADVIND)) + { case 0: + glp_term_out(GLP_OFF); + glp_adv_basis(lp->prob, 0); + glp_term_out(GLP_ON); + break; + case 1: + case 2: + break; + default: + xassert(env != env); + } + if (!glp_bf_exists(lp->prob)) + { if (glp_factorize(lp->prob) != 0) + { glp_term_out(GLP_OFF); + glp_adv_basis(lp->prob, 0); + glp_term_out(GLP_ON); + if (glp_factorize(lp->prob) != 0) + glp_std_basis(lp->prob); + } + } + xassert(glp_simplex(lp->prob, &parm) == 0); + switch (glp_get_status(lp->prob)) + { case GLP_OPT: + lp->stat = CPX_STAT_OPTIMAL; + lp->meth = meth; + break; + case GLP_NOFEAS: + lp->stat = CPX_STAT_INFEASIBLE; + lp->meth = meth; + break; + case GLP_UNBND: + lp->stat = CPX_STAT_UNBOUNDED; + lp->meth = meth; + break; + default: + xassert(lp != lp); + } +done: return errcode; +} + +int CPXprimopt(CPXENV *env, CPXLP *lp) +{ int errcode; + errcode = solvelp(env, lp, CPX_ALG_PRIMAL); + return errcode; +} + +int CPXdualopt(CPXENV *env, CPXLP *lp) +{ int errcode; + errcode = solvelp(env, lp, CPX_ALG_DUAL); + return errcode; +} + +int CPXlpopt(CPXENV *env, CPXLP *lp) +{ int errcode; + errcode = solvelp(env, lp, CPX_ALG_PRIMAL); + return errcode; +} + +/* eof */ diff --git a/glpk-5.0/examples/cplex/cplex.h b/glpk-5.0/examples/cplex/cplex.h new file mode 100644 index 0000000..f9c64dc --- /dev/null +++ b/glpk-5.0/examples/cplex/cplex.h @@ -0,0 +1,298 @@ +/* cplex.h (CPLEX-like interface to GLPK API) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* Copyright (C) 2001-2013 Free Software Foundation, Inc. +* Written by Andrew Makhorin <mao@gnu.org>. +* +* 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 3 of the License, 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. If not, see <http://www.gnu.org/licenses/>. +***********************************************************************/ + +#ifndef _CPLEX_H +#define _CPLEX_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct CPXENV CPXENV, *CPXENVptr; +typedef struct CPXLP CPXLP, *CPXLPptr; + +#define CPX_VERSION 900 + +#define CPX_OFF 0 +#define CPX_ON 1 + +#define CPX_INFBOUND 1e20 + +/* error codes: */ +#define CPXERR_NO_MEMORY 1001 +#define CPXERR_NO_ENVIRONMENT 1002 +#define CPXERR_BAD_ARGUMENT 1003 +#define CPXERR_NULL_POINTER 1004 +#define CPXERR_NO_PROBLEM 1009 +#define CPXERR_BAD_PARAM_NUM 1013 +#define CPXERR_PARAM_TOO_SMALL 1014 +#define CPXERR_PARAM_TOO_BIG 1015 +#define CPXERR_INDEX_RANGE 1200 +#define CPXERR_COL_INDEX_RANGE 1201 +#define CPXERR_ROW_INDEX_RANGE 1203 +#define CPXERR_NEGATIVE_SURPLUS 1207 +#define CPXERR_BAD_SENSE 1215 +#define CPXERR_NO_SOLN 1217 +#define CPXERR_NOT_FIXED 1221 +#define CPXERR_DUP_ENTRY 1222 +#define CPXERR_NULL_NAME 1224 +#define CPXERR_ARRAY_NOT_ASCENDING 1226 +#define CPXERR_COUNT_RANGE 1227 +#define CPXERR_BAD_LUB 1229 +#define CPXERR_BAD_STATUS 1253 +#define CPXERR_NO_BASIC_SOLN 1261 +#define CPXERR_NO_FILENAME 1421 +#define CPXERR_FAIL_OPEN_WRITE 1422 +#define CPXERR_BAD_FILETYPE 1424 +#define CPXERR_BAD_CTYPE 3021 + +/* control parameters: */ +#define CPX_PARAM_ADVIND 1001 +#define CPX_PARAM_AGGIND 1003 +#define CPX_PARAM_DPRIIND 1009 +#define CPX_PARAM_EPOPT 1014 +#define CPX_PARAM_EPPER 1015 +#define CPX_PARAM_EPRHS 1016 +#define CPX_PARAM_FASTMIP 1017 /* ??? */ +#define CPX_PARAM_SIMDISPLAY 1019 +#define CPX_PARAM_ITLIM 1020 +#define CPX_PARAM_OBJLLIM 1025 +#define CPX_PARAM_OBJULIM 1026 +#define CPX_PARAM_PERIND 1027 +#define CPX_PARAM_PPRIIND 1029 +#define CPX_PARAM_PREIND 1030 +#define CPX_PARAM_REINV 1031 +#define CPX_PARAM_SCRIND 1035 +#define CPX_PARAM_DATACHECK 1056 + +/* CPX_PARAM_DPRIIND: */ +#define CPX_DPRIIND_AUTO 0 +#define CPX_DPRIIND_FULL 1 +#define CPX_DPRIIND_STEEP 2 +#define CPX_DPRIIND_FULL_STEEP 3 +#define CPX_DPRIIND_STEEPQSTART 4 +#define CPX_DPRIIND_DEVEX 5 + +/* CPX_PARAM_PPRIIND: */ +#define CPX_PPRIIND_PARTIAL (-1) +#define CPX_PPRIIND_AUTO 0 +#define CPX_PPRIIND_DEVEX 1 +#define CPX_PPRIIND_STEEP 2 +#define CPX_PPRIIND_STEEPQSTART 3 +#define CPX_PPRIIND_FULL 4 + +/* CPXgetprobtype: */ +#define CPXPROB_LP 0 +#define CPXPROB_MIP 1 +#define CPXPROB_RELAXED 2 +#define CPXPROB_FIXED 3 +#define CPXPROB_QP 5 +#define CPXPROB_ZEROEDQP 6 + +/* CPXgetobjsen: */ +#define CPX_MIN 1 +#define CPX_MAX (-1) + +/* CPXgetbase: */ +#define CPX_AT_LOWER 0 +#define CPX_BASIC 1 +#define CPX_AT_UPPER 2 +#define CPX_FREE_SUPER 3 + +/* CPXgetstat: */ +#define CPX_STAT_OPTIMAL 1 +#define CPX_STAT_UNBOUNDED 2 +#define CPX_STAT_INFEASIBLE 3 +#define CPX_STAT_INForUNBD 4 +#define CPX_STAT_OPTIMAL_INFEAS 5 +#define CPX_STAT_ABORT_IT_LIM 10 +#define CPX_STAT_ABORT_OBJ_LIM 12 + +/* CPXgetmethod: */ +#define CPX_ALG_NONE 0 +#define CPX_ALG_PRIMAL 1 +#define CPX_ALG_DUAL 2 +#define CPX_ALG_BARRIER 4 + +/* CPXsolninfo: */ +#define CPX_NO_SOLN 0 +#define CPX_BASIC_SOLN 1 +#define CPX_NONBASIC_SOLN 2 +#define CPX_PRIMAL_SOLN 3 + +int CPXaddcols(CPXENV *env, CPXLP *lp, int ccnt, int nzcnt, + const double obj[], const int cmatbeg[], const int cmatind[], + const double cmatval[], const double lb[], const double ub[], + char *colname[]); + +int CPXaddrows(CPXENV *env, CPXLP *lp, int ccnt, int rcnt, int nzcnt, + const double rhs[], const char sense[], const int rmatbeg[], + const int rmatind[], const double rmatval[], char *colname[], + char *rowname[]); + +int CPXbaropt(CPXENV *env, CPXLP *lp); + +int CPXbinvrow(CPXENV *env, CPXLP *lp, int i, double y[]); + +int CPXchgbds(CPXENV *env, CPXLP *lp, int cnt, const int indices[], + const char lu[], const double bd[]); + +int CPXchgcoeflist(CPXENV *env, CPXLP *lp, int numcoefs, + const int rowlist[], const int collist[], const double vallist[]); + +void CPXchgobjsen(CPXENV *env, CPXLP *lp, int maxormin); + +int CPXchgsense(CPXENV *env, CPXLP *lp, int cnt, const int indices[], + const char sense[]); + +int CPXcloseCPLEX(CPXENV **env); + +int CPXcopybase(CPXENV *env, CPXLP *lp, const int cstat[], + const int rstat[]); + +int CPXcopybasednorms(CPXENV *env, CPXLP *lp, const int cstat[], + const int rstat[], const double dnorm[]); + +int CPXcopylp(CPXENV *env, CPXLP *lp, int numcols, int numrows, + int objsen, const double obj[], const double rhs[], + const char sense[], const int matbeg[], const int matcnt[], + const int matind[], const double matval[], const double lb[], + const double ub[], const double rngval[]); + +int CPXcopylpwnames(CPXENV *env, CPXLP *lp, int numcols, int numrows, + int objsen, const double obj[], const double rhs[], + const char sense[], const int matbeg[], const int matcnt[], + const int matind[], const double matval[], const double lb[], + const double ub[], const double rngval[], char *colname[], + char *rowname[]); + +CPXLP *CPXcreateprob(CPXENV *env, int *status, const char *probname); + +int CPXdelcols(CPXENV *env, CPXLP *lp, int begin, int end); + +int CPXdelrows(CPXENV *env, CPXLP *lp, int begin, int end); + +int CPXdelsetcols(CPXENV *env, CPXLP *lp, int delstat[]); + +int CPXdelsetrows(CPXENV *env, CPXLP *lp, int delstat[]); + +int CPXdualopt(CPXENV *env, CPXLP *lp); + +int CPXfreeprob(CPXENV *env, CPXLP **lp); + +int CPXgetbase(CPXENV *env, CPXLP *lp, int cstat[], int rstat[]); + +int CPXgetbasednorms(CPXENV *env, CPXLP *lp, int cstat[], int rstat[], + double dnorm[]); + +int CPXgetbhead(CPXENV *env, CPXLP *lp, int head[], double x[]); + +int CPXgetdblparam(CPXENV *env, int whichparam, double *value); + +int CPXgetdj(CPXENV *env, CPXLP *lp, double dj[], int begin, int end); + +char *CPXgeterrorstring(CPXENV *env, int errcode, char *buffer); + +int CPXgetijdiv(CPXENV *env, CPXLP *lp, int *idiv, int *jdiv); + +int CPXgetintparam(CPXENV *env, int whichparam, int *value); + +int CPXgetlb(CPXENV *env, CPXLP *lp, double lb[], int begin, int end); + +int CPXgetmethod(CPXENV *env, CPXLP *lp); + +int CPXgetnumcols(CPXENV *env, CPXLP *lp); + +int CPXgetnumnz(CPXENV *env, CPXLP *lp); + +int CPXgetnumrows(CPXENV *env, CPXLP *lp); + +int CPXgetobjval(CPXENV *env, CPXLP *lp, double *objval); + +int CPXgetpi(CPXENV *env, CPXLP *lp, double pi[], int begin, int end); + +int CPXgetsense(CPXENV *env, CPXLP *lp, char sense[], int begin, + int end); + +int CPXgetslack(CPXENV *env, CPXLP *lp, double slack[], int begin, + int end); + +int CPXgetstat(CPXENV *env, CPXLP *lp); + +int CPXgetub(CPXENV *env, CPXLP *lp, double ub[], int begin, int end); + +int CPXgetweight(CPXENV *env, CPXLP *lp, int rcnt, const int rmatbeg[], + const int rmatind[], const double rmatval[], double weight[], + int dpriind); + +int CPXgetx(CPXENV *env, CPXLP *lp, double x[], int begin, int end); + +int CPXinfodblparam(CPXENV *env, int whichparam, double *defvalue, + double *minvalue, double *maxvalue); + +int CPXinfointparam(CPXENV *env, int whichparam, int *defvalue, + int *minvalue, int *maxvalue); + +int CPXlpopt(CPXENV *env, CPXLP *lp); + +int CPXmdleave(const CPXENV *env, CPXLP *lp, const int goodlist[], + int goodlen, double downratio[], double upratio[]); + +int CPXnewcols(CPXENV *env, CPXLP *lp, int ccnt, const double obj[], + const double lb[], const double ub[], const char ctype[], + char *colname[]); + +int CPXnewrows(CPXENV *env, CPXLP *lp, int rcnt, const double rhs[], + const char sense[], const double rngval[], char *rowname[]); + +CPXENV *CPXopenCPLEX(int *status); + +int CPXpivotin(CPXENV *env, CPXLP *lp, const int rlist[], int rlen); + +int CPXpivotout(CPXENV *env, CPXLP *lp, const int clist[], int clen); + +int CPXprimopt(CPXENV *env, CPXLP *lp); + +int CPXsavwrite(CPXENV *env, CPXLP *lp, const char *filename); + +int CPXsetdblparam(CPXENV *env, int whichparam, double newvalue); + +int CPXsetintparam(CPXENV *env, int whichparam, int newvalue); + +int CPXsolninfo(CPXENV *env, CPXLP *lp, int *solnmethod, int *solntype, + int *pfeasind, int *dfeasind); + +int CPXsolution(CPXENV *env, CPXLP *lp, int *lpstat, double *objval, + double x[], double pi[], double slack[], double dj[]); + +int CPXstrongbranch(CPXENV *env, CPXLP *lp, const int goodlist[], + int goodlen, double downpen[], double uppen[], int itlim); + +int CPXwriteprob(CPXENV *env, CPXLP *lp, const char *filename, + const char *filetype); + +#ifdef __cplusplus +} +#endif + +#endif + +/* eof */ diff --git a/glpk-5.0/examples/cpp.mod b/glpk-5.0/examples/cpp.mod new file mode 100644 index 0000000..af3f120 --- /dev/null +++ b/glpk-5.0/examples/cpp.mod @@ -0,0 +1,67 @@ +/* CPP, Critical Path Problem */ + +/* Written in GNU MathProg by Andrew Makhorin <mao@gnu.org> */ + +/* Note: Reduced costs of auxiliary variables phi[j,k] (see below) + can be only zero or one. The critical path is defined by the + constraints, whose reduced cost is one. */ + +set J; +/* set of jobs (activities) */ + +set P{j in J}, in J, default {}; +/* P[j] is a subset of jobs that immediately precede job j */ + +param t{j in J}, >= 0; +/* duration required to perform job j */ + +var x{j in J}, >= 0; +/* starting time of job j */ + +s.t. phi{j in J, k in P[j]}: x[j] >= x[k] + t[k]; +/* job j can start only after all immediately preceding jobs have been + completely performed */ + +var z; +/* project makespan */ + +s.t. fin{j in J}: z >= x[j] + t[j]; +/* which is the maximum of the completion times of all the jobs */ + +minimize obj: z; +/* the objective is make z as small as possible */ + +data; + +/* The optimal solution is 46 */ + +param : J : t := + A 3 /* Excavate */ + B 4 /* Lay foundation */ + C 3 /* Rough plumbing */ + D 10 /* Frame */ + E 8 /* Finish exterior */ + F 4 /* Install HVAC */ + G 6 /* Rough electric */ + H 8 /* Sheet rock */ + I 5 /* Install cabinets */ + J 5 /* Paint */ + K 4 /* Final plumbing */ + L 2 /* Final electric */ + M 4 /* Install flooring */ +; + +set P[B] := A; +set P[C] := B; +set P[D] := B; +set P[E] := D; +set P[F] := D; +set P[G] := D; +set P[H] := C E F G; +set P[I] := H; +set P[J] := H; +set P[K] := I; +set P[L] := J; +set P[M] := K L; + +end; diff --git a/glpk-5.0/examples/crypto.mod b/glpk-5.0/examples/crypto.mod new file mode 100644 index 0000000..bad5032 --- /dev/null +++ b/glpk-5.0/examples/crypto.mod @@ -0,0 +1,84 @@ +/* CRYPTO, a crypto-arithmetic puzzle */ + +/* Written in GNU MathProg by Andrew Makhorin <mao@gnu.org> */ + +/* This problem comes from the newsgroup rec.puzzle. + The numbers from 1 to 26 are assigned to the letters of the alphabet. + The numbers beside each word are the total of the values assigned to + the letters in the word (e.g. for LYRE: L, Y, R, E might be to equal + 5, 9, 20 and 13, or any other combination that add up to 47). + Find the value of each letter under the equations: + + BALLET 45 GLEE 66 POLKA 59 SONG 61 + CELLO 43 JAZZ 58 QUARTET 50 SOPRANO 82 + CONCERT 74 LYRE 47 SAXOPHONE 134 THEME 72 + FLUTE 30 OBOE 53 SCALE 51 VIOLIN 100 + FUGUE 50 OPERA 65 SOLO 37 WALTZ 34 + + Solution: + A, B,C, D, E,F, G, H, I, J, K,L,M, N, O, P,Q, R, S,T,U, V,W, X, Y, Z + 5,13,9,16,20,4,24,21,25,17,23,2,8,12,10,19,7,11,15,3,1,26,6,22,14,18 + + Reference: + Koalog Constraint Solver <http://www.koalog.com/php/jcs.php>, + Simple problems, the crypto-arithmetic puzzle ALPHACIPHER. */ + +set LETTERS := +{ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', + 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' +}; +/* set of letters */ + +set VALUES := 1..card(LETTERS); +/* set of values assigned to the letters */ + +set WORDS; +/* set of words */ + +param total{word in WORDS}; +/* total[word] is the total of the values assigned to the letters in + the word */ + +var x{i in LETTERS, j in VALUES}, binary; +/* x[i,j] = 1 means that letter i is assigned value j */ + +s.t. phi{i in LETTERS}: sum{j in VALUES} x[i,j] = 1; + +s.t. psi{j in VALUES}: sum{i in LETTERS} x[i,j] = 1; + +s.t. eqn{word in WORDS}: sum{k in 1..length(word), j in VALUES} + j * x[substr(word,k,1), j] = total[word]; + +solve; + +printf{i in LETTERS} " %s", i; +printf "\n"; + +printf{i in LETTERS} " %2d", sum{j in VALUES} j * x[i,j]; +printf "\n"; + +data; + +param : WORDS : total := + BALLET 45 + CELLO 43 + CONCERT 74 + FLUTE 30 + FUGUE 50 + GLEE 66 + JAZZ 58 + LYRE 47 + OBOE 53 + OPERA 65 + POLKA 59 + QUARTET 50 + SAXOPHONE 134 + SCALE 51 + SOLO 37 + SONG 61 + SOPRANO 82 + THEME 72 + VIOLIN 100 + WALTZ 34 ; + +end; diff --git a/glpk-5.0/examples/csv/distances.csv b/glpk-5.0/examples/csv/distances.csv new file mode 100644 index 0000000..8c7b419 --- /dev/null +++ b/glpk-5.0/examples/csv/distances.csv @@ -0,0 +1,7 @@ +plant,market,distance +"Seattle","New York",2.5 +"Seattle","Chicago",1.7 +"Seattle","Topeka",1.8 +"San Diego","New York",2.5 +"San Diego","Chicago",1.8 +"San Diego","Topeka",1.4 diff --git a/glpk-5.0/examples/csv/markets.csv b/glpk-5.0/examples/csv/markets.csv new file mode 100644 index 0000000..d04dec8 --- /dev/null +++ b/glpk-5.0/examples/csv/markets.csv @@ -0,0 +1,4 @@ +market,demand +"New York",325. +"Chicago",300. +"Topeka",275. diff --git a/glpk-5.0/examples/csv/parameters.csv b/glpk-5.0/examples/csv/parameters.csv new file mode 100644 index 0000000..c7c37e9 --- /dev/null +++ b/glpk-5.0/examples/csv/parameters.csv @@ -0,0 +1,2 @@ +parameter,value +"transport cost",90. diff --git a/glpk-5.0/examples/csv/plants.csv b/glpk-5.0/examples/csv/plants.csv new file mode 100644 index 0000000..292f45f --- /dev/null +++ b/glpk-5.0/examples/csv/plants.csv @@ -0,0 +1,3 @@ +plant,capacity +"Seattle",350. +"San Diego",600. diff --git a/glpk-5.0/examples/csv/transp_csv.mod b/glpk-5.0/examples/csv/transp_csv.mod new file mode 100644 index 0000000..d970bf6 --- /dev/null +++ b/glpk-5.0/examples/csv/transp_csv.mod @@ -0,0 +1,70 @@ +# A TRANSPORTATION PROBLEM +# +# This problem finds a least cost shipping schedule that meets +# requirements at markets and supplies at factories. +# +# References: +# Dantzig G B, "Linear Programming and Extensions." +# Princeton University Press, Princeton, New Jersey, 1963, +# Chapter 3-3. + +set I; +/* canning plants */ + +set J; +/* markets */ + +set K dimen 2; +/* transportation lane */ + +set L; +/* parameters */ + +param a{i in I}; +/* capacity of plant i in cases */ + +param b{j in J}; +/* demand at market j in cases */ + +param d{i in I, j in J}; +/* distance in thousands of miles */ + +param e{l in L}; +/* parameters */ + +param f; +/* freight in dollars per case per thousand miles */ + +table tab_plant IN "CSV" "plants.csv" : + I <- [plant], a ~ capacity; + +table tab_market IN "CSV" "markets.csv" : + J <- [market], b ~ demand; + +table tab_distance IN "CSV" "distances.csv" : + K <- [plant, market], d ~ distance; + +table tab_parameter IN "CSV" "parameters.csv" : + L <- [parameter], e ~ value ; + +param c{i in I, j in J} := e['transport cost'] * d[i,j] / 1000; +/* transport cost in thousands of dollars per case */ + +var x{(i,j) in K} >= 0; +/* shipment quantities in cases */ + +minimize cost: sum{(i,j) in K} c[i,j] * x[i,j]; +/* total transportation costs in thousands of dollars */ + +s.t. supply{i in I}: sum{(i,j) in K} x[i,j] <= a[i]; +/* observe supply limit at plant i */ + +s.t. demand{j in J}: sum{(i,j) in K} x[i,j] >= b[j]; +/* satisfy demand at market j */ + +solve; + +table tab_result{(i,j) in K} OUT "CSV" "result.csv" : + i ~ plant, j ~ market, x[i,j] ~ shipment; + +end; diff --git a/glpk-5.0/examples/dbf/ForestMgt_Model_I_GIS_dbf.mod b/glpk-5.0/examples/dbf/ForestMgt_Model_I_GIS_dbf.mod new file mode 100644 index 0000000..2048467 --- /dev/null +++ b/glpk-5.0/examples/dbf/ForestMgt_Model_I_GIS_dbf.mod @@ -0,0 +1,226 @@ +# Model I Forest Estate Modelling using GLPK/MathProg +# Reading and writing dbf files + +# by Noli Sicad --- nsicad@gmail.com +# 18 December 2009 + +# Forest Management 4th Edition +# by Lawrence Davis, K. Norman Johnson, Pete Bettinger, Theodore Howard +# Chapter 11 - Daniel Pickett +# http://warnell.forestry.uga.edu/Warnell/Bettinger/mgtbook/index.htm + +# Model I Formulation + +/* Note: This is not the full LP model mentioned in the book. +Some of the constraints are deliberately omitted in this model for the purpose of clarity. + +The features of MathProg in this example are: +* reading and writing dbf from regular dbf files, +* reading dbf file (database of shapefile (stands.shp)) (e.g. area parameter), +* using the area data in the constraints and +* writing dbf file from result of LP model. + +Model I - Harvest Scheduling formulation for Sustainable Forest Management (SFM) + +Features are: +* Net Present Value for the objective function (Revenue - Cost) +* Harvest Constraints by period - Sustainable Yield per Period +* Even-Flow Constraint / Volume - Harvest Flow Constraint - Alpha (1-Apha) +* Even-Flow Constraint / Volume - Harvest Flow Constraint - Beta (1 +Beta) +* Forest / Land Constraint -- Total Area of the forest +* Forest Stand Constraint -- Individual stands + +What is next? -- Forest Mgt Carbon Accounting for Climate Change + +Note: The model file that the data containing in +the dbf files is public domain material (so it is compatible with the +GNU GPL) and data can be found in +http://warnell.forestry.uga.edu/Warnell/Bettinger/mgtbook/index.htm + +# Noli Sicad --- nsicad@gmail.com + +*/ + +set G_STAND_TYPE; # A, B, C + +set I_CULTURAL_PRES; +set J_MGT_YEAR; + +param K_PERIOD; +param Forest_Cost{G_STAND_TYPE,I_CULTURAL_PRES, J_MGT_YEAR}; # cost + +param Yield_Table_Vol{G_STAND_TYPE, I_CULTURAL_PRES, J_MGT_YEAR, 1..K_PERIOD} >= 0; + + +param Alpha >= 0; +param Beta >= 0; + +param TCost_Table{G_STAND_TYPE, I_CULTURAL_PRES, J_MGT_YEAR, 1..K_PERIOD} >= 0; + +param NetRev_Table{G_STAND_TYPE, I_CULTURAL_PRES, J_MGT_YEAR, 1..K_PERIOD}; + + +var XForestLand{g in G_STAND_TYPE, i in I_CULTURAL_PRES, j in J_MGT_YEAR} >= 0; + + +#reading dbf tables +table tab IN "xBASE" "standtype.dbf": G_STAND_TYPE <- [STAND]; +display G_STAND_TYPE; + + +table tab2 IN "xBASE" "cultural_pres.dbf": I_CULTURAL_PRES <- [CUL_PRES]; +display I_CULTURAL_PRES; + +table tab3 IN "xBASE" "mgt_year.dbf": J_MGT_YEAR <- [MGT_YEAR]; +display J_MGT_YEAR; + +/* +param Forest_Cost{G_STAND_TYPE,I_CULTURAL_PRES, J_MGT_YEAR} default 0; # cost +*/ + +set S1, dimen 3; +table tab4 IN "xBASE" "Forest_Cost.dbf": S1 <- [STAND, CUL_PRES, MGT_YEAR],Forest_Cost ~FCOST; +display Forest_Cost; + +set S2, dimen 4; +table tab5 IN "xBASE" "Yield_Table_Vol.dbf": S2 <- [STAND, CUL_PRES, MGT_YEAR, PERIOD],Yield_Table_Vol ~YIELD; +display Yield_Table_Vol; + +set S3, dimen 4; +table tab5 IN "xBASE" "TCost_Table.dbf": S3 <- [STAND, CUL_PRES, MGT_YEAR, PERIOD],TCost_Table ~TCOST; +display TCost_Table; + + +set S4, dimen 4; +table tab5 IN "xBASE" "NetRev_Table.dbf": S4 <- [STAND, CUL_PRES, MGT_YEAR, PERIOD],NetRev_Table ~NETREV; +display NetRev_Table; + + +param MGT; + +param Area_Stand_Indi{g in G_STAND_TYPE, m in 1..MGT} default 0; + +set ST, dimen 2; +table tab5 IN "xBASE" "stands.dbf": ST <- [VEG_TYPE, MGT], Area_Stand_Indi ~ACRES; +display Area_Stand_Indi; + +param Area_Stand_Type{g in G_STAND_TYPE}:= sum {m in 1..MGT } Area_Stand_Indi[g,m]; +display Area_Stand_Type; + + +param Total_Area := sum {g in G_STAND_TYPE, m in 1..MGT } Area_Stand_Indi[g,m]; +display Total_Area; + +param Harvest_Min_Vol_Period; + + +var NetPresentValue; + +# Objective function +maximize Net_Present_Value: NetPresentValue; + +subject to NPV: + NetPresentValue = sum {g in G_STAND_TYPE, i in I_CULTURAL_PRES, j in J_MGT_YEAR} Forest_Cost[g,i,j] * XForestLand[g,i,j]; + +# Harvest Constraint by Period +subject to Harvest_Period_H {k in 1..K_PERIOD}: + sum {g in G_STAND_TYPE, i in I_CULTURAL_PRES, j in J_MGT_YEAR} Yield_Table_Vol[g,i,j,k] * XForestLand[g,i,j] >= Harvest_Min_Vol_Period; + + +#Even-Flow Constraint / Volume - Harvest Flow Constraint - Alpha +subject to Even_Flow_Constaints_Alpha {k in 6..K_PERIOD-1}: + (1 - Alpha) * sum {g in G_STAND_TYPE, i in I_CULTURAL_PRES, j in J_MGT_YEAR} Yield_Table_Vol[g,i,j,k] * XForestLand[g,i,j] - + sum {g in G_STAND_TYPE,i in I_CULTURAL_PRES, j in J_MGT_YEAR} Yield_Table_Vol[g,i,j,k+1] * XForestLand[g,i,j] <= 0; + +# Even-Flow Constraint / Volume - Harvest Flow Constraint - Beta +subject to Even_Flow_Constaints_Beta {k in 6..K_PERIOD-1}: + (1 + Beta) * sum {g in G_STAND_TYPE, i in I_CULTURAL_PRES, j in J_MGT_YEAR} Yield_Table_Vol[g,i,j,k] * XForestLand[g,i,j] - + sum {g in G_STAND_TYPE,i in I_CULTURAL_PRES, j in J_MGT_YEAR} Yield_Table_Vol[g,i,j,k+1] * XForestLand[g,i,j] >= 0; + +# Forest / Land Constraints +subject to Total_Area_Constraint: + sum {g in G_STAND_TYPE, i in I_CULTURAL_PRES, j in J_MGT_YEAR} XForestLand[g,i,j] <= Total_Area; +display Total_Area; + +# Forest / Land Constraints for A B C +subject to Area {g in G_STAND_TYPE}: + sum {i in I_CULTURAL_PRES,j in J_MGT_YEAR} XForestLand[g,i,j] = Area_Stand_Type[g]; + + + +solve; +#RESULT SECTION +printf '#################################\n'; +printf 'Forest Management Model I - Noli Sicad\n'; +printf '\n'; +printf 'Net Present Value = %.2f\n', NetPresentValue; +printf '\n'; + +printf '\n'; +printf 'Variables\n'; +printf 'Stand_Type Age_Class Mgt_Presc Sign Value \n'; +printf{g in G_STAND_TYPE, i in I_CULTURAL_PRES, j in J_MGT_YEAR}:'%5s %10s %11s = %10.2f\n', g,i,j, XForestLand[g,i,j]; +printf '\n'; + +printf 'Constraints\n'; +printf 'Period Harvest Sign \n'; +for {k in 1..K_PERIOD} { + printf '%5s %10.2f >= %.3f\n', k, sum {g in G_STAND_TYPE, i in I_CULTURAL_PRES, j in J_MGT_YEAR} Yield_Table_Vol[g,i,j,k] * XForestLand[g,i,j], Harvest_Min_Vol_Period; + } + +# xbase (dbf) output +table Harvest{k in 1..K_PERIOD} OUT "xBASE" "HarvestArea1.dbf" "N(5)N(15,2)" : k ~ Period, (sum {g in G_STAND_TYPE, i in I_CULTURAL_PRES, j in J_MGT_YEAR} Yield_Table_Vol[g,i,j,k] * XForestLand[g,i,j]) ~ H_Area; + +# xbase (dbf) read +set S, dimen 2; +table tab2 IN "xBASE" "HarvestArea1.dbf": S <- [Period, H_Area]; +display S; + + + + +printf '\n'; +printf 'Constraint\n'; +printf 'Harvest Period\n'; +printf 'Type AgeClass PrescMgt Period Value\n'; +printf{g in G_STAND_TYPE, i in I_CULTURAL_PRES, j in J_MGT_YEAR, k in 1..K_PERIOD}:'%5s %11s %11s %5s %10.2f\n', g,i,j, k, (Yield_Table_Vol[g,i,j,k] * XForestLand[g,i,j]); + + +printf 'Even_Flow_Constaint_Alpha (1-Alpha)\n'; +printf 'Period Sign \n'; +for {k in 6..K_PERIOD-1} { + printf "%s %10.2f <= %s\n", k, ((1 - Alpha) * sum {g in G_STAND_TYPE, i in I_CULTURAL_PRES, j in J_MGT_YEAR} Yield_Table_Vol[g,i,j,k] * XForestLand[g,i,j] - sum {g in G_STAND_TYPE,i in I_CULTURAL_PRES, j in J_MGT_YEAR} Yield_Table_Vol[g,i,j,k+1] * XForestLand[g,i,j]),0; + } +printf '\n'; + + +# Forest / Land Constraints +printf '\n'; +printf 'Total Area Constraint\n'; +printf 'Type AgeClass PrescMgt Value Sign Total_Area \n'; +printf '%5s <= %.3f\n',sum {g in G_STAND_TYPE, i in I_CULTURAL_PRES, j in J_MGT_YEAR} XForestLand[g,i,j], Total_Area; + +printf 'Area\n'; +printf 'Area Value Sign Areas_Stand\n'; +for {g in G_STAND_TYPE} { + printf '%5s %10.2f <= %.3f\n', g, sum {i in I_CULTURAL_PRES,j in J_MGT_YEAR} XForestLand[g,i,j], Area_Stand_Type[g]; + } + + +#DATA SECTION + +data; + +# Most of the data has been moved to dbf format + +param MGT:=31; + +param K_PERIOD:= 7; + +param Alpha:= 0.20; +param Beta:= 0.20; + +param Harvest_Min_Vol_Period:= 12000; + +end; + diff --git a/glpk-5.0/examples/dbf/Forest_Cost.dbf b/glpk-5.0/examples/dbf/Forest_Cost.dbf Binary files differnew file mode 100644 index 0000000..acb8dcb --- /dev/null +++ b/glpk-5.0/examples/dbf/Forest_Cost.dbf diff --git a/glpk-5.0/examples/dbf/NetRev_Table.dbf b/glpk-5.0/examples/dbf/NetRev_Table.dbf Binary files differnew file mode 100644 index 0000000..6e6f2bd --- /dev/null +++ b/glpk-5.0/examples/dbf/NetRev_Table.dbf diff --git a/glpk-5.0/examples/dbf/README b/glpk-5.0/examples/dbf/README new file mode 100644 index 0000000..bbe9c3e --- /dev/null +++ b/glpk-5.0/examples/dbf/README @@ -0,0 +1,2 @@ +This subdirectory contains an example MathProg model that demonstrates +using data tables in DBF format. diff --git a/glpk-5.0/examples/dbf/TCost_Table.dbf b/glpk-5.0/examples/dbf/TCost_Table.dbf Binary files differnew file mode 100644 index 0000000..9a462c3 --- /dev/null +++ b/glpk-5.0/examples/dbf/TCost_Table.dbf diff --git a/glpk-5.0/examples/dbf/Yield_Table_Vol.dbf b/glpk-5.0/examples/dbf/Yield_Table_Vol.dbf Binary files differnew file mode 100644 index 0000000..b0d051b --- /dev/null +++ b/glpk-5.0/examples/dbf/Yield_Table_Vol.dbf diff --git a/glpk-5.0/examples/dbf/cultural_pres.dbf b/glpk-5.0/examples/dbf/cultural_pres.dbf Binary files differnew file mode 100644 index 0000000..76c8dfa --- /dev/null +++ b/glpk-5.0/examples/dbf/cultural_pres.dbf diff --git a/glpk-5.0/examples/dbf/mgt_year.dbf b/glpk-5.0/examples/dbf/mgt_year.dbf Binary files differnew file mode 100644 index 0000000..043ba5a --- /dev/null +++ b/glpk-5.0/examples/dbf/mgt_year.dbf diff --git a/glpk-5.0/examples/dbf/stands.dbf b/glpk-5.0/examples/dbf/stands.dbf Binary files differnew file mode 100644 index 0000000..5ecfd24 --- /dev/null +++ b/glpk-5.0/examples/dbf/stands.dbf diff --git a/glpk-5.0/examples/dbf/standtype.dbf b/glpk-5.0/examples/dbf/standtype.dbf Binary files differnew file mode 100644 index 0000000..0306d50 --- /dev/null +++ b/glpk-5.0/examples/dbf/standtype.dbf diff --git a/glpk-5.0/examples/dea.mod b/glpk-5.0/examples/dea.mod new file mode 100644 index 0000000..ba61073 --- /dev/null +++ b/glpk-5.0/examples/dea.mod @@ -0,0 +1,222 @@ +/* Data Envelopment Analysis (DEA) + * + * DEA quantifies the relative efficiency of decision making units (DMUs) by + * finding the efficient frontier in multiple input multiple output data. The + * inputs are resources (eg. number of employees, available machines, ...), + * the outputs are productive outputs (eg. contracts made, total sales, ...). + * The method is non-parametric. More details are available in the paper + * below. + * + * Models according to: Seiford, Threall, "Recent developments in DEA", 1990. + * + * Implementation: Sebastian Nowozin <nowozin@gmail.com> + */ + +### SETS ### + +set dmus; # Decision Making Units (DMU) +set inputs; # Input parameters +set outputs; # Output parameters + + +### PARAMETERS ### + +param input_data{dmus,inputs} >= 0; +param output_data{dmus,outputs} >= 0; + + +### PROGRAM ### + +var theta{dmus} >= 0; +var lambda{dmus,dmus} >= 0; + +minimize inefficiency: sum{td in dmus} theta[td]; + +s.t. output_lower_limit{o in outputs, td in dmus}: + sum{d in dmus} lambda[d,td]*output_data[d,o] >= output_data[td,o]; +s.t. input_upper_limit{i in inputs, td in dmus}: + sum{d in dmus} lambda[d,td]*input_data[d,i] <= theta[td]*input_data[td,i]; + + s.t. PI1{td in dmus}: + sum{d in dmus} lambda[d,td] = 1; +/* +possibilities: + i) (no constraint) + ii) s.t. PI1{td in dmus}: + sum{d in dmus} lambda[d,td] <= 1; + iii) s.t. PI1{td in dmus}: + sum{d in dmus} lambda[d,td] >= 1; +*/ + + +### SOLVE AND PRINT SOLUTION ### + +solve; + +printf "DMU\tEfficiency\n"; +for {td in dmus} { + printf "%s\t%1.4f\n", td, theta[td]; +} + +### DATA ### + +data; + +set dmus := 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 + 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 + 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 + 61 62 63 64 65 66 67 68 69 ; +set inputs := AvgInventory LaborCost OperatingCost Population ; +set outputs := PrescrVol kDollarValue ; + +param input_data default 0.0 : + + AvgInventory LaborCost OperatingCost Population := + +1 8000 17030 1280 1410 +2 9000 25890 2779 1523 +3 13694 29076 2372 1354 +4 4250 17506 1385 822 +5 6500 23208 639 746 +6 7000 12946 802 1281 +7 4500 18001 1130 1016 +8 5000 14473 1097 1070 +9 27000 31760 5559 1694 +10 21560 50972 15010 1910 +11 15000 39523 4799 1745 +12 8500 13076 3489 1353 +13 35000 35427 1704 500 +14 18000 27554 2882 1016 +15 59750 53848 14208 2500 +16 19200 38253 1480 2293 +17 40000 109404 83016 2718 +18 8466 18198 1278 2877 +19 16000 40891 7599 4150 +20 10000 45444 5556 4421 +21 25000 35623 2121 3883 +22 14000 20192 5515 3519 +23 12500 34973 10475 32366 +24 17260 32284 14498 3393 +25 7000 17920 7585 4489 +26 14000 42094 3742 2217 +27 16400 35422 14236 4641 +28 13000 19100 3529 5968 +29 30000 72167 8656 8715 +30 12530 19970 1714 5968 +31 31500 39183 4919 5607 +32 10000 32048 3483 7324 +33 22000 68877 12279 8685 +34 10000 29812 3332 8685 +35 16000 47686 2507 5420 +36 10000 33415 4738 7703 +37 9000 12359 4603 4665 +38 16439 23614 2989 6317 +39 14500 36069 1793 31839 +40 39000 76307 9539 15619 +41 24927 40706 12661 30213 +42 13858 39267 4609 34719 +43 33375 29509 11323 31839 +44 29044 44482 5542 34719 +45 32257 61365 20550 32366 +46 8800 49671 3306 43561 +47 47000 40425 10396 31263 +48 12000 33034 4915 31263 +49 28000 69163 4688 15173 +50 13300 28931 16735 73064 +51 13500 29758 4260 62309 +52 24000 40927 8285 23166 +53 16000 40403 2131 99836 +54 17000 38730 2539 60348 +55 25000 35978 2502 99836 +56 16000 37509 6278 99836 +57 20000 46950 10715 85925 +58 14000 35966 3144 85925 +59 22000 68318 8015 108987 +60 21879 69537 7778 108987 +61 15000 25425 2812 201404 +62 10000 19508 2454 201404 +63 20000 28191 3367 201404 +64 18000 37073 8624 108987 +65 19051 23763 3496 201404 +66 15000 28642 3366 201404 +67 10000 35919 3868 201404 +68 24000 54653 26494 108987 +69 1800 6276 3413 60348 + ; + +param output_data default 0.0 : + + PrescrVol kDollarValue := + +1 12293 61.00 +2 18400 92.00 +3 16789 92.65 +4 10700 45.00 +5 9800 50.00 +6 6500 29.00 +7 8200 56.00 +8 8680 45.00 +9 33800 183.00 +10 23710 156.00 +11 24000 120.00 +12 17500 75.00 +13 25000 130.00 +14 26000 122.00 +15 26830 178.513 +16 16600 106.00 +17 90000 450.00 +18 11140 73.624 +19 25868 136.00 +20 32700 191.295 +21 29117 152.864 +22 18000 100.00 +23 11100 60.00 +24 23030 137.778 +25 10656 58.00 +26 24682 152.095 +27 26908 120.00 +28 16464 80.00 +29 57000 321.00 +30 17532 94.747 +31 30035 168.00 +32 16000 100.00 +33 63700 277.00 +34 18000 90.00 +35 27339 139.134 +36 19500 116.00 +37 13000 80.00 +38 15370 102.00 +39 18446 90.00 +40 56000 260.00 +41 73845 364.951 +42 28600 145.00 +43 27000 243.00 +44 52423 279.816 +45 73759 363.388 +46 20500 80.00 +47 27100 115.00 +48 15000 110.00 +49 50895 277.852 +50 19707 128.00 +51 17994 78.80 +52 36135 167.222 +53 30000 153.00 +54 26195 125.00 +55 28000 216.00 +56 24658 152.551 +57 36850 190.00 +58 29250 183.69 +59 50000 250.00 +60 40078 265.443 +61 20200 110.00 +62 12500 75.00 +63 30890 195.00 +64 31000 175.00 +65 31277 192.992 +66 11500 75.00 +67 30000 175.668 +68 38383 190.00 +69 2075 8.650 + ; + +end; diff --git a/glpk-5.0/examples/diet.mod b/glpk-5.0/examples/diet.mod new file mode 100644 index 0000000..6d36391 --- /dev/null +++ b/glpk-5.0/examples/diet.mod @@ -0,0 +1,99 @@ +# STIGLER'S NUTRITION MODEL +# +# This model determines a least cost diet which meets the daily +# allowances of nutrients for a moderately active man weighing 154 lbs. +# +# References: +# Dantzig G B, "Linear Programming and Extensions." +# Princeton University Press, Princeton, New Jersey, 1963, +# Chapter 27-1. + +set N; +/* nutrients */ + +set F; +/* foods */ + +param b{N}; +/* required daily allowances of nutrients */ + +param a{F,N}; +/* nutritive value of foods (per dollar spent) */ + +var x{f in F} >= 0; +/* dollars of food f to be purchased daily */ + +s.t. nb{n in N}: sum{f in F} a[f,n] * x[f] = b[n]; +/* nutrient balance (units) */ + +minimize cost: sum{f in F} x[f]; +/* total food bill (dollars) */ + +data; + +param : N : b := + Calorie 3 /* thousands */ + Protein 70 /* grams */ + Calcium 0.8 /* grams */ + Iron 12 /* milligrams */ + Vitamin-A 5 /* thousands IUs */ + Vitamin-B1 1.8 /* milligrams */ + Vitamin-B2 2.7 /* milligrams */ + Niacin 18 /* milligrams */ + Vitamin-C 75 /* milligrams */ ; + +set F := Wheat Cornmeal Cannedmilk Margarine Cheese Peanut-B Lard + Liver Porkroast Salmon Greenbeans Cabbage Onions Potatoes + Spinach Sweet-Pot Peaches Prunes Limabeans Navybeans; + +param a default 0 + +: Calorie Protein Calcium Iron Vitamin-A Vitamin-B1 := +# (1000) (g) (g) (mg) (1000IU) (mg) + +Wheat 44.7 1411 2.0 365 . 55.4 +Cornmeal 36 897 1.7 99 30.9 17.4 +Cannedmilk 8.4 422 15.1 9 26 3 +Margarine 20.6 17 .6 6 55.8 .2 +Cheese 7.4 448 16.4 19 28.1 .8 +Peanut-B 15.7 661 1 48 . 9.6 +Lard 41.7 . . . .2 . +Liver 2.2 333 .2 139 169.2 6.4 +Porkroast 4.4 249 .3 37 . 18.2 +Salmon 5.8 705 6.8 45 3.5 1 +Greenbeans 2.4 138 3.7 80 69 4.3 +Cabbage 2.6 125 4 36 7.2 9 +Onions 5.8 166 3.8 59 16.6 4.7 +Potatoes 14.3 336 1.8 118 6.7 29.4 +Spinach 1.1 106 . 138 918.4 5.7 +Sweet-Pot 9.6 138 2.7 54 290.7 8.4 +Peaches 8.5 87 1.7 173 86.8 1.2 +Prunes 12.8 99 2.5 154 85.7 3.9 +Limabeans 17.4 1055 3.7 459 5.1 26.9 +Navybeans 26.9 1691 11.4 792 . 38.4 + +: Vitamin-B2 Niacin Vitamin-C := +# (mg) (mg) (mg) + +Wheat 33.3 441 . +Cornmeal 7.9 106 . +Cannedmilk 23.5 11 60 +Margarine . . . +Cheese 10.3 4 . +Peanut-B 8.1 471 . +Lard .5 5 . +Liver 50.8 316 525 +Porkroast 3.6 79 . +Salmon 4.9 209 . +Greenbeans 5.8 37 862 +Cabbage 4.5 26 5369 +Onions 5.9 21 1184 +Potatoes 7.1 198 2522 +Spinach 13.8 33 2755 +Sweet-Pot 5.4 83 1912 +Peaches 4.3 55 57 +Prunes 4.3 65 257 +Limabeans 38.2 93 . +Navybeans 24.6 217 . ; + +end; diff --git a/glpk-5.0/examples/dist.mod b/glpk-5.0/examples/dist.mod new file mode 100644 index 0000000..f3d66b5 --- /dev/null +++ b/glpk-5.0/examples/dist.mod @@ -0,0 +1,565 @@ +# DIST, a product distribution model +# +# References: +# Robert Fourer, David M. Gay and Brian W. Kernighan, "A Modeling Language +# for Mathematical Programming." Management Science 36 (1990) 519-554. + +### SHIPPING SETS AND PARAMETERS ### + +set whse 'warehouses'; # Locations from which demand is satisfied + +set dctr 'distribution centers' within whse; + + # Locations from which product may be shipped + +param sc 'shipping cost' {dctr,whse} >= 0; + + # Shipping costs, to whse from dctr, in $ / 100 lb + +param huge 'largest shipping cost' > 0; + + # Largest cost allowed for a usable shipping route + +param msr 'minimum size restriction' {dctr,whse} logical; + + # True indicates a minimum-size restriction on + # direct shipments using this dctr --> whse route + +param dsr 'direct shipment requirement' {dctr} >= 0; + + # Minimum total demand, in pallets, needed to + # allow shipment on routes subject to the + # minimum size restriction + +### PLANT SETS AND PARAMETERS ### + +set fact 'factories' within dctr; + + # Locations where product is manufactured + +param rtmin 'regular-time total minimum' >= 0; + + # Lower limit on (average) total regular-time + # crews employed at all factories + +param rtmax 'regular-time total maximum' >= rtmin; + + # Upper limit on (average) total regular-time + # crews employed at all factories + +param otmin 'overtime total minimum' >= 0; + + # Lower limit on total overtime hours at all factories + +param otmax 'overtime total maximum' >= otmin; + + # Upper limit on total overtime hours at all factories + +param rmin 'regular-time minimums' {fact} >= 0; + + # Lower limits on (average) regular-time crews + +param rmax 'regular-time maximums' {f in fact} >= rmin[f]; + + # Upper limits on (average) regular-time crews + +param omin 'overtime minimums' {fact} >= 0; + + # Lower limits on overtime hours + +param omax 'overtime maximums' {f in fact} >= omin[f]; + + # Upper limits on overtime hours + +param hd 'hours per day' {fact} >= 0; + + # Regular-time hours per working day + +param dp 'days in period' {fact} > 0; + + # Working days in the current planning period + +### PRODUCT SETS AND PARAMETERS ### + +set prd 'products'; # Elements of the product group + +param wt 'weight' {prd} > 0; + + # Weight in 100 lb / 1000 cases + +param cpp 'cases per pallet' {prd} > 0; + + # Cases of product per shipping pallet + +param tc 'transshipment cost' {prd} >= 0; + + # Transshipment cost in $ / 1000 cases + +param pt 'production time' {prd,fact} >= 0; + + # Crew-hours to produce 1000 cases + +param rpc 'regular-time production cost' {prd,fact} >= 0; + + # Cost of production on regular time, + # in $ / 1000 cases + +param opc 'overtime production cost' {prd,fact} >= 0; + + # Cost of production on overtime, in $ / 1000 cases + +### DEMAND SETS AND PARAMETERS ### + +param dt 'total demand' {prd} >= 0; + + # Total demands for products, in 1000s + +param ds 'demand shares' {prd,whse} >= 0.0, <= 1.0; + + # Historical demand data, from which each + # warehouse's share of total demand is deduced + +param dstot {p in prd} := sum {w in whse} ds[p,w]; + + # Total of demand shares; should be 1, but often isn't + +param dem 'demand' {p in prd, w in whse} := dt[p] * ds[p,w] / dstot[p]; + + # Projected demands to be satisfied, in 1000s + +set rt 'shipping routes available' := + + {d in dctr, w in whse: + d <> w and sc[d,w] < huge and + (w in dctr or sum {p in prd} dem[p,w] > 0) and + not (msr[d,w] and sum {p in prd} 1000*dem[p,w]/cpp[p] < dsr[d]) }; + + # List of ordered pairs that represent routes + # on which shipments are allowed + +### VARIABLES ### + +var Rprd 'regular-time production' {prd,fact} >= 0; + + # Regular-time production of each product + # at each factory, in 1000s of cases + +var Oprd 'overtime production' {prd,fact} >= 0; + + # Overtime production of each product + # at each factory, in 1000s of cases + +var Ship 'shipments' {prd,rt} >= 0; + + # Shipments of each product on each allowed route, + # in 1000s of cases + +var Trans 'transshipments' {prd,dctr} >= 0; + + # Transshipments of each product at each + # distribution center, in 1000s of cases + +### OBJECTIVE ### + +minimize cost: sum {p in prd, f in fact} rpc[p,f] * Rprd[p,f] + + sum {p in prd, f in fact} opc[p,f] * Oprd[p,f] + + sum {p in prd, (d,w) in rt} sc[d,w] * wt[p] * Ship[p,d,w] + + sum {p in prd, d in dctr} tc[p] * Trans[p,d]; + + # Total cost: regular production, overtime + # production, shipping, and transshipment + +### CONSTRAINTS ### + +rtlim 'regular-time total limits': + + rtmin <= sum {p in prd, f in fact} + (pt[p,f] * Rprd[p,f]) / (dp[f] * hd[f]) <= rtmax; + + # Total crews must lie between limits + +otlim 'overtime total limits': + + otmin <= sum {p in prd, f in fact} pt[p,f] * Oprd[p,f] <= otmax; + + # Total overtime must lie between limits + +rlim 'regular-time limits' {f in fact}: + + rmin[f] <= sum {p in prd} + (pt[p,f] * Rprd[p,f]) / (dp[f] * hd[f]) <= rmax[f]; + + # Crews at each factory must lie between limits + +olim 'overtime limits' {f in fact}: + + omin[f] <= sum {p in prd} pt[p,f] * Oprd[p,f] <= omax[f]; + + # Overtime at each factory must lie between limits + +noRprd 'no regular production' {p in prd, f in fact: rpc[p,f] = 0}: + + Rprd[p,f] = 0; + +noOprd 'no overtime production' {p in prd, f in fact: opc[p,f] = 0}: + + Oprd[p,f] = 0; # Do not produce where specified cost is zero + +bal 'material balance' {p in prd, w in whse}: + + sum {(v,w) in rt} + Ship [p,v,w] + (if w in fact then Rprd[p,w] + Oprd[p,w]) = + + dem[p,w] + (if w in dctr then sum {(w,v) in rt} Ship[p,w,v]); + + # Demand is satisfied by shipment into warehouse + # plus production (if it is a factory) + # minus shipment out (if it is a distn. center) + +trdef 'transshipment definition' {p in prd, d in dctr}: + + Trans[p,d] >= sum {(d,w) in rt} Ship [p,d,w] - + (if d in fact then Rprd[p,d] + Oprd[p,d]); + + # Transshipment at a distribution center is + # shipments out less production (if any) + +### DATA -- 3 PRODUCTS ### + +data; + +set prd := 18REG 24REG 24PRO ; + +set whse := w01 w02 w03 w04 w05 w06 w08 w09 w12 w14 w15 w17 + w18 w19 w20 w21 w24 w25 w26 w27 w28 w29 w30 w31 + w32 w33 w34 w35 w36 w37 w38 w39 w40 w41 w42 w43 + w44 w45 w46 w47 w48 w49 w50 w51 w53 w54 w55 w56 + w57 w59 w60 w61 w62 w63 w64 w65 w66 w68 w69 w71 + w72 w73 w74 w75 w76 w77 w78 w79 w80 w81 w82 w83 + w84 w85 w86 w87 w89 w90 w91 w92 w93 w94 w95 w96 + w98 x22 x23 ; + +set dctr := w01 w02 w03 w04 w05 w62 w76 w96 ; + +set fact := w01 w05 w96 ; + +param huge := 99. ; + +param rtmin := 0.0 ; +param rtmax := 8.0 ; + +param otmin := 0.0 ; +param otmax := 96.0 ; + +param rmin := w01 0.00 w05 0.00 w96 0.00 ; +param rmax := w01 3.00 w05 2.00 w96 3.00 ; + +param omin := w01 0.0 w05 0.0 w96 0.0 ; +param omax := w01 48.0 w05 0.0 w96 48.0 ; + +param hd := w01 8.0 w05 8.0 w96 8.0 ; + +param dp := w01 19.0 w05 19.0 w96 19.0 ; + +param wt := 18REG 47.3 24REG 63.0 24PRO 63.0 ; + +param tc := 18REG 40.00 24REG 45.00 24PRO 45.00 ; + +param dt := 18REG 376.0 24REG 172.4 24PRO 316.3 ; + +param cpp := 18REG 102. 24REG 91. 24PRO 91. ; + +param dsr := w01 96. w02 96. w03 96. w04 96. w05 96. + w62 96. w76 96. w96 96. ; + +param pt (tr) : + + 18REG 24REG 24PRO := + +w01 1.194 1.429 1.429 +w05 1.194 1.509 1.509 +w96 0.000 1.600 1.600 ; + +param rpc (tr) : + + 18REG 24REG 24PRO := + +w01 2119. 2653. 2617. +w05 2489. 3182. 3176. +w96 0. 2925. 2918. ; + +param opc (tr) : + + 18REG 24REG 24PRO := + +w01 2903. 3585. 3579. +w05 0. 0. 0. +w96 0. 3629. 3622. ; + +param sc default 99.99 (tr) : + + w01 w02 w03 w04 w05 w62 w76 w96 := + +w01 . 2.97 1.14 2.08 2.37 1.26 2.42 1.43 +w02 4.74 . 4.17 6.12 7.41 3.78 7.04 5.21 +w03 2.45 4.74 . 3.67 2.84 0.90 2.41 2.55 +w04 1.74 5.03 2.43 . 3.19 2.45 2.69 0.58 +w05 2.70 5.16 2.84 2.85 . 3.26 3.34 2.71 +w06 1.99 4.17 2.13 2.19 2.52 2.06 2.00 1.51 +w08 0.21 2.92 1.24 2.07 2.29 1.25 2.32 1.55 +w09 0.66 3.76 1.41 2.47 1.82 1.66 . 1.87 +w12 1.38 3.83 1.68 2.53 2.39 . 1.96 1.94 +w14 2.47 1.58 2.40 3.59 3.85 2.25 . 3.05 +w15 1.06 4.95 2.48 1.39 3.41 1.96 . 1.02 +w17 0.88 3.39 1.46 2.00 2.67 1.45 . 1.46 +w18 7.90 6.57 7.79 9.59 10.81 . . 6.70 +w19 1.42 4.12 1.96 1.99 3.52 1.88 . 1.26 +w20 3.03 1.59 2.34 4.76 3.98 1.88 . 3.73 +w24 1.58 2.80 2.27 2.87 3.19 1.31 . 2.05 +w25 1.51 5.05 2.74 0.57 2.98 . 2.95 0.27 +w26 1.75 3.61 2.70 1.54 4.07 3.52 . 1.03 +w27 2.48 6.87 3.17 1.59 2.08 3.45 . 0.99 +w28 2.05 6.83 2.97 1.13 2.91 . . 1.26 +w29 4.03 3.68 4.46 3.20 5.50 . . 3.20 +w30 2.48 5.78 2.99 2.24 1.79 3.10 . 1.39 +w31 2.34 5.41 2.87 1.67 1.66 . . 1.39 +w32 14.36 . . . . . . . +w33 3.87 4.27 5.11 3.48 5.66 4.03 . 3.05 +w34 3.26 4.80 3.21 2.70 4.14 . . 1.77 +w35 2.34 2.84 2.89 3.35 3.78 2.68 . 2.52 +w36 2.43 5.69 2.96 2.95 1.02 2.61 1.07 2.54 +w37 2.23 4.64 2.41 1.99 4.30 2.61 . 1.44 +w38 4.66 4.36 5.23 3.04 4.46 . . 3.82 +w39 1.11 3.51 1.10 2.53 3.07 1.12 . 2.23 +w40 2.99 4.78 4.23 1.57 3.92 . . 1.80 +w41 4.93 4.00 5.43 4.45 6.31 . . 3.81 +w42 3.86 6.55 5.03 2.11 4.41 . . 2.63 +w43 4.61 4.45 3.77 1.22 4.31 . . 2.35 +w44 2.05 4.48 1.06 3.70 3.46 1.10 . 3.21 +w45 0.92 3.42 1.58 3.04 1.82 1.94 . 2.52 +w46 1.36 2.44 0.95 3.08 2.78 0.39 2.16 2.37 +w47 1.30 3.39 1.60 2.49 4.29 2.04 . 1.68 +w48 1.65 3.78 1.03 2.97 2.21 1.31 . 2.74 +w49 1.96 3.00 1.50 3.24 3.68 1.00 . 2.99 +w50 0.90 4.14 1.60 1.95 3.61 1.61 . 1.52 +w51 1.59 3.95 0.25 2.96 2.58 1.00 2.41 2.71 +w53 1.59 3.79 1.28 3.12 3.10 0.89 . 2.98 +w54 1.72 4.36 1.61 2.92 2.34 1.91 1.97 3.05 +w55 2.45 2.73 2.21 4.47 4.30 2.57 . 4.48 +w56 1.10 3.73 1.59 2.74 2.33 1.45 . 2.44 +w57 0.95 3.39 1.37 2.30 2.47 1.15 . 1.95 +w59 3.29 5.35 3.32 3.81 1.52 3.38 1.34 4.08 +w60 2.41 6.12 2.46 3.65 2.35 . 1.37 4.06 +w61 3.32 5.50 3.41 3.38 1.23 . 0.99 4.28 +w62 1.12 3.00 0.82 3.22 2.95 . 3.33 2.53 +w63 3.59 6.36 3.25 4.12 1.84 3.59 1.46 4.03 +w64 1.85 4.45 2.17 3.43 2.13 2.03 . 4.02 +w65 2.78 4.79 2.81 2.94 1.54 2.90 1.07 2.94 +w66 3.90 5.79 3.05 3.65 1.36 3.39 1.22 3.57 +w68 2.61 5.20 2.90 2.34 1.68 3.19 1.48 2.31 +w69 2.94 5.21 2.78 3.43 0.21 3.26 0.68 2.54 +w71 2.06 4.98 2.38 2.44 1.59 2.97 1.05 2.55 +w72 2.61 5.50 2.83 3.12 1.35 3.23 0.88 2.99 +w73 8.52 6.16 8.03 8.83 10.44 7.38 10.26 . +w74 6.11 5.46 9.07 9.38 10.80 . . 8.25 +w75 2.66 4.94 2.87 3.69 1.52 3.15 1.24 4.00 +w76 1.99 5.26 2.23 3.36 0.58 3.17 . 2.50 +w77 4.32 3.07 5.05 3.88 6.04 . . 4.15 +w78 5.60 2.59 5.78 5.56 7.10 . . 5.60 +w79 4.25 2.32 4.93 4.57 6.04 . . 4.58 +w80 5.94 4.00 5.60 7.02 9.46 . . 7.51 +w81 5.39 2.21 5.10 6.22 6.46 . . 6.58 +w82 8.80 5.69 9.29 9.88 11.69 8.63 11.52 . +w83 4.40 . 5.24 5.21 5.81 3.91 7.04 5.33 +w84 5.87 5.43 6.17 5.70 7.63 . . 5.70 +w85 3.90 3.65 3.38 4.57 5.64 3.05 . 5.04 +w86 5.48 2.10 5.70 6.37 7.33 . . 6.19 +w87 8.88 5.54 9.50 9.71 11.64 8.85 11.68 . +w89 4.62 4.01 4.03 6.30 6.30 3.81 . 7.77 +w90 4.35 2.72 4.61 4.01 5.60 . . 3.20 +w91 7.61 4.42 7.83 6.85 8.79 . . 7.66 +w92 7.15 2.69 6.91 7.20 . . . 7.06 +w93 3.17 3.95 4.37 3.74 5.05 . . 2.40 +w94 1.21 3.07 0.90 2.74 3.17 . 2.63 2.39 +w95 5.82 3.29 6.55 7.06 11.47 . . 7.83 +w96 1.77 5.20 2.72 0.59 3.47 2.48 . . +w98 3.04 1.92 3.64 3.70 4.90 3.05 . 3.88 +x22 4.08 6.25 4.15 4.30 1.77 . 1.77 . +x23 3.39 5.74 3.55 4.08 1.69 . 1.47 . ; + +param msr (tr) : + + w01 w02 w03 w04 w05 w62 w76 w96 := + +w01 0 0 0 0 0 0 1 0 +w02 0 0 0 0 0 0 1 0 +w03 0 0 0 0 0 0 1 0 +w04 0 0 0 0 0 0 1 0 +w05 0 0 0 0 0 0 0 0 +w06 0 1 1 1 1 1 1 1 +w08 0 1 1 1 1 1 1 1 +w09 0 1 1 1 1 1 0 1 +w12 0 1 1 1 1 0 1 1 +w14 1 1 1 1 1 0 0 1 +w15 0 1 1 1 1 1 0 1 +w17 0 1 1 1 1 1 0 1 +w18 0 1 1 1 1 0 0 1 +w19 0 1 1 1 1 0 0 1 +w20 1 1 1 1 1 0 0 1 +w24 0 1 1 1 1 0 0 1 +w25 0 1 1 1 1 0 1 0 +w26 1 1 1 0 1 1 0 1 +w27 1 1 1 0 1 1 0 1 +w28 1 1 1 0 1 0 0 1 +w29 0 1 1 1 1 0 0 1 +w30 1 1 1 0 1 1 0 1 +w31 1 1 1 0 1 0 0 1 +w32 0 0 0 0 0 0 0 0 +w33 1 0 1 1 1 1 0 1 +w34 1 1 1 0 1 0 0 1 +w35 1 1 1 1 1 0 0 1 +w36 0 1 1 1 0 1 1 1 +w37 1 1 1 0 1 1 0 1 +w38 1 1 1 0 1 0 0 1 +w39 0 1 1 1 1 1 0 1 +w40 1 1 1 0 1 0 0 1 +w41 1 0 1 1 1 0 0 1 +w42 1 1 1 0 1 0 0 1 +w43 1 1 1 0 1 0 0 1 +w44 1 1 1 1 1 0 0 1 +w45 0 1 1 1 1 1 0 1 +w46 0 1 1 1 1 0 1 1 +w47 0 1 1 1 1 1 0 1 +w48 0 1 1 1 1 0 0 1 +w49 1 1 1 1 1 0 0 1 +w50 0 1 1 1 1 1 0 1 +w51 0 1 1 1 1 0 1 1 +w53 1 1 1 1 1 0 0 1 +w54 0 1 1 1 1 1 1 1 +w55 0 1 1 1 1 0 0 1 +w56 0 1 1 1 1 1 0 1 +w57 0 1 1 1 1 1 0 1 +w59 0 1 1 1 0 1 1 1 +w60 0 1 1 1 1 0 1 1 +w61 0 1 1 1 0 0 1 1 +w62 0 0 0 0 0 0 1 0 +w63 0 1 1 1 0 1 1 1 +w64 0 1 1 1 1 1 0 1 +w65 0 1 1 1 0 1 1 1 +w66 0 1 1 1 0 1 1 1 +w68 0 1 1 1 0 1 1 1 +w69 0 1 1 1 0 1 1 1 +w71 0 1 1 1 0 1 1 1 +w72 0 1 1 1 0 1 1 1 +w73 0 1 1 1 0 1 1 0 +w74 0 1 1 1 0 0 0 1 +w75 0 1 1 1 0 1 1 1 +w76 0 0 0 0 0 0 0 0 +w77 1 0 1 1 1 0 0 1 +w78 1 0 1 1 1 0 0 1 +w79 1 0 1 1 1 0 0 1 +w80 1 0 1 1 1 0 0 1 +w81 1 0 1 1 1 0 0 1 +w82 1 0 1 1 1 1 1 0 +w83 1 0 1 1 1 0 1 1 +w84 1 0 1 1 1 0 0 1 +w85 1 1 1 1 1 0 0 1 +w86 1 0 1 1 1 0 0 1 +w87 1 0 1 1 1 1 1 0 +w89 1 0 1 1 1 1 0 1 +w90 0 1 1 1 1 0 0 1 +w91 1 0 1 1 1 0 0 1 +w92 1 0 1 1 1 0 0 1 +w93 1 1 1 0 1 0 0 1 +w94 0 0 1 1 1 0 1 1 +w95 1 0 1 1 1 0 0 1 +w96 0 0 0 0 0 0 0 0 +w98 1 0 1 1 1 1 0 1 +x22 1 1 1 1 0 0 1 0 +x23 1 1 1 1 0 0 1 0 ; + +param ds default 0.000 (tr) : + + 18REG 24REG 24PRO := + +w01 0.000 0.000 0.008 +w02 0.004 0.000 0.000 +w03 0.000 0.000 0.000 +w04 0.010 0.002 0.000 +w05 0.000 0.000 0.000 +w06 0.010 0.008 0.008 +w08 0.030 0.024 0.024 +w09 0.014 0.018 0.020 +w12 0.014 0.012 0.010 +w14 0.007 0.007 0.012 +w15 0.010 0.019 0.018 +w17 0.013 0.010 0.011 +w19 0.015 0.012 0.009 +w20 0.012 0.021 0.022 +w21 0.000 0.000 0.000 +w24 0.012 0.022 0.018 +w25 0.019 0.025 0.020 +w26 0.006 0.015 0.021 +w27 0.008 0.010 0.015 +w28 0.011 0.016 0.019 +w29 0.008 0.020 0.013 +w30 0.011 0.013 0.015 +w31 0.011 0.013 0.017 +w32 0.006 0.000 0.000 +w33 0.000 0.015 0.014 +w34 0.008 0.007 0.005 +w35 0.002 0.006 0.014 +w36 0.015 0.013 0.005 +w37 0.017 0.016 0.015 +w38 0.015 0.009 0.012 +w39 0.007 0.017 0.022 +w40 0.009 0.014 0.020 +w41 0.003 0.014 0.011 +w42 0.017 0.011 0.012 +w43 0.009 0.013 0.011 +w44 0.002 0.012 0.012 +w45 0.016 0.025 0.028 +w46 0.038 0.062 0.040 +w47 0.007 0.010 0.010 +w48 0.003 0.015 0.016 +w49 0.005 0.016 0.017 +w50 0.011 0.008 0.007 +w51 0.010 0.022 0.021 +w53 0.004 0.026 0.020 +w54 0.020 0.017 0.025 +w55 0.004 0.019 0.028 +w56 0.004 0.010 0.008 +w57 0.014 0.020 0.018 +w59 0.012 0.006 0.007 +w60 0.019 0.010 0.009 +w61 0.028 0.010 0.012 +w62 0.000 0.000 0.000 +w63 0.070 0.027 0.037 +w64 0.009 0.004 0.005 +w65 0.022 0.015 0.016 +w66 0.046 0.017 0.020 +w68 0.005 0.012 0.016 +w69 0.085 0.036 0.039 +w71 0.011 0.013 0.010 +w72 0.089 0.031 0.034 +w75 0.026 0.012 0.010 +w77 0.001 0.004 0.002 +w78 0.002 0.004 0.002 +w79 0.001 0.004 0.002 +w80 0.001 0.001 0.002 +w81 0.001 0.003 0.002 +w83 0.009 0.010 0.008 +w84 0.001 0.002 0.002 +w85 0.001 0.004 0.005 +w86 0.001 0.002 0.002 +w87 0.002 0.003 0.000 +w89 0.001 0.001 0.002 +w90 0.006 0.017 0.013 +w91 0.002 0.010 0.013 +w92 0.000 0.003 0.002 +w93 0.002 0.006 0.007 +w95 0.001 0.007 0.007 +w96 0.000 0.000 0.000 +w98 0.006 0.005 0.002 ; + +end; diff --git a/glpk-5.0/examples/egypt.mod b/glpk-5.0/examples/egypt.mod new file mode 100644 index 0000000..b051d4a --- /dev/null +++ b/glpk-5.0/examples/egypt.mod @@ -0,0 +1,519 @@ +# EGYPT, a static model of fertilizer production +# +# References: +# Robert Fourer, David M. Gay and Brian W. Kernighan, "A Modeling Language +# for Mathematical Programming." Management Science 36 (1990) 519-554. + +### SETS ### + +set center; # Locations from which final product may be shipped +set port within center; # Locations at which imports can be received +set plant within center; # Locations of plants + +set region; # Demand regions + +set unit; # Productive units +set proc; # Processes + +set nutr; # Nutrients + +set c_final; # Final products (fertilizers) +set c_inter; # Intermediate products +set c_ship within c_inter; # Intermediates for shipment +set c_raw; # Domestic raw materials and miscellaneous inputs + +set commod := c_final union c_inter union c_raw; + + # All commodities + +### PARAMETERS ### + +param cf75 {region,c_final} >= 0; + + # Consumption of fertilizer 1974-75 (1000 tpy) + +param fn {c_final,nutr} >= 0; + + # Nutrient content of fertilizers + +param cn75 {r in region, n in nutr} := sum {c in c_final} cf75[r,c] * fn[c,n]; + + # Consumption of nutrients 1974-75 (1000 tpy) + +param road {region,center} >= 0; + + # Road distances + +param rail_half {plant,plant} >= 0; +param rail {p1 in plant, p2 in plant} := + if rail_half[p1,p2] > 0 then rail_half[p1,p2] else rail_half[p2,p1]; + + # Interplant rail distances (kms) + +param impd_barg {plant} >= 0; +param impd_road {plant} >= 0; + + # Import distances (kms) by barge and road + +param tran_final {pl in plant, r in region} := + if road[r,pl] > 0 then .5 + .0144 * road[r,pl] else 0; + +param tran_import {r in region, po in port} := + if road[r,po] > 0 then .5 + .0144 * road[r,po] else 0; + +param tran_inter {p1 in plant, p2 in plant} := + if rail[p1,p2] > 0 then 3.5 + .03 * rail[p1,p2] else 0; + +param tran_raw {pl in plant} := + (if impd_barg[pl] > 0 then 1.0 + .0030 * impd_barg[pl] else 0) + + (if impd_road[pl] > 0 then 0.5 + .0144 * impd_road[pl] else 0); + + # Transport cost (le per ton) for: + # final products, imported final products, + # interplant shipment, imported raw materials + +param io {commod,proc}; # Input-output coefficients + +param util {unit,proc} >= 0; + + # Capacity utilization coefficients + +param p_imp {commod} >= 0; # Import Price (cif US$ per ton 1975) + +param p_r {c_raw} >= 0; +param p_pr {plant,c_raw} >= 0; + +param p_dom {pl in plant, c in c_raw} := + if p_r[c] > 0 then p_r[c] else p_pr[pl,c]; + + # Domestic raw material prices + +param dcap {plant,unit} >= 0; + + # Design capacity of plants (t/day) + +param icap {u in unit, pl in plant} := 0.33 * dcap[pl,u]; + + # Initial capacity of plants (t/day) + +param exch := 0.4; # Exchange rate + +param util_pct := 0.85; # Utilization percent for initial capacity + +### DERIVED SETS OF "POSSIBILITIES" ### + +set m_pos {pl in plant} := {u in unit: icap[u,pl] > 0}; + + # At each plant, set of units for which there is + # initial capacity + +set p_cap {pl in plant} := + {pr in proc: forall {u in unit: util[u,pr] > 0} u in m_pos[pl] }; + + # At each plant, set of processes for which + # all necessary units have some initial capacity + +set p_except {plant} within proc; + + # At each plant, list of processes that are + # arbitrarily ruled out + +set p_pos {pl in plant} := p_cap[pl] diff p_except[pl]; + + # At each plant, set of possible processes + +set cp_pos {c in commod} := {pl in plant: sum {pr in p_pos[pl]} io[c,pr] > 0}; + +set cc_pos {c in commod} := {pl in plant: sum {pr in p_pos[pl]} io[c,pr] < 0}; + +set c_pos {c in commod} := cp_pos[c] union cc_pos[c]; + + # For each commodity, set of plants that can + # produce it (cp_pos) or consume it (cc_pos), + # and their union (c_pos) + +### VARIABLES ### + +var Z {pl in plant, p_pos[pl]} >= 0; + + # Z[pl,pr] is level of process pr at plant pl + +var Xf {c in c_final, cp_pos[c], region} >= 0; + + # Xf[c,pl,r] is amount of final product c + # shipped from plant pl to region r + +var Xi {c in c_ship, cp_pos[c], cc_pos[c]} >= 0; + + # Xi[c,p1,p2] is amount of intermediate c + # shipped from plant p1 to plant p2 + +var Vf {c_final,region,port} >= 0; + + # Vf[c,r,po] is amount of final product c + # imported by region r from port po + +var Vr {c in c_raw, cc_pos[c]} >= 0; + + # Vr[c,pl] is amount of raw material c + # imported for use at plant pl + +var U {c in c_raw, cc_pos[c]} >= 0; + + # U[c,pl] is amount of raw material c + # purchased domestically for use at plant pl + +var Psip; # Domestic recurrent cost +var Psil; # Transport cost +var Psii; # Import cost + +### OBJECTIVE ### + +minimize Psi: Psip + Psil + Psii; + +### CONSTRAINTS ### + +subject to mbd {n in nutr, r in region}: + + sum {c in c_final} fn[c,n] * + (sum {po in port} Vf[c,r,po] + + sum {pl in cp_pos[c]} Xf[c,pl,r]) >= cn75[r,n]; + + # Total nutrients supplied to a region by all + # final products (sum of imports plus internal + # shipments from plants) must meet requirements + +subject to mbdb {c in c_final, r in region: cf75[r,c] > 0}: + + sum {po in port} Vf[c,r,po] + + sum {pl in cp_pos[c]} Xf[c,pl,r] >= cf75[r,c]; + + # Total of each final product supplied to each + # region (as in previous constraint) must meet + # requirements + +subject to mb {c in commod, pl in plant}: + + sum {pr in p_pos[pl]} io[c,pr] * Z[pl,pr] + + + ( if c in c_ship then + ( if pl in cp_pos[c] then sum {p2 in cc_pos[c]} Xi[c,pl,p2] ) + - ( if pl in cc_pos[c] then sum {p2 in cp_pos[c]} Xi[c,p2,pl] )) + + + ( if (c in c_raw and pl in cc_pos[c]) then + (( if p_imp[c] > 0 then Vr[c,pl] ) + + ( if p_dom[pl,c] > 0 then U[c,pl] ))) + + >= if (c in c_final and pl in cp_pos[c]) then sum {r in region} Xf[c,pl,r]; + + # For each commodity at each plant: sum of + # (1) production or consumption at plant, + # (2) inter-plant shipments in or out, + # (3) import and domestic purchases (raw only) + # is >= 0 for raw materials and intermediates; + # is >= the total shipped for final products + +subject to cc {pl in plant, u in m_pos[pl]}: + + sum {pr in p_pos[pl]} util[u,pr] * Z[pl,pr] <= util_pct * icap[u,pl]; + + # For each productive unit at each plant, + # total utilization by all processes + # may not exceed the unit's capacity + +subject to ap: + + Psip = sum {c in c_raw, pl in cc_pos[c]} p_dom[pl,c] * U[c,pl]; + + # Psip is the cost of domestic raw materials, + # summed over all plants that consume them + +subject to al: + + Psil = sum {c in c_final} ( + + sum {pl in cp_pos[c], r in region} + tran_final[pl,r] * Xf[c,pl,r] + + + sum {po in port, r in region} tran_import[r,po] * Vf[c,r,po] ) + + + sum {c in c_ship, p1 in cp_pos[c], p2 in cc_pos[c]} + tran_inter[p1,p2] * Xi[c,p1,p2] + + + sum {c in c_raw, pl in cc_pos[c]: p_imp[c] > 0} + tran_raw[pl] * Vr[c,pl]; + + # Total transport cost is sum of shipping costs for + # (1) all final products from all plants, + # (2) all imports of final products, + # (3) all intermediates shipped between plants, + # (4) all imports of raw materials + +subject to ai: + + Psii / exch = sum {c in c_final, r in region, po in port} + p_imp[c] * Vf[c,r,po] + + + sum {c in c_raw, pl in cc_pos[c]} p_imp[c] * Vr[c,pl]; + + # Total import cost -- at exchange rate -- + # is sum of import costs for final products + # in each region and raw materials at each plant + +### DATA ### + +data; + +set center := ASWAN HELWAN ASSIOUT KAFR_EL_ZT ABU_ZAABAL ABU_KIR TALKHA SUEZ ; + +set port := ABU_KIR ; + +set plant := ASWAN HELWAN ASSIOUT KAFR_EL_ZT ABU_ZAABAL ; + +set region := ALEXANDRIA BEHERA GHARBIA KAFR_EL_SH DAKAHLIA DAMIETTA + SHARKIA ISMAILIA SUEZ MENOUFIA KALUBIA GIZA BENI_SUEF FAYOUM + MINIA ASSIOUT NEW_VALLEY SOHAG QUENA ASWAN ; + +set unit := SULF_A_S SULF_A_P NITR_ACID AMM_ELEC AMM_C_GAS C_AMM_NITR + AMM_SULF SSP ; + +set proc := SULF_A_S SULF_A_P NITR_ACID AMM_ELEC AMM_C_GAS CAN_310 CAN_335 + AMM_SULF SSP_155 ; + +set nutr := N P205 ; + +set c_final := UREA CAN_260 CAN_310 CAN_335 AMM_SULF DAP SSP_155 C_250_55 + C_300_100 ; + +set c_inter := AMMONIA NITR_ACID SULF_ACID ; + +set c_ship := AMMONIA SULF_ACID ; + +set c_raw := EL_ASWAN COKE_GAS PHOS_ROCK LIMESTONE EL_SULFUR PYRITES + ELECTRIC BF_GAS WATER STEAM BAGS ; + +set p_except[ASWAN] := CAN_335 ; +set p_except[HELWAN] := CAN_310 ; +set p_except[ASSIOUT] := ; +set p_except[KAFR_EL_ZT] := ; +set p_except[ABU_ZAABAL] := ; + +param cf75 default 0.0 : + + CAN_260 CAN_310 CAN_335 AMM_SULF UREA := + +ALEXANDRIA . . 5.0 3.0 1.0 +ASSIOUT 1.0 20.0 26.0 1.0 27.0 +ASWAN . 40.0 . . . +BEHERA 1.0 . 25.0 90.0 35.0 +BENI_SUEF 1.0 . 15.0 1.0 20.0 +DAKAHLIA 1.0 . 26.0 60.0 20.0 +DAMIETTA . . 2.0 15.0 8.0 +FAYOUM 1.0 . 20.0 6.0 20.0 +GHARBIA . . 17.0 60.0 28.0 +GIZA . . 40.0 6.0 2.0 +ISMAILIA . . 4.0 6.0 2.0 +KAFR_EL_SH 1.0 . 10.0 45.0 22.0 +KALUBIA . . 25.0 16.0 7.0 +MENOUFIA 1.0 . 24.0 21.0 30.0 +MINIA 2.0 15.0 35.0 1.0 41.0 +NEW_VALLEY . . . . 1.0 +QUENA . 95.0 2.0 . 3.0 +SHARKIA 1.0 . 31.0 50.0 28.0 +SOHAG . 65.0 3.0 . 7.0 +SUEZ . . 1.0 . . + + : SSP_155 C_250_55 C_300_100 DAP := + +ALEXANDRIA 8.0 . . . +ASSIOUT 35.0 5.0 .1 . +ASWAN 8.0 . . . +BEHERA 64.0 1.0 .1 .1 +BENI_SUEF 13.0 3.0 . . +DAKAHLIA 52.0 1.0 . . +DAMIETTA 5.0 . . . +FAYOUM 17.0 1.0 . . +GHARBIA 57.0 1.0 .2 .1 +GIZA 14.0 1.0 .1 . +ISMAILIA 4.0 . . . +KAFR_EL_SH 25.0 2.0 .1 . +KALUBIA 22.0 1.0 . .1 +MENOUFIA 33.0 2.0 .1 .1 +MINIA 50.0 3.0 .2 .1 +NEW_VALLEY 1.0 . . . +QUENA 8.0 . . . +SHARKIA 43.0 1.0 .1 . +SOHAG 20.0 1.0 . . +SUEZ 1.0 . . . ; + +param fn default 0.0 : N P205 := + + AMM_SULF .206 . + CAN_260 .26 . + CAN_310 .31 . + CAN_335 .335 . + C_250_55 .25 .055 + C_300_100 .30 .10 + DAP .18 .46 + SSP_155 . .15 + UREA .46 . ; + +param road default 0.0 : + + ABU_KIR ABU_ZAABAL ASSIOUT ASWAN HELWAN KAFR_EL_ZT SUEZ TALKHA := + +ALEXANDRIA 16 210 607 1135 244 119 362 187 +ASSIOUT 616 420 . 518 362 504 527 518 +ASWAN 1134 938 518 . 880 1022 1045 1036 +BEHERA 76 50 547 1065 184 42 288 120 +BENI_SUEF 359 163 257 775 105 248 270 261 +DAKAHLIA 208 138 515 1033 152 58 219 3 +DAMIETTA 267 216 596 1114 233 131 286 66 +FAYOUM 341 145 308 826 88 230 252 243 +GHARBIA 150 65 485 1003 122 20 226 55 +GIZA 287 48 372 890 .9 133 169 146 +ISMAILIA 365 142 536 1054 173 241 89 146 +KAFR_EL_SH 145 105 525 1043 162 20 266 35 +KALUBIA 190 97 439 957 76 66 180 81 +MENOUFIA 157 154 472 990 109 33 213 90 +MINIA 384 288 132 650 230 372 394 386 +NEW_VALLEY 815 619 199 519 561 703 726 717 +QUENA 858 662 242 276 604 746 769 760 +SHARKIA 240 60 473 991 110 78 214 58 +SOHAG 715 519 99 419 461 603 626 617 +SUEZ 370 224 541 1059 178 246 . 298 ; + +param rail_half default 0 : + + KAFR_EL_ZT ABU_ZAABAL HELWAN ASSIOUT := + +ABU_ZAABAL 85 . . . +HELWAN 142 57 . . +ASSIOUT 504 420 362 . +ASWAN 1022 938 880 518 ; + +param : impd_barg impd_road := + +ABU_ZAABAL 210 .1 +ASSIOUT 583 0 +ASWAN 1087 10 +HELWAN 183 0 +KAFR_EL_ZT 104 6 ; + +param io default 0.0 := + + [*,AMM_C_GAS] AMMONIA 1.0 + BF_GAS -609. + COKE_GAS -2.0 + ELECTRIC -1960. + STEAM -4. + WATER -700. + + [*,AMM_ELEC] AMMONIA 1.0 + EL_ASWAN -12.0 + + [*,AMM_SULF] AMMONIA -.26 + AMM_SULF 1.0 + BAGS -22. + ELECTRIC -19. + SULF_ACID -.76 + WATER -17. + + [*,CAN_310] AMMONIA -.20 + BAGS -23. + CAN_310 1.0 + LIMESTONE -.12 + NITR_ACID -.71 + STEAM -.4 + WATER -49. + + [*,CAN_335] AMMONIA -.21 + BAGS -23. + CAN_335 1.0 + LIMESTONE -.04 + NITR_ACID -.76 + STEAM -.4 + WATER -49. + + [*,NITR_ACID] AMMONIA -.292 + ELECTRIC -231. + NITR_ACID 1.0 + WATER -.6 + + [*,SSP_155] BAGS -22. + ELECTRIC -14. + PHOS_ROCK -.62 + SSP_155 1.0 + SULF_ACID -.41 + WATER -6. + + [*,SULF_A_P] ELECTRIC -75. + PYRITES -.826 + SULF_ACID 1.0 + WATER -60. + + [*,SULF_A_S] ELECTRIC -50. + EL_SULFUR -.334 + SULF_ACID 1.0 + WATER -20. ; + +param util default 0 := + + [*,*] SULF_A_S SULF_A_S 1 SULF_A_P SULF_A_P 1 + NITR_ACID NITR_ACID 1 AMM_ELEC AMM_ELEC 1 + AMM_C_GAS AMM_C_GAS 1 SSP SSP_155 1 + C_AMM_NITR CAN_310 1 C_AMM_NITR CAN_335 1 + AMM_SULF AMM_SULF 1 ; + +param p_imp default 0.0 := + + PYRITES 17.5 AMM_SULF 75. + EL_SULFUR 55. DAP 175. + UREA 150. SSP_155 80. + CAN_260 75. C_250_55 100. + CAN_310 90. C_300_100 130. + CAN_335 100. ; + +param p_r default 0.0 := + + ELECTRIC .007 + BF_GAS .007 + WATER .031 + STEAM 1.25 + BAGS .28 ; + +param p_pr default 0.0 := + + [HELWAN,COKE_GAS] 16.0 + [ASWAN,EL_ASWAN] 1.0 + + [*,LIMESTONE] ASWAN 1.2 + HELWAN 1.2 + + [*,PHOS_ROCK] ABU_ZAABAL 4.0 + ASSIOUT 3.5 + KAFR_EL_ZT 5.0 ; + +param dcap default 0.0 := + + [ABU_ZAABAL,*] SSP 600 + SULF_A_P 227 + SULF_A_S 242 + + [ASSIOUT,*] SSP 600 + SULF_A_S 250 + + [ASWAN,*] AMM_ELEC 450 + C_AMM_NITR 1100 + NITR_ACID 800 + + [HELWAN,*] AMM_C_GAS 172 + AMM_SULF 24 + C_AMM_NITR 364 + NITR_ACID 282 + + [KAFR_EL_ZT,*] SSP 600 + SULF_A_P 50 + SULF_A_S 200 ; + +end; diff --git a/glpk-5.0/examples/fctp.mod b/glpk-5.0/examples/fctp.mod new file mode 100644 index 0000000..9d6382d --- /dev/null +++ b/glpk-5.0/examples/fctp.mod @@ -0,0 +1,93 @@ +/* FCTP, Fixed-Charge Transportation Problem */ + +/* Written in GNU MathProg by Andrew Makhorin <mao@gnu.org> */ + +/* The Fixed-Charge Transportation Problem (FCTP) is obtained from + classical transportation problem by imposing a fixed cost on each + transportation link if there is a positive flow on that link. */ + +param m, integer, > 0; +/* number of sources */ + +param n, integer, > 0; +/* number of customers */ + +set I := 1..m; +/* set of sources */ + +set J := 1..n; +/* set of customers */ + +param supply{i in I}, >= 0; +/* supply at source i */ + +param demand{j in J}, >= 0; +/* demand at customer j */ + +param varcost{i in I, j in J}, >= 0; +/* variable cost (a cost per one unit shipped from i to j) */ + +param fixcost{i in I, j in J}, >= 0; +/* fixed cost (a cost for shipping any amount from i to j) */ + +var x{i in I, j in J}, >= 0; +/* amount shipped from source i to customer j */ + +s.t. f{i in I}: sum{j in J} x[i,j] = supply[i]; +/* observe supply at source i */ + +s.t. g{j in J}: sum{i in I} x[i,j] = demand[j]; +/* satisfy demand at customer j */ + +var y{i in I, j in J}, binary; +/* y[i,j] = 1 means some amount is shipped from i to j */ + +s.t. h{i in I, j in J}: x[i,j] <= min(supply[i], demand[j]) * y[i,j]; +/* if y[i,j] is 0, force x[i,j] to be 0 (may note that supply[i] and + demand[j] are implicit upper bounds for x[i,j] as follows from the + constraints f[i] and g[j]) */ + +minimize cost: sum{i in I, j in J} varcost[i,j] * x[i,j] + + sum{i in I, j in J} fixcost[i,j] * y[i,j]; +/* total transportation costs */ + +data; + +/* These data correspond to the instance bal8x12 from [Balinski]. */ + +/* The optimal solution is 471.55 */ + +param m := 8; + +param n := 12; + +param supply := 1 15.00, 2 20.00, 3 45.00, 4 35.00, + 5 25.00, 6 35.00, 7 10.00, 8 25.00; + +param demand := 1 20.00, 2 15.00, 3 20.00, 4 15.00, + 5 5.00, 6 20.00, 7 30.00, 8 10.00, + 9 35.00, 10 25.00, 11 10.00, 12 5.00; + +param varcost + : 1 2 3 4 5 6 7 8 9 10 11 12 := + 1 0.69 0.64 0.71 0.79 1.70 2.83 2.02 5.64 5.94 5.94 5.94 7.68 + 2 1.01 0.75 0.88 0.59 1.50 2.63 2.26 5.64 5.85 5.62 5.85 4.94 + 3 1.05 1.06 1.08 0.64 1.22 2.37 1.66 5.64 5.91 5.62 5.91 4.94 + 4 1.94 1.50 1.56 1.22 1.98 1.98 1.36 6.99 6.99 6.99 6.99 3.68 + 5 1.61 1.40 1.61 1.33 1.68 2.83 1.54 4.26 4.26 4.26 4.26 2.99 + 6 5.29 5.94 6.08 5.29 5.96 6.77 5.08 0.31 0.21 0.17 0.31 1.53 + 7 5.29 5.94 6.08 5.29 5.96 6.77 5.08 0.55 0.35 0.40 0.19 1.53 + 8 5.29 6.08 6.08 5.29 5.96 6.45 5.08 2.43 2.30 2.33 1.81 2.50 ; + +param fixcost + : 1 2 3 4 5 6 7 8 9 10 11 12 := + 1 11.0 16.0 18.0 17.0 10.0 20.0 17.0 13.0 15.0 12.0 14.0 14.0 + 2 14.0 17.0 17.0 13.0 15.0 13.0 16.0 11.0 20.0 11.0 15.0 10.0 + 3 12.0 13.0 20.0 17.0 13.0 15.0 16.0 13.0 12.0 13.0 10.0 18.0 + 4 16.0 19.0 16.0 11.0 15.0 12.0 18.0 12.0 18.0 13.0 13.0 14.0 + 5 19.0 18.0 15.0 16.0 12.0 14.0 20.0 19.0 11.0 17.0 16.0 18.0 + 6 13.0 20.0 20.0 17.0 15.0 12.0 14.0 11.0 12.0 19.0 15.0 16.0 + 7 11.0 12.0 15.0 10.0 17.0 11.0 11.0 16.0 10.0 18.0 17.0 12.0 + 8 17.0 10.0 20.0 12.0 17.0 20.0 16.0 15.0 10.0 12.0 16.0 18.0 ; + +end; diff --git a/glpk-5.0/examples/food.mod b/glpk-5.0/examples/food.mod new file mode 100644 index 0000000..cb1aa05 --- /dev/null +++ b/glpk-5.0/examples/food.mod @@ -0,0 +1,127 @@ +/* Food Manufacture 1, section 12.1 in + * Williams, "Model Building in Mathematical Programming" + * + * Sebastian Nowozin <nowozin@gmail.com> + */ + +set oils; +set month; + +/* Buying prices of the raw oils in the next six month. */ +param buyingprices{month,oils}; + +/* Actual amount bought in each month. */ +var buys{month,oils} >= 0; + +/* Stock for each oil. */ +var stock{month,oils} >= 0; + +/* Price of the produced product */ +param productprice >= 0; +param storagecost; + +param oilhardness{oils} >= 0; + +/* Actual amount of output oil produced in each month */ +var production{m in month} >= 0; +var useoil{m in month, o in oils} >= 0; + +maximize totalprofit: + sum{m in month} productprice*production[m] + - sum{m in month, o in oils} buyingprices[m,o]*buys[m,o] + - sum{m in month, o in oils} storagecost*stock[m,o]; + +/* Constraints */ + +/* 1. Starting stock */ +s.t. startstock{o in oils}: + stock[1,o] = 500; +s.t. endstock{o in oils}: + stock[6,o] + buys[6,o] - useoil[6,o] >= 500; + +/* 2. Stock constraints */ +s.t. stocklimit{m in month, o in oils}: + stock[m,o] <= 1000; + +s.t. production1{m in month, o in oils}: + useoil[m,o] <= stock[m,o] + buys[m,o]; +s.t. production2{m1 in month, m2 in month, o in oils : m2 = m1+1}: + stock[m2,o] = stock[m1,o] + buys[m1,o] - useoil[m1,o]; + +s.t. production3a{m in month}: + sum{o in oils} oilhardness[o]*useoil[m,o] >= 3*production[m]; +s.t. production3b{m in month}: + sum{o in oils} oilhardness[o]*useoil[m,o] <= 6*production[m]; + +s.t. production4{m in month}: + production[m] = sum{o in oils} useoil[m,o]; + +/* 3. Refining constraints */ +s.t. refine1{m in month}: + useoil[m,"VEG1"]+useoil[m,"VEG2"] <= 200; +s.t. refine2{m in month}: + useoil[m,"OIL1"]+useoil[m,"OIL2"]+useoil[m,"OIL3"] <= 250; + +solve; + +for {m in month} { + printf "Month %d\n", m; + printf "PRODUCE %4.2f tons, hardness %4.2f\n", production[m], + (sum{o in oils} oilhardness[o]*useoil[m,o]) / (sum{o in oils} useoil[m,o]); + + printf "\tVEG1\tVEG2\tOIL1\tOIL2\tOIL3\n"; + printf "STOCK"; + printf "%d", m; + for {o in oils} { + printf "\t%4.2f", stock[m,o]; + } + printf "\nBUY"; + for {o in oils} { + printf "\t%4.2f", buys[m,o]; + } + printf "\nUSE"; + printf "%d", m; + for {o in oils} { + printf "\t%4.2f", useoil[m,o]; + } + printf "\n"; + printf "\n"; +} +printf "Total profit: %4.2f\n", + (sum{m in month} productprice*production[m] + - sum{m in month, o in oils} buyingprices[m,o]*buys[m,o] + - sum{m in month, o in oils} storagecost*stock[m,o]); +printf " turnover: %4.2f\n", + sum{m in month} productprice*production[m]; +printf " buying costs: %4.2f\n", + sum{m in month, o in oils} buyingprices[m,o]*buys[m,o]; +printf " storage costs: %4.2f\n", + sum{m in month, o in oils} storagecost*stock[m,o]; + + +data; + +param : oils : oilhardness := + VEG1 8.8 + VEG2 6.1 + OIL1 2.0 + OIL2 4.2 + OIL3 5.0 ; + +set month := 1 2 3 4 5 6; + +param buyingprices + +: VEG1 VEG2 OIL1 OIL2 OIL3 := + +1 110 120 130 110 115 +2 130 130 110 90 115 +3 110 140 130 100 95 +4 120 110 120 120 125 +5 100 120 150 110 105 +6 90 100 140 80 135 ; + +param productprice := 150; +param storagecost := 5; + +end; diff --git a/glpk-5.0/examples/food2.mod b/glpk-5.0/examples/food2.mod new file mode 100644 index 0000000..694b594 --- /dev/null +++ b/glpk-5.0/examples/food2.mod @@ -0,0 +1,150 @@ +/* Food Manufacture 2, section 12.2 in + * Williams, "Model Building in Mathematical Programming" + * + * Sebastian Nowozin <nowozin@gmail.com> + */ + +set oils; +set month; + +/* Buying prices of the raw oils in the next six month. */ +param buyingprices{month,oils}; + +/* Actual amount bought in each month. */ +var buys{month,oils} >= 0; + +/* Stock for each oil. */ +var stock{month,oils} >= 0; + +/* Price of the produced product */ +param productprice >= 0; +param storagecost; + +param oilhardness{oils} >= 0; +param M >= 0; + +/* Actual amount of output oil produced in each month */ +var production{m in month} >= 0; +var useoil{m in month, o in oils} >= 0, <= M; +var useoilb{m in month, o in oils}, binary; + +maximize totalprofit: + sum{m in month} productprice*production[m] + - sum{m in month, o in oils} buyingprices[m,o]*buys[m,o] + - sum{m in month, o in oils} storagecost*stock[m,o]; + +/* Constraints */ + +/* 1. Starting stock */ +s.t. startstock{o in oils}: + stock[1,o] = 500; +s.t. endstock{o in oils}: + stock[6,o] + buys[6,o] - useoil[6,o] >= 500; + +/* 2. Stock constraints */ +s.t. stocklimit{m in month, o in oils}: + stock[m,o] <= 1000; + +s.t. production1{m in month, o in oils}: + useoil[m,o] <= stock[m,o] + buys[m,o]; +s.t. production2{m1 in month, m2 in month, o in oils : m2 = m1+1}: + stock[m2,o] = stock[m1,o] + buys[m1,o] - useoil[m1,o]; + +s.t. production3a{m in month}: + sum{o in oils} oilhardness[o]*useoil[m,o] >= 3*production[m]; +s.t. production3b{m in month}: + sum{o in oils} oilhardness[o]*useoil[m,o] <= 6*production[m]; + +s.t. production4{m in month}: + production[m] = sum{o in oils} useoil[m,o]; + +/* 3. Refining constraints */ +s.t. refine1{m in month}: + useoil[m,"VEG1"]+useoil[m,"VEG2"] <= 200; +s.t. refine2{m in month}: + useoil[m,"OIL1"]+useoil[m,"OIL2"]+useoil[m,"OIL3"] <= 250; + +/* 4. Additional conditions: + * i) The food may never be made up of more than three oils every month + */ +s.t. useoilb_calc{m in month, o in oils}: + M*useoilb[m,o] >= useoil[m,o]; +s.t. useoilb_limit{m in month}: + sum{o in oils} useoilb[m,o] <= 3; + +/* ii) If an oil is used in a month, at least 20 tons must be used. + */ +s.t. useminimum{m in month, o in oils}: + 20*useoilb[m,o] <= useoil[m,o]; + +/* iii) If either of VEG1 or VEG2 is used in a month, OIL2 must also be used + */ +s.t. use_oil2a{m in month}: + useoilb[m,"VEG1"] <= useoilb[m,"OIL3"]; +s.t. use_oil2b{m in month}: + useoilb[m,"VEG2"] <= useoilb[m,"OIL3"]; + +solve; + +for {m in month} { + printf "Month %d\n", m; + printf "PRODUCE %4.2f tons, hardness %4.2f\n", production[m], + (sum{o in oils} oilhardness[o]*useoil[m,o]) / (sum{o in oils} useoil[m,o]); + + printf "\tVEG1\tVEG2\tOIL1\tOIL2\tOIL3\n"; + printf "STOCK"; + printf "%d", m; + for {o in oils} { + printf "\t%4.2f", stock[m,o]; + } + printf "\nBUY"; + for {o in oils} { + printf "\t%4.2f", buys[m,o]; + } + printf "\nUSE"; + printf "%d", m; + for {o in oils} { + printf "\t%4.2f", useoil[m,o]; + } + printf "\n"; + printf "\n"; +} +printf "Total profit: %4.2f\n", + (sum{m in month} productprice*production[m] + - sum{m in month, o in oils} buyingprices[m,o]*buys[m,o] + - sum{m in month, o in oils} storagecost*stock[m,o]); +printf " turnover: %4.2f\n", + sum{m in month} productprice*production[m]; +printf " buying costs: %4.2f\n", + sum{m in month, o in oils} buyingprices[m,o]*buys[m,o]; +printf " storage costs: %4.2f\n", + sum{m in month, o in oils} storagecost*stock[m,o]; + + +data; + +param : oils : oilhardness := + VEG1 8.8 + VEG2 6.1 + OIL1 2.0 + OIL2 4.2 + OIL3 5.0 ; + +set month := 1 2 3 4 5 6; + +param buyingprices + +: VEG1 VEG2 OIL1 OIL2 OIL3 := + +1 110 120 130 110 115 +2 130 130 110 90 115 +3 110 140 130 100 95 +4 120 110 120 120 125 +5 100 120 150 110 105 +6 90 100 140 80 135 ; + +param productprice := 150; +param storagecost := 5; +param M := 1000; + +end; diff --git a/glpk-5.0/examples/furnace.mps b/glpk-5.0/examples/furnace.mps new file mode 100644 index 0000000..b89b7ac --- /dev/null +++ b/glpk-5.0/examples/furnace.mps @@ -0,0 +1,164 @@ +*NAME: FURNACE +*ROWS: 18 +*COLUMNS: 18 +*NONZERO: 90 +*OPT SOLN: 2141.923551 +*SOURCE: Linear Programming--Electric-Arc Furnace Steelmaking +* Data Processing Application. N.Y.: IBM Corp. +*APPLICATION: Electric-Arc Furnace Steelmaking +*COMMENTS: fixed MPS format +* encoded by Andrew Makhorin <mao@gnu.org> +* +NAME FURNACE +ROWS + N VALUE $ Price per pound (of initial charge materials) + E CR $ Chromium + E MN $ Manganese + E SI $ Silicon + E C $ Carbon + E FE $ Iron + E TOTCHG $ Total elements charged + E CRSLAG $ Chromium-oxidized-to-slag relationship + E TOTCRS $ Total modified chromium specification constraint + E MN/CR $ Total manganese specification constraint + E FESLAG $ Iron-oxidized-to-slag relationship + G ENDFE $ Total iron specification constraint + L CSPEC $ Total carbon specification constraint + E BASE $ Basicity relationship + L SISPEC $ Total silicon specification constraint + G TOTAL $ Total end metal + L TOTRS4 $ Inventory limitation on 430 grade scrap + L TOTRCF $ Inventory limitation on low-carbon ferrochrome +COLUMNS +* Steel scrap + STSCP VALUE .02 + CR 0 + MN .01 + SI .002 + C .006 + FE .982 +* 430 grade scrap + SP430 VALUE .075 + CR .16 + MN .01 + SI .0095 + C .0012 + FE .8143 + TOTRS4 1 +* High-carbon ferrochrome + HCFCR VALUE .27 + CR .556 + MN 0 + SI .02 + C .08 + FE .334 +* Low-carbon ferrochrome + LCFCR VALUE .40 + CR .65 + MN 0 + SI .01 + C .0009 + FE .3391 + TOTRCF 1 +* Chromium initially charged + CRIT VALUE 0 + CR -1 + TOTCHG 1 + CRSLAG 1 +* Manganese initially charged + MNIT VALUE 0 + MN -1 + TOTCHG 1 + CRSLAG 1 + MN/CR .98 +* Silicon initially charged + SIIT VALUE 0 + SI -1 + TOTCHG 1 + CSPEC -5 + BASE 2.14 + TOTAL -1 +* Carbon initially charged + CEIT VALUE 0 + C -1 + TOTCHG 1 + TOTAL -1 +* Iron initially charged + FEIT VALUE 0 + FE -1 + TOTCHG 1 + ENDFE 1 +* Total initial charge weight + TICW VALUE 0 + TOTCHG -1 + CRSLAG -.074 + TOTCRS .074 + FESLAG .075 + CSPEC 5 + TOTAL 1 +* Modified chromium in the slag + ISCR VALUE 0 + CRSLAG -1 + TOTCRS .95 + FESLAG -1 + CSPEC -.25 + SISPEC -.395 + TOTAL -.05 +* Chrome silicide additive at refining stage + CRSI VALUE .27 + TOTCRS .39 + ENDFE .18 + BASE 2.7606 + SISPEC .43 + TOTAL .57 +* 430 grade scrap at refining stage + RS430 VALUE .075 + TOTCRS .17 + MN/CR .01 + ENDFE .8143 + CSPEC 12 + SISPEC .0095 + TOTAL 1 + TOTRS4 1 +* Low-carbon ferrochrome at refining stage + RCFCR VALUE .40 + TOTCRS .65 + ENDFE .3391 + CSPEC 9 + SISPEC .01 + TOTAL 1 + TOTRCF 1 +* Iron in the slag + ISFE VALUE 0 + FESLAG -1 + ENDFE -.05 + CSPEC -.25 + SISPEC -.238 + TOTAL -.05 +* Lime at refining stage + LIME VALUE .01 + BASE -2 +* Low-carbon ferrochrome at finishing stage + FCFCR VALUE .40 + TOTCRS .65 + ENDFE .3391 + CSPEC 9 + SISPEC .01 + TOTAL 1 + TOTRCF 1 +* Slack in the chromium and manganese specifications + SIS VALUE 0 + TOTCRS 1 + MN/CR 1 +RHS + TOTCRS 3400 + MN/CR 200 + ENDFE 16200 + CSPEC 100000 + SISPEC 200 + TOTAL 20000 + TOTRS4 2000 + TOTRCF 2000 +BOUNDS + UP HCFCR 2000 +ENDATA diff --git a/glpk-5.0/examples/gap.mod b/glpk-5.0/examples/gap.mod new file mode 100644 index 0000000..22cdefa --- /dev/null +++ b/glpk-5.0/examples/gap.mod @@ -0,0 +1,79 @@ +/* GAP, Generalized Assignment Problem */ + +/* Written in GNU MathProg by Andrew Makhorin <mao@gnu.org> */ + +/* The Generalized Assignment Problem (GAP) is to assign a set of jobs + to a set of agents subject to the constraints that each job must be + assigned exactly to one agent and the total resources consumed by all + jobs assigned to an agent must not exceed the agent's capacity. */ + +param m, integer, > 0; +/* number of agents */ + +param n, integer, > 0; +/* number of jobs */ + +set I := 1..m; +/* set of agents */ + +set J := 1..n; +/* set of jobs */ + +param a{i in I, j in J}, >= 0; +/* resource consumed in allocating job j to agent i */ + +param b{i in I}, >= 0; +/* resource capacity of agent i */ + +param c{i in I, j in J}, >= 0; +/* cost of allocating job j to agent i */ + +var x{i in I, j in J}, binary; +/* x[i,j] = 1 means job j is assigned to agent i */ + +s.t. one{j in J}: sum{i in I} x[i,j] = 1; +/* job j must be assigned exactly to one agent */ + +s.t. lim{i in I}: sum{j in J} a[i,j] * x[i,j] <= b[i]; +/* total amount of resources consumed by all jobs assigned to agent i + must not exceed the agent's capacity */ + +minimize obj: sum{i in I, j in J} c[i,j] * x[i,j]; +/* the objective is to find cheapest assignment (note that gap can also + be formulated as maximization problem) */ + +data; + +/* These data correspond to the instance c515-1 (gap1) from: + + I.H. Osman, "Heuristics for the Generalised Assignment Problem: + Simulated Annealing and Tabu Search Approaches", OR Spektrum, Volume + 17, 211-225, 1995 + + D. Cattrysse, M. Salomon and L.N. Van Wassenhove, "A set partitioning + heuristic for the generalized assignment problem", European Journal + of Operational Research, Volume 72, 167-174, 1994 */ + +/* The optimal solution is 261 (minimization) or 336 (maximization) */ + +param m := 5; + +param n := 15; + +param a : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 := + 1 8 15 14 23 8 16 8 25 9 17 25 15 10 8 24 + 2 15 7 23 22 11 11 12 10 17 16 7 16 10 18 22 + 3 21 20 6 22 24 10 24 9 21 14 11 14 11 19 16 + 4 20 11 8 14 9 5 6 19 19 7 6 6 13 9 18 + 5 8 13 13 13 10 20 25 16 16 17 10 10 5 12 23 ; + +param b := 1 36, 2 34, 3 38, 4 27, 5 33; + +param c : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 := + 1 17 21 22 18 24 15 20 18 19 18 16 22 24 24 16 + 2 23 16 21 16 17 16 19 25 18 21 17 15 25 17 24 + 3 16 20 16 25 24 16 17 19 19 18 20 16 17 21 24 + 4 19 19 22 22 20 16 19 17 21 19 25 23 25 25 25 + 5 18 19 15 15 21 25 16 16 23 15 22 17 19 22 24 ; + +end; diff --git a/glpk-5.0/examples/glpsol.c b/glpk-5.0/examples/glpsol.c new file mode 100644 index 0000000..f67e47c --- /dev/null +++ b/glpk-5.0/examples/glpsol.c @@ -0,0 +1,1579 @@ +/* glpsol.c (stand-alone GLPK LP/MIP solver) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* Copyright (C) 2000-2020 Free Software Foundation, Inc. +* Written by Andrew Makhorin <mao@gnu.org>. +* +* 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 3 of the License, 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. If not, see <http://www.gnu.org/licenses/>. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <ctype.h> +#include <float.h> +#include <limits.h> +#include <math.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <glpk.h> + +#define xassert glp_assert +#define xerror glp_error +#define xprintf glp_printf + +struct csa +{ /* common storage area */ + glp_prob *prob; + /* LP/MIP problem object */ + glp_bfcp bfcp; + /* basis factorization control parameters */ + glp_smcp smcp; + /* simplex method control parameters */ + glp_iptcp iptcp; + /* interior-point method control parameters */ + glp_iocp iocp; + /* integer optimizer control parameters */ + glp_tran *tran; + /* model translator workspace */ + glp_graph *graph; + /* network problem object */ + int format; + /* problem file format: */ +#define FMT_MPS_DECK 1 /* fixed MPS */ +#define FMT_MPS_FILE 2 /* free MPS */ +#define FMT_LP 3 /* CPLEX LP */ +#define FMT_GLP 4 /* GLPK LP/MIP */ +#define FMT_MATHPROG 5 /* MathProg */ +#define FMT_MIN_COST 6 /* DIMACS min-cost flow */ +#define FMT_MAX_FLOW 7 /* DIMACS maximum flow */ +#if 1 /* 06/VIII-2011 */ +#define FMT_CNF 8 /* DIMACS CNF-SAT */ +#endif + const char *in_file; + /* name of input problem file */ +#define DATA_MAX 10 + /* maximal number of input data files */ + int ndf; + /* number of input data files specified */ + const char *in_data[1+DATA_MAX]; + /* name(s) of input data file(s) */ + const char *out_dpy; + /* name of output file to send display output; NULL means the + display output is sent to the terminal */ + int seed; + /* seed value to be passed to the MathProg translator; initially + set to 1; 0x80000000 means the value is omitted */ + int solution; + /* solution type flag: */ +#define SOL_BASIC 1 /* basic */ +#define SOL_INTERIOR 2 /* interior-point */ +#define SOL_INTEGER 3 /* mixed integer */ + const char *in_res; + /* name of input solution file in raw format */ + int dir; + /* optimization direction flag: + 0 - not specified + GLP_MIN - minimization + GLP_MAX - maximization */ + int scale; + /* automatic problem scaling flag */ + const char *out_sol; + /* name of output solution file in printable format */ + const char *out_res; + /* name of output solution file in raw format */ + const char *out_ranges; + /* name of output file to write sensitivity analysis report */ + int check; + /* input data checking flag; no solution is performed */ + const char *new_name; + /* new name to be assigned to the problem */ +#if 1 /* 18/I-2018 */ + int hide; + /* clear all symbolic names in the problem object */ +#endif + const char *out_mps; + /* name of output problem file in fixed MPS format */ + const char *out_freemps; + /* name of output problem file in free MPS format */ + const char *out_cpxlp; + /* name of output problem file in CPLEX LP format */ + const char *out_glp; + /* name of output problem file in GLPK format */ +#if 0 + const char *out_pb; + /* name of output problem file in OPB format */ + const char *out_npb; + /* name of output problem file in normalized OPB format */ +#endif +#if 1 /* 06/VIII-2011 */ + const char *out_cnf; + /* name of output problem file in DIMACS CNF-SAT format */ +#endif + const char *log_file; + /* name of output file to hardcopy terminal output */ + int crash; + /* initial basis option: */ +#define USE_STD_BASIS 1 /* use standard basis */ +#define USE_ADV_BASIS 2 /* use advanced basis */ +#define USE_CPX_BASIS 3 /* use Bixby's basis */ +#define USE_INI_BASIS 4 /* use initial basis from ini_file */ + const char *ini_file; + /* name of input file containing initial basis */ + int exact; + /* flag to use glp_exact rather than glp_simplex */ + int xcheck; + /* flag to check final basis with glp_exact */ + int nomip; + /* flag to consider MIP as pure LP */ +#if 1 /* 15/VIII-2011 */ + int minisat; + /* option to solve feasibility problem with MiniSat solver */ + int use_bnd; + /* option to bound objective function */ + int obj_bnd; + /* upper (minization) or lower (maximization) objective bound */ +#endif +#if 1 /* 11/VII-2013 */ + const char *use_sol; + /* name of input mip solution file in GLPK format */ +#endif +}; + +static int str2int(const char *s, int *x) +{ /* convert string to integer */ + long t; + char *endptr; + t = strtol(s, &endptr, 10); + if (*endptr != '\0') + return 2; + if (!(INT_MIN <= t && t <= INT_MAX)) + return 1; + *x = t; +#if 0 + xprintf("str2int: x = %d\n", *x); +#endif + return 0; +} + +static int str2num(const char *s, double *x) +{ /* convert string to floating point */ + double t; + char *endptr; + t = strtod(s, &endptr); + if (*endptr != '\0') + return 2; + if (!(-DBL_MAX <= t && t <= +DBL_MAX)) + return 1; + *x = t; +#if 0 + xprintf("str2num: x = %g\n", *x); +#endif + return 0; +} + +static void print_help(const char *my_name) +{ /* print help information */ + xprintf("Usage: %s [options...] filename\n", my_name); + xprintf("\n"); + xprintf("General options:\n"); + xprintf(" --mps read LP/MIP problem in fixed MPS fo" + "rmat\n"); + xprintf(" --freemps read LP/MIP problem in free MPS for" + "mat (default)\n"); + xprintf(" --lp read LP/MIP problem in CPLEX LP for" + "mat\n"); + xprintf(" --glp read LP/MIP problem in GLPK format " + "\n"); + xprintf(" --math read LP/MIP model written in GNU Ma" + "thProg modeling\n"); + xprintf(" language\n"); + xprintf(" -m filename, --model filename\n"); + xprintf(" read model section and optional dat" + "a section from\n"); + xprintf(" filename (same as --math)\n"); + xprintf(" -d filename, --data filename\n"); + xprintf(" read data section from filename (fo" + "r --math only);\n"); + xprintf(" if model file also has data section" + ", it is ignored\n"); + xprintf(" -y filename, --display filename\n"); + xprintf(" send display output to filename (fo" + "r --math only);\n"); + xprintf(" by default the output is sent to te" + "rminal\n"); + xprintf(" --seed value initialize pseudo-random number gen" + "erator used in\n"); + xprintf(" MathProg model with specified seed " + "(any integer);\n"); + xprintf(" if seed value is ?, some random see" + "d will be used\n"); + xprintf(" --mincost read min-cost flow problem in DIMAC" + "S format\n"); + xprintf(" --maxflow read maximum flow problem in DIMACS" + " format\n"); +#if 1 /* 06/VIII-2011 */ + xprintf(" --cnf read CNF-SAT problem in DIMACS form" + "at\n"); +#endif + xprintf(" --simplex use simplex method (default)\n"); + xprintf(" --interior use interior point method (LP only)" + "\n"); + xprintf(" -r filename, --read filename\n"); + xprintf(" read solution from filename rather " + "to find it with\n"); + xprintf(" the solver\n"); + xprintf(" --min minimization\n"); + xprintf(" --max maximization\n"); + xprintf(" --scale scale problem (default)\n"); + xprintf(" --noscale do not scale problem\n"); + xprintf(" -o filename, --output filename\n"); + xprintf(" write solution to filename in print" + "able format\n"); + xprintf(" -w filename, --write filename\n"); + xprintf(" write solution to filename in plain" + " text format\n"); + xprintf(" --ranges filename\n"); + xprintf(" write sensitivity analysis report t" + "o filename in\n"); + xprintf(" printable format (simplex only)\n"); + xprintf(" --tmlim nnn limit solution time to nnn seconds " + "\n"); + xprintf(" --memlim nnn limit available memory to nnn megab" + "ytes\n"); + xprintf(" --check do not solve problem, check input d" + "ata only\n"); + xprintf(" --name probname change problem name to probname\n"); +#if 1 /* 18/I-2018 */ + xprintf(" --hide remove all symbolic names from prob" + "lem object\n"); +#endif + xprintf(" --wmps filename write problem to filename in fixed " + "MPS format\n"); + xprintf(" --wfreemps filename\n"); + xprintf(" write problem to filename in free M" + "PS format\n"); + xprintf(" --wlp filename write problem to filename in CPLEX " + "LP format\n"); + xprintf(" --wglp filename write problem to filename in GLPK f" + "ormat\n"); +#if 0 + xprintf(" --wpb filename write problem to filename in OPB fo" + "rmat\n"); + xprintf(" --wnpb filename write problem to filename in normal" + "ized OPB format\n"); +#endif +#if 1 /* 06/VIII-2011 */ + xprintf(" --wcnf filename write problem to filename in DIMACS" + " CNF-SAT format\n"); +#endif + xprintf(" --log filename write copy of terminal output to fi" + "lename\n"); + xprintf(" -h, --help display this help information and e" + "xit\n"); + xprintf(" -v, --version display program version and exit\n") + ; + xprintf("\n"); + xprintf("LP basis factorization options:\n"); +#if 0 /* 08/III-2014 */ + xprintf(" --luf LU + Forrest-Tomlin update\n"); + xprintf(" (faster, less stable; default)\n"); + xprintf(" --cbg LU + Schur complement + Bartels-Gol" + "ub update\n"); + xprintf(" (slower, more stable)\n"); + xprintf(" --cgr LU + Schur complement + Givens rota" + "tion update\n"); + xprintf(" (slower, more stable)\n"); +#else + xprintf(" --luf plain LU-factorization (default)\n") + ; + xprintf(" --btf block triangular LU-factorization\n" + ); + xprintf(" --ft Forrest-Tomlin update (requires --l" + "uf; default)\n"); + xprintf(" --cbg Schur complement + Bartels-Golub up" + "date\n"); + xprintf(" --cgr Schur complement + Givens rotation " + "update\n"); +#endif + xprintf("\n"); + xprintf("Options specific to simplex solver:\n"); + xprintf(" --primal use primal simplex (default)\n"); + xprintf(" --dual use dual simplex\n"); + xprintf(" --std use standard initial basis of all s" + "lacks\n"); + xprintf(" --adv use advanced initial basis (default" + ")\n"); + xprintf(" --bib use Bixby's initial basis\n"); + xprintf(" --ini filename use as initial basis previously sav" + "ed with -w\n"); + xprintf(" (disables LP presolver)\n"); + xprintf(" --steep use steepest edge technique (defaul" + "t)\n"); + xprintf(" --nosteep use standard \"textbook\" pricing\n" + ); + xprintf(" --relax use Harris' two-pass ratio test (de" + "fault)\n"); + xprintf(" --norelax use standard \"textbook\" ratio tes" + "t\n"); +#if 0 /* 23/VI-2017 */ +#if 1 /* 28/III-2016 */ + xprintf(" --flip use flip-flop ratio test (assumes -" + "-dual)\n"); +#endif +#else + /* now this option is implemented in both primal and dual */ + xprintf(" --flip use long-step ratio test\n"); +#endif + xprintf(" --presol use presolver (default; assumes --s" + "cale and --adv)\n"); + xprintf(" --nopresol do not use presolver\n"); + xprintf(" --exact use simplex method based on exact a" + "rithmetic\n"); + xprintf(" --xcheck check final basis using exact arith" + "metic\n"); + xprintf("\n"); + xprintf("Options specific to interior-point solver:\n"); + xprintf(" --nord use natural (original) ordering\n"); + xprintf(" --qmd use quotient minimum degree orderin" + "g\n"); + xprintf(" --amd use approximate minimum degree orde" + "ring (default)\n"); + xprintf(" --symamd use approximate minimum degree orde" + "ring\n"); + xprintf("\n"); + xprintf("Options specific to MIP solver:\n"); + xprintf(" --nomip consider all integer variables as c" + "ontinuous\n"); + xprintf(" (allows solving MIP as pure LP)\n"); + xprintf(" --first branch on first integer variable\n") + ; + xprintf(" --last branch on last integer variable\n"); + xprintf(" --mostf branch on most fractional variable " + "\n"); + xprintf(" --drtom branch using heuristic by Driebeck " + "and Tomlin\n"); + xprintf(" (default)\n"); + xprintf(" --pcost branch using hybrid pseudocost heur" + "istic (may be\n"); + xprintf(" useful for hard instances)\n"); + xprintf(" --dfs backtrack using depth first search " + "\n"); + xprintf(" --bfs backtrack using breadth first searc" + "h\n"); + xprintf(" --bestp backtrack using the best projection" + " heuristic\n"); + xprintf(" --bestb backtrack using node with best loca" + "l bound\n"); + xprintf(" (default)\n"); + xprintf(" --intopt use MIP presolver (default)\n"); + xprintf(" --nointopt do not use MIP presolver\n"); + xprintf(" --binarize replace general integer variables b" + "y binary ones\n"); + xprintf(" (assumes --intopt)\n"); + xprintf(" --fpump apply feasibility pump heuristic\n") + ; +#if 1 /* 29/VI-2013 */ + xprintf(" --proxy [nnn] apply proximity search heuristic (n" + "nn is time limit\n"); + xprintf(" in seconds; default is 60)\n"); +#endif + xprintf(" --gomory generate Gomory's mixed integer cut" + "s\n"); + xprintf(" --mir generate MIR (mixed integer roundin" + "g) cuts\n"); + xprintf(" --cover generate mixed cover cuts\n"); + xprintf(" --clique generate clique cuts\n"); + xprintf(" --cuts generate all cuts above\n"); + xprintf(" --mipgap tol set relative mip gap tolerance to t" + "ol\n"); +#if 1 /* 15/VIII-2011 */ + xprintf(" --minisat translate integer feasibility probl" + "em to CNF-SAT\n"); + xprintf(" and solve it with MiniSat solver\n") + ; + xprintf(" --objbnd bound add inequality obj <= bound (minimi" + "zation) or\n"); + xprintf(" obj >= bound (maximization) to inte" + "ger feasibility\n"); + xprintf(" problem (assumes --minisat)\n"); +#endif + xprintf("\n"); + xprintf("For description of the MPS and CPLEX LP formats see Refe" + "rence Manual.\n"); + xprintf("For description of the modeling language see \"GLPK: Mod" + "eling Language\n"); + xprintf("GNU MathProg\". Both documents are included in the GLPK " + "distribution.\n"); + xprintf("\n"); + xprintf("See GLPK web page at <http://www.gnu.org/software/glpk/g" + "lpk.html>.\n"); + xprintf("\n"); + xprintf("Please report bugs to <bug-glpk@gnu.org>.\n"); + return; +} + +static void print_version(int briefly) +{ /* print version information */ + xprintf("GLPSOL--GLPK LP/MIP Solver %s\n", glp_version()); + if (briefly) goto done; + xprintf("Copyright (C) 2000-2020 Free Software Foundation, Inc.\n" + ); + xprintf("\n"); + xprintf("This program has ABSOLUTELY NO WARRANTY.\n"); + xprintf("\n"); + xprintf("This program is free software; you may re-distribute it " + "under the terms\n"); + xprintf("of the GNU General Public License version 3 or later.\n") + ; +done: return; +} + +static int parse_cmdline(struct csa *csa, int argc, char *argv[]) +{ /* parse command-line parameters */ + int k; +#define p(str) (strcmp(argv[k], str) == 0) + for (k = 1; k < argc; k++) + { if (p("--mps")) + csa->format = FMT_MPS_DECK; + else if (p("--freemps")) + csa->format = FMT_MPS_FILE; + else if (p("--lp") || p("--cpxlp")) + csa->format = FMT_LP; + else if (p("--glp")) + csa->format = FMT_GLP; + else if (p("--math") || p("-m") || p("--model")) + csa->format = FMT_MATHPROG; + else if (p("-d") || p("--data")) + { k++; + if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') + { xprintf("No input data file specified\n"); + return 1; + } + if (csa->ndf == DATA_MAX) + { xprintf("Too many input data files\n"); + return 1; + } + csa->in_data[++(csa->ndf)] = argv[k]; + } + else if (p("-y") || p("--display")) + { k++; + if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') + { xprintf("No display output file specified\n"); + return 1; + } + if (csa->out_dpy != NULL) + { xprintf("Only one display output file allowed\n"); + return 1; + } + csa->out_dpy = argv[k]; + } + else if (p("--seed")) + { k++; + if (k == argc || argv[k][0] == '\0' || + argv[k][0] == '-' && !isdigit((unsigned char)argv[k][1])) + { xprintf("No seed value specified\n"); + return 1; + } + if (strcmp(argv[k], "?") == 0) + csa->seed = 0x80000000; + else if (str2int(argv[k], &csa->seed)) + { xprintf("Invalid seed value '%s'\n", argv[k]); + return 1; + } + } + else if (p("--mincost")) + csa->format = FMT_MIN_COST; + else if (p("--maxflow")) + csa->format = FMT_MAX_FLOW; +#if 1 /* 06/VIII-2011 */ + else if (p("--cnf")) + csa->format = FMT_CNF; +#endif + else if (p("--simplex")) + csa->solution = SOL_BASIC; + else if (p("--interior")) + csa->solution = SOL_INTERIOR; +#if 1 /* 28/V-2010 */ + else if (p("--alien")) + csa->iocp.alien = GLP_ON; +#endif + else if (p("-r") || p("--read")) + { k++; + if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') + { xprintf("No input solution file specified\n"); + return 1; + } + if (csa->in_res != NULL) + { xprintf("Only one input solution file allowed\n"); + return 1; + } + csa->in_res = argv[k]; + } + else if (p("--min")) + csa->dir = GLP_MIN; + else if (p("--max")) + csa->dir = GLP_MAX; + else if (p("--scale")) + csa->scale = 1; + else if (p("--noscale")) + csa->scale = 0; + else if (p("-o") || p("--output")) + { k++; + if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') + { xprintf("No output solution file specified\n"); + return 1; + } + if (csa->out_sol != NULL) + { xprintf("Only one output solution file allowed\n"); + return 1; + } + csa->out_sol = argv[k]; + } + else if (p("-w") || p("--write")) + { k++; + if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') + { xprintf("No output solution file specified\n"); + return 1; + } + if (csa->out_res != NULL) + { xprintf("Only one output solution file allowed\n"); + return 1; + } + csa->out_res = argv[k]; + } + else if (p("--ranges") || p("--bounds")) + { k++; + if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') + { xprintf("No output file specified to write sensitivity a" + "nalysis report\n"); + return 1; + } + if (csa->out_ranges != NULL) + { xprintf("Only one output file allowed to write sensitivi" + "ty analysis report\n"); + return 1; + } + csa->out_ranges = argv[k]; + } + else if (p("--tmlim")) + { int tm_lim; + k++; + if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') + { xprintf("No time limit specified\n"); + return 1; + } + if (str2int(argv[k], &tm_lim) || tm_lim < 0) + { xprintf("Invalid time limit '%s'\n", argv[k]); + return 1; + } + if (tm_lim <= INT_MAX / 1000) + csa->smcp.tm_lim = csa->iocp.tm_lim = 1000 * tm_lim; + else + csa->smcp.tm_lim = csa->iocp.tm_lim = INT_MAX; + } + else if (p("--memlim")) + { int mem_lim; + k++; + if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') + { xprintf("No memory limit specified\n"); + return 1; + } + if (str2int(argv[k], &mem_lim) || mem_lim < 1) + { xprintf("Invalid memory limit '%s'\n", argv[k]); + return 1; + } + glp_mem_limit(mem_lim); + } + else if (p("--check")) + csa->check = 1; + else if (p("--name")) + { k++; + if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') + { xprintf("No problem name specified\n"); + return 1; + } + if (csa->new_name != NULL) + { xprintf("Only one problem name allowed\n"); + return 1; + } + csa->new_name = argv[k]; + } +#if 1 /* 18/I-2018 */ + else if (p("--hide")) + csa->hide = 1; +#endif + else if (p("--wmps")) + { k++; + if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') + { xprintf("No fixed MPS output file specified\n"); + return 1; + } + if (csa->out_mps != NULL) + { xprintf("Only one fixed MPS output file allowed\n"); + return 1; + } + csa->out_mps = argv[k]; + } + else if (p("--wfreemps")) + { k++; + if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') + { xprintf("No free MPS output file specified\n"); + return 1; + } + if (csa->out_freemps != NULL) + { xprintf("Only one free MPS output file allowed\n"); + return 1; + } + csa->out_freemps = argv[k]; + } + else if (p("--wlp") || p("--wcpxlp") || p("--wlpt")) + { k++; + if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') + { xprintf("No CPLEX LP output file specified\n"); + return 1; + } + if (csa->out_cpxlp != NULL) + { xprintf("Only one CPLEX LP output file allowed\n"); + return 1; + } + csa->out_cpxlp = argv[k]; + } + else if (p("--wglp")) + { k++; + if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') + { xprintf("No GLPK LP/MIP output file specified\n"); + return 1; + } + if (csa->out_glp != NULL) + { xprintf("Only one GLPK LP/MIP output file allowed\n"); + return 1; + } + csa->out_glp = argv[k]; + } +#if 0 + else if (p("--wpb")) + { k++; + if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') + { xprintf("No problem output file specified\n"); + return 1; + } + if (csa->out_pb != NULL) + { xprintf("Only one OPB output file allowed\n"); + return 1; + } + csa->out_pb = argv[k]; + } + else if (p("--wnpb")) + { k++; + if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') + { xprintf("No problem output file specified\n"); + return 1; + } + if (csa->out_npb != NULL) + { xprintf("Only one normalized OPB output file allowed\n"); + return 1; + } + csa->out_npb = argv[k]; + } +#endif +#if 1 /* 06/VIII-2011 */ + else if (p("--wcnf")) + { k++; + if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') + { xprintf("No problem output file specified\n"); + return 1; + } + if (csa->out_cnf != NULL) + { xprintf("Only one output DIMACS CNF-SAT file allowed\n"); + return 1; + } + csa->out_cnf = argv[k]; + } +#endif + else if (p("--log")) + { k++; + if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') + { xprintf("No log file specified\n"); + return 1; + } + if (csa->log_file != NULL) + { xprintf("Only one log file allowed\n"); + return 1; + } + csa->log_file = argv[k]; + } + else if (p("-h") || p("--help")) + { print_help(argv[0]); + return -1; + } + else if (p("-v") || p("--version")) + { print_version(0); + return -1; + } +#if 0 /* 08/III-2014 */ + else if (p("--luf")) + csa->bfcp.type = GLP_BF_FT; + else if (p("--cbg")) + csa->bfcp.type = GLP_BF_BG; + else if (p("--cgr")) + csa->bfcp.type = GLP_BF_GR; +#else + else if (p("--luf")) + { csa->bfcp.type &= 0x0F; + csa->bfcp.type |= GLP_BF_LUF; + } + else if (p("--btf")) + { csa->bfcp.type &= 0x0F; + csa->bfcp.type |= GLP_BF_BTF; + } + else if (p("--ft")) + { csa->bfcp.type &= 0xF0; + csa->bfcp.type |= GLP_BF_FT; + } + else if (p("--cbg")) + { csa->bfcp.type &= 0xF0; + csa->bfcp.type |= GLP_BF_BG; + } + else if (p("--cgr")) + { csa->bfcp.type &= 0xF0; + csa->bfcp.type |= GLP_BF_GR; + } +#endif + else if (p("--primal")) + csa->smcp.meth = GLP_PRIMAL; + else if (p("--dual")) + csa->smcp.meth = GLP_DUAL; + else if (p("--std")) + csa->crash = USE_STD_BASIS; + else if (p("--adv")) + csa->crash = USE_ADV_BASIS; + else if (p("--bib")) + csa->crash = USE_CPX_BASIS; + else if (p("--ini")) + { csa->crash = USE_INI_BASIS; + csa->smcp.presolve = GLP_OFF; + k++; + if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') + { xprintf("No initial basis file specified\n"); + return 1; + } + if (csa->ini_file != NULL) + { xprintf("Only one initial basis file allowed\n"); + return 1; + } + csa->ini_file = argv[k]; + } + else if (p("--steep")) + csa->smcp.pricing = GLP_PT_PSE; + else if (p("--nosteep")) + csa->smcp.pricing = GLP_PT_STD; + else if (p("--relax")) + csa->smcp.r_test = GLP_RT_HAR; + else if (p("--norelax")) + csa->smcp.r_test = GLP_RT_STD; +#if 1 /* 28/III-2016 */ + else if (p("--flip")) +#if 0 /* 23/VI-2017 */ + { csa->smcp.meth = GLP_DUAL; +#else + /* now this option is implemented in both primal and dual */ + { +#endif + csa->smcp.r_test = GLP_RT_FLIP; + csa->iocp.flip = GLP_ON; + } +#endif + else if (p("--presol")) + csa->smcp.presolve = GLP_ON; + else if (p("--nopresol")) + csa->smcp.presolve = GLP_OFF; + else if (p("--exact")) + csa->exact = 1; + else if (p("--xcheck")) + csa->xcheck = 1; + else if (p("--nord")) + csa->iptcp.ord_alg = GLP_ORD_NONE; + else if (p("--qmd")) + csa->iptcp.ord_alg = GLP_ORD_QMD; + else if (p("--amd")) + csa->iptcp.ord_alg = GLP_ORD_AMD; + else if (p("--symamd")) + csa->iptcp.ord_alg = GLP_ORD_SYMAMD; + else if (p("--nomip")) + csa->nomip = 1; + else if (p("--first")) + csa->iocp.br_tech = GLP_BR_FFV; + else if (p("--last")) + csa->iocp.br_tech = GLP_BR_LFV; + else if (p("--drtom")) + csa->iocp.br_tech = GLP_BR_DTH; + else if (p("--mostf")) + csa->iocp.br_tech = GLP_BR_MFV; + else if (p("--pcost")) + csa->iocp.br_tech = GLP_BR_PCH; + else if (p("--dfs")) + csa->iocp.bt_tech = GLP_BT_DFS; + else if (p("--bfs")) + csa->iocp.bt_tech = GLP_BT_BFS; + else if (p("--bestp")) + csa->iocp.bt_tech = GLP_BT_BPH; + else if (p("--bestb")) + csa->iocp.bt_tech = GLP_BT_BLB; + else if (p("--intopt")) + csa->iocp.presolve = GLP_ON; + else if (p("--nointopt")) + csa->iocp.presolve = GLP_OFF; + else if (p("--binarize")) + csa->iocp.presolve = csa->iocp.binarize = GLP_ON; + else if (p("--fpump")) + csa->iocp.fp_heur = GLP_ON; +#if 1 /* 29/VI-2013 */ + else if (p("--proxy")) + { csa->iocp.ps_heur = GLP_ON; + if (argv[k+1] && isdigit((unsigned char)argv[k+1][0])) + { int nnn; + k++; + if (str2int(argv[k], &nnn) || nnn < 1) + { xprintf("Invalid proxy time limit '%s'\n", argv[k]); + return 1; + } + csa->iocp.ps_tm_lim = 1000 * nnn; + } + } +#endif + else if (p("--gomory")) + csa->iocp.gmi_cuts = GLP_ON; + else if (p("--mir")) + csa->iocp.mir_cuts = GLP_ON; + else if (p("--cover")) + csa->iocp.cov_cuts = GLP_ON; + else if (p("--clique")) + csa->iocp.clq_cuts = GLP_ON; + else if (p("--cuts")) + csa->iocp.gmi_cuts = csa->iocp.mir_cuts = + csa->iocp.cov_cuts = csa->iocp.clq_cuts = GLP_ON; + else if (p("--mipgap")) + { double mip_gap; + k++; + if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') + { xprintf("No relative gap tolerance specified\n"); + return 1; + } + if (str2num(argv[k], &mip_gap) || mip_gap < 0.0) + { xprintf("Invalid relative mip gap tolerance '%s'\n", + argv[k]); + return 1; + } + csa->iocp.mip_gap = mip_gap; + } +#if 1 /* 15/VIII-2011 */ + else if (p("--minisat")) + csa->minisat = 1; + else if (p("--objbnd")) + { k++; + if (k == argc || argv[k][0] == '\0' || + argv[k][0] == '-' && !isdigit((unsigned char)argv[k][1])) + { xprintf("No objective bound specified\n"); + return 1; + } + csa->minisat = 1; + csa->use_bnd = 1; + if (str2int(argv[k], &csa->obj_bnd)) + { xprintf("Invalid objective bound '%s' (should be integer" + " value)\n", argv[k]); + return 1; + } + } +#endif +#if 1 /* 11/VII-2013 */ + else if (p("--use")) + { k++; + if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') + { xprintf("No input MIP solution file specified\n"); + return 1; + } + if (csa->use_sol != NULL) + { xprintf("Only one input MIP solution file allowed\n"); + return 1; + } + csa->use_sol = argv[k]; + } + else if (p("--save")) + { k++; + if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') + { xprintf("No output MIP solution file specified\n"); + return 1; + } + if (csa->iocp.save_sol != NULL) + { xprintf("Only one output MIP solution file allowed\n"); + return 1; + } + csa->iocp.save_sol = argv[k]; + } +#endif + else if (argv[k][0] == '-' || + (argv[k][0] == '-' && argv[k][1] == '-')) + { xprintf("Invalid option '%s'; try %s --help\n", + argv[k], argv[0]); + return 1; + } + else + { if (csa->in_file != NULL) + { xprintf("Only one input problem file allowed\n"); + return 1; + } + csa->in_file = argv[k]; + } + } +#undef p + return 0; +} + +typedef struct { double rhs, pi; } v_data; +typedef struct { double low, cap, cost, x; } a_data; + +#ifndef __WOE__ +int main(int argc, char *argv[]) +#else +int __cdecl main(int argc, char *argv[]) +#endif +{ /* stand-alone LP/MIP solver */ + struct csa _csa, *csa = &_csa; + int ret; +#if 0 /* 10/VI-2013 */ + glp_long start; +#else + double start; +#endif + /* perform initialization */ + csa->prob = glp_create_prob(); + glp_get_bfcp(csa->prob, &csa->bfcp); + glp_init_smcp(&csa->smcp); + csa->smcp.presolve = GLP_ON; + glp_init_iptcp(&csa->iptcp); + glp_init_iocp(&csa->iocp); + csa->iocp.presolve = GLP_ON; + csa->tran = NULL; + csa->graph = NULL; + csa->format = FMT_MPS_FILE; + csa->in_file = NULL; + csa->ndf = 0; + csa->out_dpy = NULL; + csa->seed = 1; + csa->solution = SOL_BASIC; + csa->in_res = NULL; + csa->dir = 0; + csa->scale = 1; + csa->out_sol = NULL; + csa->out_res = NULL; + csa->out_ranges = NULL; + csa->check = 0; + csa->new_name = NULL; +#if 1 /* 18/I-2018 */ + csa->hide = 0; +#endif + csa->out_mps = NULL; + csa->out_freemps = NULL; + csa->out_cpxlp = NULL; + csa->out_glp = NULL; +#if 0 + csa->out_pb = NULL; + csa->out_npb = NULL; +#endif +#if 1 /* 06/VIII-2011 */ + csa->out_cnf = NULL; +#endif + csa->log_file = NULL; + csa->crash = USE_ADV_BASIS; + csa->ini_file = NULL; + csa->exact = 0; + csa->xcheck = 0; + csa->nomip = 0; +#if 1 /* 15/VIII-2011 */ + csa->minisat = 0; + csa->use_bnd = 0; + csa->obj_bnd = 0; +#endif +#if 1 /* 11/VII-2013 */ + csa->use_sol = NULL; +#endif + /* parse command-line parameters */ + ret = parse_cmdline(csa, argc, argv); + if (ret < 0) + { ret = EXIT_SUCCESS; + goto done; + } + if (ret > 0) + { ret = EXIT_FAILURE; + goto done; + } + /*--------------------------------------------------------------*/ + /* remove all output files specified in the command line */ + if (csa->out_dpy != NULL) remove(csa->out_dpy); + if (csa->out_sol != NULL) remove(csa->out_sol); + if (csa->out_res != NULL) remove(csa->out_res); + if (csa->out_ranges != NULL) remove(csa->out_ranges); + if (csa->out_mps != NULL) remove(csa->out_mps); + if (csa->out_freemps != NULL) remove(csa->out_freemps); + if (csa->out_cpxlp != NULL) remove(csa->out_cpxlp); + if (csa->out_glp != NULL) remove(csa->out_glp); +#if 0 + if (csa->out_pb != NULL) remove(csa->out_pb); + if (csa->out_npb != NULL) remove(csa->out_npb); +#endif +#if 1 /* 06/VIII-2011 */ + if (csa->out_cnf != NULL) remove(csa->out_cnf); +#endif + if (csa->log_file != NULL) remove(csa->log_file); + /*--------------------------------------------------------------*/ + /* open log file, if required */ + if (csa->log_file != NULL) + { if (glp_open_tee(csa->log_file)) + { xprintf("Unable to create log file\n"); + ret = EXIT_FAILURE; + goto done; + } + } + /*--------------------------------------------------------------*/ + /* print version information */ + print_version(1); + /*--------------------------------------------------------------*/ + /* print parameters specified in the command line */ + if (argc > 1) + { int k, len = INT_MAX; + xprintf("Parameter(s) specified in the command line:"); + for (k = 1; k < argc; k++) + { if (len > 72) + xprintf("\n"), len = 0; + xprintf(" %s", argv[k]); + len += 1 + strlen(argv[k]); + } + xprintf("\n"); + } + /*--------------------------------------------------------------*/ + /* read problem data from the input file */ + if (csa->in_file == NULL) + { xprintf("No input problem file specified; try %s --help\n", + argv[0]); + ret = EXIT_FAILURE; + goto done; + } + if (csa->format == FMT_MPS_DECK) + { ret = glp_read_mps(csa->prob, GLP_MPS_DECK, NULL, + csa->in_file); + if (ret != 0) +err1: { xprintf("MPS file processing error\n"); + ret = EXIT_FAILURE; + goto done; + } + } + else if (csa->format == FMT_MPS_FILE) + { ret = glp_read_mps(csa->prob, GLP_MPS_FILE, NULL, + csa->in_file); + if (ret != 0) goto err1; + } + else if (csa->format == FMT_LP) + { ret = glp_read_lp(csa->prob, NULL, csa->in_file); + if (ret != 0) + { xprintf("CPLEX LP file processing error\n"); + ret = EXIT_FAILURE; + goto done; + } + } + else if (csa->format == FMT_GLP) + { ret = glp_read_prob(csa->prob, 0, csa->in_file); + if (ret != 0) + { xprintf("GLPK LP/MIP file processing error\n"); + ret = EXIT_FAILURE; + goto done; + } + } + else if (csa->format == FMT_MATHPROG) + { int k; + /* allocate the translator workspace */ + csa->tran = glp_mpl_alloc_wksp(); + /* set seed value */ + if (csa->seed == 0x80000000) +#if 0 /* 10/VI-2013 */ + { csa->seed = glp_time().lo; +#else + { csa->seed = (int)fmod(glp_time(), 1000000000.0); +#endif + xprintf("Seed value %d will be used\n", csa->seed); + } + glp_mpl_init_rand(csa->tran, csa->seed); + /* read model section and optional data section */ + if (glp_mpl_read_model(csa->tran, csa->in_file, csa->ndf > 0)) +err2: { xprintf("MathProg model processing error\n"); + ret = EXIT_FAILURE; + goto done; + } + /* read optional data section(s), if necessary */ + for (k = 1; k <= csa->ndf; k++) + { if (glp_mpl_read_data(csa->tran, csa->in_data[k])) + goto err2; + } + /* generate the model */ + if (glp_mpl_generate(csa->tran, csa->out_dpy)) goto err2; + /* build the problem instance from the model */ + glp_mpl_build_prob(csa->tran, csa->prob); + } + else if (csa->format == FMT_MIN_COST) + { csa->graph = glp_create_graph(sizeof(v_data), sizeof(a_data)); + ret = glp_read_mincost(csa->graph, offsetof(v_data, rhs), + offsetof(a_data, low), offsetof(a_data, cap), + offsetof(a_data, cost), csa->in_file); + if (ret != 0) + { xprintf("DIMACS file processing error\n"); + ret = EXIT_FAILURE; + goto done; + } + glp_mincost_lp(csa->prob, csa->graph, GLP_ON, + offsetof(v_data, rhs), offsetof(a_data, low), + offsetof(a_data, cap), offsetof(a_data, cost)); + glp_set_prob_name(csa->prob, csa->in_file); + } + else if (csa->format == FMT_MAX_FLOW) + { int s, t; + csa->graph = glp_create_graph(sizeof(v_data), sizeof(a_data)); + ret = glp_read_maxflow(csa->graph, &s, &t, + offsetof(a_data, cap), csa->in_file); + if (ret != 0) + { xprintf("DIMACS file processing error\n"); + ret = EXIT_FAILURE; + goto done; + } + glp_maxflow_lp(csa->prob, csa->graph, GLP_ON, s, t, + offsetof(a_data, cap)); + glp_set_prob_name(csa->prob, csa->in_file); + } +#if 1 /* 06/VIII-2011 */ + else if (csa->format == FMT_CNF) + { ret = glp_read_cnfsat(csa->prob, csa->in_file); + if (ret != 0) + { xprintf("DIMACS file processing error\n"); + ret = EXIT_FAILURE; + goto done; + } + glp_set_prob_name(csa->prob, csa->in_file); + } +#endif + else + xassert(csa != csa); + /*--------------------------------------------------------------*/ + /* change problem name, if required */ + if (csa->new_name != NULL) + glp_set_prob_name(csa->prob, csa->new_name); + /* change optimization direction, if required */ + if (csa->dir != 0) + glp_set_obj_dir(csa->prob, csa->dir); + /* sort elements of the constraint matrix */ + glp_sort_matrix(csa->prob); +#if 1 /* 18/I-2018 */ + /*--------------------------------------------------------------*/ + /* remove all symbolic names from problem object, if required */ + if (csa->hide) + { int i, j; + glp_set_obj_name(csa->prob, NULL); + glp_delete_index(csa->prob); + for (i = glp_get_num_rows(csa->prob); i >= 1; i--) + glp_set_row_name(csa->prob, i, NULL); + for (j = glp_get_num_cols(csa->prob); j >= 1; j--) + glp_set_col_name(csa->prob, j, NULL); + } +#endif + /*--------------------------------------------------------------*/ + /* write problem data in fixed MPS format, if required */ + if (csa->out_mps != NULL) + { ret = glp_write_mps(csa->prob, GLP_MPS_DECK, NULL, + csa->out_mps); + if (ret != 0) + { xprintf("Unable to write problem in fixed MPS format\n"); + ret = EXIT_FAILURE; + goto done; + } + } + /* write problem data in free MPS format, if required */ + if (csa->out_freemps != NULL) + { ret = glp_write_mps(csa->prob, GLP_MPS_FILE, NULL, + csa->out_freemps); + if (ret != 0) + { xprintf("Unable to write problem in free MPS format\n"); + ret = EXIT_FAILURE; + goto done; + } + } + /* write problem data in CPLEX LP format, if required */ + if (csa->out_cpxlp != NULL) + { ret = glp_write_lp(csa->prob, NULL, csa->out_cpxlp); + if (ret != 0) + { xprintf("Unable to write problem in CPLEX LP format\n"); + ret = EXIT_FAILURE; + goto done; + } + } + /* write problem data in GLPK format, if required */ + if (csa->out_glp != NULL) + { ret = glp_write_prob(csa->prob, 0, csa->out_glp); + if (ret != 0) + { xprintf("Unable to write problem in GLPK format\n"); + ret = EXIT_FAILURE; + goto done; + } + } +#if 0 + /* write problem data in OPB format, if required */ + if (csa->out_pb != NULL) + { ret = lpx_write_pb(csa->prob, csa->out_pb, 0, 0); + if (ret != 0) + { xprintf("Unable to write problem in OPB format\n"); + ret = EXIT_FAILURE; + goto done; + } + } + /* write problem data in normalized OPB format, if required */ + if (csa->out_npb != NULL) + { ret = lpx_write_pb(csa->prob, csa->out_npb, 1, 1); + if (ret != 0) + { xprintf( + "Unable to write problem in normalized OPB format\n"); + ret = EXIT_FAILURE; + goto done; + } + } +#endif +#if 1 /* 06/VIII-2011 */ + /* write problem data in DIMACS CNF-SAT format, if required */ + if (csa->out_cnf != NULL) + { ret = glp_write_cnfsat(csa->prob, csa->out_cnf); + if (ret != 0) + { xprintf( + "Unable to write problem in DIMACS CNF-SAT format\n"); + ret = EXIT_FAILURE; + goto done; + } + } +#endif + /*--------------------------------------------------------------*/ + /* if only problem data check is required, skip computations */ + if (csa->check) + { +#if 1 /* 29/III-2016 */ + /* report problem characteristics */ + int j, cnt = 0; + xprintf("--- Problem Characteristics ---\n"); + xprintf("Number of rows = %8d\n", + glp_get_num_rows(csa->prob)); + xprintf("Number of columns = %8d\n", + glp_get_num_cols(csa->prob)); + xprintf("Number of non-zeros (matrix) = %8d\n", + glp_get_num_nz(csa->prob)); + for (j = glp_get_num_cols(csa->prob); j >= 1; j--) + { if (glp_get_obj_coef(csa->prob, j) != 0.0) + cnt++; + } + xprintf("Number of non-zeros (objrow) = %8d\n", + cnt); +#endif + ret = EXIT_SUCCESS; + goto done; + } + /*--------------------------------------------------------------*/ + /* determine the solution type */ + if (!csa->nomip && + glp_get_num_int(csa->prob) + glp_get_num_bin(csa->prob) > 0) + { if (csa->solution == SOL_INTERIOR) + { xprintf("Interior-point method is not able to solve MIP pro" + "blem; use --simplex\n"); + ret = EXIT_FAILURE; + goto done; + } + csa->solution = SOL_INTEGER; + } + /*--------------------------------------------------------------*/ + /* if solution is provided, read it and skip computations */ + if (csa->in_res != NULL) + { if (csa->solution == SOL_BASIC) + ret = glp_read_sol(csa->prob, csa->in_res); + else if (csa->solution == SOL_INTERIOR) + ret = glp_read_ipt(csa->prob, csa->in_res); + else if (csa->solution == SOL_INTEGER) + ret = glp_read_mip(csa->prob, csa->in_res); + else + xassert(csa != csa); + if (ret != 0) + { xprintf("Unable to read problem solution\n"); + ret = EXIT_FAILURE; + goto done; + } + goto skip; + } +#if 1 /* 11/VII-2013 */ + /*--------------------------------------------------------------*/ + /* if initial MIP solution is provided, read it */ + if (csa->solution == SOL_INTEGER && csa->use_sol != NULL) + { ret = glp_read_mip(csa->prob, csa->use_sol); + if (ret != 0) + { xprintf("Unable to read initial MIP solution\n"); + ret = EXIT_FAILURE; + goto done; + } + csa->iocp.use_sol = GLP_ON; + } +#endif + /*--------------------------------------------------------------*/ + /* scale the problem data, if required */ + if (csa->scale) + { if (csa->solution == SOL_BASIC && !csa->smcp.presolve || + csa->solution == SOL_INTERIOR || + csa->solution == SOL_INTEGER && !csa->iocp.presolve) + glp_scale_prob(csa->prob, GLP_SF_AUTO); + } + /*--------------------------------------------------------------*/ + /* construct starting LP basis */ + if (csa->solution == SOL_BASIC && !csa->smcp.presolve || + csa->solution == SOL_INTEGER && !csa->iocp.presolve) + { if (csa->crash == USE_STD_BASIS) + glp_std_basis(csa->prob); + else if (csa->crash == USE_ADV_BASIS) + glp_adv_basis(csa->prob, 0); + else if (csa->crash == USE_CPX_BASIS) + glp_cpx_basis(csa->prob); + else if (csa->crash == USE_INI_BASIS) + { ret = glp_read_sol(csa->prob, csa->ini_file); + if (ret != 0) + { xprintf("Unable to read initial basis\n"); + ret = EXIT_FAILURE; + goto done; + } + } + else + xassert(csa != csa); + } + /*--------------------------------------------------------------*/ + /* solve the problem */ + start = glp_time(); + if (csa->solution == SOL_BASIC) + { if (!csa->exact) + { glp_set_bfcp(csa->prob, &csa->bfcp); + glp_simplex(csa->prob, &csa->smcp); + if (csa->xcheck) + { if (csa->smcp.presolve && + glp_get_status(csa->prob) != GLP_OPT) + xprintf("If you need to check final basis for non-opt" + "imal solution, use --nopresol\n"); + else + glp_exact(csa->prob, &csa->smcp); + } + if (csa->out_sol != NULL || csa->out_res != NULL) + { if (csa->smcp.presolve && + glp_get_status(csa->prob) != GLP_OPT) + xprintf("If you need actual output for non-optimal solut" + "ion, use --nopresol\n"); + } + } + else + glp_exact(csa->prob, &csa->smcp); + } + else if (csa->solution == SOL_INTERIOR) + glp_interior(csa->prob, &csa->iptcp); +#if 1 /* 15/VIII-2011 */ + else if (csa->solution == SOL_INTEGER && csa->minisat) + { if (glp_check_cnfsat(csa->prob) == 0) + glp_minisat1(csa->prob); + else + glp_intfeas1(csa->prob, csa->use_bnd, csa->obj_bnd); + } +#endif + else if (csa->solution == SOL_INTEGER) + { glp_set_bfcp(csa->prob, &csa->bfcp); + if (!csa->iocp.presolve) + glp_simplex(csa->prob, &csa->smcp); +#if 0 + csa->iocp.msg_lev = GLP_MSG_DBG; + csa->iocp.pp_tech = GLP_PP_NONE; +#endif +#ifdef GLP_CB_FUNC /* 05/IV-2016 */ + { extern void GLP_CB_FUNC(glp_tree *, void *); + csa->iocp.cb_func = GLP_CB_FUNC; + csa->iocp.cb_info = NULL; + } +#endif + glp_intopt(csa->prob, &csa->iocp); + } + else + xassert(csa != csa); + /*--------------------------------------------------------------*/ + /* display statistics */ + xprintf("Time used: %.1f secs\n", glp_difftime(glp_time(), + start)); +#if 0 /* 16/II-2012 */ + { glp_long tpeak; + char buf[50]; + glp_mem_usage(NULL, NULL, NULL, &tpeak); + xprintf("Memory used: %.1f Mb (%s bytes)\n", + xltod(tpeak) / 1048576.0, xltoa(tpeak, buf)); + } +#else + { size_t tpeak; + glp_mem_usage(NULL, NULL, NULL, &tpeak); + xprintf("Memory used: %.1f Mb (%.0f bytes)\n", + (double)tpeak / 1048576.0, (double)tpeak); + } +#endif + /*--------------------------------------------------------------*/ +skip: /* postsolve the model, if necessary */ + if (csa->tran != NULL) + { if (csa->solution == SOL_BASIC) + { if (!(glp_get_status(csa->prob) == GLP_OPT || + glp_get_status(csa->prob) == GLP_FEAS)) + ret = -1; + else + ret = glp_mpl_postsolve(csa->tran, csa->prob, GLP_SOL); + } + else if (csa->solution == SOL_INTERIOR) + { if (!(glp_ipt_status(csa->prob) == GLP_OPT || + glp_ipt_status(csa->prob) == GLP_FEAS)) + ret = -1; + else + ret = glp_mpl_postsolve(csa->tran, csa->prob, GLP_IPT); + } + else if (csa->solution == SOL_INTEGER) + { if (!(glp_mip_status(csa->prob) == GLP_OPT || + glp_mip_status(csa->prob) == GLP_FEAS)) + ret = -1; + else + ret = glp_mpl_postsolve(csa->tran, csa->prob, GLP_MIP); + } + else + xassert(csa != csa); + if (ret > 0) + { xprintf("Model postsolving error\n"); + ret = EXIT_FAILURE; + goto done; + } + } + /*--------------------------------------------------------------*/ + /* write problem solution in printable format, if required */ + if (csa->out_sol != NULL) + { if (csa->solution == SOL_BASIC) + ret = glp_print_sol(csa->prob, csa->out_sol); + else if (csa->solution == SOL_INTERIOR) + ret = glp_print_ipt(csa->prob, csa->out_sol); + else if (csa->solution == SOL_INTEGER) + ret = glp_print_mip(csa->prob, csa->out_sol); + else + xassert(csa != csa); + if (ret != 0) + { xprintf("Unable to write problem solution\n"); + ret = EXIT_FAILURE; + goto done; + } + } + /* write problem solution in printable format, if required */ + if (csa->out_res != NULL) + { if (csa->solution == SOL_BASIC) + ret = glp_write_sol(csa->prob, csa->out_res); + else if (csa->solution == SOL_INTERIOR) + ret = glp_write_ipt(csa->prob, csa->out_res); + else if (csa->solution == SOL_INTEGER) + ret = glp_write_mip(csa->prob, csa->out_res); + else + xassert(csa != csa); + if (ret != 0) + { xprintf("Unable to write problem solution\n"); + ret = EXIT_FAILURE; + goto done; + } + } + /* write sensitivity analysis report, if required */ + if (csa->out_ranges != NULL) + { if (csa->solution == SOL_BASIC) + { if (glp_get_status(csa->prob) == GLP_OPT) + { if (glp_bf_exists(csa->prob)) +ranges: { ret = glp_print_ranges(csa->prob, 0, NULL, 0, + csa->out_ranges); + if (ret != 0) + { xprintf("Unable to write sensitivity analysis repo" + "rt\n"); + ret = EXIT_FAILURE; + goto done; + } + } + else + { ret = glp_factorize(csa->prob); + if (ret == 0) goto ranges; + xprintf("Cannot produce sensitivity analysis report d" + "ue to error in basis factorization (glp_factorize" + " returned %d); try --nopresol\n", ret); + } + } + else + xprintf("Cannot produce sensitivity analysis report for " + "non-optimal basic solution\n"); + } + else + xprintf("Cannot produce sensitivity analysis report for int" + "erior-point or MIP solution\n"); + } + /*--------------------------------------------------------------*/ + /* all seems to be ok */ + ret = EXIT_SUCCESS; + /*--------------------------------------------------------------*/ +done: /* delete the LP/MIP problem object */ + if (csa->prob != NULL) + glp_delete_prob(csa->prob); + /* free the translator workspace, if necessary */ + if (csa->tran != NULL) + glp_mpl_free_wksp(csa->tran); + /* delete the network problem object, if necessary */ + if (csa->graph != NULL) + glp_delete_graph(csa->graph); +#if 0 /* 23/XI-2015 */ + xassert(gmp_pool_count() == 0); + gmp_free_mem(); +#endif + /* close log file, if necessary */ + if (csa->log_file != NULL) glp_close_tee(); + /* check that no memory blocks are still allocated */ +#if 0 /* 16/II-2012 */ + { int count; + glp_long total; + glp_mem_usage(&count, NULL, &total, NULL); + if (count != 0) + xerror("Error: %d memory block(s) were lost\n", count); + xassert(count == 0); + xassert(total.lo == 0 && total.hi == 0); + } +#else + { int count; + size_t total; + glp_mem_usage(&count, NULL, &total, NULL); + if (count != 0) + xerror("Error: %d memory block(s) were lost\n", count); + xassert(total == 0); + } +#endif + /* free the GLPK environment */ + glp_free_env(); + /* return to the control program */ + return ret; +} + +/* eof */ diff --git a/glpk-5.0/examples/graceful.mod b/glpk-5.0/examples/graceful.mod new file mode 100644 index 0000000..4042065 --- /dev/null +++ b/glpk-5.0/examples/graceful.mod @@ -0,0 +1,152 @@ +/* Graceful Tree Labeling Problem */ + +/* Author: Mike Appleby <mike@app.leby.org> */ + +/* The Graceful Labeling Problem for a tree G = (V, E), where V is the + set of vertices and E is the set of edges, is to find a labeling of + the vertices with the integers between 1 and |V| inclusive, such + that no two vertices share a label, and such that each edge is + uniquely identified by the positive, or absolute difference between + the labels of its endpoints. + + In other words, if vl are the vertex labels and el are the edge + labels, then for every edge (u,v) in E, el[u,v]=abs(vl[u] - vl[v]). + + https://en.wikipedia.org/wiki/Graceful_labeling */ + +set V; +/* set of vertices */ + +set E within V cross V; +/* set of edges */ + +set N := 1..card(V); +/* vertex labels */ + +set M := 1..card(V)-1; +/* edge labels */ + +var vx{V, N}, binary; +/* binary encoding of vertex labels. + vx[v,n] == 1 means vertex v has label n. */ + +s.t. vxa{v in V}: sum{n in N} vx[v,n] = 1; +/* each vertex is assigned exactly one label. */ + +s.t. vxb{n in N}: sum{v in V} vx[v,n] = 1; +/* each label is assigned to exactly one vertex. */ + +var vl{V}, integer, >= 1, <= card(V); +/* integer encoding of vertex labels. + vl[v] == n means vertex v has label n. */ + +s.t. vla{v in V}: vl[v] = sum{n in N} n * vx[v,n]; +/* by constraint vxa, exactly one of vx[v,n] == 1 and the rest are + zero. So if vx[v,3] == 1, then vl[v] = 3. */ + +var ex{E, M}, binary; +/* binary encoding of edge labels. + ex[u,v,n] == 1 means edge (u,v) has label n. */ + +s.t. exa{(u,v) in E}: sum{m in M} ex[u,v,m] = 1; +/* each edge is assigned exactly one label. */ + +s.t. exb{m in M}: sum{(u,v) in E} ex[u,v,m] = 1; +/* each label is assigned to exactly one edge. */ + +var el{E}, integer, >= 1, <= card(E); +/* integer encoding of edge labels. + el[u,v] == n means edge (u,v) has label n. */ + +s.t. ela{(u,v) in E}: el[u,v] = sum{m in M} m * ex[u,v,m]; +/* similar to vla above, define integer encoding of edge labels in + terms of the corresponding binary variable. */ + +var gt{E}, binary; +/* gt[u,v] = 1 if vl[u] > vl[v] else 0. + gt helps encode the absolute value constraint, below. */ + +s.t. elb{(u,v) in E}: el[u,v] >= vl[u] - vl[v]; +s.t. elc{(u,v) in E}: el[u,v] <= vl[u] - vl[v] + 2*card(V)*(1-gt[u,v]); +s.t. eld{(u,v) in E}: el[u,v] >= vl[v] - vl[u]; +s.t. ele{(u,v) in E}: el[u,v] <= vl[v] - vl[u] + 2*card(V)*gt[u,v]; + +/* These four constraints together model the absolute value constraint + of the graceful labeling problem: el[u,v] == abs(vl[u] - vl[v]). + However, since the absolute value is a non-linear function, we + transform it into a series of linear constraints, as above. + + To see that these four constraints model the absolute value + condition, consider the following cases: + + if vl[u] > vl[v] and gt[u,v] == 0 then + - ele is unsatisfiable, since the constraint ele amounts to + + el[u,v] <= vl[v] - vl[u] + 0 (since gt[u,v] == 0) + <= -1 (since vl[u] > vl[v]) + + but el[u,v] is declared with lower bound >= 1; hence, the + constraints cannot be satisfied if vl[u] > vl[v] and + gt[u,v] == 0. + + if vl[u] > vl[v] and gt[u,v] == 1 then + - elb and elc together are equivalent to + + vl[u] - vl[v] <= el[u,v] <= vl[u] - vl[v], i.e. + el[u,v] = vl[u] - vl[v] + = abs(vl[u] - vl[v]) (since vl[u] > vl[v]) + + - eld and elc together are equivalent to + + vl[v] - vl[u] <= el[u,v] <= vl[v] - vl[u] + 2|V| + + the tightest possible bounds are + + -1 <= el[u,v] <= |V|+1 + + which is satisfied since both bounds are looser than the + constraints on el's variable declaration, namely + + var el{E}, integer, >= 1, <= card(E); + + where |E| = |V|-1 + + The cases for vl[v] > vl[u] are similar, but with roles reversed + for elb/elc and eld/ele. + + In other words, when vl[u] > vl[v], then gt[u,v] == 1, elb and elc + together model the absolute value constraint, and ele and eld are + satisfied due to bounds constraints on el. When vl[v] > vl[u], then + gt[u,v] == 0, ele and eld model the absolute value constraint, and + elb and elc are satisfied due to bounds constraints on el. + + Note that vl[u] != vl[v], by a combination of constraints vxa, vxb, + and vla. */ + +solve; + +check 0 = card(N symdiff setof{v in V} vl[v]); +/* every vertex label is assigned to one vertex */ + +check 0 = card(M symdiff setof{(u,v) in E} el[u,v]); +/* every edge label is assigned to one edge */ + +check {(u,v) in E} el[u,v] = abs(vl[u] - vl[v]); +/* every edge label for every edge (u,v) == abs(vl[u] - vl[v]) */ + +printf "vertices:\n"; +for{v in V} { printf "\t%s: %d\n", v, vl[v]; } + +printf "edges:\n"; +printf "\torig\tvlabel\telabel\tabs(u-v)\n"; +for{(u,v) in E} { + printf "\t(%s,%s)\t(%d,%d)\t%d\t%d\n", + u, v, vl[u], vl[v], el[u,v], abs(vl[u]-vl[v]); +} + +data; + +set V := a b c d e f g; +set E := a b, a d, a g, b c, b e, e f; + +end; diff --git a/glpk-5.0/examples/graph.mod b/glpk-5.0/examples/graph.mod new file mode 100644 index 0000000..bdcc969 --- /dev/null +++ b/glpk-5.0/examples/graph.mod @@ -0,0 +1,98 @@ +/* graph.mod - graph visualization */ + +/* Written in GNU MathProg by Andrew Makhorin <mao@gnu.org> */ + +/* This model creates a picture in EPS format to visualize a graph. */ + +param file, symbolic, default "graph.eps"; +/* output file to write the picture */ + +param R, default 2; +/* radius to draw vertices, in mm */ + +param n, integer, > 0; +/* number of vertices */ + +set V, default 1..n; +/* set of vertices */ + +set E, within V cross V; +/* set of edges */ + +param x{i in V}, default 50 * cos((i - 1) / card(V) * 8 * atan(1)); +param y{i in V}, default 50 * sin((i - 1) / card(V) * 8 * atan(1)); +/* x[i] and y[i] are coordinates of node i, in mm */ + +param x0 := (min{i in V} x[i]) - R - 3.0; +param y0 := (min{i in V} y[i]) - R - 3.0; +param x1 := (max{i in V} x[i]) + R + 3.0; +param y1 := (max{i in V} y[i]) + R + 3.0; + +printf "%%!PS-Adobe-3.0 EPSF-3.0\n" > file; +printf "%%%%BoundingBox: 0 0 %d %d\n", + (72 / 25.4) * (x1 - x0), (72 / 25.4) * (y1 - y0) >> file; +printf "/Helvetica findfont 6 scalefont setfont\n" >> file; +printf "/mm { 72 mul 25.4 div } def\n" >> file; + +for {(i,j) in E} +{ printf "newpath\n" >> file; + printf "%g mm %g mm moveto\n", x[i] - x0, y[i] - y0 >> file; + printf "%g mm %g mm lineto\n", x[j] - x0, y[j] - y0 >> file; + printf "closepath\n" >> file; + printf "stroke\n" >> file; +} + +for {i in V} +{ printf "newpath\n" >> file; + printf "%g mm %g mm %g mm 0 360 arc\n", + x[i] - x0, y[i] - y0, R >> file; + printf "closepath\n" >> file; + printf "gsave 1 1 1 setrgbcolor fill grestore\n" >> file; + printf "stroke\n" >> file; + printf "%g mm %g mm moveto\n", + x[i] - (if i <= 9 then 1.2 else 1.8) - x0, + y[i] - 0.8 - y0 >> file; + printf "( %d ) show\n", i >> file; +} + +printf "showpage\n" >> file; +printf "%%%%EOF\n" >> file; + +data; + +param +: V : x y := + 1 0 40 + 2 38 12 + 3 24 -32 + 4 -24 -32 + 5 -38 12 + 6 -19 26 + 7 19 26 + 8 31 -10 + 9 0 -32 + 10 -31 -10 + 11 -9 12 + 12 9 12 + 13 14 -5 + 14 0 -15 + 15 -14 -5 + 16 0 0 ; + +set E := + (1,*) 6 10 16 12 7 + (2,*) 7 6 16 13 8 + (3,*) 8 7 16 14 9 + (4,*) 9 8 16 15 10 + (5,*) 10 9 16 11 6 + (6,*) 14 + (7,*) 15 + (8,*) 11 + (9,*) 12 + (10,*) 13 + (11,*) 12 15 + (12,*) 13 + (13,*) 14 + (14,*) 15 ; + +end; diff --git a/glpk-5.0/examples/hashi.mod b/glpk-5.0/examples/hashi.mod new file mode 100644 index 0000000..48e8d9f --- /dev/null +++ b/glpk-5.0/examples/hashi.mod @@ -0,0 +1,168 @@ +/* A solver for the Japanese number-puzzle Hashiwokakero + * (http://en.wikipedia.org/wiki/Hashiwokakero) + * + * Sebastian Nowozin <nowozin@gmail.com>, 13th January 2009 + */ + +param n := 25; +set rows := 1..n; +set cols := 1..n; +param givens{rows, cols}, integer, >= 0, <= 8, default 0; + +/* Set of vertices as (row,col) coordinates */ +set V := { (i,j) in { rows, cols }: givens[i,j] != 0 }; + +/* Set of feasible horizontal edges from (i,j) to (k,l) rightwards */ +set Eh := { (i,j,k,l) in { V, V }: + i = k and j < l and # Same row and left to right + card({ (s,t) in V: s = i and t > j and t < l }) = 0 # No vertex inbetween + }; + +/* Set of feasible vertical edges from (i,j) to (k,l) downwards */ +set Ev := { (i,j,k,l) in { V, V }: + j = l and i < k and # Same column and top to bottom + card({ (s,t) in V: t = j and s > i and s < k }) = 0 # No vertex inbetween + }; + +set E := Eh union Ev; + +/* Indicators: use edge once/twice */ +var xe1{E}, binary; +var xe2{E}, binary; + +/* Constraint: Do not use edge or do use once or do use twice */ +s.t. edge_sel{(i,j,k,l) in E}: + xe1[i,j,k,l] + xe2[i,j,k,l] <= 1; + +/* Constraint: There must be as many edges used as the node value */ +s.t. satisfy_vertex_demand{(s,t) in V}: + sum{(i,j,k,l) in E: (i = s and j = t) or (k = s and l = t)} + (xe1[i,j,k,l] + 2.0*xe2[i,j,k,l]) = givens[s,t]; + +/* Constraint: No crossings */ +s.t. no_crossing1{(i,j,k,l) in Eh, (s,t,u,v) in Ev: + s < i and u > i and j < t and l > t}: + xe1[i,j,k,l] + xe1[s,t,u,v] <= 1; +s.t. no_crossing2{(i,j,k,l) in Eh, (s,t,u,v) in Ev: + s < i and u > i and j < t and l > t}: + xe1[i,j,k,l] + xe2[s,t,u,v] <= 1; +s.t. no_crossing3{(i,j,k,l) in Eh, (s,t,u,v) in Ev: + s < i and u > i and j < t and l > t}: + xe2[i,j,k,l] + xe1[s,t,u,v] <= 1; +s.t. no_crossing4{(i,j,k,l) in Eh, (s,t,u,v) in Ev: + s < i and u > i and j < t and l > t}: + xe2[i,j,k,l] + xe2[s,t,u,v] <= 1; + + +/* Model connectivity by auxiliary network flow problem: + * One vertex becomes a target node and all other vertices send a unit flow + * to it. The edge selection variables xe1/xe2 are VUB constraints and + * therefore xe1/xe2 select the feasible graph for the max-flow problems. + */ +set node_target := { (s,t) in V: + card({ (i,j) in V: i < s or (i = s and j < t) }) = 0}; +set node_sources := { (s,t) in V: (s,t) not in node_target }; + +var flow_forward{ E }, >= 0; +var flow_backward{ E }, >= 0; +s.t. flow_conservation{ (s,t) in node_target, (p,q) in V }: + /* All incoming flows */ + - sum{(i,j,k,l) in E: k = p and l = q} flow_forward[i,j,k,l] + - sum{(i,j,k,l) in E: i = p and j = q} flow_backward[i,j,k,l] + /* All outgoing flows */ + + sum{(i,j,k,l) in E: k = p and l = q} flow_backward[i,j,k,l] + + sum{(i,j,k,l) in E: i = p and j = q} flow_forward[i,j,k,l] + = 0 + (if (p = s and q = t) then card(node_sources) else -1); + +/* Variable-Upper-Bound (VUB) constraints: xe1/xe2 bound the flows. + */ +s.t. connectivity_vub1{(i,j,k,l) in E}: + flow_forward[i,j,k,l] <= card(node_sources)*(xe1[i,j,k,l] + xe2[i,j,k,l]); +s.t. connectivity_vub2{(i,j,k,l) in E}: + flow_backward[i,j,k,l] <= card(node_sources)*(xe1[i,j,k,l] + xe2[i,j,k,l]); + +/* A feasible solution is enough + */ +minimize cost: 0; + +solve; + +/* Output solution graphically */ +printf "\nSolution:\n"; +for { row in rows } { + for { col in cols } { + /* First print this cell information: givens or space */ + printf{0..0: givens[row,col] != 0} "%d", givens[row,col]; + printf{0..0: givens[row,col] = 0 and + card({(i,j,k,l) in Eh: i = row and col >= j and col < l and + xe1[i,j,k,l] = 1}) = 1} "-"; + printf{0..0: givens[row,col] = 0 and + card({(i,j,k,l) in Eh: i = row and col >= j and col < l and + xe2[i,j,k,l] = 1}) = 1} "="; + printf{0..0: givens[row,col] = 0 + and card({(i,j,k,l) in Ev: j = col and row >= i and row < k and + xe1[i,j,k,l] = 1}) = 1} "|"; + printf{0..0: givens[row,col] = 0 + and card({(i,j,k,l) in Ev: j = col and row >= i and row < k and + xe2[i,j,k,l] = 1}) = 1} '"'; + printf{0..0: givens[row,col] = 0 + and card({(i,j,k,l) in Eh: i = row and col >= j and col < l and + (xe1[i,j,k,l] = 1 or xe2[i,j,k,l] = 1)}) = 0 + and card({(i,j,k,l) in Ev: j = col and row >= i and row < k and + (xe1[i,j,k,l] = 1 or xe2[i,j,k,l] = 1)}) = 0} " "; + + /* Now print any edges */ + printf{(i,j,k,l) in Eh: i = row and col >= j and col < l and xe1[i,j,k,l] = 1} "-"; + printf{(i,j,k,l) in Eh: i = row and col >= j and col < l and xe2[i,j,k,l] = 1} "="; + + printf{(i,j,k,l) in Eh: i = row and col >= j and col < l and + xe1[i,j,k,l] = 0 and xe2[i,j,k,l] = 0} " "; + printf{0..0: card({(i,j,k,l) in Eh: i = row and col >= j and col < l}) = 0} " "; + } + printf "\n"; + for { col in cols } { + printf{(i,j,k,l) in Ev: j = col and row >= i and row < k and xe1[i,j,k,l] = 1} "|"; + printf{(i,j,k,l) in Ev: j = col and row >= i and row < k and xe2[i,j,k,l] = 1} '"'; + printf{(i,j,k,l) in Ev: j = col and row >= i and row < k and + xe1[i,j,k,l] = 0 and xe2[i,j,k,l] = 0} " "; + /* No vertical edges: skip also a field */ + printf{0..0: card({(i,j,k,l) in Ev: j = col and row >= i and row < k}) = 0} " "; + printf " "; + } + printf "\n"; +} + +data; + +/* This is a difficult 25x25 Hashiwokakero. + */ +param givens : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 +25 := + 1 2 . 2 . 2 . . 2 . 2 . . 2 . . . . 2 . 2 . 2 . 2 . + 2 . 1 . . . . 2 . . . 4 . . 5 . 2 . . 1 . 2 . 2 . 1 + 3 2 . . 5 . 4 . . 3 . . . . . 1 . . 4 . 5 . 1 . 1 . + 4 . . . . . . . . . . . 1 . 3 . . 1 . . . . . . . . + 5 2 . . 6 . 6 . . 8 . 5 . 2 . . 3 . 5 . 7 . . 2 . . + 6 . 1 . . . . . . . . . 1 . . 2 . . . . . 1 . . . 3 + 7 2 . . . . 5 . . 6 . 4 . . 2 . . . 2 . 5 . 4 . 2 . + 8 . 2 . 2 . . . . . . . . . . . 3 . . 3 . . . 1 . 2 + 9 . . . . . . . . . . 4 . 2 . 2 . . 1 . . . 3 . 1 . + 10 2 . 3 . . 6 . . 2 . . . . . . . . . . 3 . . . . . + 11 . . . . 1 . . 2 . . 5 . . 1 . 4 . 3 . . . . 2 . 4 + 12 . . 2 . . 1 . . . . . . 5 . 4 . . . . 4 . 3 . . . + 13 2 . . . 3 . 1 . . . . . . . . 3 . . 5 . 5 . . 2 . + 14 . . . . . 2 . 5 . . 7 . 5 . 3 . 1 . . 1 . . 1 . 4 + 15 2 . 5 . 3 . . . . 1 . 2 . 1 . . . . 2 . 4 . . 2 . + 16 . . . . . 1 . . . . . . . . . . 2 . . 2 . 1 . . 3 + 17 2 . 6 . 6 . . 2 . . 2 . 2 . 5 . . . . . 2 . . . . + 18 . . . . . 1 . . . 3 . . . . . 1 . . 1 . . 4 . 3 . + 19 . . 4 . 5 . . 2 . . . 2 . . 6 . 6 . . 3 . . . . 3 + 20 2 . . . . . . . . . 2 . . 1 . . . . . . 1 . . 1 . + 21 . . 3 . . 3 . 5 . 5 . . 4 . 6 . 7 . . 4 . 6 . . 4 + 22 2 . . . 3 . 5 . 2 . 1 . . . . . . . . . . . . . . + 23 . . . . . . . . . 1 . . . . . . 3 . 2 . . 5 . . 5 + 24 2 . 3 . 3 . 5 . 4 . 3 . 3 . 4 . . 2 . 2 . . . 1 . + 25 . 1 . 2 . 2 . . . 2 . 2 . . . 2 . . . . 2 . 2 . 2 + ; + +end; diff --git a/glpk-5.0/examples/huge.mod b/glpk-5.0/examples/huge.mod new file mode 100644 index 0000000..a7d17e4 --- /dev/null +++ b/glpk-5.0/examples/huge.mod @@ -0,0 +1,25 @@ +/*Arithmetic Mean of a large number of Integers + - or - solve a very large constraint matrix + over 1 million rows and columns + Nigel_Galloway@operamail.com + March 18th., 2008. +*/ + +param e := 20; +/* set Sample := {-2**e..2**e-1}; */ +set Sample := {1..2**e-1}; + +var Mean; +var E{z in Sample}; + +/* sum of variances is zero */ +zumVariance: sum{z in Sample} E[z] = 0; + +/* Mean + variance[n] = Sample[n] */ +variances{z in Sample}: Mean + E[z] = z; + +solve; + +printf "The arithmetic mean of the integers from 1 to %d is %f\n", 2**e-1, Mean; + +end; diff --git a/glpk-5.0/examples/icecream.mps b/glpk-5.0/examples/icecream.mps new file mode 100644 index 0000000..5d74130 --- /dev/null +++ b/glpk-5.0/examples/icecream.mps @@ -0,0 +1,345 @@ +*NAME: ICECREAM +*ROWS: 17 +*COLUMNS: 27 +*NONZERO: 264 +*OPT SOLN: 962.8214691 +*SOURCE: Linear Programming--Ice Cream Blending +* Data Processing Application. N.Y.: IBM Corp. +*APPLICATION: Ice Cream Blending +*COMMENTS: fixed MPS format +* encoded by Andrew Makhorin <mao@gnu.org> +* +NAME ICECREAM +ROWS + N COST $ Minimum cost $ + G MIN.BF $ Butterfat lbs + L MAX.BF + G MIN.MSNF $ Milk solids (nonfat) lbs + L MAX.MSNF + G MIN.TMS $ Total milk solids lbs + L MAX.TMS + G MIN.SUG $ Sweetness lbs + L MAX.SUG + L CSS $ Corn syrup solids lbs + G MIN.TS $ Total solids lbs + L MAX.TS + G MIN.H2O $ Water lbs + L MAX.H2O + E STAB $ Stabilizer lbs + E EMUL $ Emulsifier lbs + E YIELD $ Amount to be made lbs +COLUMNS +* Cream (40%) + I1 COST 27.9 + MIN.BF .40 + MAX.BF .40 + MIN.MSNF .054 + MAX.MSNF .054 + MIN.TMS .454 + MAX.TMS .454 + MIN.TS .454 + MAX.TS .454 + MIN.H2O .546 + MAX.H2O .546 + YIELD 1 +* Cream (38%) + I2 COST 26.3 + MIN.BF .38 + MAX.BF .38 + MIN.MSNF .056 + MAX.MSNF .056 + MIN.TMS .436 + MAX.TMS .436 + MIN.TS .436 + MAX.TS .436 + MIN.H2O .564 + MAX.H2O .564 + YIELD 1 +* Milk (3.2%) + I3 COST 3.2 + MIN.BF .032 + MAX.BF .032 + MIN.MSNF .087 + MAX.MSNF .087 + MIN.TMS .119 + MAX.TMS .119 + MIN.TS .119 + MAX.TS .119 + MIN.H2O .881 + MAX.H2O .881 + YIELD 1 +* Milk (3.4%) + I4 COST 3.2 + MIN.BF .034 + MAX.BF .034 + MIN.MSNF .087 + MAX.MSNF .087 + MIN.TMS .121 + MAX.TMS .121 + MIN.TS .121 + MAX.TS .121 + MIN.H2O .879 + MAX.H2O .879 + YIELD 1 +* Milk (3.5%) + I5 COST 3.3 + MIN.BF .035 + MAX.BF .035 + MIN.MSNF .087 + MAX.MSNF .087 + MIN.TMS .122 + MAX.TMS .122 + MIN.TS .122 + MAX.TS .122 + MIN.H2O .879 + MAX.H2O .879 + YIELD 1 +* Milk (3.6%) + I6 COST 3.3 + MIN.BF .036 + MAX.BF .036 + MIN.MSNF .087 + MAX.MSNF .087 + MIN.TMS .123 + MAX.TMS .123 + MIN.TS .123 + MAX.TS .123 + MIN.H2O .877 + MAX.H2O .877 + YIELD 1 +* Milk (3.7%) + I7 COST 3.4 + MIN.BF .037 + MAX.BF .037 + MIN.MSNF .087 + MAX.MSNF .087 + MIN.TMS .124 + MAX.TMS .124 + MIN.TS .124 + MAX.TS .124 + MIN.H2O .876 + MAX.H2O .876 + YIELD 1 +* Milk (3.8%) + I8 COST 3.5 + MIN.BF .038 + MAX.BF .038 + MIN.MSNF .087 + MAX.MSNF .087 + MIN.TMS .125 + MAX.TMS .125 + MIN.TS .125 + MAX.TS .125 + MIN.H2O .875 + MAX.H2O .875 + YIELD 1 +* Milk (3.9%) + I9 COST 3.5 + MIN.BF .039 + MAX.BF .039 + MIN.MSNF .086 + MAX.MSNF .086 + MIN.TMS .125 + MAX.TMS .125 + MIN.TS .125 + MAX.TS .125 + MIN.H2O .875 + MAX.H2O .875 + YIELD 1 +* Milk (4.0%) + I10 COST 3.6 + MIN.BF .040 + MAX.BF .040 + MIN.MSNF .086 + MAX.MSNF .086 + MIN.TMS .126 + MAX.TMS .126 + MIN.TS .126 + MAX.TS .126 + MIN.H2O .874 + MAX.H2O .874 + YIELD 1 +* Milk (4.2%) + I11 COST 3.7 + MIN.BF .042 + MAX.BF .042 + MIN.MSNF .086 + MAX.MSNF .086 + MIN.TMS .128 + MAX.TMS .128 + MIN.TS .128 + MAX.TS .128 + MIN.H2O .872 + MAX.H2O .872 + YIELD 1 +* Skim Milk + I12 COST 1.8 + MIN.MSNF .09 + MAX.MSNF .09 + MIN.TMS .09 + MAX.TMS .09 + MIN.TS .09 + MAX.TS .09 + MIN.H2O .91 + MAX.H2O .91 + YIELD 1 +* Condensed Whole Milk + I13 COST 7.6 + MIN.BF .08 + MAX.BF .08 + MIN.MSNF .2 + MAX.MSNF .2 + MIN.TMS .28 + MAX.TMS .28 + MIN.TS .28 + MAX.TS .28 + MIN.H2O .72 + MAX.H2O .72 + YIELD 1 +* Condensed Skim Milk (28%) + I14 COST 3.9 + MIN.MSNF .28 + MAX.MSNF .28 + MIN.TMS .28 + MAX.TMS .28 + MIN.TS .28 + MAX.TS .28 + MIN.H2O .72 + MAX.H2O .72 + YIELD 1 +* Condensed Skim Milk (30%) + I15 COST 4.9 + MIN.MSNF .3 + MAX.MSNF .3 + MIN.TMS .3 + MAX.TMS .3 + MIN.TS .3 + MAX.TS .3 + MIN.H2O .7 + MAX.H2O .7 + YIELD 1 +* Condensed Skim Milk (32%) + I16 COST 4.5 + MIN.MSNF .32 + MAX.MSNF .32 + MIN.TMS .32 + MAX.TMS .32 + MIN.TS .32 + MAX.TS .32 + MIN.H2O .68 + MAX.H2O .68 + YIELD 1 +* Dry Skim Milk + I17 COST 14.8 + MIN.BF .01 + MAX.BF .01 + MIN.MSNF .96 + MAX.MSNF .96 + MIN.TMS .97 + MAX.TMS .97 + MIN.TS .97 + MAX.TS .97 + MIN.H2O .03 + MAX.H2O .03 + YIELD 1 +* Dry Buttermilk + I18 COST 15.0 + MIN.BF .05 + MAX.BF .05 + MIN.MSNF .92 + MAX.MSNF .92 + MIN.TMS .97 + MAX.TMS .97 + MIN.TS .97 + MAX.TS .97 + MIN.H2O .03 + MAX.H2O .03 + YIELD 1 +* Dry Whey Solids + I19 COST 10.7 + MIN.MSNF .95 + MAX.MSNF .95 + MIN.TMS .95 + MAX.TMS .95 + MIN.TS .95 + MAX.TS .95 + MIN.H2O .05 + MAX.H2O .05 + YIELD 1 +* Dry Sucrose + I20 COST 10.2 + MIN.SUG 1.0 + MAX.SUG 1.0 + MIN.TS 1.0 + MAX.TS 1.0 + YIELD 1 +* Cane Syrup + I21 COST 9.9 + MIN.SUG .67 + MAX.SUG .67 + MIN.TS .67 + MAX.TS .67 + MIN.H2O .33 + MAX.H2O .33 + YIELD 1 +* Corn Sgr. Solids (50% Sweetness) + I22 COST 7.0 + MIN.SUG .5 + MAX.SUG .5 + CSS 1.0 + MIN.TS 1.0 + MAX.TS 1.0 + YIELD 1 +* Corn Sgr. Solids (45% Sweetness) + I23 COST 9.0 + MIN.SUG .45 + MAX.SUG .45 + CSS 1.0 + MIN.TS 1.0 + MAX.TS 1.0 + YIELD 1 +* Corn Syrup + I24 COST 6.6 + MIN.SUG .4 + MAX.SUG .4 + CSS .8 + MIN.TS .8 + MAX.TS .8 + MIN.H2O .2 + MAX.H2O .2 + YIELD 1 +* Stabilizer + I25 COST 55.0 + STAB 1.0 + YIELD 1 +* Emulsifier + I26 COST 78.0 + EMUL 1.0 + YIELD 1 +* Water + I27 COST 0 + MIN.H2O 1.0 + MAX.H2O 1.0 + YIELD 1 +RHS + MIN.BF 10 + MAX.BF 16 + MIN.MSNF 10.5 + MAX.MSNF 13 + MIN.TMS 20.5 + MAX.TMS 25 + MIN.SUG 11 + MAX.SUG 17 + CSS 6 + MIN.TS 37.5 + MAX.TS 41.5 + MIN.H2O 58.5 + MAX.H2O 62.5 + STAB .37 + EMUL .01 + YIELD 100 +BOUNDS + UP I1 10 + LO I6 40 + UP I19 4 +ENDATA diff --git a/glpk-5.0/examples/iptsamp.c b/glpk-5.0/examples/iptsamp.c new file mode 100644 index 0000000..d622d73 --- /dev/null +++ b/glpk-5.0/examples/iptsamp.c @@ -0,0 +1,17 @@ +/* iptsamp.c */ + +#include <stdio.h> +#include <stdlib.h> +#include <glpk.h> + +int main(void) +{ glp_prob *P; + P = glp_create_prob(); + glp_read_mps(P, GLP_MPS_DECK, NULL, "25fv47.mps"); + glp_interior(P, NULL); + glp_print_ipt(P, "25fv47.txt"); + glp_delete_prob(P); + return 0; +} + +/* eof */ diff --git a/glpk-5.0/examples/jssp.mod b/glpk-5.0/examples/jssp.mod new file mode 100644 index 0000000..7ee51b9 --- /dev/null +++ b/glpk-5.0/examples/jssp.mod @@ -0,0 +1,114 @@ +/* JSSP, Job-Shop Scheduling Problem */ + +/* Written in GNU MathProg by Andrew Makhorin <mao@gnu.org> */ + +/* The Job-Shop Scheduling Problem (JSSP) is to schedule a set of jobs + on a set of machines, subject to the constraint that each machine can + handle at most one job at a time and the fact that each job has a + specified processing order through the machines. The objective is to + schedule the jobs so as to minimize the maximum of their completion + times. + + Reference: + D. Applegate and W. Cook, "A Computational Study of the Job-Shop + Scheduling Problem", ORSA J. On Comput., Vol. 3, No. 2, Spring 1991, + pp. 149-156. */ + +param n, integer, > 0; +/* number of jobs */ + +param m, integer, > 0; +/* number of machines */ + +set J := 1..n; +/* set of jobs */ + +set M := 1..m; +/* set of machines */ + +param sigma{j in J, t in 1..m}, in M; +/* permutation of the machines, which represents the processing order + of j through the machines: j must be processed first on sigma[j,1], + then on sigma[j,2], etc. */ + +check{j in J, t1 in 1..m, t2 in 1..m: t1 <> t2}: + sigma[j,t1] != sigma[j,t2]; +/* sigma must be permutation */ + +param p{j in J, a in M}, >= 0; +/* processing time of j on a */ + +var x{j in J, a in M}, >= 0; +/* starting time of j on a */ + +s.t. ord{j in J, t in 2..m}: + x[j, sigma[j,t]] >= x[j, sigma[j,t-1]] + p[j, sigma[j,t-1]]; +/* j can be processed on sigma[j,t] only after it has been completely + processed on sigma[j,t-1] */ + +/* The disjunctive condition that each machine can handle at most one + job at a time is the following: + + x[i,a] >= x[j,a] + p[j,a] or x[j,a] >= x[i,a] + p[i,a] + + for all i, j in J, a in M. This condition is modeled through binary + variables Y as shown below. */ + +var Y{i in J, j in J, a in M}, binary; +/* Y[i,j,a] is 1 if i scheduled before j on machine a, and 0 if j is + scheduled before i */ + +param K := sum{j in J, a in M} p[j,a]; +/* some large constant */ + +display K; + +s.t. phi{i in J, j in J, a in M: i <> j}: + x[i,a] >= x[j,a] + p[j,a] - K * Y[i,j,a]; +/* x[i,a] >= x[j,a] + p[j,a] iff Y[i,j,a] is 0 */ + +s.t. psi{i in J, j in J, a in M: i <> j}: + x[j,a] >= x[i,a] + p[i,a] - K * (1 - Y[i,j,a]); +/* x[j,a] >= x[i,a] + p[i,a] iff Y[i,j,a] is 1 */ + +var z; +/* so-called makespan */ + +s.t. fin{j in J}: z >= x[j, sigma[j,m]] + p[j, sigma[j,m]]; +/* which is the maximum of the completion times of all the jobs */ + +minimize obj: z; +/* the objective is to make z as small as possible */ + +data; + +/* These data correspond to the instance ft06 (mt06) from: + + H. Fisher, G.L. Thompson (1963), Probabilistic learning combinations + of local job-shop scheduling rules, J.F. Muth, G.L. Thompson (eds.), + Industrial Scheduling, Prentice Hall, Englewood Cliffs, New Jersey, + 225-251 */ + +/* The optimal solution is 55 */ + +param n := 6; + +param m := 6; + +param sigma : 1 2 3 4 5 6 := + 1 3 1 2 4 6 5 + 2 2 3 5 6 1 4 + 3 3 4 6 1 2 5 + 4 2 1 3 4 5 6 + 5 3 2 5 6 1 4 + 6 2 4 6 1 5 3 ; + +param p : 1 2 3 4 5 6 := + 1 3 6 1 7 6 3 + 2 10 8 5 4 10 10 + 3 9 1 5 4 7 8 + 4 5 5 5 3 8 9 + 5 3 3 9 1 5 4 + 6 10 3 1 3 4 9 ; + +end; diff --git a/glpk-5.0/examples/life_goe.mod b/glpk-5.0/examples/life_goe.mod new file mode 100644 index 0000000..57ca3c3 --- /dev/null +++ b/glpk-5.0/examples/life_goe.mod @@ -0,0 +1,165 @@ +/* Conway's Game of Life garden of eden checker */ + +/* Written and converted to GNU MathProg by NASZVADI, Peter, 199x-2017 + <vuk@cs.elte.hu> */ + +/* + Conway's Game of Life (ref'd: CGoL) is a Cellular Automata described and + inspected by John H. Conway in the 1970s. CGoL is nothing but a 0-player + game on an infinite two-dimensional Euclydean grid. In the beginning of + the "game", some 1 values are put on some of the grid vertices, and all + others are set to 0. Grid vertices with values are called cells, and a + cell is called "alive", if its value is 1, and called "dead" otherwise, + these are the two "states". The game then turns to an infinite repetitive + process: all cells change together independently at the same time their + states depending only on their actual state and the actual number of + living cells in their so called Moore-neighbourhood: the 4 orthogonal and + 4 diagonal neighbouring cells. Conway also defined the transitions rule: + dead cell become alive if it has exactly 3 living adjacents, and an alive + cell survives only if it has 2 or 3 living neighbours. After executing a + transition for all cells, the two patterns are in a relationship: the + older is the father, the newer is the child. + + It is an interesting problem both in Mathematics and Phylosophy if + there is a fatherless pattern (in CGoL). Fairly trivial existence + proofs had been published since then, and immediately explicit + constructions are followed. + + This GMPL model searches for a father pattern of the pattern specified in + the c parameter matrix, and prints the found one if any both in human + readable format and in RLE format, which could be open with some Cellular + Automata simulators like Golly, for example. + + See more about Garden of Edens: + http://conwaylife.com/wiki/Garden_of_Eden + + Golly CA simulator: + http://golly.sourceforge.net/ + + Tip for running with the example pattern: + glpsol --math life_goe.mod --cuts --last + + WARNING: Rather CPU- and memory-intensive process to find out if a given + pattern is a GOE if it really is! +*/ + +param height, integer, > 0; +/* height of the successor pattern */ + +param width, integer, > 0; +/* width of the successor pattern */ + +set ROWS := 0..height + 1; +/* set of rows of the predecessor */ + +set COLUMNS := 0..width + 1; +/* set of columns of the predecessor */ + +set MOORE := {(0, 1), (0, -1), (1, 0), (-1, 0), (1, 1), (-1, 1), (1, -1), + (-1, -1)}; +/* Moore-neighbourhood relative coordinates */ + +param c{ROWS, COLUMNS}, >= 0; +/* Denotes the cellspace of 1st generation, where 0, 1 and 2 means dead, + alive or arbitrary cell values respectively. Usually the frame values + must be set to "2", and also "2" is allowed in the inner rectangle. */ + +set IJalive := setof{(i, j) in ROWS cross COLUMNS: c[i, j] = 1}(i, j); +/* set of alive cells in the child */ + +set IJdead := setof{(i, j) in ROWS cross COLUMNS: c[i, j] = 0}(i, j); +/* set of dead cells in the child */ + +set IJ := IJalive union IJdead; +/* set of cells in the child with enforced states */ + +var x{ROWS, COLUMNS}, binary; +/* father's states */ + +var dpos{ROWS, COLUMNS}, >= 0; +/* positive part of the distances from 6 */ + +var dneg{ROWS, COLUMNS}, >= 0; +/* negative part of the distances from 6 */ + +var dposup{ROWS, COLUMNS}, binary; +/* positive part's upper bound enforcement */ + +var dnegup{ROWS, COLUMNS}, binary; +/* negative part's upper bound enforcement */ + +s.t. maincons{(i, j) in IJ}: + x[i, j] + sum{(a, b) in MOORE} (2 * x[i + a, j + b]) = + 6 + dpos[i,j] - dneg[i,j]; +/* in the LHS, there is a function that maps from all possible 512 state + combinations of a father cell and its Moore-neighbourhood to [0..17]. + And for CGoL, if the child is alive, then it should be between 5 and 7. + Also implicit introduced "d" as distance from 6 in RHS, and immediately + decomposed "d" into positive and negative parts denoted dpos and dneg. */ + +s.t. posbound{(i,j) in IJ}: dpos[i,j] <= 11 * dposup[i,j]; +/* constraining positive part of distance */ + +s.t. negbound{(i,j) in IJ}: dneg[i,j] <= 6 * dnegup[i,j]; +/* constraining negative part of distance */ + +s.t. mutex{(i,j) in IJ}: dposup[i,j] + dnegup[i,j] = 1; +/* Ensuring that at most one is positive among the pos./neg. parts */ + +s.t. alive{(i,j) in IJalive}: dpos[i,j] + dneg[i,j] <= 1; +/* LHS of maincons must be 5, 6 or 7 either due to child cell is alive */ + +s.t. dead{(i,j) in IJdead}: dpos[i,j] + dneg[i,j] >= 2; +/* LHS of maincons must be at most 4 or at least 8 */ + +/* This is a feasibility problem, so no objective is needed */ + +solve; + +printf '\nFound a father pattern:\n\n'; +for{i in ROWS}{ + for{j in COLUMNS}{ + printf '%s%s', if j then ' ' else '', x[i, j].val; + } + printf '\n'; +} + +printf '\nThe father pattern in rle format:\n\n'; +for{i in ROWS}{ + for{j in COLUMNS}{ + printf '%s', if x[i, j].val then 'o' else 'b'; + } + printf '$'; +} +printf '!\n\n'; + +data; +/* + This example is a halved of a 10x10 garden of eden pattern from: + http://wwwhomes.uni-bielefeld.de/achim/orphan_7th.html + It has a 90 degree rotational symmetry, so if having enough resources, + just comment the line denoted with "8", and uncomment the following part! + And also do not forget to increase height parameter, respectively! +*/ + +param height := 7; + +param width := 10; + +param c : 0 1 2 3 4 5 6 7 8 9 10 11 := + 0 2 2 2 2 2 2 2 2 2 2 2 2 + 1 2 0 1 0 1 1 1 0 1 0 0 2 + 2 2 0 0 1 0 1 0 1 0 0 1 2 + 3 2 1 0 1 1 1 0 0 1 1 0 2 + 4 2 0 1 0 1 1 1 1 1 0 1 2 + 5 2 1 0 0 1 0 0 1 1 1 1 2 + 6 2 1 1 1 1 0 0 1 0 0 1 2 + 7 2 1 0 1 1 1 1 1 0 1 0 2 + 8 2 2 2 2 2 2 2 2 2 2 2 2; + +/* 8 2 0 1 1 0 0 1 1 1 0 1 2 + 9 2 1 0 0 1 0 1 0 1 0 0 2 + 10 2 0 0 1 0 1 1 1 0 1 0 2 + 11 2 2 2 2 2 2 2 2 2 2 2 2; */ + +end; diff --git a/glpk-5.0/examples/magic.mod b/glpk-5.0/examples/magic.mod new file mode 100644 index 0000000..d1e64d0 --- /dev/null +++ b/glpk-5.0/examples/magic.mod @@ -0,0 +1,54 @@ +/* MAGIC, Magic Square */ + +/* Written in GNU MathProg by Andrew Makhorin <mao@gnu.org> */ + +/* In recreational mathematics, a magic square of order n is an + arrangement of n^2 numbers, usually distinct integers, in a square, + such that n numbers in all rows, all columns, and both diagonals sum + to the same constant. A normal magic square contains the integers + from 1 to n^2. + + (From Wikipedia, the free encyclopedia.) */ + +param n, integer, > 0, default 4; +/* square order */ + +set N := 1..n^2; +/* integers to be placed */ + +var x{i in 1..n, j in 1..n, k in N}, binary; +/* x[i,j,k] = 1 means that cell (i,j) contains integer k */ + +s.t. a{i in 1..n, j in 1..n}: sum{k in N} x[i,j,k] = 1; +/* each cell must be assigned exactly one integer */ + +s.t. b{k in N}: sum{i in 1..n, j in 1..n} x[i,j,k] = 1; +/* each integer must be assigned exactly to one cell */ + +var s; +/* the magic sum */ + +s.t. r{i in 1..n}: sum{j in 1..n, k in N} k * x[i,j,k] = s; +/* the sum in each row must be the magic sum */ + +s.t. c{j in 1..n}: sum{i in 1..n, k in N} k * x[i,j,k] = s; +/* the sum in each column must be the magic sum */ + +s.t. d: sum{i in 1..n, k in N} k * x[i,i,k] = s; +/* the sum in the diagonal must be the magic sum */ + +s.t. e: sum{i in 1..n, k in N} k * x[i,n-i+1,k] = s; +/* the sum in the co-diagonal must be the magic sum */ + +solve; + +printf "\n"; +printf "Magic sum is %d\n", s; +printf "\n"; +for{i in 1..n} +{ printf{j in 1..n} "%3d", sum{k in N} k * x[i,j,k]; + printf "\n"; +} +printf "\n"; + +end; diff --git a/glpk-5.0/examples/maxcut.mod b/glpk-5.0/examples/maxcut.mod new file mode 100644 index 0000000..db30b92 --- /dev/null +++ b/glpk-5.0/examples/maxcut.mod @@ -0,0 +1,85 @@ +/* MAXCUT, Maximum Cut Problem */ + +/* Written in GNU MathProg by Andrew Makhorin <mao@gnu.org> */ + +/* The Maximum Cut Problem in a network G = (V, E), where V is a set + of nodes, E is a set of edges, is to find the partition of V into + disjoint sets V1 and V2, which maximizes the sum of edge weights + w(e), where edge e has one endpoint in V1 and other endpoint in V2. + + Reference: + Garey, M.R., and Johnson, D.S. (1979), Computers and Intractability: + A guide to the theory of NP-completeness [Network design, Cuts and + Connectivity, Maximum Cut, ND16]. */ + +set E, dimen 2; +/* set of edges */ + +param w{(i,j) in E}, >= 0, default 1; +/* w[i,j] is weight of edge (i,j) */ + +set V := (setof{(i,j) in E} i) union (setof{(i,j) in E} j); +/* set of nodes */ + +var x{i in V}, binary; +/* x[i] = 0 means that node i is in set V1 + x[i] = 1 means that node i is in set V2 */ + +/* We need to include in the objective function only that edges (i,j) + from E, for which x[i] != x[j]. This can be modeled through binary + variables s[i,j] as follows: + + s[i,j] = x[i] xor x[j] = (x[i] + x[j]) mod 2, (1) + + where s[i,j] = 1 iff x[i] != x[j], that leads to the following + objective function: + + z = sum{(i,j) in E} w[i,j] * s[i,j]. (2) + + To describe "exclusive or" (1) we could think that s[i,j] is a minor + bit of the sum x[i] + x[j]. Then introducing binary variables t[i,j], + which represent a major bit of the sum x[i] + x[j], we can write: + + x[i] + x[j] = s[i,j] + 2 * t[i,j]. (3) + + An easy check shows that conditions (1) and (3) are equivalent. + + Note that condition (3) can be simplified by eliminating variables + s[i,j]. Indeed, from (3) it follows that: + + s[i,j] = x[i] + x[j] - 2 * t[i,j]. (4) + + Since the expression in the right-hand side of (4) is integral, this + condition can be rewritten in the equivalent form: + + 0 <= x[i] + x[j] - 2 * t[i,j] <= 1. (5) + + (One might note that (5) means t[i,j] = x[i] and x[j].) + + Substituting s[i,j] from (4) to (2) leads to the following objective + function: + + z = sum{(i,j) in E} w[i,j] * (x[i] + x[j] - 2 * t[i,j]), (6) + + which does not include variables s[i,j]. */ + +var t{(i,j) in E}, binary; +/* t[i,j] = x[i] and x[j] = (x[i] + x[j]) div 2 */ + +s.t. xor{(i,j) in E}: 0 <= x[i] + x[j] - 2 * t[i,j] <= 1; +/* see (4) */ + +maximize z: sum{(i,j) in E} w[i,j] * (x[i] + x[j] - 2 * t[i,j]); +/* see (6) */ + +data; + +/* In this example the network has 15 nodes and 22 edges. */ + +/* Optimal solution is 20 */ + +set E := + 1 2, 1 5, 2 3, 2 6, 3 4, 3 8, 4 9, 5 6, 5 7, 6 8, 7 8, 7 12, 8 9, + 8 12, 9 10, 9 14, 10 11, 10 14, 11 15, 12 13, 13 14, 14 15; + +end; diff --git a/glpk-5.0/examples/maxflow.mod b/glpk-5.0/examples/maxflow.mod new file mode 100644 index 0000000..20dfc3e --- /dev/null +++ b/glpk-5.0/examples/maxflow.mod @@ -0,0 +1,83 @@ +/* MAXFLOW, Maximum Flow Problem */ + +/* Written in GNU MathProg by Andrew Makhorin <mao@gnu.org> */ + +/* The Maximum Flow Problem in a network G = (V, E), where V is a set + of nodes, E within V x V is a set of arcs, is to maximize the flow + from one given node s (source) to another given node t (sink) subject + to conservation of flow constraints at each node and flow capacities + on each arc. */ + +param n, integer, >= 2; +/* number of nodes */ + +set V, default {1..n}; +/* set of nodes */ + +set E, within V cross V; +/* set of arcs */ + +param a{(i,j) in E}, > 0; +/* a[i,j] is capacity of arc (i,j) */ + +param s, symbolic, in V, default 1; +/* source node */ + +param t, symbolic, in V, != s, default n; +/* sink node */ + +var x{(i,j) in E}, >= 0, <= a[i,j]; +/* x[i,j] is elementary flow through arc (i,j) to be found */ + +var flow, >= 0; +/* total flow from s to t */ + +s.t. node{i in V}: +/* node[i] is conservation constraint for node i */ + + sum{(j,i) in E} x[j,i] + (if i = s then flow) + /* summary flow into node i through all ingoing arcs */ + + = /* must be equal to */ + + sum{(i,j) in E} x[i,j] + (if i = t then flow); + /* summary flow from node i through all outgoing arcs */ + +maximize obj: flow; +/* objective is to maximize the total flow through the network */ + +solve; + +printf{1..56} "="; printf "\n"; +printf "Maximum flow from node %s to node %s is %g\n\n", s, t, flow; +printf "Starting node Ending node Arc capacity Flow in arc\n"; +printf "------------- ----------- ------------ -----------\n"; +printf{(i,j) in E: x[i,j] != 0}: "%13s %11s %12g %11g\n", i, j, + a[i,j], x[i,j]; +printf{1..56} "="; printf "\n"; + +data; + +/* These data correspond to an example from [Christofides]. */ + +/* Optimal solution is 29 */ + +param n := 9; + +param : E : a := + 1 2 14 + 1 4 23 + 2 3 10 + 2 4 9 + 3 5 12 + 3 8 18 + 4 5 26 + 5 2 11 + 5 6 25 + 5 7 4 + 6 7 7 + 6 8 8 + 7 9 15 + 8 9 20; + +end; diff --git a/glpk-5.0/examples/mfasp.mod b/glpk-5.0/examples/mfasp.mod new file mode 100644 index 0000000..b438281 --- /dev/null +++ b/glpk-5.0/examples/mfasp.mod @@ -0,0 +1,62 @@ +/* MFASP, Minimum Feedback Arc Set Problem */ + +/* Written in GNU MathProg by Andrew Makhorin <mao@gnu.org> */ + +/* The Minimum Feedback Arc Set Problem for a given directed graph + G = (V, E), where V is a set of vertices and E is a set of arcs, is + to find a minimal subset of arcs, which being removed from the graph + make it acyclic. + + Reference: + Garey, M.R., and Johnson, D.S. (1979), Computers and Intractability: + A guide to the theory of NP-completeness [Graph Theory, Covering and + Partitioning, Minimum Feedback Arc Set, GT9]. */ + +param n, integer, >= 0; +/* number of vertices */ + +set V, default 1..n; +/* set of vertices */ + +set E, within V cross V, +default setof{i in V, j in V: i <> j and Uniform(0,1) <= 0.15} (i,j); +/* set of arcs */ + +printf "Graph has %d vertices and %d arcs\n", card(V), card(E); + +var x{(i,j) in E}, binary; +/* x[i,j] = 1 means that (i->j) is a feedback arc */ + +/* It is known that a digraph G = (V, E) is acyclic if and only if its + vertices can be assigned numbers from 1 to |V| in such a way that + k[i] + 1 <= k[j] for every arc (i->j) in E, where k[i] is a number + assigned to vertex i. We may use this condition to require that the + digraph G = (V, E \ E'), where E' is a subset of feedback arcs, is + acyclic. */ + +var k{i in V}, >= 1, <= card(V); +/* k[i] is a number assigned to vertex i */ + +s.t. r{(i,j) in E}: k[j] - k[i] >= 1 - card(V) * x[i,j]; +/* note that x[i,j] = 1 leads to a redundant constraint */ + +minimize obj: sum{(i,j) in E} x[i,j]; +/* the objective is to minimize the cardinality of a subset of feedback + arcs */ + +solve; + +printf "Minimum feedback arc set:\n"; +printf{(i,j) in E: x[i,j]} "%d %d\n", i, j; + +data; + +/* The optimal solution is 3 */ + +param n := 15; + +set E := 1 2, 2 3, 3 4, 3 8, 4 9, 5 1, 6 5, 7 5, 8 6, 8 7, 8 9, 9 10, + 10 11, 10 14, 11 15, 12 7, 12 8, 12 13, 13 8, 13 12, 13 14, + 14 9, 15 14; + +end; diff --git a/glpk-5.0/examples/mfvsp.mod b/glpk-5.0/examples/mfvsp.mod new file mode 100644 index 0000000..a03009d --- /dev/null +++ b/glpk-5.0/examples/mfvsp.mod @@ -0,0 +1,62 @@ +/* MFVSP, Minimum Feedback Vertex Set Problem */ + +/* Written in GNU MathProg by Andrew Makhorin <mao@gnu.org> */ + +/* The Minimum Feedback Vertex Set Problem for a given directed graph + G = (V, E), where V is a set of vertices and E is a set of arcs, is + to find a minimal subset of vertices, which being removed from the + graph make it acyclic. + + Reference: + Garey, M.R., and Johnson, D.S. (1979), Computers and Intractability: + A guide to the theory of NP-completeness [Graph Theory, Covering and + Partitioning, Minimum Feedback Vertex Set, GT8]. */ + +param n, integer, >= 0; +/* number of vertices */ + +set V, default 1..n; +/* set of vertices */ + +set E, within V cross V, +default setof{i in V, j in V: i <> j and Uniform(0,1) <= 0.15} (i,j); +/* set of arcs */ + +printf "Graph has %d vertices and %d arcs\n", card(V), card(E); + +var x{i in V}, binary; +/* x[i] = 1 means that i is a feedback vertex */ + +/* It is known that a digraph G = (V, E) is acyclic if and only if its + vertices can be assigned numbers from 1 to |V| in such a way that + k[i] + 1 <= k[j] for every arc (i->j) in E, where k[i] is a number + assigned to vertex i. We may use this condition to require that the + digraph G = (V, E \ E'), where E' is a subset of feedback arcs, is + acyclic. */ + +var k{i in V}, >= 1, <= card(V); +/* k[i] is a number assigned to vertex i */ + +s.t. r{(i,j) in E}: k[j] - k[i] >= 1 - card(V) * (x[i] + x[j]); +/* note that x[i] = 1 or x[j] = 1 leads to a redundant constraint */ + +minimize obj: sum{i in V} x[i]; +/* the objective is to minimize the cardinality of a subset of feedback + vertices */ + +solve; + +printf "Minimum feedback vertex set:\n"; +printf{i in V: x[i]} "%d\n", i; + +data; + +/* The optimal solution is 3 */ + +param n := 15; + +set E := 1 2, 2 3, 3 4, 3 8, 4 9, 5 1, 6 5, 7 5, 8 6, 8 7, 8 9, 9 10, + 10 11, 10 14, 11 15, 12 7, 12 8, 12 13, 13 8, 13 12, 13 14, + 14 9, 15 14; + +end; diff --git a/glpk-5.0/examples/min01ks.mod b/glpk-5.0/examples/min01ks.mod new file mode 100644 index 0000000..4baa3f4 --- /dev/null +++ b/glpk-5.0/examples/min01ks.mod @@ -0,0 +1,111 @@ +/* min01ks.mod - finding minimal equivalent 0-1 knapsack inequality */ + +/* Written in GNU MathProg by Andrew Makhorin <mao@gnu.org> */ + +/* It is obvious that for a given 0-1 knapsack inequality + + a[1] x[1] + ... + a[n] x[n] <= b, x[j] in {0, 1} (1) + + there exist infinitely many equivalent inequalities with exactly the + same feasible solutions. + + Given a[j]'s and b this model allows to find an inequality + + alfa[1] x[1] + ... + alfa[n] x[n] <= beta, x[j] in {0, 1}, (2) + + which is equivalent to (1) and where alfa[j]'s and beta are smallest + non-negative integers. + + This model has the following formulation: + + minimize + + z = |alfa[1]| + ... + |alfa[n]| + |beta| = (3) + + = alfa[1] + ... + alfa[n] + beta + + subject to + + alfa[1] x[1] + ... + alfa[n] x[n] <= beta (4) + + for all x satisfying to (1) + + alfa[1] x[1] + ... + alfa[n] x[n] >= beta + 1 (5) + + for all x not satisfying to (1) + + alfa[1], ..., alfa[n], beta are non-negative integers. + + Note that this model has n+1 variables and 2^n constraints. + + It is interesting, as noticed in [1] and explained in [2], that + in most cases LP relaxation of the MIP formulation above has integer + optimal solution. + + References + + 1. G.H.Bradley, P.L.Hammer, L.Wolsey, "Coefficient Reduction for + Inequalities in 0-1 Variables", Math.Prog.7 (1974), 263-282. + + 2. G.J.Koehler, "A Study on Coefficient Reduction of Binary Knapsack + Inequalities", University of Florida, 2001. */ + +param n, integer, > 0; +/* number of variables in the knapsack inequality */ + +set N := 1..n; +/* set of knapsack items */ + +/* all binary n-vectors are numbered by 0, 1, ..., 2^n-1, where vector + 0 is 00...00, vector 1 is 00...01, etc. */ + +set U := 0..2^n-1; +/* set of numbers of all binary n-vectors */ + +param x{i in U, j in N}, binary, := (i div 2^(j-1)) mod 2; +/* x[i,j] is j-th component of i-th binary n-vector */ + +param a{j in N}, >= 0; +/* original coefficients */ + +param b, >= 0; +/* original right-hand side */ + +set D := setof{i in U: sum{j in N} a[j] * x[i,j] <= b} i; +/* set of numbers of binary n-vectors, which (vectors) are feasible, + i.e. satisfy to the original knapsack inequality (1) */ + +var alfa{j in N}, integer, >= 0; +/* coefficients to be found */ + +var beta, integer, >= 0; +/* right-hand side to be found */ + +minimize z: sum{j in N} alfa[j] + beta; /* (3) */ + +phi{i in D}: sum{j in N} alfa[j] * x[i,j] <= beta; /* (4) */ + +psi{i in U diff D}: sum{j in N} alfa[j] * x[i,j] >= beta + 1; /* (5) */ + +solve; + +printf "\nOriginal 0-1 knapsack inequality:\n"; +for {j in 1..n} printf (if j = 1 then "" else " + ") & "%g x%d", + a[j], j; +printf " <= %g\n", b; +printf "\nMinimized equivalent inequality:\n"; +for {j in 1..n} printf (if j = 1 then "" else " + ") & "%g x%d", + alfa[j], j; +printf " <= %g\n\n", beta; + +data; + +/* These data correspond to the very first example from [1]. */ + +param n := 8; + +param a := [1]65, [2]64, [3]41, [4]22, [5]13, [6]12, [7]8, [8]2; + +param b := 80; + +end; diff --git a/glpk-5.0/examples/misp.mod b/glpk-5.0/examples/misp.mod new file mode 100644 index 0000000..b2b1f6b --- /dev/null +++ b/glpk-5.0/examples/misp.mod @@ -0,0 +1,665 @@ +/* MISP, Maximum Independent Set Problem */ + +/* Written in GNU MathProg by Andrew Makhorin <mao@gnu.org> */ + +/* Let G = (V,E) be an undirected graph with vertex set V and edge set + * E. Vertices u, v in V are non-adjacent if (u,v) not in E. A subset + * of the vertices S within V is independent if all vertices in S are + * pairwise non-adjacent. The Maximum Independent Set Problem (MISP) is + * to find an independent set having the largest cardinality. */ + +param n, integer, > 0; +/* number of vertices */ + +set V := 1..n; +/* set of vertices */ + +set E within V cross V; +/* set of edges */ + +var x{i in V}, binary; +/* x[i] = 1 means vertex i belongs to independent set */ + +s.t. edge{(i,j) in E}: x[i] + x[j] <= 1; +/* if there is edge (i,j), vertices i and j cannot belong to the same + independent set */ + +maximize obj: sum{i in V} x[i]; +/* the objective is to maximize the cardinality of independent set */ + +data; + +/* These data corresponds to the test instance from: + * + * M.G.C. Resende, T.A.Feo, S.H.Smith, "Algorithm 787 -- FORTRAN + * subroutines for approximate solution of the maximum independent set + * problem using GRASP," Trans. on Math. Softw., Vol. 24, No. 4, + * December 1998, pp. 386-394. */ + +/* The optimal solution is 7. */ + +param n := 50; + +set E := + 1 2 + 1 3 + 1 5 + 1 7 + 1 8 + 1 12 + 1 15 + 1 16 + 1 19 + 1 20 + 1 21 + 1 22 + 1 28 + 1 30 + 1 34 + 1 35 + 1 37 + 1 41 + 1 42 + 1 47 + 1 50 + 2 3 + 2 5 + 2 6 + 2 7 + 2 8 + 2 9 + 2 10 + 2 13 + 2 17 + 2 19 + 2 20 + 2 21 + 2 23 + 2 25 + 2 26 + 2 29 + 2 31 + 2 35 + 2 36 + 2 44 + 2 45 + 2 46 + 2 50 + 3 5 + 3 6 + 3 8 + 3 9 + 3 10 + 3 11 + 3 14 + 3 16 + 3 23 + 3 24 + 3 26 + 3 27 + 3 28 + 3 29 + 3 30 + 3 31 + 3 34 + 3 35 + 3 36 + 3 39 + 3 41 + 3 42 + 3 43 + 3 44 + 3 50 + 4 6 + 4 7 + 4 9 + 4 10 + 4 11 + 4 13 + 4 14 + 4 15 + 4 17 + 4 21 + 4 22 + 4 23 + 4 24 + 4 25 + 4 27 + 4 28 + 4 30 + 4 31 + 4 33 + 4 34 + 4 35 + 4 36 + 4 37 + 4 38 + 4 40 + 4 41 + 4 42 + 4 46 + 4 49 + 5 6 + 5 11 + 5 14 + 5 21 + 5 24 + 5 25 + 5 28 + 5 35 + 5 38 + 5 39 + 5 41 + 5 44 + 5 49 + 5 50 + 6 8 + 6 9 + 6 10 + 6 13 + 6 14 + 6 16 + 6 17 + 6 19 + 6 22 + 6 23 + 6 26 + 6 27 + 6 30 + 6 34 + 6 35 + 6 38 + 6 39 + 6 40 + 6 41 + 6 44 + 6 45 + 6 47 + 6 50 + 7 8 + 7 9 + 7 10 + 7 11 + 7 13 + 7 15 + 7 16 + 7 18 + 7 20 + 7 22 + 7 23 + 7 24 + 7 25 + 7 33 + 7 35 + 7 36 + 7 38 + 7 43 + 7 45 + 7 46 + 7 47 + 8 10 + 8 11 + 8 13 + 8 16 + 8 17 + 8 18 + 8 19 + 8 20 + 8 21 + 8 22 + 8 23 + 8 24 + 8 25 + 8 26 + 8 33 + 8 35 + 8 36 + 8 39 + 8 42 + 8 44 + 8 48 + 8 49 + 9 12 + 9 14 + 9 17 + 9 19 + 9 20 + 9 23 + 9 28 + 9 30 + 9 31 + 9 32 + 9 33 + 9 34 + 9 38 + 9 39 + 9 42 + 9 44 + 9 45 + 9 46 + 10 11 + 10 13 + 10 15 + 10 16 + 10 17 + 10 20 + 10 21 + 10 22 + 10 23 + 10 25 + 10 26 + 10 27 + 10 28 + 10 30 + 10 31 + 10 32 + 10 37 + 10 38 + 10 41 + 10 43 + 10 44 + 10 45 + 10 50 + 11 12 + 11 14 + 11 15 + 11 18 + 11 21 + 11 24 + 11 25 + 11 26 + 11 29 + 11 32 + 11 33 + 11 35 + 11 36 + 11 37 + 11 39 + 11 40 + 11 42 + 11 43 + 11 45 + 11 47 + 11 49 + 11 50 + 12 13 + 12 16 + 12 17 + 12 19 + 12 24 + 12 25 + 12 26 + 12 30 + 12 31 + 12 32 + 12 34 + 12 36 + 12 37 + 12 39 + 12 41 + 12 44 + 12 47 + 12 48 + 12 49 + 13 15 + 13 16 + 13 18 + 13 19 + 13 20 + 13 22 + 13 23 + 13 24 + 13 27 + 13 28 + 13 29 + 13 31 + 13 33 + 13 35 + 13 36 + 13 37 + 13 44 + 13 47 + 13 49 + 13 50 + 14 15 + 14 16 + 14 17 + 14 18 + 14 19 + 14 20 + 14 21 + 14 26 + 14 28 + 14 29 + 14 30 + 14 31 + 14 32 + 14 34 + 14 35 + 14 36 + 14 38 + 14 39 + 14 41 + 14 44 + 14 46 + 14 47 + 14 48 + 15 18 + 15 21 + 15 22 + 15 23 + 15 25 + 15 28 + 15 29 + 15 30 + 15 33 + 15 34 + 15 36 + 15 37 + 15 38 + 15 39 + 15 40 + 15 43 + 15 44 + 15 46 + 15 50 + 16 17 + 16 19 + 16 20 + 16 25 + 16 26 + 16 29 + 16 35 + 16 38 + 16 39 + 16 40 + 16 41 + 16 42 + 16 44 + 17 18 + 17 19 + 17 21 + 17 22 + 17 23 + 17 25 + 17 26 + 17 28 + 17 29 + 17 33 + 17 37 + 17 44 + 17 45 + 17 48 + 18 20 + 18 24 + 18 27 + 18 28 + 18 31 + 18 32 + 18 34 + 18 35 + 18 36 + 18 37 + 18 38 + 18 45 + 18 48 + 18 49 + 18 50 + 19 22 + 19 24 + 19 28 + 19 29 + 19 36 + 19 37 + 19 39 + 19 41 + 19 43 + 19 45 + 19 48 + 19 49 + 20 21 + 20 22 + 20 24 + 20 25 + 20 26 + 20 27 + 20 29 + 20 30 + 20 31 + 20 33 + 20 34 + 20 35 + 20 38 + 20 39 + 20 41 + 20 42 + 20 43 + 20 44 + 20 45 + 20 46 + 20 48 + 20 49 + 21 22 + 21 23 + 21 29 + 21 31 + 21 35 + 21 38 + 21 42 + 21 46 + 21 47 + 22 23 + 22 26 + 22 27 + 22 28 + 22 29 + 22 30 + 22 39 + 22 40 + 22 41 + 22 42 + 22 44 + 22 45 + 22 46 + 22 47 + 22 49 + 22 50 + 23 28 + 23 31 + 23 32 + 23 33 + 23 34 + 23 35 + 23 36 + 23 39 + 23 40 + 23 41 + 23 42 + 23 44 + 23 45 + 23 48 + 23 49 + 23 50 + 24 25 + 24 27 + 24 29 + 24 30 + 24 31 + 24 33 + 24 34 + 24 38 + 24 42 + 24 43 + 24 44 + 24 49 + 24 50 + 25 26 + 25 27 + 25 29 + 25 30 + 25 33 + 25 34 + 25 36 + 25 38 + 25 40 + 25 41 + 25 42 + 25 44 + 25 46 + 25 47 + 25 48 + 25 49 + 26 28 + 26 31 + 26 32 + 26 33 + 26 37 + 26 38 + 26 39 + 26 40 + 26 41 + 26 42 + 26 45 + 26 47 + 26 48 + 26 49 + 27 29 + 27 30 + 27 33 + 27 34 + 27 35 + 27 39 + 27 40 + 27 46 + 27 48 + 28 29 + 28 37 + 28 40 + 28 42 + 28 44 + 28 46 + 28 47 + 28 50 + 29 35 + 29 38 + 29 39 + 29 41 + 29 42 + 29 48 + 30 31 + 30 32 + 30 35 + 30 37 + 30 38 + 30 40 + 30 43 + 30 45 + 30 46 + 30 47 + 30 48 + 31 33 + 31 35 + 31 38 + 31 40 + 31 41 + 31 42 + 31 44 + 31 46 + 31 47 + 31 50 + 32 33 + 32 35 + 32 39 + 32 40 + 32 46 + 32 49 + 32 50 + 33 34 + 33 36 + 33 37 + 33 40 + 33 42 + 33 43 + 33 44 + 33 45 + 33 50 + 34 35 + 34 36 + 34 37 + 34 38 + 34 40 + 34 43 + 34 44 + 34 49 + 34 50 + 35 36 + 35 38 + 35 41 + 35 42 + 35 43 + 35 45 + 35 46 + 35 47 + 35 49 + 35 50 + 36 37 + 36 39 + 36 40 + 36 41 + 36 42 + 36 43 + 36 48 + 36 50 + 37 38 + 37 41 + 37 43 + 37 46 + 37 47 + 37 48 + 37 49 + 37 50 + 38 41 + 38 45 + 38 46 + 38 48 + 38 49 + 38 50 + 39 43 + 39 46 + 39 47 + 39 48 + 39 49 + 40 43 + 40 45 + 40 48 + 40 50 + 41 42 + 41 43 + 41 44 + 41 45 + 41 46 + 41 48 + 41 49 + 42 43 + 42 44 + 42 46 + 42 48 + 42 49 + 43 45 + 43 46 + 43 48 + 43 50 + 44 45 + 44 48 + 45 46 + 45 47 + 45 48 + 46 49 + 47 49 + 47 50 + 48 49 + 48 50 + 49 50 +; + +end; diff --git a/glpk-5.0/examples/misp1.dat b/glpk-5.0/examples/misp1.dat new file mode 100644 index 0000000..2c2ed1b --- /dev/null +++ b/glpk-5.0/examples/misp1.dat @@ -0,0 +1,1489 @@ +/* misp1.dat (data for misp.mod to illustrate clique cuts) */ + +/* These data corresponds to the test instance 1dc.128 (graphs from + * single-deletion-correcting codes) from: + * + * N.J.A.Sloane, "Challenge Problems: Independent Sets In Graphs." + * http://neilsloane.com/doc/graphs.html (June 2013). */ + +/* Optimal solution is 16. */ + +data; + +param n := 128; + +set E := /* 1471 edges */ + 1 2 + 1 3 + 1 5 + 1 9 + 1 17 + 1 33 + 1 65 + 2 3 + 2 4 + 2 5 + 2 6 + 2 9 + 2 10 + 2 17 + 2 18 + 2 33 + 2 34 + 2 65 + 2 66 + 3 4 + 3 5 + 3 6 + 3 7 + 3 9 + 3 10 + 3 11 + 3 17 + 3 18 + 3 19 + 3 33 + 3 34 + 3 35 + 3 65 + 3 66 + 3 67 + 4 6 + 4 7 + 4 8 + 4 10 + 4 12 + 4 18 + 4 20 + 4 34 + 4 36 + 4 66 + 4 68 + 5 6 + 5 7 + 5 9 + 5 10 + 5 11 + 5 13 + 5 17 + 5 19 + 5 21 + 5 33 + 5 35 + 5 37 + 5 65 + 5 67 + 5 69 + 6 7 + 6 8 + 6 10 + 6 11 + 6 12 + 6 14 + 6 18 + 6 19 + 6 20 + 6 22 + 6 34 + 6 35 + 6 36 + 6 38 + 6 66 + 6 67 + 6 68 + 6 70 + 7 8 + 7 11 + 7 12 + 7 13 + 7 14 + 7 15 + 7 19 + 7 20 + 7 23 + 7 35 + 7 36 + 7 39 + 7 67 + 7 68 + 7 71 + 8 12 + 8 14 + 8 15 + 8 16 + 8 20 + 8 24 + 8 36 + 8 40 + 8 68 + 8 72 + 9 10 + 9 11 + 9 13 + 9 17 + 9 18 + 9 19 + 9 21 + 9 25 + 9 33 + 9 37 + 9 41 + 9 65 + 9 69 + 9 73 + 10 11 + 10 12 + 10 13 + 10 14 + 10 18 + 10 19 + 10 20 + 10 21 + 10 22 + 10 26 + 10 34 + 10 37 + 10 38 + 10 42 + 10 66 + 10 69 + 10 70 + 10 74 + 11 12 + 11 13 + 11 14 + 11 15 + 11 19 + 11 21 + 11 22 + 11 23 + 11 27 + 11 35 + 11 37 + 11 38 + 11 39 + 11 43 + 11 67 + 11 69 + 11 70 + 11 71 + 11 75 + 12 14 + 12 15 + 12 16 + 12 20 + 12 22 + 12 23 + 12 24 + 12 28 + 12 36 + 12 38 + 12 40 + 12 44 + 12 68 + 12 70 + 12 72 + 12 76 + 13 14 + 13 15 + 13 21 + 13 23 + 13 25 + 13 26 + 13 27 + 13 29 + 13 37 + 13 39 + 13 45 + 13 69 + 13 71 + 13 77 + 14 15 + 14 16 + 14 22 + 14 23 + 14 24 + 14 26 + 14 27 + 14 28 + 14 30 + 14 38 + 14 39 + 14 40 + 14 46 + 14 70 + 14 71 + 14 72 + 14 78 + 15 16 + 15 23 + 15 24 + 15 27 + 15 29 + 15 30 + 15 31 + 15 39 + 15 40 + 15 47 + 15 71 + 15 72 + 15 79 + 16 24 + 16 28 + 16 30 + 16 31 + 16 32 + 16 40 + 16 48 + 16 72 + 16 80 + 17 18 + 17 19 + 17 21 + 17 25 + 17 33 + 17 34 + 17 35 + 17 37 + 17 41 + 17 49 + 17 65 + 17 73 + 17 81 + 18 19 + 18 20 + 18 21 + 18 22 + 18 25 + 18 26 + 18 34 + 18 35 + 18 36 + 18 38 + 18 41 + 18 42 + 18 50 + 18 66 + 18 73 + 18 74 + 18 82 + 19 20 + 19 21 + 19 22 + 19 23 + 19 25 + 19 26 + 19 27 + 19 35 + 19 37 + 19 38 + 19 39 + 19 41 + 19 42 + 19 43 + 19 51 + 19 67 + 19 73 + 19 74 + 19 75 + 19 83 + 20 22 + 20 23 + 20 24 + 20 26 + 20 28 + 20 36 + 20 38 + 20 39 + 20 40 + 20 42 + 20 44 + 20 52 + 20 68 + 20 74 + 20 76 + 20 84 + 21 22 + 21 23 + 21 25 + 21 26 + 21 27 + 21 29 + 21 37 + 21 41 + 21 42 + 21 43 + 21 45 + 21 53 + 21 69 + 21 73 + 21 75 + 21 77 + 21 85 + 22 23 + 22 24 + 22 26 + 22 27 + 22 28 + 22 30 + 22 38 + 22 42 + 22 43 + 22 44 + 22 46 + 22 54 + 22 70 + 22 74 + 22 75 + 22 76 + 22 78 + 22 86 + 23 24 + 23 27 + 23 28 + 23 29 + 23 30 + 23 31 + 23 39 + 23 43 + 23 44 + 23 45 + 23 46 + 23 47 + 23 55 + 23 71 + 23 75 + 23 76 + 23 79 + 23 87 + 24 28 + 24 30 + 24 31 + 24 32 + 24 40 + 24 44 + 24 46 + 24 47 + 24 48 + 24 56 + 24 72 + 24 76 + 24 80 + 24 88 + 25 26 + 25 27 + 25 29 + 25 41 + 25 45 + 25 49 + 25 50 + 25 51 + 25 53 + 25 57 + 25 73 + 25 77 + 25 89 + 26 27 + 26 28 + 26 29 + 26 30 + 26 42 + 26 45 + 26 46 + 26 50 + 26 51 + 26 52 + 26 54 + 26 58 + 26 74 + 26 77 + 26 78 + 26 90 + 27 28 + 27 29 + 27 30 + 27 31 + 27 43 + 27 45 + 27 46 + 27 47 + 27 51 + 27 53 + 27 54 + 27 55 + 27 59 + 27 75 + 27 77 + 27 78 + 27 79 + 27 91 + 28 30 + 28 31 + 28 32 + 28 44 + 28 46 + 28 48 + 28 52 + 28 54 + 28 55 + 28 56 + 28 60 + 28 76 + 28 78 + 28 80 + 28 92 + 29 30 + 29 31 + 29 45 + 29 47 + 29 53 + 29 57 + 29 58 + 29 59 + 29 61 + 29 77 + 29 79 + 29 93 + 30 31 + 30 32 + 30 46 + 30 47 + 30 48 + 30 54 + 30 58 + 30 59 + 30 60 + 30 62 + 30 78 + 30 79 + 30 80 + 30 94 + 31 32 + 31 47 + 31 48 + 31 55 + 31 59 + 31 61 + 31 62 + 31 63 + 31 79 + 31 80 + 31 95 + 32 48 + 32 56 + 32 60 + 32 62 + 32 63 + 32 64 + 32 80 + 32 96 + 33 34 + 33 35 + 33 37 + 33 41 + 33 49 + 33 65 + 33 66 + 33 67 + 33 69 + 33 73 + 33 81 + 33 97 + 34 35 + 34 36 + 34 37 + 34 38 + 34 41 + 34 42 + 34 49 + 34 50 + 34 66 + 34 67 + 34 68 + 34 70 + 34 74 + 34 81 + 34 82 + 34 98 + 35 36 + 35 37 + 35 38 + 35 39 + 35 41 + 35 42 + 35 43 + 35 49 + 35 50 + 35 51 + 35 67 + 35 69 + 35 70 + 35 71 + 35 75 + 35 81 + 35 82 + 35 83 + 35 99 + 36 38 + 36 39 + 36 40 + 36 42 + 36 44 + 36 50 + 36 52 + 36 68 + 36 70 + 36 71 + 36 72 + 36 76 + 36 82 + 36 84 + 36 100 + 37 38 + 37 39 + 37 41 + 37 42 + 37 43 + 37 45 + 37 49 + 37 51 + 37 53 + 37 69 + 37 73 + 37 74 + 37 75 + 37 77 + 37 81 + 37 83 + 37 85 + 37 101 + 38 39 + 38 40 + 38 42 + 38 43 + 38 44 + 38 46 + 38 50 + 38 51 + 38 52 + 38 54 + 38 70 + 38 74 + 38 75 + 38 76 + 38 78 + 38 82 + 38 83 + 38 84 + 38 86 + 38 102 + 39 40 + 39 43 + 39 44 + 39 45 + 39 46 + 39 47 + 39 51 + 39 52 + 39 55 + 39 71 + 39 75 + 39 77 + 39 78 + 39 79 + 39 83 + 39 84 + 39 87 + 39 103 + 40 44 + 40 46 + 40 47 + 40 48 + 40 52 + 40 56 + 40 72 + 40 76 + 40 78 + 40 79 + 40 80 + 40 84 + 40 88 + 40 104 + 41 42 + 41 43 + 41 45 + 41 49 + 41 50 + 41 51 + 41 53 + 41 57 + 41 73 + 41 81 + 41 82 + 41 83 + 41 85 + 41 89 + 41 105 + 42 43 + 42 44 + 42 45 + 42 46 + 42 50 + 42 51 + 42 52 + 42 53 + 42 54 + 42 58 + 42 74 + 42 82 + 42 83 + 42 84 + 42 85 + 42 86 + 42 90 + 42 106 + 43 44 + 43 45 + 43 46 + 43 47 + 43 51 + 43 53 + 43 54 + 43 55 + 43 59 + 43 75 + 43 83 + 43 85 + 43 86 + 43 87 + 43 91 + 43 107 + 44 46 + 44 47 + 44 48 + 44 52 + 44 54 + 44 55 + 44 56 + 44 60 + 44 76 + 44 84 + 44 86 + 44 87 + 44 88 + 44 92 + 44 108 + 45 46 + 45 47 + 45 53 + 45 55 + 45 57 + 45 58 + 45 59 + 45 61 + 45 77 + 45 85 + 45 87 + 45 89 + 45 90 + 45 91 + 45 93 + 45 109 + 46 47 + 46 48 + 46 54 + 46 55 + 46 56 + 46 58 + 46 59 + 46 60 + 46 62 + 46 78 + 46 86 + 46 87 + 46 88 + 46 90 + 46 91 + 46 92 + 46 94 + 46 110 + 47 48 + 47 55 + 47 56 + 47 59 + 47 61 + 47 62 + 47 63 + 47 79 + 47 87 + 47 88 + 47 91 + 47 93 + 47 94 + 47 95 + 47 111 + 48 56 + 48 60 + 48 62 + 48 63 + 48 64 + 48 80 + 48 88 + 48 92 + 48 94 + 48 95 + 48 96 + 48 112 + 49 50 + 49 51 + 49 53 + 49 57 + 49 81 + 49 89 + 49 97 + 49 98 + 49 99 + 49 101 + 49 105 + 49 113 + 50 51 + 50 52 + 50 53 + 50 54 + 50 57 + 50 58 + 50 82 + 50 89 + 50 90 + 50 98 + 50 99 + 50 100 + 50 102 + 50 106 + 50 114 + 51 52 + 51 53 + 51 54 + 51 55 + 51 57 + 51 58 + 51 59 + 51 83 + 51 89 + 51 90 + 51 91 + 51 99 + 51 101 + 51 102 + 51 103 + 51 107 + 51 115 + 52 54 + 52 55 + 52 56 + 52 58 + 52 60 + 52 84 + 52 90 + 52 92 + 52 100 + 52 102 + 52 103 + 52 104 + 52 108 + 52 116 + 53 54 + 53 55 + 53 57 + 53 58 + 53 59 + 53 61 + 53 85 + 53 89 + 53 91 + 53 93 + 53 101 + 53 105 + 53 106 + 53 107 + 53 109 + 53 117 + 54 55 + 54 56 + 54 58 + 54 59 + 54 60 + 54 62 + 54 86 + 54 90 + 54 91 + 54 92 + 54 94 + 54 102 + 54 106 + 54 107 + 54 108 + 54 110 + 54 118 + 55 56 + 55 59 + 55 60 + 55 61 + 55 62 + 55 63 + 55 87 + 55 91 + 55 92 + 55 95 + 55 103 + 55 107 + 55 109 + 55 110 + 55 111 + 55 119 + 56 60 + 56 62 + 56 63 + 56 64 + 56 88 + 56 92 + 56 96 + 56 104 + 56 108 + 56 110 + 56 111 + 56 112 + 56 120 + 57 58 + 57 59 + 57 61 + 57 89 + 57 93 + 57 105 + 57 113 + 57 114 + 57 115 + 57 117 + 57 121 + 58 59 + 58 60 + 58 61 + 58 62 + 58 90 + 58 93 + 58 94 + 58 106 + 58 114 + 58 115 + 58 116 + 58 118 + 58 122 + 59 60 + 59 61 + 59 62 + 59 63 + 59 91 + 59 93 + 59 94 + 59 95 + 59 107 + 59 115 + 59 117 + 59 118 + 59 119 + 59 123 + 60 62 + 60 63 + 60 64 + 60 92 + 60 94 + 60 96 + 60 108 + 60 116 + 60 118 + 60 119 + 60 120 + 60 124 + 61 62 + 61 63 + 61 93 + 61 95 + 61 109 + 61 117 + 61 121 + 61 122 + 61 123 + 61 125 + 62 63 + 62 64 + 62 94 + 62 95 + 62 96 + 62 110 + 62 118 + 62 122 + 62 123 + 62 124 + 62 126 + 63 64 + 63 95 + 63 96 + 63 111 + 63 119 + 63 123 + 63 125 + 63 126 + 63 127 + 64 96 + 64 112 + 64 120 + 64 124 + 64 126 + 64 127 + 64 128 + 65 66 + 65 67 + 65 69 + 65 73 + 65 81 + 65 97 + 66 67 + 66 68 + 66 69 + 66 70 + 66 73 + 66 74 + 66 81 + 66 82 + 66 97 + 66 98 + 67 68 + 67 69 + 67 70 + 67 71 + 67 73 + 67 74 + 67 75 + 67 81 + 67 82 + 67 83 + 67 97 + 67 98 + 67 99 + 68 70 + 68 71 + 68 72 + 68 74 + 68 76 + 68 82 + 68 84 + 68 98 + 68 100 + 69 70 + 69 71 + 69 73 + 69 74 + 69 75 + 69 77 + 69 81 + 69 83 + 69 85 + 69 97 + 69 99 + 69 101 + 70 71 + 70 72 + 70 74 + 70 75 + 70 76 + 70 78 + 70 82 + 70 83 + 70 84 + 70 86 + 70 98 + 70 99 + 70 100 + 70 102 + 71 72 + 71 75 + 71 76 + 71 77 + 71 78 + 71 79 + 71 83 + 71 84 + 71 87 + 71 99 + 71 100 + 71 103 + 72 76 + 72 78 + 72 79 + 72 80 + 72 84 + 72 88 + 72 100 + 72 104 + 73 74 + 73 75 + 73 77 + 73 81 + 73 82 + 73 83 + 73 85 + 73 89 + 73 97 + 73 101 + 73 105 + 74 75 + 74 76 + 74 77 + 74 78 + 74 82 + 74 83 + 74 84 + 74 85 + 74 86 + 74 90 + 74 98 + 74 101 + 74 102 + 74 106 + 75 76 + 75 77 + 75 78 + 75 79 + 75 83 + 75 85 + 75 86 + 75 87 + 75 91 + 75 99 + 75 101 + 75 102 + 75 103 + 75 107 + 76 78 + 76 79 + 76 80 + 76 84 + 76 86 + 76 87 + 76 88 + 76 92 + 76 100 + 76 102 + 76 104 + 76 108 + 77 78 + 77 79 + 77 85 + 77 87 + 77 89 + 77 90 + 77 91 + 77 93 + 77 101 + 77 103 + 77 109 + 78 79 + 78 80 + 78 86 + 78 87 + 78 88 + 78 90 + 78 91 + 78 92 + 78 94 + 78 102 + 78 103 + 78 104 + 78 110 + 79 80 + 79 87 + 79 88 + 79 91 + 79 93 + 79 94 + 79 95 + 79 103 + 79 104 + 79 111 + 80 88 + 80 92 + 80 94 + 80 95 + 80 96 + 80 104 + 80 112 + 81 82 + 81 83 + 81 85 + 81 89 + 81 97 + 81 98 + 81 99 + 81 101 + 81 105 + 81 113 + 82 83 + 82 84 + 82 85 + 82 86 + 82 89 + 82 90 + 82 98 + 82 99 + 82 100 + 82 102 + 82 105 + 82 106 + 82 114 + 83 84 + 83 85 + 83 86 + 83 87 + 83 89 + 83 90 + 83 91 + 83 99 + 83 101 + 83 102 + 83 103 + 83 105 + 83 106 + 83 107 + 83 115 + 84 86 + 84 87 + 84 88 + 84 90 + 84 92 + 84 100 + 84 102 + 84 103 + 84 104 + 84 106 + 84 108 + 84 116 + 85 86 + 85 87 + 85 89 + 85 90 + 85 91 + 85 93 + 85 101 + 85 105 + 85 106 + 85 107 + 85 109 + 85 117 + 86 87 + 86 88 + 86 90 + 86 91 + 86 92 + 86 94 + 86 102 + 86 106 + 86 107 + 86 108 + 86 110 + 86 118 + 87 88 + 87 91 + 87 92 + 87 93 + 87 94 + 87 95 + 87 103 + 87 107 + 87 108 + 87 109 + 87 110 + 87 111 + 87 119 + 88 92 + 88 94 + 88 95 + 88 96 + 88 104 + 88 108 + 88 110 + 88 111 + 88 112 + 88 120 + 89 90 + 89 91 + 89 93 + 89 105 + 89 109 + 89 113 + 89 114 + 89 115 + 89 117 + 89 121 + 90 91 + 90 92 + 90 93 + 90 94 + 90 106 + 90 109 + 90 110 + 90 114 + 90 115 + 90 116 + 90 118 + 90 122 + 91 92 + 91 93 + 91 94 + 91 95 + 91 107 + 91 109 + 91 110 + 91 111 + 91 115 + 91 117 + 91 118 + 91 119 + 91 123 + 92 94 + 92 95 + 92 96 + 92 108 + 92 110 + 92 112 + 92 116 + 92 118 + 92 119 + 92 120 + 92 124 + 93 94 + 93 95 + 93 109 + 93 111 + 93 117 + 93 121 + 93 122 + 93 123 + 93 125 + 94 95 + 94 96 + 94 110 + 94 111 + 94 112 + 94 118 + 94 122 + 94 123 + 94 124 + 94 126 + 95 96 + 95 111 + 95 112 + 95 119 + 95 123 + 95 125 + 95 126 + 95 127 + 96 112 + 96 120 + 96 124 + 96 126 + 96 127 + 96 128 + 97 98 + 97 99 + 97 101 + 97 105 + 97 113 + 98 99 + 98 100 + 98 101 + 98 102 + 98 105 + 98 106 + 98 113 + 98 114 + 99 100 + 99 101 + 99 102 + 99 103 + 99 105 + 99 106 + 99 107 + 99 113 + 99 114 + 99 115 + 100 102 + 100 103 + 100 104 + 100 106 + 100 108 + 100 114 + 100 116 + 101 102 + 101 103 + 101 105 + 101 106 + 101 107 + 101 109 + 101 113 + 101 115 + 101 117 + 102 103 + 102 104 + 102 106 + 102 107 + 102 108 + 102 110 + 102 114 + 102 115 + 102 116 + 102 118 + 103 104 + 103 107 + 103 108 + 103 109 + 103 110 + 103 111 + 103 115 + 103 116 + 103 119 + 104 108 + 104 110 + 104 111 + 104 112 + 104 116 + 104 120 + 105 106 + 105 107 + 105 109 + 105 113 + 105 114 + 105 115 + 105 117 + 105 121 + 106 107 + 106 108 + 106 109 + 106 110 + 106 114 + 106 115 + 106 116 + 106 117 + 106 118 + 106 122 + 107 108 + 107 109 + 107 110 + 107 111 + 107 115 + 107 117 + 107 118 + 107 119 + 107 123 + 108 110 + 108 111 + 108 112 + 108 116 + 108 118 + 108 119 + 108 120 + 108 124 + 109 110 + 109 111 + 109 117 + 109 119 + 109 121 + 109 122 + 109 123 + 109 125 + 110 111 + 110 112 + 110 118 + 110 119 + 110 120 + 110 122 + 110 123 + 110 124 + 110 126 + 111 112 + 111 119 + 111 120 + 111 123 + 111 125 + 111 126 + 111 127 + 112 120 + 112 124 + 112 126 + 112 127 + 112 128 + 113 114 + 113 115 + 113 117 + 113 121 + 114 115 + 114 116 + 114 117 + 114 118 + 114 121 + 114 122 + 115 116 + 115 117 + 115 118 + 115 119 + 115 121 + 115 122 + 115 123 + 116 118 + 116 119 + 116 120 + 116 122 + 116 124 + 117 118 + 117 119 + 117 121 + 117 122 + 117 123 + 117 125 + 118 119 + 118 120 + 118 122 + 118 123 + 118 124 + 118 126 + 119 120 + 119 123 + 119 124 + 119 125 + 119 126 + 119 127 + 120 124 + 120 126 + 120 127 + 120 128 + 121 122 + 121 123 + 121 125 + 122 123 + 122 124 + 122 125 + 122 126 + 123 124 + 123 125 + 123 126 + 123 127 + 124 126 + 124 127 + 124 128 + 125 126 + 125 127 + 126 127 + 126 128 + 127 128 +; + +end; diff --git a/glpk-5.0/examples/misp2.dat b/glpk-5.0/examples/misp2.dat new file mode 100644 index 0000000..c9a6116 --- /dev/null +++ b/glpk-5.0/examples/misp2.dat @@ -0,0 +1,3857 @@ +/* misp2.dat (data for misp.mod to illustrate clique cuts) */ + +/* These data corresponds to the test instance 1dc.256 (graphs from + * single-deletion-correcting codes) from: + * + * N.J.A.Sloane, "Challenge Problems: Independent Sets In Graphs." + * http://neilsloane.com/doc/graphs.html (June 2013). */ + +/* Optimal solution is 30. */ + +data; + +param n := 256; + +set E := /* 3839 edges */ + 1 2 + 1 3 + 1 5 + 1 9 + 1 17 + 1 33 + 1 65 + 1 129 + 2 3 + 2 4 + 2 5 + 2 6 + 2 9 + 2 10 + 2 17 + 2 18 + 2 33 + 2 34 + 2 65 + 2 66 + 2 129 + 2 130 + 3 4 + 3 5 + 3 6 + 3 7 + 3 9 + 3 10 + 3 11 + 3 17 + 3 18 + 3 19 + 3 33 + 3 34 + 3 35 + 3 65 + 3 66 + 3 67 + 3 129 + 3 130 + 3 131 + 4 6 + 4 7 + 4 8 + 4 10 + 4 12 + 4 18 + 4 20 + 4 34 + 4 36 + 4 66 + 4 68 + 4 130 + 4 132 + 5 6 + 5 7 + 5 9 + 5 10 + 5 11 + 5 13 + 5 17 + 5 19 + 5 21 + 5 33 + 5 35 + 5 37 + 5 65 + 5 67 + 5 69 + 5 129 + 5 131 + 5 133 + 6 7 + 6 8 + 6 10 + 6 11 + 6 12 + 6 14 + 6 18 + 6 19 + 6 20 + 6 22 + 6 34 + 6 35 + 6 36 + 6 38 + 6 66 + 6 67 + 6 68 + 6 70 + 6 130 + 6 131 + 6 132 + 6 134 + 7 8 + 7 11 + 7 12 + 7 13 + 7 14 + 7 15 + 7 19 + 7 20 + 7 23 + 7 35 + 7 36 + 7 39 + 7 67 + 7 68 + 7 71 + 7 131 + 7 132 + 7 135 + 8 12 + 8 14 + 8 15 + 8 16 + 8 20 + 8 24 + 8 36 + 8 40 + 8 68 + 8 72 + 8 132 + 8 136 + 9 10 + 9 11 + 9 13 + 9 17 + 9 18 + 9 19 + 9 21 + 9 25 + 9 33 + 9 37 + 9 41 + 9 65 + 9 69 + 9 73 + 9 129 + 9 133 + 9 137 + 10 11 + 10 12 + 10 13 + 10 14 + 10 18 + 10 19 + 10 20 + 10 21 + 10 22 + 10 26 + 10 34 + 10 37 + 10 38 + 10 42 + 10 66 + 10 69 + 10 70 + 10 74 + 10 130 + 10 133 + 10 134 + 10 138 + 11 12 + 11 13 + 11 14 + 11 15 + 11 19 + 11 21 + 11 22 + 11 23 + 11 27 + 11 35 + 11 37 + 11 38 + 11 39 + 11 43 + 11 67 + 11 69 + 11 70 + 11 71 + 11 75 + 11 131 + 11 133 + 11 134 + 11 135 + 11 139 + 12 14 + 12 15 + 12 16 + 12 20 + 12 22 + 12 23 + 12 24 + 12 28 + 12 36 + 12 38 + 12 40 + 12 44 + 12 68 + 12 70 + 12 72 + 12 76 + 12 132 + 12 134 + 12 136 + 12 140 + 13 14 + 13 15 + 13 21 + 13 23 + 13 25 + 13 26 + 13 27 + 13 29 + 13 37 + 13 39 + 13 45 + 13 69 + 13 71 + 13 77 + 13 133 + 13 135 + 13 141 + 14 15 + 14 16 + 14 22 + 14 23 + 14 24 + 14 26 + 14 27 + 14 28 + 14 30 + 14 38 + 14 39 + 14 40 + 14 46 + 14 70 + 14 71 + 14 72 + 14 78 + 14 134 + 14 135 + 14 136 + 14 142 + 15 16 + 15 23 + 15 24 + 15 27 + 15 29 + 15 30 + 15 31 + 15 39 + 15 40 + 15 47 + 15 71 + 15 72 + 15 79 + 15 135 + 15 136 + 15 143 + 16 24 + 16 28 + 16 30 + 16 31 + 16 32 + 16 40 + 16 48 + 16 72 + 16 80 + 16 136 + 16 144 + 17 18 + 17 19 + 17 21 + 17 25 + 17 33 + 17 34 + 17 35 + 17 37 + 17 41 + 17 49 + 17 65 + 17 73 + 17 81 + 17 129 + 17 137 + 17 145 + 18 19 + 18 20 + 18 21 + 18 22 + 18 25 + 18 26 + 18 34 + 18 35 + 18 36 + 18 38 + 18 41 + 18 42 + 18 50 + 18 66 + 18 73 + 18 74 + 18 82 + 18 130 + 18 137 + 18 138 + 18 146 + 19 20 + 19 21 + 19 22 + 19 23 + 19 25 + 19 26 + 19 27 + 19 35 + 19 37 + 19 38 + 19 39 + 19 41 + 19 42 + 19 43 + 19 51 + 19 67 + 19 73 + 19 74 + 19 75 + 19 83 + 19 131 + 19 137 + 19 138 + 19 139 + 19 147 + 20 22 + 20 23 + 20 24 + 20 26 + 20 28 + 20 36 + 20 38 + 20 39 + 20 40 + 20 42 + 20 44 + 20 52 + 20 68 + 20 74 + 20 76 + 20 84 + 20 132 + 20 138 + 20 140 + 20 148 + 21 22 + 21 23 + 21 25 + 21 26 + 21 27 + 21 29 + 21 37 + 21 41 + 21 42 + 21 43 + 21 45 + 21 53 + 21 69 + 21 73 + 21 75 + 21 77 + 21 85 + 21 133 + 21 137 + 21 139 + 21 141 + 21 149 + 22 23 + 22 24 + 22 26 + 22 27 + 22 28 + 22 30 + 22 38 + 22 42 + 22 43 + 22 44 + 22 46 + 22 54 + 22 70 + 22 74 + 22 75 + 22 76 + 22 78 + 22 86 + 22 134 + 22 138 + 22 139 + 22 140 + 22 142 + 22 150 + 23 24 + 23 27 + 23 28 + 23 29 + 23 30 + 23 31 + 23 39 + 23 43 + 23 44 + 23 45 + 23 46 + 23 47 + 23 55 + 23 71 + 23 75 + 23 76 + 23 79 + 23 87 + 23 135 + 23 139 + 23 140 + 23 143 + 23 151 + 24 28 + 24 30 + 24 31 + 24 32 + 24 40 + 24 44 + 24 46 + 24 47 + 24 48 + 24 56 + 24 72 + 24 76 + 24 80 + 24 88 + 24 136 + 24 140 + 24 144 + 24 152 + 25 26 + 25 27 + 25 29 + 25 41 + 25 45 + 25 49 + 25 50 + 25 51 + 25 53 + 25 57 + 25 73 + 25 77 + 25 89 + 25 137 + 25 141 + 25 153 + 26 27 + 26 28 + 26 29 + 26 30 + 26 42 + 26 45 + 26 46 + 26 50 + 26 51 + 26 52 + 26 54 + 26 58 + 26 74 + 26 77 + 26 78 + 26 90 + 26 138 + 26 141 + 26 142 + 26 154 + 27 28 + 27 29 + 27 30 + 27 31 + 27 43 + 27 45 + 27 46 + 27 47 + 27 51 + 27 53 + 27 54 + 27 55 + 27 59 + 27 75 + 27 77 + 27 78 + 27 79 + 27 91 + 27 139 + 27 141 + 27 142 + 27 143 + 27 155 + 28 30 + 28 31 + 28 32 + 28 44 + 28 46 + 28 48 + 28 52 + 28 54 + 28 55 + 28 56 + 28 60 + 28 76 + 28 78 + 28 80 + 28 92 + 28 140 + 28 142 + 28 144 + 28 156 + 29 30 + 29 31 + 29 45 + 29 47 + 29 53 + 29 57 + 29 58 + 29 59 + 29 61 + 29 77 + 29 79 + 29 93 + 29 141 + 29 143 + 29 157 + 30 31 + 30 32 + 30 46 + 30 47 + 30 48 + 30 54 + 30 58 + 30 59 + 30 60 + 30 62 + 30 78 + 30 79 + 30 80 + 30 94 + 30 142 + 30 143 + 30 144 + 30 158 + 31 32 + 31 47 + 31 48 + 31 55 + 31 59 + 31 61 + 31 62 + 31 63 + 31 79 + 31 80 + 31 95 + 31 143 + 31 144 + 31 159 + 32 48 + 32 56 + 32 60 + 32 62 + 32 63 + 32 64 + 32 80 + 32 96 + 32 144 + 32 160 + 33 34 + 33 35 + 33 37 + 33 41 + 33 49 + 33 65 + 33 66 + 33 67 + 33 69 + 33 73 + 33 81 + 33 97 + 33 129 + 33 145 + 33 161 + 34 35 + 34 36 + 34 37 + 34 38 + 34 41 + 34 42 + 34 49 + 34 50 + 34 66 + 34 67 + 34 68 + 34 70 + 34 74 + 34 81 + 34 82 + 34 98 + 34 130 + 34 145 + 34 146 + 34 162 + 35 36 + 35 37 + 35 38 + 35 39 + 35 41 + 35 42 + 35 43 + 35 49 + 35 50 + 35 51 + 35 67 + 35 69 + 35 70 + 35 71 + 35 75 + 35 81 + 35 82 + 35 83 + 35 99 + 35 131 + 35 145 + 35 146 + 35 147 + 35 163 + 36 38 + 36 39 + 36 40 + 36 42 + 36 44 + 36 50 + 36 52 + 36 68 + 36 70 + 36 71 + 36 72 + 36 76 + 36 82 + 36 84 + 36 100 + 36 132 + 36 146 + 36 148 + 36 164 + 37 38 + 37 39 + 37 41 + 37 42 + 37 43 + 37 45 + 37 49 + 37 51 + 37 53 + 37 69 + 37 73 + 37 74 + 37 75 + 37 77 + 37 81 + 37 83 + 37 85 + 37 101 + 37 133 + 37 145 + 37 147 + 37 149 + 37 165 + 38 39 + 38 40 + 38 42 + 38 43 + 38 44 + 38 46 + 38 50 + 38 51 + 38 52 + 38 54 + 38 70 + 38 74 + 38 75 + 38 76 + 38 78 + 38 82 + 38 83 + 38 84 + 38 86 + 38 102 + 38 134 + 38 146 + 38 147 + 38 148 + 38 150 + 38 166 + 39 40 + 39 43 + 39 44 + 39 45 + 39 46 + 39 47 + 39 51 + 39 52 + 39 55 + 39 71 + 39 75 + 39 77 + 39 78 + 39 79 + 39 83 + 39 84 + 39 87 + 39 103 + 39 135 + 39 147 + 39 148 + 39 151 + 39 167 + 40 44 + 40 46 + 40 47 + 40 48 + 40 52 + 40 56 + 40 72 + 40 76 + 40 78 + 40 79 + 40 80 + 40 84 + 40 88 + 40 104 + 40 136 + 40 148 + 40 152 + 40 168 + 41 42 + 41 43 + 41 45 + 41 49 + 41 50 + 41 51 + 41 53 + 41 57 + 41 73 + 41 81 + 41 82 + 41 83 + 41 85 + 41 89 + 41 105 + 41 137 + 41 145 + 41 149 + 41 153 + 41 169 + 42 43 + 42 44 + 42 45 + 42 46 + 42 50 + 42 51 + 42 52 + 42 53 + 42 54 + 42 58 + 42 74 + 42 82 + 42 83 + 42 84 + 42 85 + 42 86 + 42 90 + 42 106 + 42 138 + 42 146 + 42 149 + 42 150 + 42 154 + 42 170 + 43 44 + 43 45 + 43 46 + 43 47 + 43 51 + 43 53 + 43 54 + 43 55 + 43 59 + 43 75 + 43 83 + 43 85 + 43 86 + 43 87 + 43 91 + 43 107 + 43 139 + 43 147 + 43 149 + 43 150 + 43 151 + 43 155 + 43 171 + 44 46 + 44 47 + 44 48 + 44 52 + 44 54 + 44 55 + 44 56 + 44 60 + 44 76 + 44 84 + 44 86 + 44 87 + 44 88 + 44 92 + 44 108 + 44 140 + 44 148 + 44 150 + 44 152 + 44 156 + 44 172 + 45 46 + 45 47 + 45 53 + 45 55 + 45 57 + 45 58 + 45 59 + 45 61 + 45 77 + 45 85 + 45 87 + 45 89 + 45 90 + 45 91 + 45 93 + 45 109 + 45 141 + 45 149 + 45 151 + 45 157 + 45 173 + 46 47 + 46 48 + 46 54 + 46 55 + 46 56 + 46 58 + 46 59 + 46 60 + 46 62 + 46 78 + 46 86 + 46 87 + 46 88 + 46 90 + 46 91 + 46 92 + 46 94 + 46 110 + 46 142 + 46 150 + 46 151 + 46 152 + 46 158 + 46 174 + 47 48 + 47 55 + 47 56 + 47 59 + 47 61 + 47 62 + 47 63 + 47 79 + 47 87 + 47 88 + 47 91 + 47 93 + 47 94 + 47 95 + 47 111 + 47 143 + 47 151 + 47 152 + 47 159 + 47 175 + 48 56 + 48 60 + 48 62 + 48 63 + 48 64 + 48 80 + 48 88 + 48 92 + 48 94 + 48 95 + 48 96 + 48 112 + 48 144 + 48 152 + 48 160 + 48 176 + 49 50 + 49 51 + 49 53 + 49 57 + 49 81 + 49 89 + 49 97 + 49 98 + 49 99 + 49 101 + 49 105 + 49 113 + 49 145 + 49 153 + 49 177 + 50 51 + 50 52 + 50 53 + 50 54 + 50 57 + 50 58 + 50 82 + 50 89 + 50 90 + 50 98 + 50 99 + 50 100 + 50 102 + 50 106 + 50 114 + 50 146 + 50 153 + 50 154 + 50 178 + 51 52 + 51 53 + 51 54 + 51 55 + 51 57 + 51 58 + 51 59 + 51 83 + 51 89 + 51 90 + 51 91 + 51 99 + 51 101 + 51 102 + 51 103 + 51 107 + 51 115 + 51 147 + 51 153 + 51 154 + 51 155 + 51 179 + 52 54 + 52 55 + 52 56 + 52 58 + 52 60 + 52 84 + 52 90 + 52 92 + 52 100 + 52 102 + 52 103 + 52 104 + 52 108 + 52 116 + 52 148 + 52 154 + 52 156 + 52 180 + 53 54 + 53 55 + 53 57 + 53 58 + 53 59 + 53 61 + 53 85 + 53 89 + 53 91 + 53 93 + 53 101 + 53 105 + 53 106 + 53 107 + 53 109 + 53 117 + 53 149 + 53 153 + 53 155 + 53 157 + 53 181 + 54 55 + 54 56 + 54 58 + 54 59 + 54 60 + 54 62 + 54 86 + 54 90 + 54 91 + 54 92 + 54 94 + 54 102 + 54 106 + 54 107 + 54 108 + 54 110 + 54 118 + 54 150 + 54 154 + 54 155 + 54 156 + 54 158 + 54 182 + 55 56 + 55 59 + 55 60 + 55 61 + 55 62 + 55 63 + 55 87 + 55 91 + 55 92 + 55 95 + 55 103 + 55 107 + 55 109 + 55 110 + 55 111 + 55 119 + 55 151 + 55 155 + 55 156 + 55 159 + 55 183 + 56 60 + 56 62 + 56 63 + 56 64 + 56 88 + 56 92 + 56 96 + 56 104 + 56 108 + 56 110 + 56 111 + 56 112 + 56 120 + 56 152 + 56 156 + 56 160 + 56 184 + 57 58 + 57 59 + 57 61 + 57 89 + 57 93 + 57 105 + 57 113 + 57 114 + 57 115 + 57 117 + 57 121 + 57 153 + 57 157 + 57 185 + 58 59 + 58 60 + 58 61 + 58 62 + 58 90 + 58 93 + 58 94 + 58 106 + 58 114 + 58 115 + 58 116 + 58 118 + 58 122 + 58 154 + 58 157 + 58 158 + 58 186 + 59 60 + 59 61 + 59 62 + 59 63 + 59 91 + 59 93 + 59 94 + 59 95 + 59 107 + 59 115 + 59 117 + 59 118 + 59 119 + 59 123 + 59 155 + 59 157 + 59 158 + 59 159 + 59 187 + 60 62 + 60 63 + 60 64 + 60 92 + 60 94 + 60 96 + 60 108 + 60 116 + 60 118 + 60 119 + 60 120 + 60 124 + 60 156 + 60 158 + 60 160 + 60 188 + 61 62 + 61 63 + 61 93 + 61 95 + 61 109 + 61 117 + 61 121 + 61 122 + 61 123 + 61 125 + 61 157 + 61 159 + 61 189 + 62 63 + 62 64 + 62 94 + 62 95 + 62 96 + 62 110 + 62 118 + 62 122 + 62 123 + 62 124 + 62 126 + 62 158 + 62 159 + 62 160 + 62 190 + 63 64 + 63 95 + 63 96 + 63 111 + 63 119 + 63 123 + 63 125 + 63 126 + 63 127 + 63 159 + 63 160 + 63 191 + 64 96 + 64 112 + 64 120 + 64 124 + 64 126 + 64 127 + 64 128 + 64 160 + 64 192 + 65 66 + 65 67 + 65 69 + 65 73 + 65 81 + 65 97 + 65 129 + 65 130 + 65 131 + 65 133 + 65 137 + 65 145 + 65 161 + 65 193 + 66 67 + 66 68 + 66 69 + 66 70 + 66 73 + 66 74 + 66 81 + 66 82 + 66 97 + 66 98 + 66 130 + 66 131 + 66 132 + 66 134 + 66 138 + 66 146 + 66 161 + 66 162 + 66 194 + 67 68 + 67 69 + 67 70 + 67 71 + 67 73 + 67 74 + 67 75 + 67 81 + 67 82 + 67 83 + 67 97 + 67 98 + 67 99 + 67 131 + 67 133 + 67 134 + 67 135 + 67 139 + 67 147 + 67 161 + 67 162 + 67 163 + 67 195 + 68 70 + 68 71 + 68 72 + 68 74 + 68 76 + 68 82 + 68 84 + 68 98 + 68 100 + 68 132 + 68 134 + 68 135 + 68 136 + 68 140 + 68 148 + 68 162 + 68 164 + 68 196 + 69 70 + 69 71 + 69 73 + 69 74 + 69 75 + 69 77 + 69 81 + 69 83 + 69 85 + 69 97 + 69 99 + 69 101 + 69 133 + 69 137 + 69 138 + 69 139 + 69 141 + 69 149 + 69 161 + 69 163 + 69 165 + 69 197 + 70 71 + 70 72 + 70 74 + 70 75 + 70 76 + 70 78 + 70 82 + 70 83 + 70 84 + 70 86 + 70 98 + 70 99 + 70 100 + 70 102 + 70 134 + 70 138 + 70 139 + 70 140 + 70 142 + 70 150 + 70 162 + 70 163 + 70 164 + 70 166 + 70 198 + 71 72 + 71 75 + 71 76 + 71 77 + 71 78 + 71 79 + 71 83 + 71 84 + 71 87 + 71 99 + 71 100 + 71 103 + 71 135 + 71 139 + 71 141 + 71 142 + 71 143 + 71 151 + 71 163 + 71 164 + 71 167 + 71 199 + 72 76 + 72 78 + 72 79 + 72 80 + 72 84 + 72 88 + 72 100 + 72 104 + 72 136 + 72 140 + 72 142 + 72 143 + 72 144 + 72 152 + 72 164 + 72 168 + 72 200 + 73 74 + 73 75 + 73 77 + 73 81 + 73 82 + 73 83 + 73 85 + 73 89 + 73 97 + 73 101 + 73 105 + 73 137 + 73 145 + 73 146 + 73 147 + 73 149 + 73 153 + 73 161 + 73 165 + 73 169 + 73 201 + 74 75 + 74 76 + 74 77 + 74 78 + 74 82 + 74 83 + 74 84 + 74 85 + 74 86 + 74 90 + 74 98 + 74 101 + 74 102 + 74 106 + 74 138 + 74 146 + 74 147 + 74 148 + 74 150 + 74 154 + 74 162 + 74 165 + 74 166 + 74 170 + 74 202 + 75 76 + 75 77 + 75 78 + 75 79 + 75 83 + 75 85 + 75 86 + 75 87 + 75 91 + 75 99 + 75 101 + 75 102 + 75 103 + 75 107 + 75 139 + 75 147 + 75 149 + 75 150 + 75 151 + 75 155 + 75 163 + 75 165 + 75 166 + 75 167 + 75 171 + 75 203 + 76 78 + 76 79 + 76 80 + 76 84 + 76 86 + 76 87 + 76 88 + 76 92 + 76 100 + 76 102 + 76 104 + 76 108 + 76 140 + 76 148 + 76 150 + 76 151 + 76 152 + 76 156 + 76 164 + 76 166 + 76 168 + 76 172 + 76 204 + 77 78 + 77 79 + 77 85 + 77 87 + 77 89 + 77 90 + 77 91 + 77 93 + 77 101 + 77 103 + 77 109 + 77 141 + 77 149 + 77 153 + 77 154 + 77 155 + 77 157 + 77 165 + 77 167 + 77 173 + 77 205 + 78 79 + 78 80 + 78 86 + 78 87 + 78 88 + 78 90 + 78 91 + 78 92 + 78 94 + 78 102 + 78 103 + 78 104 + 78 110 + 78 142 + 78 150 + 78 154 + 78 155 + 78 156 + 78 158 + 78 166 + 78 167 + 78 168 + 78 174 + 78 206 + 79 80 + 79 87 + 79 88 + 79 91 + 79 93 + 79 94 + 79 95 + 79 103 + 79 104 + 79 111 + 79 143 + 79 151 + 79 155 + 79 157 + 79 158 + 79 159 + 79 167 + 79 168 + 79 175 + 79 207 + 80 88 + 80 92 + 80 94 + 80 95 + 80 96 + 80 104 + 80 112 + 80 144 + 80 152 + 80 156 + 80 158 + 80 159 + 80 160 + 80 168 + 80 176 + 80 208 + 81 82 + 81 83 + 81 85 + 81 89 + 81 97 + 81 98 + 81 99 + 81 101 + 81 105 + 81 113 + 81 145 + 81 161 + 81 162 + 81 163 + 81 165 + 81 169 + 81 177 + 81 209 + 82 83 + 82 84 + 82 85 + 82 86 + 82 89 + 82 90 + 82 98 + 82 99 + 82 100 + 82 102 + 82 105 + 82 106 + 82 114 + 82 146 + 82 162 + 82 163 + 82 164 + 82 166 + 82 169 + 82 170 + 82 178 + 82 210 + 83 84 + 83 85 + 83 86 + 83 87 + 83 89 + 83 90 + 83 91 + 83 99 + 83 101 + 83 102 + 83 103 + 83 105 + 83 106 + 83 107 + 83 115 + 83 147 + 83 163 + 83 165 + 83 166 + 83 167 + 83 169 + 83 170 + 83 171 + 83 179 + 83 211 + 84 86 + 84 87 + 84 88 + 84 90 + 84 92 + 84 100 + 84 102 + 84 103 + 84 104 + 84 106 + 84 108 + 84 116 + 84 148 + 84 164 + 84 166 + 84 167 + 84 168 + 84 170 + 84 172 + 84 180 + 84 212 + 85 86 + 85 87 + 85 89 + 85 90 + 85 91 + 85 93 + 85 101 + 85 105 + 85 106 + 85 107 + 85 109 + 85 117 + 85 149 + 85 165 + 85 169 + 85 170 + 85 171 + 85 173 + 85 181 + 85 213 + 86 87 + 86 88 + 86 90 + 86 91 + 86 92 + 86 94 + 86 102 + 86 106 + 86 107 + 86 108 + 86 110 + 86 118 + 86 150 + 86 166 + 86 170 + 86 171 + 86 172 + 86 174 + 86 182 + 86 214 + 87 88 + 87 91 + 87 92 + 87 93 + 87 94 + 87 95 + 87 103 + 87 107 + 87 108 + 87 109 + 87 110 + 87 111 + 87 119 + 87 151 + 87 167 + 87 171 + 87 172 + 87 173 + 87 174 + 87 175 + 87 183 + 87 215 + 88 92 + 88 94 + 88 95 + 88 96 + 88 104 + 88 108 + 88 110 + 88 111 + 88 112 + 88 120 + 88 152 + 88 168 + 88 172 + 88 174 + 88 175 + 88 176 + 88 184 + 88 216 + 89 90 + 89 91 + 89 93 + 89 105 + 89 109 + 89 113 + 89 114 + 89 115 + 89 117 + 89 121 + 89 153 + 89 169 + 89 173 + 89 177 + 89 178 + 89 179 + 89 181 + 89 185 + 89 217 + 90 91 + 90 92 + 90 93 + 90 94 + 90 106 + 90 109 + 90 110 + 90 114 + 90 115 + 90 116 + 90 118 + 90 122 + 90 154 + 90 170 + 90 173 + 90 174 + 90 178 + 90 179 + 90 180 + 90 182 + 90 186 + 90 218 + 91 92 + 91 93 + 91 94 + 91 95 + 91 107 + 91 109 + 91 110 + 91 111 + 91 115 + 91 117 + 91 118 + 91 119 + 91 123 + 91 155 + 91 171 + 91 173 + 91 174 + 91 175 + 91 179 + 91 181 + 91 182 + 91 183 + 91 187 + 91 219 + 92 94 + 92 95 + 92 96 + 92 108 + 92 110 + 92 112 + 92 116 + 92 118 + 92 119 + 92 120 + 92 124 + 92 156 + 92 172 + 92 174 + 92 176 + 92 180 + 92 182 + 92 183 + 92 184 + 92 188 + 92 220 + 93 94 + 93 95 + 93 109 + 93 111 + 93 117 + 93 121 + 93 122 + 93 123 + 93 125 + 93 157 + 93 173 + 93 175 + 93 181 + 93 185 + 93 186 + 93 187 + 93 189 + 93 221 + 94 95 + 94 96 + 94 110 + 94 111 + 94 112 + 94 118 + 94 122 + 94 123 + 94 124 + 94 126 + 94 158 + 94 174 + 94 175 + 94 176 + 94 182 + 94 186 + 94 187 + 94 188 + 94 190 + 94 222 + 95 96 + 95 111 + 95 112 + 95 119 + 95 123 + 95 125 + 95 126 + 95 127 + 95 159 + 95 175 + 95 176 + 95 183 + 95 187 + 95 189 + 95 190 + 95 191 + 95 223 + 96 112 + 96 120 + 96 124 + 96 126 + 96 127 + 96 128 + 96 160 + 96 176 + 96 184 + 96 188 + 96 190 + 96 191 + 96 192 + 96 224 + 97 98 + 97 99 + 97 101 + 97 105 + 97 113 + 97 161 + 97 177 + 97 193 + 97 194 + 97 195 + 97 197 + 97 201 + 97 209 + 97 225 + 98 99 + 98 100 + 98 101 + 98 102 + 98 105 + 98 106 + 98 113 + 98 114 + 98 162 + 98 177 + 98 178 + 98 194 + 98 195 + 98 196 + 98 198 + 98 202 + 98 210 + 98 226 + 99 100 + 99 101 + 99 102 + 99 103 + 99 105 + 99 106 + 99 107 + 99 113 + 99 114 + 99 115 + 99 163 + 99 177 + 99 178 + 99 179 + 99 195 + 99 197 + 99 198 + 99 199 + 99 203 + 99 211 + 99 227 + 100 102 + 100 103 + 100 104 + 100 106 + 100 108 + 100 114 + 100 116 + 100 164 + 100 178 + 100 180 + 100 196 + 100 198 + 100 199 + 100 200 + 100 204 + 100 212 + 100 228 + 101 102 + 101 103 + 101 105 + 101 106 + 101 107 + 101 109 + 101 113 + 101 115 + 101 117 + 101 165 + 101 177 + 101 179 + 101 181 + 101 197 + 101 201 + 101 202 + 101 203 + 101 205 + 101 213 + 101 229 + 102 103 + 102 104 + 102 106 + 102 107 + 102 108 + 102 110 + 102 114 + 102 115 + 102 116 + 102 118 + 102 166 + 102 178 + 102 179 + 102 180 + 102 182 + 102 198 + 102 202 + 102 203 + 102 204 + 102 206 + 102 214 + 102 230 + 103 104 + 103 107 + 103 108 + 103 109 + 103 110 + 103 111 + 103 115 + 103 116 + 103 119 + 103 167 + 103 179 + 103 180 + 103 183 + 103 199 + 103 203 + 103 205 + 103 206 + 103 207 + 103 215 + 103 231 + 104 108 + 104 110 + 104 111 + 104 112 + 104 116 + 104 120 + 104 168 + 104 180 + 104 184 + 104 200 + 104 204 + 104 206 + 104 207 + 104 208 + 104 216 + 104 232 + 105 106 + 105 107 + 105 109 + 105 113 + 105 114 + 105 115 + 105 117 + 105 121 + 105 169 + 105 177 + 105 181 + 105 185 + 105 201 + 105 209 + 105 210 + 105 211 + 105 213 + 105 217 + 105 233 + 106 107 + 106 108 + 106 109 + 106 110 + 106 114 + 106 115 + 106 116 + 106 117 + 106 118 + 106 122 + 106 170 + 106 178 + 106 181 + 106 182 + 106 186 + 106 202 + 106 210 + 106 211 + 106 212 + 106 214 + 106 218 + 106 234 + 107 108 + 107 109 + 107 110 + 107 111 + 107 115 + 107 117 + 107 118 + 107 119 + 107 123 + 107 171 + 107 179 + 107 181 + 107 182 + 107 183 + 107 187 + 107 203 + 107 211 + 107 213 + 107 214 + 107 215 + 107 219 + 107 235 + 108 110 + 108 111 + 108 112 + 108 116 + 108 118 + 108 119 + 108 120 + 108 124 + 108 172 + 108 180 + 108 182 + 108 184 + 108 188 + 108 204 + 108 212 + 108 214 + 108 215 + 108 216 + 108 220 + 108 236 + 109 110 + 109 111 + 109 117 + 109 119 + 109 121 + 109 122 + 109 123 + 109 125 + 109 173 + 109 181 + 109 183 + 109 189 + 109 205 + 109 213 + 109 217 + 109 218 + 109 219 + 109 221 + 109 237 + 110 111 + 110 112 + 110 118 + 110 119 + 110 120 + 110 122 + 110 123 + 110 124 + 110 126 + 110 174 + 110 182 + 110 183 + 110 184 + 110 190 + 110 206 + 110 214 + 110 218 + 110 219 + 110 220 + 110 222 + 110 238 + 111 112 + 111 119 + 111 120 + 111 123 + 111 125 + 111 126 + 111 127 + 111 175 + 111 183 + 111 184 + 111 191 + 111 207 + 111 215 + 111 219 + 111 221 + 111 222 + 111 223 + 111 239 + 112 120 + 112 124 + 112 126 + 112 127 + 112 128 + 112 176 + 112 184 + 112 192 + 112 208 + 112 216 + 112 220 + 112 222 + 112 223 + 112 224 + 112 240 + 113 114 + 113 115 + 113 117 + 113 121 + 113 177 + 113 185 + 113 209 + 113 225 + 113 226 + 113 227 + 113 229 + 113 233 + 113 241 + 114 115 + 114 116 + 114 117 + 114 118 + 114 121 + 114 122 + 114 178 + 114 185 + 114 186 + 114 210 + 114 226 + 114 227 + 114 228 + 114 230 + 114 234 + 114 242 + 115 116 + 115 117 + 115 118 + 115 119 + 115 121 + 115 122 + 115 123 + 115 179 + 115 185 + 115 186 + 115 187 + 115 211 + 115 227 + 115 229 + 115 230 + 115 231 + 115 235 + 115 243 + 116 118 + 116 119 + 116 120 + 116 122 + 116 124 + 116 180 + 116 186 + 116 188 + 116 212 + 116 228 + 116 230 + 116 231 + 116 232 + 116 236 + 116 244 + 117 118 + 117 119 + 117 121 + 117 122 + 117 123 + 117 125 + 117 181 + 117 185 + 117 187 + 117 189 + 117 213 + 117 229 + 117 233 + 117 234 + 117 235 + 117 237 + 117 245 + 118 119 + 118 120 + 118 122 + 118 123 + 118 124 + 118 126 + 118 182 + 118 186 + 118 187 + 118 188 + 118 190 + 118 214 + 118 230 + 118 234 + 118 235 + 118 236 + 118 238 + 118 246 + 119 120 + 119 123 + 119 124 + 119 125 + 119 126 + 119 127 + 119 183 + 119 187 + 119 188 + 119 191 + 119 215 + 119 231 + 119 235 + 119 237 + 119 238 + 119 239 + 119 247 + 120 124 + 120 126 + 120 127 + 120 128 + 120 184 + 120 188 + 120 192 + 120 216 + 120 232 + 120 236 + 120 238 + 120 239 + 120 240 + 120 248 + 121 122 + 121 123 + 121 125 + 121 185 + 121 189 + 121 217 + 121 233 + 121 241 + 121 242 + 121 243 + 121 245 + 121 249 + 122 123 + 122 124 + 122 125 + 122 126 + 122 186 + 122 189 + 122 190 + 122 218 + 122 234 + 122 242 + 122 243 + 122 244 + 122 246 + 122 250 + 123 124 + 123 125 + 123 126 + 123 127 + 123 187 + 123 189 + 123 190 + 123 191 + 123 219 + 123 235 + 123 243 + 123 245 + 123 246 + 123 247 + 123 251 + 124 126 + 124 127 + 124 128 + 124 188 + 124 190 + 124 192 + 124 220 + 124 236 + 124 244 + 124 246 + 124 247 + 124 248 + 124 252 + 125 126 + 125 127 + 125 189 + 125 191 + 125 221 + 125 237 + 125 245 + 125 249 + 125 250 + 125 251 + 125 253 + 126 127 + 126 128 + 126 190 + 126 191 + 126 192 + 126 222 + 126 238 + 126 246 + 126 250 + 126 251 + 126 252 + 126 254 + 127 128 + 127 191 + 127 192 + 127 223 + 127 239 + 127 247 + 127 251 + 127 253 + 127 254 + 127 255 + 128 192 + 128 224 + 128 240 + 128 248 + 128 252 + 128 254 + 128 255 + 128 256 + 129 130 + 129 131 + 129 133 + 129 137 + 129 145 + 129 161 + 129 193 + 130 131 + 130 132 + 130 133 + 130 134 + 130 137 + 130 138 + 130 145 + 130 146 + 130 161 + 130 162 + 130 193 + 130 194 + 131 132 + 131 133 + 131 134 + 131 135 + 131 137 + 131 138 + 131 139 + 131 145 + 131 146 + 131 147 + 131 161 + 131 162 + 131 163 + 131 193 + 131 194 + 131 195 + 132 134 + 132 135 + 132 136 + 132 138 + 132 140 + 132 146 + 132 148 + 132 162 + 132 164 + 132 194 + 132 196 + 133 134 + 133 135 + 133 137 + 133 138 + 133 139 + 133 141 + 133 145 + 133 147 + 133 149 + 133 161 + 133 163 + 133 165 + 133 193 + 133 195 + 133 197 + 134 135 + 134 136 + 134 138 + 134 139 + 134 140 + 134 142 + 134 146 + 134 147 + 134 148 + 134 150 + 134 162 + 134 163 + 134 164 + 134 166 + 134 194 + 134 195 + 134 196 + 134 198 + 135 136 + 135 139 + 135 140 + 135 141 + 135 142 + 135 143 + 135 147 + 135 148 + 135 151 + 135 163 + 135 164 + 135 167 + 135 195 + 135 196 + 135 199 + 136 140 + 136 142 + 136 143 + 136 144 + 136 148 + 136 152 + 136 164 + 136 168 + 136 196 + 136 200 + 137 138 + 137 139 + 137 141 + 137 145 + 137 146 + 137 147 + 137 149 + 137 153 + 137 161 + 137 165 + 137 169 + 137 193 + 137 197 + 137 201 + 138 139 + 138 140 + 138 141 + 138 142 + 138 146 + 138 147 + 138 148 + 138 149 + 138 150 + 138 154 + 138 162 + 138 165 + 138 166 + 138 170 + 138 194 + 138 197 + 138 198 + 138 202 + 139 140 + 139 141 + 139 142 + 139 143 + 139 147 + 139 149 + 139 150 + 139 151 + 139 155 + 139 163 + 139 165 + 139 166 + 139 167 + 139 171 + 139 195 + 139 197 + 139 198 + 139 199 + 139 203 + 140 142 + 140 143 + 140 144 + 140 148 + 140 150 + 140 151 + 140 152 + 140 156 + 140 164 + 140 166 + 140 168 + 140 172 + 140 196 + 140 198 + 140 200 + 140 204 + 141 142 + 141 143 + 141 149 + 141 151 + 141 153 + 141 154 + 141 155 + 141 157 + 141 165 + 141 167 + 141 173 + 141 197 + 141 199 + 141 205 + 142 143 + 142 144 + 142 150 + 142 151 + 142 152 + 142 154 + 142 155 + 142 156 + 142 158 + 142 166 + 142 167 + 142 168 + 142 174 + 142 198 + 142 199 + 142 200 + 142 206 + 143 144 + 143 151 + 143 152 + 143 155 + 143 157 + 143 158 + 143 159 + 143 167 + 143 168 + 143 175 + 143 199 + 143 200 + 143 207 + 144 152 + 144 156 + 144 158 + 144 159 + 144 160 + 144 168 + 144 176 + 144 200 + 144 208 + 145 146 + 145 147 + 145 149 + 145 153 + 145 161 + 145 162 + 145 163 + 145 165 + 145 169 + 145 177 + 145 193 + 145 201 + 145 209 + 146 147 + 146 148 + 146 149 + 146 150 + 146 153 + 146 154 + 146 162 + 146 163 + 146 164 + 146 166 + 146 169 + 146 170 + 146 178 + 146 194 + 146 201 + 146 202 + 146 210 + 147 148 + 147 149 + 147 150 + 147 151 + 147 153 + 147 154 + 147 155 + 147 163 + 147 165 + 147 166 + 147 167 + 147 169 + 147 170 + 147 171 + 147 179 + 147 195 + 147 201 + 147 202 + 147 203 + 147 211 + 148 150 + 148 151 + 148 152 + 148 154 + 148 156 + 148 164 + 148 166 + 148 167 + 148 168 + 148 170 + 148 172 + 148 180 + 148 196 + 148 202 + 148 204 + 148 212 + 149 150 + 149 151 + 149 153 + 149 154 + 149 155 + 149 157 + 149 165 + 149 169 + 149 170 + 149 171 + 149 173 + 149 181 + 149 197 + 149 201 + 149 203 + 149 205 + 149 213 + 150 151 + 150 152 + 150 154 + 150 155 + 150 156 + 150 158 + 150 166 + 150 170 + 150 171 + 150 172 + 150 174 + 150 182 + 150 198 + 150 202 + 150 203 + 150 204 + 150 206 + 150 214 + 151 152 + 151 155 + 151 156 + 151 157 + 151 158 + 151 159 + 151 167 + 151 171 + 151 172 + 151 173 + 151 174 + 151 175 + 151 183 + 151 199 + 151 203 + 151 204 + 151 207 + 151 215 + 152 156 + 152 158 + 152 159 + 152 160 + 152 168 + 152 172 + 152 174 + 152 175 + 152 176 + 152 184 + 152 200 + 152 204 + 152 208 + 152 216 + 153 154 + 153 155 + 153 157 + 153 169 + 153 173 + 153 177 + 153 178 + 153 179 + 153 181 + 153 185 + 153 201 + 153 205 + 153 217 + 154 155 + 154 156 + 154 157 + 154 158 + 154 170 + 154 173 + 154 174 + 154 178 + 154 179 + 154 180 + 154 182 + 154 186 + 154 202 + 154 205 + 154 206 + 154 218 + 155 156 + 155 157 + 155 158 + 155 159 + 155 171 + 155 173 + 155 174 + 155 175 + 155 179 + 155 181 + 155 182 + 155 183 + 155 187 + 155 203 + 155 205 + 155 206 + 155 207 + 155 219 + 156 158 + 156 159 + 156 160 + 156 172 + 156 174 + 156 176 + 156 180 + 156 182 + 156 183 + 156 184 + 156 188 + 156 204 + 156 206 + 156 208 + 156 220 + 157 158 + 157 159 + 157 173 + 157 175 + 157 181 + 157 185 + 157 186 + 157 187 + 157 189 + 157 205 + 157 207 + 157 221 + 158 159 + 158 160 + 158 174 + 158 175 + 158 176 + 158 182 + 158 186 + 158 187 + 158 188 + 158 190 + 158 206 + 158 207 + 158 208 + 158 222 + 159 160 + 159 175 + 159 176 + 159 183 + 159 187 + 159 189 + 159 190 + 159 191 + 159 207 + 159 208 + 159 223 + 160 176 + 160 184 + 160 188 + 160 190 + 160 191 + 160 192 + 160 208 + 160 224 + 161 162 + 161 163 + 161 165 + 161 169 + 161 177 + 161 193 + 161 194 + 161 195 + 161 197 + 161 201 + 161 209 + 161 225 + 162 163 + 162 164 + 162 165 + 162 166 + 162 169 + 162 170 + 162 177 + 162 178 + 162 194 + 162 195 + 162 196 + 162 198 + 162 202 + 162 209 + 162 210 + 162 226 + 163 164 + 163 165 + 163 166 + 163 167 + 163 169 + 163 170 + 163 171 + 163 177 + 163 178 + 163 179 + 163 195 + 163 197 + 163 198 + 163 199 + 163 203 + 163 209 + 163 210 + 163 211 + 163 227 + 164 166 + 164 167 + 164 168 + 164 170 + 164 172 + 164 178 + 164 180 + 164 196 + 164 198 + 164 199 + 164 200 + 164 204 + 164 210 + 164 212 + 164 228 + 165 166 + 165 167 + 165 169 + 165 170 + 165 171 + 165 173 + 165 177 + 165 179 + 165 181 + 165 197 + 165 201 + 165 202 + 165 203 + 165 205 + 165 209 + 165 211 + 165 213 + 165 229 + 166 167 + 166 168 + 166 170 + 166 171 + 166 172 + 166 174 + 166 178 + 166 179 + 166 180 + 166 182 + 166 198 + 166 202 + 166 203 + 166 204 + 166 206 + 166 210 + 166 211 + 166 212 + 166 214 + 166 230 + 167 168 + 167 171 + 167 172 + 167 173 + 167 174 + 167 175 + 167 179 + 167 180 + 167 183 + 167 199 + 167 203 + 167 205 + 167 206 + 167 207 + 167 211 + 167 212 + 167 215 + 167 231 + 168 172 + 168 174 + 168 175 + 168 176 + 168 180 + 168 184 + 168 200 + 168 204 + 168 206 + 168 207 + 168 208 + 168 212 + 168 216 + 168 232 + 169 170 + 169 171 + 169 173 + 169 177 + 169 178 + 169 179 + 169 181 + 169 185 + 169 201 + 169 209 + 169 210 + 169 211 + 169 213 + 169 217 + 169 233 + 170 171 + 170 172 + 170 173 + 170 174 + 170 178 + 170 179 + 170 180 + 170 181 + 170 182 + 170 186 + 170 202 + 170 210 + 170 211 + 170 212 + 170 213 + 170 214 + 170 218 + 170 234 + 171 172 + 171 173 + 171 174 + 171 175 + 171 179 + 171 181 + 171 182 + 171 183 + 171 187 + 171 203 + 171 211 + 171 213 + 171 214 + 171 215 + 171 219 + 171 235 + 172 174 + 172 175 + 172 176 + 172 180 + 172 182 + 172 183 + 172 184 + 172 188 + 172 204 + 172 212 + 172 214 + 172 215 + 172 216 + 172 220 + 172 236 + 173 174 + 173 175 + 173 181 + 173 183 + 173 185 + 173 186 + 173 187 + 173 189 + 173 205 + 173 213 + 173 215 + 173 217 + 173 218 + 173 219 + 173 221 + 173 237 + 174 175 + 174 176 + 174 182 + 174 183 + 174 184 + 174 186 + 174 187 + 174 188 + 174 190 + 174 206 + 174 214 + 174 215 + 174 216 + 174 218 + 174 219 + 174 220 + 174 222 + 174 238 + 175 176 + 175 183 + 175 184 + 175 187 + 175 189 + 175 190 + 175 191 + 175 207 + 175 215 + 175 216 + 175 219 + 175 221 + 175 222 + 175 223 + 175 239 + 176 184 + 176 188 + 176 190 + 176 191 + 176 192 + 176 208 + 176 216 + 176 220 + 176 222 + 176 223 + 176 224 + 176 240 + 177 178 + 177 179 + 177 181 + 177 185 + 177 209 + 177 217 + 177 225 + 177 226 + 177 227 + 177 229 + 177 233 + 177 241 + 178 179 + 178 180 + 178 181 + 178 182 + 178 185 + 178 186 + 178 210 + 178 217 + 178 218 + 178 226 + 178 227 + 178 228 + 178 230 + 178 234 + 178 242 + 179 180 + 179 181 + 179 182 + 179 183 + 179 185 + 179 186 + 179 187 + 179 211 + 179 217 + 179 218 + 179 219 + 179 227 + 179 229 + 179 230 + 179 231 + 179 235 + 179 243 + 180 182 + 180 183 + 180 184 + 180 186 + 180 188 + 180 212 + 180 218 + 180 220 + 180 228 + 180 230 + 180 231 + 180 232 + 180 236 + 180 244 + 181 182 + 181 183 + 181 185 + 181 186 + 181 187 + 181 189 + 181 213 + 181 217 + 181 219 + 181 221 + 181 229 + 181 233 + 181 234 + 181 235 + 181 237 + 181 245 + 182 183 + 182 184 + 182 186 + 182 187 + 182 188 + 182 190 + 182 214 + 182 218 + 182 219 + 182 220 + 182 222 + 182 230 + 182 234 + 182 235 + 182 236 + 182 238 + 182 246 + 183 184 + 183 187 + 183 188 + 183 189 + 183 190 + 183 191 + 183 215 + 183 219 + 183 220 + 183 223 + 183 231 + 183 235 + 183 237 + 183 238 + 183 239 + 183 247 + 184 188 + 184 190 + 184 191 + 184 192 + 184 216 + 184 220 + 184 224 + 184 232 + 184 236 + 184 238 + 184 239 + 184 240 + 184 248 + 185 186 + 185 187 + 185 189 + 185 217 + 185 221 + 185 233 + 185 241 + 185 242 + 185 243 + 185 245 + 185 249 + 186 187 + 186 188 + 186 189 + 186 190 + 186 218 + 186 221 + 186 222 + 186 234 + 186 242 + 186 243 + 186 244 + 186 246 + 186 250 + 187 188 + 187 189 + 187 190 + 187 191 + 187 219 + 187 221 + 187 222 + 187 223 + 187 235 + 187 243 + 187 245 + 187 246 + 187 247 + 187 251 + 188 190 + 188 191 + 188 192 + 188 220 + 188 222 + 188 224 + 188 236 + 188 244 + 188 246 + 188 247 + 188 248 + 188 252 + 189 190 + 189 191 + 189 221 + 189 223 + 189 237 + 189 245 + 189 249 + 189 250 + 189 251 + 189 253 + 190 191 + 190 192 + 190 222 + 190 223 + 190 224 + 190 238 + 190 246 + 190 250 + 190 251 + 190 252 + 190 254 + 191 192 + 191 223 + 191 224 + 191 239 + 191 247 + 191 251 + 191 253 + 191 254 + 191 255 + 192 224 + 192 240 + 192 248 + 192 252 + 192 254 + 192 255 + 192 256 + 193 194 + 193 195 + 193 197 + 193 201 + 193 209 + 193 225 + 194 195 + 194 196 + 194 197 + 194 198 + 194 201 + 194 202 + 194 209 + 194 210 + 194 225 + 194 226 + 195 196 + 195 197 + 195 198 + 195 199 + 195 201 + 195 202 + 195 203 + 195 209 + 195 210 + 195 211 + 195 225 + 195 226 + 195 227 + 196 198 + 196 199 + 196 200 + 196 202 + 196 204 + 196 210 + 196 212 + 196 226 + 196 228 + 197 198 + 197 199 + 197 201 + 197 202 + 197 203 + 197 205 + 197 209 + 197 211 + 197 213 + 197 225 + 197 227 + 197 229 + 198 199 + 198 200 + 198 202 + 198 203 + 198 204 + 198 206 + 198 210 + 198 211 + 198 212 + 198 214 + 198 226 + 198 227 + 198 228 + 198 230 + 199 200 + 199 203 + 199 204 + 199 205 + 199 206 + 199 207 + 199 211 + 199 212 + 199 215 + 199 227 + 199 228 + 199 231 + 200 204 + 200 206 + 200 207 + 200 208 + 200 212 + 200 216 + 200 228 + 200 232 + 201 202 + 201 203 + 201 205 + 201 209 + 201 210 + 201 211 + 201 213 + 201 217 + 201 225 + 201 229 + 201 233 + 202 203 + 202 204 + 202 205 + 202 206 + 202 210 + 202 211 + 202 212 + 202 213 + 202 214 + 202 218 + 202 226 + 202 229 + 202 230 + 202 234 + 203 204 + 203 205 + 203 206 + 203 207 + 203 211 + 203 213 + 203 214 + 203 215 + 203 219 + 203 227 + 203 229 + 203 230 + 203 231 + 203 235 + 204 206 + 204 207 + 204 208 + 204 212 + 204 214 + 204 215 + 204 216 + 204 220 + 204 228 + 204 230 + 204 232 + 204 236 + 205 206 + 205 207 + 205 213 + 205 215 + 205 217 + 205 218 + 205 219 + 205 221 + 205 229 + 205 231 + 205 237 + 206 207 + 206 208 + 206 214 + 206 215 + 206 216 + 206 218 + 206 219 + 206 220 + 206 222 + 206 230 + 206 231 + 206 232 + 206 238 + 207 208 + 207 215 + 207 216 + 207 219 + 207 221 + 207 222 + 207 223 + 207 231 + 207 232 + 207 239 + 208 216 + 208 220 + 208 222 + 208 223 + 208 224 + 208 232 + 208 240 + 209 210 + 209 211 + 209 213 + 209 217 + 209 225 + 209 226 + 209 227 + 209 229 + 209 233 + 209 241 + 210 211 + 210 212 + 210 213 + 210 214 + 210 217 + 210 218 + 210 226 + 210 227 + 210 228 + 210 230 + 210 233 + 210 234 + 210 242 + 211 212 + 211 213 + 211 214 + 211 215 + 211 217 + 211 218 + 211 219 + 211 227 + 211 229 + 211 230 + 211 231 + 211 233 + 211 234 + 211 235 + 211 243 + 212 214 + 212 215 + 212 216 + 212 218 + 212 220 + 212 228 + 212 230 + 212 231 + 212 232 + 212 234 + 212 236 + 212 244 + 213 214 + 213 215 + 213 217 + 213 218 + 213 219 + 213 221 + 213 229 + 213 233 + 213 234 + 213 235 + 213 237 + 213 245 + 214 215 + 214 216 + 214 218 + 214 219 + 214 220 + 214 222 + 214 230 + 214 234 + 214 235 + 214 236 + 214 238 + 214 246 + 215 216 + 215 219 + 215 220 + 215 221 + 215 222 + 215 223 + 215 231 + 215 235 + 215 236 + 215 237 + 215 238 + 215 239 + 215 247 + 216 220 + 216 222 + 216 223 + 216 224 + 216 232 + 216 236 + 216 238 + 216 239 + 216 240 + 216 248 + 217 218 + 217 219 + 217 221 + 217 233 + 217 237 + 217 241 + 217 242 + 217 243 + 217 245 + 217 249 + 218 219 + 218 220 + 218 221 + 218 222 + 218 234 + 218 237 + 218 238 + 218 242 + 218 243 + 218 244 + 218 246 + 218 250 + 219 220 + 219 221 + 219 222 + 219 223 + 219 235 + 219 237 + 219 238 + 219 239 + 219 243 + 219 245 + 219 246 + 219 247 + 219 251 + 220 222 + 220 223 + 220 224 + 220 236 + 220 238 + 220 240 + 220 244 + 220 246 + 220 247 + 220 248 + 220 252 + 221 222 + 221 223 + 221 237 + 221 239 + 221 245 + 221 249 + 221 250 + 221 251 + 221 253 + 222 223 + 222 224 + 222 238 + 222 239 + 222 240 + 222 246 + 222 250 + 222 251 + 222 252 + 222 254 + 223 224 + 223 239 + 223 240 + 223 247 + 223 251 + 223 253 + 223 254 + 223 255 + 224 240 + 224 248 + 224 252 + 224 254 + 224 255 + 224 256 + 225 226 + 225 227 + 225 229 + 225 233 + 225 241 + 226 227 + 226 228 + 226 229 + 226 230 + 226 233 + 226 234 + 226 241 + 226 242 + 227 228 + 227 229 + 227 230 + 227 231 + 227 233 + 227 234 + 227 235 + 227 241 + 227 242 + 227 243 + 228 230 + 228 231 + 228 232 + 228 234 + 228 236 + 228 242 + 228 244 + 229 230 + 229 231 + 229 233 + 229 234 + 229 235 + 229 237 + 229 241 + 229 243 + 229 245 + 230 231 + 230 232 + 230 234 + 230 235 + 230 236 + 230 238 + 230 242 + 230 243 + 230 244 + 230 246 + 231 232 + 231 235 + 231 236 + 231 237 + 231 238 + 231 239 + 231 243 + 231 244 + 231 247 + 232 236 + 232 238 + 232 239 + 232 240 + 232 244 + 232 248 + 233 234 + 233 235 + 233 237 + 233 241 + 233 242 + 233 243 + 233 245 + 233 249 + 234 235 + 234 236 + 234 237 + 234 238 + 234 242 + 234 243 + 234 244 + 234 245 + 234 246 + 234 250 + 235 236 + 235 237 + 235 238 + 235 239 + 235 243 + 235 245 + 235 246 + 235 247 + 235 251 + 236 238 + 236 239 + 236 240 + 236 244 + 236 246 + 236 247 + 236 248 + 236 252 + 237 238 + 237 239 + 237 245 + 237 247 + 237 249 + 237 250 + 237 251 + 237 253 + 238 239 + 238 240 + 238 246 + 238 247 + 238 248 + 238 250 + 238 251 + 238 252 + 238 254 + 239 240 + 239 247 + 239 248 + 239 251 + 239 253 + 239 254 + 239 255 + 240 248 + 240 252 + 240 254 + 240 255 + 240 256 + 241 242 + 241 243 + 241 245 + 241 249 + 242 243 + 242 244 + 242 245 + 242 246 + 242 249 + 242 250 + 243 244 + 243 245 + 243 246 + 243 247 + 243 249 + 243 250 + 243 251 + 244 246 + 244 247 + 244 248 + 244 250 + 244 252 + 245 246 + 245 247 + 245 249 + 245 250 + 245 251 + 245 253 + 246 247 + 246 248 + 246 250 + 246 251 + 246 252 + 246 254 + 247 248 + 247 251 + 247 252 + 247 253 + 247 254 + 247 255 + 248 252 + 248 254 + 248 255 + 248 256 + 249 250 + 249 251 + 249 253 + 250 251 + 250 252 + 250 253 + 250 254 + 251 252 + 251 253 + 251 254 + 251 255 + 252 254 + 252 255 + 252 256 + 253 254 + 253 255 + 254 255 + 254 256 + 255 256 +; + +end; diff --git a/glpk-5.0/examples/money.mod b/glpk-5.0/examples/money.mod new file mode 100644 index 0000000..e43ef39 --- /dev/null +++ b/glpk-5.0/examples/money.mod @@ -0,0 +1,62 @@ +/* MONEY, a crypto-arithmetic puzzle */ + +/* Written in GNU MathProg by Andrew Makhorin <mao@gnu.org> */ + +/* This is the classic example of a crypto-arithmetic puzzle published + in the Strand Magazine by Henry Dudeney: + + S E N D + + + M O R E + --------- + M O N E Y + + In this puzzle the same letters mean the same digits. The question + is: how to replace all the letters with the respective digits that + makes the calculation correct? + + The solution to this puzzle is: + O = 0, M = 1, Y = 2, E = 5, N = 6, D = 7, R = 8, and S = 9. + + References: + H. E. Dudeney, in Strand Magazine vol. 68 (July 1924), pp. 97, 214. + + (From Wikipedia, the free encyclopedia.) */ + +set LETTERS := { 'D', 'E', 'M', 'N', 'O', 'R', 'S', 'Y' }; +/* set of letters */ + +set DIGITS := 0..9; +/* set of digits */ + +var x{i in LETTERS, d in DIGITS}, binary; +/* x[i,d] = 1 means that letter i is digit d */ + +s.t. one{i in LETTERS}: sum{d in DIGITS} x[i,d] = 1; +/* each letter must correspond exactly to one digit */ + +s.t. alldiff{d in DIGITS}: sum{i in LETTERS} x[i,d] <= 1; +/* different letters must correspond to different digits; note that + some digits may not correspond to any letters at all */ + +var dig{i in LETTERS}; +/* dig[i] is a digit corresponding to letter i */ + +s.t. map{i in LETTERS}: dig[i] = sum{d in DIGITS} d * x[i,d]; + +var carry{1..3}, binary; +/* carry bits */ + +s.t. sum1: dig['D'] + dig['E'] = dig['Y'] + 10 * carry[1]; +s.t. sum2: dig['N'] + dig['R'] + carry[1] = dig['E'] + 10 * carry[2]; +s.t. sum3: dig['E'] + dig['O'] + carry[2] = dig['N'] + 10 * carry[3]; +s.t. sum4: dig['S'] + dig['M'] + carry[3] = dig['O'] + 10 * dig['M']; +s.t. note: dig['M'] >= 1; /* M must not be 0 */ + +solve; +/* solve the puzzle */ + +display dig; +/* and display its solution */ + +end; diff --git a/glpk-5.0/examples/mplsamp1.c b/glpk-5.0/examples/mplsamp1.c new file mode 100644 index 0000000..7c5e47d --- /dev/null +++ b/glpk-5.0/examples/mplsamp1.c @@ -0,0 +1,32 @@ +/* mplsamp1.c */ + +#include <stdio.h> +#include <stdlib.h> +#include <glpk.h> + +int main(void) +{ glp_prob *lp; + glp_tran *tran; + int ret; + lp = glp_create_prob(); + tran = glp_mpl_alloc_wksp(); + ret = glp_mpl_read_model(tran, "egypt.mod", 0); + if (ret != 0) + { fprintf(stderr, "Error on translating model\n"); + goto skip; + } + ret = glp_mpl_generate(tran, NULL); + if (ret != 0) + { fprintf(stderr, "Error on generating model\n"); + goto skip; + } + glp_mpl_build_prob(tran, lp); + ret = glp_write_mps(lp, GLP_MPS_FILE, NULL, "egypt.mps"); + if (ret != 0) + fprintf(stderr, "Error on writing MPS file\n"); +skip: glp_mpl_free_wksp(tran); + glp_delete_prob(lp); + return 0; +} + +/* eof */ diff --git a/glpk-5.0/examples/mplsamp2.c b/glpk-5.0/examples/mplsamp2.c new file mode 100644 index 0000000..0ff6ad0 --- /dev/null +++ b/glpk-5.0/examples/mplsamp2.c @@ -0,0 +1,39 @@ +/* mplsamp2.c */ + +#include <stdio.h> +#include <stdlib.h> +#include <glpk.h> + +int main(void) +{ glp_prob *mip; + glp_tran *tran; + int ret; + mip = glp_create_prob(); + tran = glp_mpl_alloc_wksp(); + ret = glp_mpl_read_model(tran, "sudoku.mod", 1); + if (ret != 0) + { fprintf(stderr, "Error on translating model\n"); + goto skip; + } + ret = glp_mpl_read_data(tran, "sudoku.dat"); + if (ret != 0) + { fprintf(stderr, "Error on translating data\n"); + goto skip; + } + ret = glp_mpl_generate(tran, NULL); + if (ret != 0) + { fprintf(stderr, "Error on generating model\n"); + goto skip; + } + glp_mpl_build_prob(tran, mip); + glp_simplex(mip, NULL); + glp_intopt(mip, NULL); + ret = glp_mpl_postsolve(tran, mip, GLP_MIP); + if (ret != 0) + fprintf(stderr, "Error on postsolving model\n"); +skip: glp_mpl_free_wksp(tran); + glp_delete_prob(mip); + return 0; +} + +/* eof */ diff --git a/glpk-5.0/examples/murtagh.mps b/glpk-5.0/examples/murtagh.mps new file mode 100644 index 0000000..c03741b --- /dev/null +++ b/glpk-5.0/examples/murtagh.mps @@ -0,0 +1,600 @@ +*NAME: OIL +*ROWS: 74 +*COLUMNS: 81 +*NONZERO: 504 +*OPT SOLN: 126.057 +*SOURCE: Bruce Murtagh, "Advanced Linear Programming" +*APPLICATION: oil refinery model +*COMMENTS: problem is maximization +* +NAME OIL REFINERY EXAMPLE +ROWS + N PROFIT + L MVOLBOL + L MVOLCOL + E MVOLLNC + E MVOLLNB + E MVOLSRK + E MVOLSRD + E MVOLVBB + E MVOLVBC + E MVOLRCR + E MVOLHVO + E UBALKWH + E UBALH2O + E UBALSTM + E UBALFUL + E MVOLB95 + E MVOLB90 + E MVOLLHG + E MVOLC3S + E MVOLNC4 + E MVOLLSR + E MVOLHSR + E MVOLIC4 + L VCAPSGP + E MVOLRFG + E MSCFHYL + E MVOLR90 + E MVOLR95 + E MVOLF90 + E MVOLF95 + L VCAPRFG + E MVOLLCO + E MVOLHHG + E MVOLHCD + L VCAPHVO + L VCAPHOL + E MVOLC3U + E MVOLC4U + E MVOLFCG + E MVOLSLR + L VCAPCCU + E MVOLLA3 + E MVOLLA4 + L VCAPALK + L XLPRPRE + L XHPRPRE + L XTELPRE + L XRVPPRE + L X200PRE + L X230PRE + E EVOLPRE + L XPSCPRE + L XRSCREG + L XLPRINT + L XHPRINT + L XTELINT + L XRVPINT + L X200INT + L X230INT + E EVOLINT + L XLPRREG + L XHPRREG + L XTELREG + L XRVPREG + L X200REG + L X230REG + E EVOLREG + E EVOLLPG + E EVOLJP4 + L XRVXJP4 + L XRVNJP4 + E EVOLDSL + E EVOLRSD + L XVISRSD +COLUMNS + VCRDBOL MVOLBOL 1.0 + VCRDBOL MVOLLNB -.537 + VCRDBOL MVOLSRK -.131 + VCRDBOL MVOLSRD -.1155 + VCRDBOL MVOLVBB -.037 + VCRDBOL MVOLRCR -.0365 + VCRDBOL MVOLHVO -.143 + VCRDBOL UBALKWH .302 + VCRDBOL UBALH2O .150 + VCRDBOL UBALSTM .003 + VCRDBOL UBALFUL .0587 + VCRDBOL PROFIT -12.8 + VCRDCOL MVOLCOL 1. + VCRDCOL MVOLLNC -.2931 + VCRDCOL MVOLSRK -.1170 + VCRDCOL MVOLSRD -.0649 + VCRDCOL MVOLVBC -.18 + VCRDCOL MVOLRCR -.1233 + VCRDCOL MVOLHVO -.2217 + VCRDCOL UBALKWH .384 + VCRDCOL UBALH2O .185 + VCRDCOL UBALSTM .003 + VCRDCOL UBALFUL .1053 + VCRDCOL PROFIT -11.48 + VSGPLNC MVOLLNC 1. + VSGPLNC MVOLC3S -.0112 + VSGPLNC MVOLNC4 -.0378 + VSGPLNC MVOLLSR -.1502 + VSGPLNC MVOLHSR -.7953 + VSGPLNC MVOLIC4 -.0099 + VSGPLNC UBALKWH .721 + VSGPLNC UBALH2O .185 + VSGPLNC UBALSTM .013 + VSGPLNC UBALFUL .0488 + VSGPLNC VCAPSGP 1. + VSGPLNB MVOLLNB 1. + VSGPLNB MVOLC3S -.0277 + VSGPLNB MVOLNC4 -.0563 + VSGPLNB MVOLLSR -.199 + VSGPLNB MVOLHSR -.6873 + VSGPLNB MVOLIC4 -.017 + VSGPLNB UBALKWH .495 + VSGPLNB UBALH2O .209 + VSGPLNB UBALSTM .013 + VSGPLNB UBALFUL .0506 + VSGPLNB VCAPSGP 1. + VSGPLHG MVOLLHG 1.0 + VSGPLHG MVOLC3S -.175 + VSGPLHG MVOLNC4 -.27 + VSGPLHG MVOLLSR -.028 + VSGPLHG MVOLIC4 -.455 + VSGPLHG UBALKWH .495 + VSGPLHG UBALH2O .209 + VSGPLHG UBALSTM .013 + VSGPLHG UBALFUL .0448 + VSGPB95 MVOLB95 1. + VSGPB95 MVOLC3S -.2836 + VSGPB95 MVOLNC4 -.3285 + VSGPB95 MVOLLSR -.0241 + VSGPB95 MVOLIC4 -.2502 + VSGPB95 UBALKWH .495 + VSGPB95 UBALH2O .209 + VSGPB95 UBALSTM .013 + VSGPB95 UBALFUL .0506 + VSGPB90 MVOLB90 1. + VSGPB90 MVOLC3S -.271 + VSGPB90 MVOLNC4 -.3289 + VSGPB90 MVOLLSR -.0255 + VSGPB90 MVOLIC4 -.2656 + VSGPB90 UBALKWH .495 + VSGPB90 UBALH2O .209 + VSGPB90 UBALSTM .013 + VSGPB90 UBALFUL .0506 + VH2RHSR MVOLHSR 1. + VH2RHSR MVOLRFG -1. + VH2RHSR MSCFHYL .0327 + VH2RHSR UBALKWH .793 + VH2RHSR UBALH2O .045 + VH2RHSR UBALFUL .094 + VH2RHSR PROFIT -.0176 + VRFFRF1 MVOLRFG 1.0 + VRFFRF1 MVOLR90 -1.0 + VRFFRF2 MVOLRFG 1.0 + VRFFRF2 MVOLR95 -1.0 + VRFFHH1 MVOLR90 -1.0 + VRFFHH1 MVOLHHG 1.0 + VRFFHH2 MVOLR95 -1.0 + VRFFHH2 MVOLHHG 1.0 + VRFGR90 MVOLR90 1.0 + VRFGR90 MVOLB90 -.0404 + VRFGR90 MVOLF90 -0.8564 + VRFGR90 MSCFHYL -0.8239 + VRFGR90 UBALKWH .792 + VRFGR90 UBALH2O .297 + VRFGR90 UBALSTM 0.0063 + VRFGR90 UBALFUL -0.156 + VRFGR90 VCAPRFG 1.0 + VRFGR90 PROFIT -0.1512 + VRFGR95 MVOLR95 1.0 + VRFGR95 MVOLB95 -0.0588 + VRFGR95 MVOLF95 -0.8145 + VRFGR95 MSCFHYL -.7689 + VRFGR95 UBALKWH 1.03 + VRFGR95 UBALH2O .387 + VRFGR95 UBALSTM 0.008 + VRFGR95 UBALFUL -.2112 + VRFGR95 VCAPRFG 1.3 + VRFGR95 PROFIT -0.304 + VHOLLCO MVOLLCO 1.0 + VHOLLCO MVOLHHG -.6627 + VHOLLCO MVOLLHG -0.2414 + VHOLLCO MVOLHCD -.2930 + VHOLLCO MSCFHYL 2.3 + VHOLLCO UBALFUL -.2054 + VHOLLCO UBALH2O 0.826 + VHOLLCO UBALKWH 14.61 + VHOLLCO VCAPHOL 1.0 + VHOLLCO PROFIT -0.2112 + VHOLSRD MVOLSRD 1.0 + VHOLSRD MVOLHHG -.6627 + VHOLSRD MVOLLHG -0.2414 + VHOLSRD MVOLHCD -.2930 + VHOLSRD MSCFHYL 2.3 + VHOLSRD UBALFUL -.2054 + VHOLSRD UBALH2O 0.826 + VHOLSRD UBALKWH 14.61 + VHOLSRD VCAPHOL 1.0 + VHOLSRD PROFIT -0.2112 + VHOLRCR MVOLRCR 1.0 + VHOLRCR MVOLHHG -.5875 + VHOLRCR MVOLLHG -0.3321 + VHOLRCR MVOLHCD -.3620 + VHOLRCR MSCFHYL 2.3 + VHOLRCR UBALFUL -.2054 + VHOLRCR UBALH2O 0.826 + VHOLRCR UBALKWH 14.61 + VHOLRCR VCAPHOL 1.0 + VHOLRCR PROFIT -0.2112 + VHOLHVO MVOLHVO 1.0 + VHOLHVO MVOLHHG -.5875 + VHOLHVO MVOLLHG -0.3321 + VHOLHVO MVOLHCD -.3620 + VHOLHVO MSCFHYL 2.3 + VHOLHVO UBALFUL -.2054 + VHOLHVO UBALH2O 0.826 + VHOLHVO UBALKWH 14.61 + VHOLHVO VCAPHVO 1.0 + VHOLHVO VCAPHOL 1.0 + VHOLHVO PROFIT -0.2112 + VCCUSRK MVOLSRK 1.0 + VCCUSRK MVOLNC4 -0.0184 + VCCUSRK MVOLC3S -0.0303 + VCCUSRK MVOLIC4 -0.0564 + VCCUSRK MVOLC3U -0.0655 + VCCUSRK MVOLC4U -0.0780 + VCCUSRK MVOLFCG -0.4750 + VCCUSRK MVOLLCO -0.3050 + VCCUSRK UBALSTM -.0654 + VCCUSRK UBALFUL -.2703 + VCCUSRK UBALH2O .632 + VCCUSRK UBALKWH .6807 + VCCUSRK VCAPCCU 1. + VCCUSRK PROFIT -.2112 + VCCUSRD MVOLSRD 1. + VCCUSRD MVOLNC4 -.0184 + VCCUSRD MVOLC3S -.0303 + VCCUSRD MVOLIC4 -.0564 + VCCUSRD MVOLC3U -.0655 + VCCUSRD MVOLC4U -.0780 + VCCUSRD MVOLFCG -.4750 + VCCUSRD MVOLLCO -.3050 + VCCUSRD UBALSTM -.0654 + VCCUSRD UBALFUL -.2703 + VCCUSRD UBALH2O 0.632 + VCCUSRD UBALKWH .6807 + VCCUSRD VCAPCCU 1. + VCCUSRD PROFIT -.2112 + VCCURCR MVOLRCR 1.0 + VCCURCR MVOLNC4 -.0185 + VCCURCR MVOLC3S -.0328 + VCCURCR MVOLIC4 -.0568 + VCCURCR MVOLC3U -.0658 + VCCURCR MVOLC4U -.0806 + VCCURCR MVOLFCG -.4934 + VCCURCR MVOLLCO -.2922 + VCCURCR MVOLSLR -.0096 + VCCURCR UBALSTM -.0654 + VCCURCR UBALFUL -.2703 + VCCURCR UBALH2O 0.632 + VCCURCR UBALKWH .6807 + VCCURCR VCAPCCU 1. + VCCURCR PROFIT -.2112 + VCCUHVO MVOLHVO 1.0 + VCCUHVO MVOLNC4 -.0185 + VCCUHVO MVOLC3S -.0328 + VCCUHVO MVOLIC4 -.0568 + VCCUHVO MVOLC3U -.0658 + VCCUHVO MVOLC4U -.0806 + VCCUHVO MVOLFCG -.4934 + VCCUHVO MVOLLCO -.2922 + VCCUHVO MVOLSLR -.0096 + VCCUHVO UBALSTM -.0654 + VCCUHVO UBALFUL -.2703 + VCCUHVO UBALH2O 0.632 + VCCUHVO UBALKWH .6807 + VCCUHVO VCAPHVO 1. + VCCUHVO VCAPCCU 1. + VCCUHVO PROFIT -.2112 + VALKLA3 MVOLIC4 .7600 + VALKLA3 MVOLC3U .5714 + VALKLA3 MVOLLA3 -1.0 + VALKLA3 UBALSTM .1869 + VALKLA3 UBALFUL .2796 + VALKLA3 UBALH2O 2.241 + VALKLA3 UBALKWH 2.766 + VALKLA3 VCAPALK 1.0 + VALKLA3 PROFIT -.512 + VALKLA4 MVOLIC4 .6571 + VALKLA4 MVOLC4U .5714 + VALKLA4 MVOLC3S -.0571 + VALKLA4 MVOLNC4 -.0114 + VALKLA4 MVOLLA4 -1.0 + VALKLA4 UBALSTM .1724 + VALKLA4 UBALFUL .2579 + VALKLA4 UBALH2O 2.067 + VALKLA4 UBALKWH 2.552 + VALKLA4 VCAPALK 1.0 + VALKLA4 PROFIT -.472 + VALKIC4 MVOLIC4 1.0 + VALKIC4 MVOLNC4 -1.0 + VALKC3U MVOLC3U 1.0 + VALKC3U MVOLC3S -1.0 + VALKC4U MVOLC4U 1.0 + VALKC4U MVOLNC4 -1.0 + UTILC3S MVOLC3S 1. + UTILC3S UBALFUL -3.814 + UTILNC4 MVOLNC4 1. + UTILNC4 UBALFUL -4.316 + UTILIC4 MVOLIC4 1. + UTILIC4 UBALFUL -4.153 + UTILC3U MVOLC3U 1. + UTILC3U UBALFUL -3.808 + UTILC4U MVOLC4U 1. + UTILC4U UBALFUL -4.44 + UTILHYL MSCFHYL 1. + UTILHYL UBALFUL -.305 + UTILSTM UBALSTM -1. + UTILSTM UBALFUL 1.42 + UTILSTM PROFIT -.16 + PURCPC4 MVOLIC4 -.5 + PURCPC4 MVOLNC4 -.5 + PURCPC4 PROFIT -12. + PURCH2O UBALH2O -1. + PURCH2O PROFIT -.0528 + PURCKWH UBALKWH -1. + PURCKWH PROFIT -.04 + PURCFUL UBALFUL -1. + PURCFUL PROFIT -1.6 + PURCFLR UBALFUL 1. + BLPGC3S MVOLC3S 1.0 + BLPGC3S EVOLLPG -1.0 + BLPGNC4 MVOLNC4 1.0 + BLPGNC4 EVOLLPG -1.0 + SELLLPG EVOLLPG 1.0 + SELLLPG PROFIT 11.0 + BUP4LSR MVOLLSR 1.0 + BUP4LSR EVOLJP4 -1.0 + BUP4LSR XRVXJP4 14.0 + BUP4LSR XRVNJP4 -14.0 + BUP4HSR MVOLHSR 1.0 + BUP4HSR EVOLJP4 -1.0 + BUP4HSR XRVXJP4 0.8 + BUP4HSR XRVNJP4 -0.8 + SELLJP4 EVOLJP4 1.0 + SELLJP4 XRVXJP4 -3.0 + SELLJP4 XRVNJP4 2.0 + SELLJP4 PROFIT 16.8 + BDSLSRK MVOLSRK 1.0 + BDSLSRK EVOLDSL -1.0 + BDSLSRD MVOLSRD 1.0 + BDSLSRD EVOLDSL -1.0 + SELLDSL EVOLDSL 1.0 + SELLDSL PROFIT 14.4 + BPRELSR MVOLLSR 1. + BPRELSR XLPRPRE -7.95 + BPRELSR XHPRPRE -8.70 + BPRELSR XTELPRE -3.00 + BPRELSR XRVPPRE 14.00 + BPRELSR X200PRE 1. + BPRELSR X230PRE -1. + BPRELSR EVOLPRE -1. + BPREHCD MVOLHCD 1.0 + BPREHCD XLPRPRE -8.84 + BPREHCD XHPRPRE -9.45 + BPREHCD XTELPRE -3.00 + BPREHCD XRVPPRE 12.00 + BPREHCD X200PRE 1. + BPREHCD X230PRE -1. + BPREHCD EVOLPRE -1. + BPREF95 MVOLF95 1.0 + BPREF95 XLPRPRE -9.43 + BPREF95 XHPRPRE -9.57 + BPREF95 XTELPRE -3. + BPREF95 XRVPPRE 3.5 + BPREF95 X200PRE .233 + BPREF95 X230PRE -.358 + BPREF95 EVOLPRE -1. + BPREF90 MVOLF90 1.0 + BPREF90 XLPRPRE -9.03 + BPREF90 XHPRPRE -9.32 + BPREF90 XTELPRE -3.0 + BPREF90 XRVPPRE 3.5 + BPREF90 X200PRE .205 + BPREF90 X230PRE -.333 + BPREF90 EVOLPRE -1. + BPREFCG MVOLFCG 1.0 + BPREFCG XLPRPRE -9.23 + BPREFCG XHPRPRE -9.22 + BPREFCG XTELPRE -3. + BPREFCG XRVPPRE 6. + BPREFCG X200PRE .381 + BPREFCG X230PRE -.509 + BPREFCG EVOLPRE -1. + BPRELA3 MVOLLA3 1.0 + BPRELA3 XLPRPRE -9.4 + BPRELA3 XHPRPRE -9.85 + BPRELA3 XTELPRE -3.0 + BPRELA3 XRVPPRE 2.5 + BPRELA3 X200PRE 0.39 + BPRELA3 X230PRE -0.77 + BPRELA3 EVOLPRE -1.0 + BPRELA4 MVOLLA4 1.0 + BPRELA4 XLPRPRE -9.74 + BPRELA4 XHPRPRE -10.1 + BPRELA4 XTELPRE -3.0 + BPRELA4 XRVPPRE 3.3 + BPRELA4 X200PRE 0.233 + BPRELA4 X230PRE -0.58 + BPRELA4 EVOLPRE -1.0 + BPRENC4 MVOLNC4 1.0 + BPRENC4 XLPRPRE -9.74 + BPRENC4 XHPRPRE -9.9 + BPRENC4 XTELPRE -3.0 + BPRENC4 XRVPPRE 66.0 + BPRENC4 X200PRE 1.0 + BPRENC4 X230PRE -1.0 + BPRENC4 EVOLPRE -1.0 + BPRETEL XLPRPRE -0.493 + BPRETEL XHPRPRE -0.165 + BPRETEL XTELPRE 1.0 + BPRETEL PROFIT -0.3696 + SELLPRE XLPRPRE 10.03 + SELLPRE XHPRPRE 10.03 + SELLPRE XRVPPRE -9.5 + SELLPRE X200PRE -0.5 + SELLPRE X230PRE 0.5 + SELLPRE XPSCPRE 0.64 + SELLPRE XRSCREG 0.35 + SELLPRE EVOLPRE 1.0 + SELLPRE PROFIT 21.44 + BINTLSR MVOLLSR 1.0 + BINTLSR XLPRINT -7.98 + BINTLSR XHPRINT -8.58 + BINTLSR XTELINT -3.0 + BINTLSR XRVPINT 14.0 + BINTLSR X200INT 1.0 + BINTLSR X230INT -1.0 + BINTLSR EVOLINT -1.0 + BINTHCD MVOLHCD 1. + BINTHCD XLPRINT -8.87 + BINTHCD XHPRINT -9.33 + BINTHCD XTELINT -3.0 + BINTHCD XRVPINT 12.0 + BINTHCD X200INT 1.0 + BINTHCD X230INT -1. + BINTHCD EVOLINT -1.0 + BINTF95 MVOLF95 1. + BINTF95 XLPRINT -9.46 + BINTF95 XHPRINT -9.45 + BINTF95 XTELINT -3.0 + BINTF95 XRVPINT 3.5 + BINTF95 X200INT .233 + BINTF95 X230INT -.358 + BINTF95 EVOLINT -1.0 + BINTF90 MVOLF90 1. + BINTF90 XLPRINT -9.06 + BINTF90 XHPRINT -9.20 + BINTF90 XTELINT -3.0 + BINTF90 XRVPINT 3.5 + BINTF90 X200INT .205 + BINTF90 X230INT -.333 + BINTF90 EVOLINT -1.0 + BINTFCG MVOLFCG 1. + BINTFCG XLPRINT -9.26 + BINTFCG XHPRINT -9.13 + BINTFCG XTELINT -3.0 + BINTFCG XRVPINT 6. + BINTFCG X200INT .318 + BINTFCG X230INT -.509 + BINTFCG EVOLINT -1.0 + BINTNC4 MVOLNC4 1. + BINTNC4 XLPRINT -9.77 + BINTNC4 XHPRINT -9.78 + BINTNC4 XTELINT -3.0 + BINTNC4 XRVPINT 66. + BINTNC4 X200INT 1.0 + BINTNC4 X230INT -1. + BINTNC4 EVOLINT -1.0 + BINTTEL XLPRINT -.435 + BINTTEL XHPRINT -.208 + BINTTEL XTELINT 1. + BINTTEL PROFIT -.3696 + SELLINT XLPRINT 9.65 + SELLINT XHPRINT 9.65 + SELLINT XRVPINT -9.5 + SELLINT X200INT -0.5 + SELLINT X230INT 0.5 + SELLINT XPSCPRE -.36 + SELLINT XRSCREG 0.35 + SELLINT EVOLINT 1.0 + SELLINT PROFIT 20.32 + BREGLSR MVOLLSR 1.0 + BREGLSR XLPRREG -7.99 + BREGLSR XHPRREG -8.59 + BREGLSR XTELREG -3.0 + BREGLSR XRVPREG 14.0 + BREGLSR X200REG 1.0 + BREGLSR X230REG -1.0 + BREGLSR EVOLREG -1.0 + BREGHCD MVOLHCD 1.0 + BREGHCD XLPRREG -8.88 + BREGHCD XHPRREG -9.34 + BREGHCD XTELREG -3.0 + BREGHCD XRVPREG 12.0 + BREGHCD X200REG 1.0 + BREGHCD X230REG -1.0 + BREGHCD EVOLREG -1.0 + BREGF95 MVOLF95 1.0 + BREGF95 XLPRREG -9.47 + BREGF95 XHPRREG -9.46 + BREGF95 XTELREG -3.0 + BREGF95 XRVPREG 3.5 + BREGF95 X200REG .233 + BREGF95 X230REG -0.358 + BREGF95 EVOLREG -1.0 + BREGF90 MVOLF90 1.0 + BREGF90 XLPRREG -9.07 + BREGF90 XHPRREG -9.21 + BREGF90 XTELREG -3.0 + BREGF90 XRVPREG 3.5 + BREGF90 X200REG .205 + BREGF90 X230REG -0.333 + BREGF90 EVOLREG -1.0 + BREGFCG MVOLFCG 1.0 + BREGFCG XLPRREG -9.27 + BREGFCG XHPRREG -9.14 + BREGFCG XTELREG -3.0 + BREGFCG XRVPREG 6.0 + BREGFCG X200REG 0.318 + BREGFCG X230REG -0.509 + BREGFCG EVOLREG -1.0 + BREGNC4 MVOLNC4 1.0 + BREGNC4 XLPRREG -9.78 + BREGNC4 XHPRREG -9.79 + BREGNC4 XTELREG -3.0 + BREGNC4 XRVPREG 66.0 + BREGNC4 X200REG 1.0 + BREGNC4 X230REG -1.0 + BREGNC4 EVOLREG -1.0 + BREGTEL XLPRREG -0.426 + BREGTEL XHPRREG -.204 + BREGTEL XTELREG 1.0 + BREGTEL PROFIT -0.3696 + SELLREG XLPRREG 9.05 + SELLREG XHPRREG 9.05 + SELLREG XRVPREG -9.5 + SELLREG X200REG -0.5 + SELLREG X230REG 0.5 + SELLREG XPSCPRE -0.36 + SELLREG XRSCREG -0.65 + SELLREG EVOLREG 1.0 + SELLREG PROFIT 18.04 + BRSDVBB MVOLVBB 1.0 + BRSDVBB EVOLRSD -1.0 + BRSDVBB XVISRSD 10.1 + BRSDVBC MVOLVBC 1.0 + BRSDVBC EVOLRSD -1.0 + BRSDVBC XVISRSD 12.63 + BRSDRCR MVOLRCR 1.0 + BRSDRCR EVOLRSD -1.0 + BRSDRCR XVISRSD 6.9 + BRSDHVO MVOLHVO 1.0 + BRSDHVO EVOLRSD -1.0 + BRSDHVO XVISRSD 8.05 + BRSDHVO VCAPHVO 1.0 + BRSDSLR MVOLSLR 1.0 + BRSDSLR EVOLRSD -1.0 + BRSDSLR XVISRSD 8.05 + BRSDLCO MVOLLCO 1.0 + BRSDLCO EVOLRSD -1.0 + BRSDLCO XVISRSD 4.4 + SELLRSD EVOLRSD 1.0 + SELLRSD XVISRSD -10.1 + SELLRSD PROFIT 8.00 +RHS + LIMITMAX MVOLBOL 26.316 + LIMITMAX MVOLCOL 21.052 + LIMITMAX VCAPSGP 23.25 + LIMITMAX VCAPHVO 5.25 + LIMITMAX VCAPRFG 13.455 + LIMITMAX VCAPHOL 3.87 + LIMITMAX VCAPCCU 7.26 + LIMITMAX VCAPALK 10. +ENDATA diff --git a/glpk-5.0/examples/mvcp.mod b/glpk-5.0/examples/mvcp.mod new file mode 100644 index 0000000..e016bda --- /dev/null +++ b/glpk-5.0/examples/mvcp.mod @@ -0,0 +1,43 @@ +/* MVCP, Minimum Vertex Cover Problem */ + +/* Written in GNU MathProg by Andrew Makhorin <mao@gnu.org> */ + +/* The Minimum Vertex Cover Problem in a network G = (V, E), where V + is a set of nodes, E is a set of arcs, is to find a subset V' within + V such that each edge (i,j) in E has at least one its endpoint in V' + and which minimizes the sum of node weights w(i) over V'. + + Reference: + Garey, M.R., and Johnson, D.S. (1979), Computers and Intractability: + A guide to the theory of NP-completeness [Graph Theory, Covering and + Partitioning, Minimum Vertex Cover, GT1]. */ + +set E, dimen 2; +/* set of edges */ + +set V := (setof{(i,j) in E} i) union (setof{(i,j) in E} j); +/* set of nodes */ + +param w{i in V}, >= 0, default 1; +/* w[i] is weight of vertex i */ + +var x{i in V}, binary; +/* x[i] = 1 means that node i is included into V' */ + +s.t. cov{(i,j) in E}: x[i] + x[j] >= 1; +/* each edge (i,j) must have node i or j (or both) in V' */ + +minimize z: sum{i in V} w[i] * x[i]; +/* we need to minimize the sum of node weights over V' */ + +data; + +/* These data correspond to an example from [Papadimitriou]. */ + +/* Optimal solution is 6 (greedy heuristic gives 13) */ + +set E := a1 b1, b1 c1, a1 b2, b2 c2, a2 b3, b3 c3, a2 b4, b4 c4, a3 b5, + b5 c5, a3 b6, b6 c6, a4 b1, a4 b2, a4 b3, a5 b4, a5 b5, a5 b6, + a6 b1, a6 b2, a6 b3, a6 b4, a7 b2, a7 b3, a7 b4, a7 b5, a7 b6; + +end; diff --git a/glpk-5.0/examples/netgen.c b/glpk-5.0/examples/netgen.c new file mode 100644 index 0000000..eebb2c8 --- /dev/null +++ b/glpk-5.0/examples/netgen.c @@ -0,0 +1,141 @@ +/* netgen.c */ + +/* This main program generates 50 original NETGEN instances of the + minimum cost flow problem and writes them in DIMACS format to the + current directory. */ + +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <glpk.h> + +static int parm[50][15] = +{ {13502460, 101, + 5000, 2500, 2500, 25000, 1, 100, 250000, 0, 0, 0, 100, 1, 1000, + },{4281922, 102, + 5000, 2500, 2500, 25000, 1, 100, 2500000, 0, 0, 0, 100, 1, 1000, + },{44820113, 103, + 5000, 2500, 2500, 25000, 1, 100, 6250000, 0, 0, 0, 100, 1, 1000, + },{13450451, 104, + 5000, 2500, 2500, 25000, -100, -1, 250000, 0, 0, 0, 100, 1, 1000, + },{14719436, 105, + 5000, 2500, 2500, 25000, 101, 200, 250000, 0, 0, 0, 100, 1, 1000, + },{17365786, 106, + 5000, 2500, 2500, 12500, 1, 100, 125000, 0, 0, 0, 100, 1, 1000, + },{19540113, 107, + 5000, 2500, 2500, 37500, 1, 100, 375000, 0, 0, 0, 100, 1, 1000, + },{19560313, 108, + 5000, 2500, 2500, 50000, 1, 100, 500000, 0, 0, 0, 100, 1, 1000, + },{2403509, 109, + 5000, 2500, 2500, 75000, 1, 100, 750000, 0, 0, 0, 100, 1, 1000, + },{92480414, 110, + 5000, 2500, 2500, 12500, 1, 100, 250000, 0, 0, 0, 100, 1, 1000, + },{4230140, 111, + 5000, 2500, 2500, 37500, 1, 100, 250000, 0, 0, 0, 100, 1, 1000, + },{10032490, 112, + 5000, 2500, 2500, 50000, 1, 100, 250000, 0, 0, 0, 100, 1, 1000, + },{17307474, 113, + 5000, 2500, 2500, 75000, 1, 100, 250000, 0, 0, 0, 100, 1, 1000, + },{4925114, 114, + 5000, 500, 4500, 25000, 1, 100, 250000, 0, 0, 0, 100, 1, 1000, + },{19842704, 115, + 5000, 1500, 3500, 25000, 1, 100, 250000, 0, 0, 0, 100, 1, 1000, + },{88392060, 116, + 5000, 2500, 2500, 25000, 1, 100, 250000, 0, 0, 0, 0, 1, 1000, + },{12904407, 117, + 5000, 2500, 2500, 12500, 1, 100, 125000, 0, 0, 0, 0, 1, 1000, + },{11811811, 118, + 5000, 2500, 2500, 37500, 1, 100, 375000, 0, 0, 0, 0, 1, 1000, + },{90023593, 119, + 5000, 2500, 2500, 50000, 1, 100, 500000, 0, 0, 0, 0, 1, 1000, + },{93028922, 120, + 5000, 2500, 2500, 75000, 1, 100, 750000, 0, 0, 0, 0, 1, 1000, + },{72707401, 121, + 5000, 50, 50, 25000, 1, 100, 250000, 50, 50, 0, 100, 1, 1000, + },{93040771, 122, + 5000, 250, 250, 25000, 1, 100, 250000, 250, 250, 0, 100, 1, 1000, + },{70220611, 123, + 5000, 500, 500, 25000, 1, 100, 250000, 500, 500, 0, 100, 1, 1000, + },{52774811, 124, + 5000, 1000, 1000, 25000, 1, 100, 250000, 1000, 1000, 0, 100, 1, + 1000, + },{22492311, 125, + 5000, 1500, 1500, 25000, 1, 100, 250000, 1500, 1500, 0, 100, 1, + 1000, + },{35269337, 126, + 5000, 500, 500, 12500, 1, 100, 125000, 500, 500, 0, 100, 1, 1000, + },{30140502, 127, + 5000, 500, 500, 37500, 1, 100, 375000, 500, 500, 0, 100, 1, 1000, + },{49205455, 128, + 5000, 500, 500, 50000, 1, 100, 500000, 500, 500, 0, 100, 1, 1000, + },{42958341, 129, + 5000, 500, 500, 75000, 1, 100, 750000, 500, 500, 0, 100, 1, 1000, + },{25440925, 130, + 5000, 500, 500, 12500, 1, 100, 250000, 500, 500, 0, 100, 1, 1000, + },{75294924, 131, + 5000, 500, 500, 37500, 1, 100, 250000, 500, 500, 0, 100, 1, 1000, + },{4463965, 132, + 5000, 500, 500, 50000, 1, 100, 250000, 500, 500, 0, 100, 1, 1000, + },{13390427, 133, + 5000, 500, 500, 75000, 1, 100, 250000, 500, 500, 0, 100, 1, 1000, + },{95250971, 134, + 1000, 500, 500, 25000, 1, 100, 250000, 500, 500, 0, 100, 1, 1000, + },{54830522, 135, + 2500, 500, 500, 25000, 1, 100, 250000, 500, 500, 0, 100, 1, 1000, + },{520593, 136, + 7500, 500, 500, 25000, 1, 100, 250000, 500, 500, 0, 100, 1, 1000, + },{52900925, 137, + 10000, 500, 500, 25000, 1, 100, 250000, 500, 500, 0, 100, 1, 1000, + },{22603395, 138, + 5000, 500, 500, 25000, 1, 100, 250000, 500, 500, 0, 100, 1, 50, + },{55253099, 139, + 5000, 500, 500, 25000, 1, 100, 250000, 500, 500, 0, 100, 1, 250, + },{75357001, 140, + 5000, 500, 500, 25000, 1, 100, 250000, 500, 500, 0, 100, 1, 500, + },{10072459, 141, + 5000, 500, 500, 25000, 1, 100, 250000, 500, 500, 0, 100, 1, 2500, + },{55728492, 142, + 5000, 500, 500, 25000, 1, 100, 250000, 500, 500, 0, 100, 1, 5000, + },{593043, 143, + 5000, 500, 500, 25000, 1, 100, 250000, 500, 500, 0, 0, 1, 1000, + },{94236572, 144, + 5000, 500, 500, 25000, 1, 10, 250000, 500, 500, 0, 100, 1, 1000, + },{94882955, 145, + 5000, 500, 500, 25000, 1, 1000, 250000, 500, 500, 0, 100, 1, 1000, + },{48489922, 146, + 5000, 500, 500, 25000, 1, 10000, 250000, 500, 500, 0, 100, 1, + 1000, + },{75578374, 147, + 5000, 500, 500, 25000, -100, -1, 250000, 500, 500, 0, 100, 1, + 1000, + },{44821152, 148, + 5000, 500, 500, 25000, -50, 49, 250000, 500, 500, 0, 100, 1, 1000, + },{45224103, 149, + 5000, 500, 500, 25000, 101, 200, 250000, 500, 500, 0, 100, 1, + 1000, + },{63491741, 150, + 5000, 500, 500, 25000, 1001, 1100, 250000, 500, 500, 0, 100, 1, + 1000, + } +}; + +typedef struct { double rhs; } v_data; +typedef struct { double cap, cost; } a_data; + +int main(void) +{ glp_graph *G; + int k; + char fname[100+1]; + G = glp_create_graph(sizeof(v_data), sizeof(a_data)); + for (k = 1; k <= 50; k++) + { sprintf(fname, "netgn%03d.min", parm[k-1][1]); + glp_netgen(G, offsetof(v_data, rhs), offsetof(a_data, cap), + offsetof(a_data, cost), &parm[k-1][-1]); + glp_write_mincost(G, offsetof(v_data, rhs), -1, + offsetof(a_data, cap), offsetof(a_data, cost), fname); + } + glp_delete_graph(G); + return 0; +} + +/* eof */ diff --git a/glpk-5.0/examples/nppsamp.c b/glpk-5.0/examples/nppsamp.c new file mode 100644 index 0000000..65f0e69 --- /dev/null +++ b/glpk-5.0/examples/nppsamp.c @@ -0,0 +1,48 @@ +/* nppsamp.c */ + +#include <stdio.h> +#include <stdlib.h> +#include <glpk.h> + +int main(void) +{ glp_prep *prep; + glp_prob *P, *Q; + int ret; + prep = glp_npp_alloc_wksp(); + P = glp_create_prob(); + ret = glp_read_mps(P, GLP_MPS_DECK, NULL, "murtagh.mps"); + if (ret != 0) + { printf("Error on reading problem data\n"); + goto skip; + } + glp_set_obj_dir(P, GLP_MAX); + glp_npp_load_prob(prep, P, GLP_SOL, GLP_ON); + ret = glp_npp_preprocess1(prep, 0); + switch (ret) + { case 0: + break; + case GLP_ENOPFS: + printf("LP has no primal feasible solution\n"); + goto skip; + case GLP_ENODFS: + printf("LP has no dual feasible solution\n"); + goto skip; + default: + glp_assert(ret != ret); + } + Q = glp_create_prob(); + glp_npp_build_prob(prep, Q); + ret = glp_simplex(Q, NULL); + if (ret == 0 && glp_get_status(Q) == GLP_OPT) + { glp_npp_postprocess(prep, Q); + glp_npp_obtain_sol(prep, P); + } + else + printf("Unable to recover non-optimal solution\n"); + glp_delete_prob(Q); +skip: glp_npp_free_wksp(prep); + glp_delete_prob(P); + return 0; +} + +/* eof */ diff --git a/glpk-5.0/examples/numbrix.mod b/glpk-5.0/examples/numbrix.mod new file mode 100644 index 0000000..b36fbfd --- /dev/null +++ b/glpk-5.0/examples/numbrix.mod @@ -0,0 +1,84 @@ +/* Numbrix, Number Placement Puzzle */ + +/* Written in GNU MathProg by Robert Wood <rwood@targus.com> */ + +/* Numbrix is a logic-based number-placement puzzle.[1] + * The objective is to fill the grid so that each cell contains + * digits in sequential order taking a horizontal or vertical + * path; diagonal paths are not allowed. The puzzle setter + * provides a grid often with the outer most cells completed. + * + * Completed Numbrix puzzles are usually a square of numbers + * in order from 1 to 64 (8x8 grid) or from 1 to 81 (9x9 grid), + * following a continuous path in sequence. + * + * The modern puzzle was invented by Marilyn vos Savant in 2008 + * and published by Parade Magazine under the name "Numbrix", + * near her weekly Ask Marilyn article. + * + * http://en.wikipedia.org/wiki/Numbrix */ + +set I := {1..9}; +set J := {1..9}; +set VALS := {1..81}; + +param givens{I, J}, integer, >= 0, <= 81, default 0; +/* the "givens" */ + +param neighbors{i in I,j in J, i2 in I, j2 in J} , binary := +(if abs(i - i2) + abs(j -j2) == 1 then + 1 + else + 0 +); +/* defines which spots are the boards are neighbors */ + +var x{i in I, j in J, k in VALS}, binary; +/* x[i,j,k] = 1 means cell [i,j] is assigned number k */ + +s.t. fa{i in I, j in J, k in VALS: givens[i,j] != 0}: + x[i,j,k] = (if givens[i,j] = k then 1 else 0); +/* assign pre-defined numbers using the "givens" */ + +s.t. fb{i in I, j in J}: sum{k in VALS} x[i,j,k] = 1; +/* each cell must be assigned exactly one number */ + +s.t. singleNum {k in VALS}: sum{i in I, j in J} x[i,j,k] = 1; +/* a value can only occur once */ + +s.t. neighborContraint {i in I, j in J, k in 1..80}: + x[i,j,k] <= sum{i2 in I, j2 in J} x[i2,j2,k+1] * neighbors[i,j,i2,j2]; +/* each cell must have a neighbor with the next higher value */ + + +/* there is no need for an objective function here */ + + +solve; + +for {i in I} +{ for {0..0: i = 1 or i = 4 or i = 7} + printf " +----------+----------+----------+\n"; + for {j in J} + { for {0..0: j = 1 or j = 4 or j = 7} printf(" |"); + printf " %2d", sum{k in VALS} x[i,j,k] * k; + for {0..0: j = 9} printf(" |\n"); + } + for {0..0: i = 9} + printf " +----------+----------+----------+\n"; +} + +data; + +param givens : 1 2 3 4 5 6 7 8 9 := + 1 . . . . . . . . . + 2 . 11 12 15 18 21 62 61 . + 3 . 6 . . . . . 60 . + 4 . 33 . . . . . 57 . + 5 . 32 . . . . . 56 . + 6 . 37 . . . . . 73 . + 7 . 38 . . . . . 72 . + 8 . 43 44 47 48 51 76 77 . + 9 . . . . . . . . . ; + +end; diff --git a/glpk-5.0/examples/oldapi/README b/glpk-5.0/examples/oldapi/README new file mode 100644 index 0000000..e52ee2c --- /dev/null +++ b/glpk-5.0/examples/oldapi/README @@ -0,0 +1,11 @@ +The program module in this subdirectory contains an implementation of +the old GLPK API as it was defined in GLPK 4.48. + +To compile an existing project using the old GLPK API you need to add +to the project two files lpx.h and lpx.c. + +Please note that you may mix calls to old and new GLPK API routines in +the same project (except calls to glp_create_prob and glp_delete_prob). + +The file lpxsamp.c is an example that illustrates using the old GLPK +API routines. diff --git a/glpk-5.0/examples/oldapi/lpx.c b/glpk-5.0/examples/oldapi/lpx.c new file mode 100644 index 0000000..c508306 --- /dev/null +++ b/glpk-5.0/examples/oldapi/lpx.c @@ -0,0 +1,1505 @@ +/* lpx.c (old GLPK API) */ + +/* Written by Andrew Makhorin <mao@gnu.org>, August 2013. */ + +/* This file contains routines that implement the old GLPK API as it +* was defined in GLPK 4.48. +* +* To compile an existing project using these routines you need to add +* to the project this file and the header lpx.h. +* +* Please note that you may mix calls to old and new GLPK API routines +* (except calls to glp_create_prob and glp_delete_prob). */ + +#include <float.h> +#include <limits.h> +#include "lpx.h" + +#define xassert glp_assert +#define xerror glp_error + +struct CPS +{ /* control parameters */ + LPX *lp; + /* pointer to corresponding problem object */ + 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) */ + int scale; + /* scaling option: + 0 - no scaling + 1 - equilibration scaling + 2 - geometric mean scaling + 3 - geometric mean scaling, then equilibration scaling */ + int dual; + /* dual simplex option: + 0 - use primal simplex + 1 - use dual simplex */ + int price; + /* pricing option (for both primal and dual simplex): + 0 - textbook pricing + 1 - steepest edge pricing */ + double relax; + /* relaxation parameter used in the ratio test; if it is zero, + the textbook ratio test is used; if it is non-zero (should be + positive), Harris' two-pass ratio test is used; in the latter + case on the first pass basic variables (in the case of primal + simplex) or reduced costs of non-basic variables (in the case + of dual simplex) are allowed to slightly violate their bounds, + but not more than (relax * tol_bnd) or (relax * tol_dj) (thus, + relax is a percentage of tol_bnd or tol_dj) */ + double tol_bnd; + /* relative tolerance used to check if the current basic solution + is primal feasible */ + double tol_dj; + /* absolute tolerance used to check if the current basic solution + is dual feasible */ + double tol_piv; + /* relative tolerance used to choose eligible pivotal elements of + the simplex table in the ratio test */ + int round; + /* solution rounding option: + 0 - report all computed values and reduced costs "as is" + 1 - if possible (allowed by the tolerances), replace computed + values and reduced costs which are close to zero by exact + zeros */ + double obj_ll; + /* lower limit of the objective function; if on the phase II the + objective function reaches this limit and continues decreasing, + the solver stops the search */ + double obj_ul; + /* upper limit of the objective function; if on the phase II the + objective function reaches this limit and continues increasing, + the solver stops the search */ + 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 */ + double tm_lim; + /* searching time limit, in seconds; if this value is positive, + it is decreased each time when one simplex iteration has been + performed by the amount of time spent for the iteration, and + reaching zero value signals the solver to stop the search; + negative value means no time limit */ + int out_frq; + /* output frequency, in iterations; this parameter specifies how + frequently the solver sends information about the solution to + the standard output */ + double out_dly; + /* output delay, in seconds; this parameter specifies how long + the solver should delay sending information about the solution + to the standard output; zero value means no delay */ + int branch; /* MIP */ + /* branching heuristic: + 0 - branch on first variable + 1 - branch on last variable + 2 - branch using heuristic by Driebeck and Tomlin + 3 - branch on most fractional variable */ + int btrack; /* MIP */ + /* backtracking heuristic: + 0 - select most recent node (depth first search) + 1 - select earliest node (breadth first search) + 2 - select node using the best projection heuristic + 3 - select node with best local bound */ + double tol_int; /* MIP */ + /* absolute tolerance used to check if the current basic solution + is integer feasible */ + double tol_obj; /* MIP */ + /* relative tolerance used to check if the value of the objective + function is not better than in the best known integer feasible + solution */ + int mps_info; /* lpx_write_mps */ + /* if this flag is set, the routine lpx_write_mps outputs several + comment cards that contains some information about the problem; + otherwise the routine outputs no comment cards */ + int mps_obj; /* lpx_write_mps */ + /* this parameter tells the routine lpx_write_mps how to output + the objective function row: + 0 - never output objective function row + 1 - always output objective function row + 2 - output objective function row if and only if the problem + has no free rows */ + int mps_orig; /* lpx_write_mps */ + /* if this flag is set, the routine lpx_write_mps uses original + row and column symbolic names; otherwise the routine generates + plain names using ordinal numbers of rows and columns */ + int mps_wide; /* lpx_write_mps */ + /* if this flag is set, the routine lpx_write_mps uses all data + fields; otherwise the routine keeps fields 5 and 6 empty */ + int mps_free; /* lpx_write_mps */ + /* if this flag is set, the routine lpx_write_mps omits column + and vector names everytime if possible (free style); otherwise + the routine never omits these names (pedantic style) */ + int mps_skip; /* lpx_write_mps */ + /* if this flag is set, the routine lpx_write_mps skips empty + columns (i.e. which has no constraint coefficients); otherwise + the routine outputs all columns */ + int lpt_orig; /* lpx_write_lpt */ + /* if this flag is set, the routine lpx_write_lpt uses original + row and column symbolic names; otherwise the routine generates + plain names using ordinal numbers of rows and columns */ + int presol; /* lpx_simplex */ + /* LP presolver option: + 0 - do not use LP presolver + 1 - use LP presolver */ + int binarize; /* lpx_intopt */ + /* if this flag is set, the routine lpx_intopt replaces integer + columns by binary ones */ + int use_cuts; /* lpx_intopt */ + /* if this flag is set, the routine lpx_intopt tries generating + cutting planes: + LPX_C_COVER - mixed cover cuts + LPX_C_CLIQUE - clique cuts + LPX_C_GOMORY - Gomory's mixed integer cuts + LPX_C_ALL - all cuts */ + double mip_gap; /* MIP */ + /* relative MIP gap tolerance */ + struct CPS *link; + /* pointer to CPS for another problem object */ +}; + +static struct CPS *cps_ptr = NULL; +/* initial pointer to CPS linked list */ + +static struct CPS *find_cps(LPX *lp) +{ /* find CPS for specified problem object */ + struct CPS *cps; + for (cps = cps_ptr; cps != NULL; cps = cps->link) + if (cps->lp == lp) break; + /* if cps is NULL (not found), the problem object was created + with glp_create_prob rather than with lpx_create_prob */ + xassert(cps != NULL); + return cps; +} + +static void reset_cps(struct CPS *cps) +{ /* reset control parameters to default values */ + cps->msg_lev = 3; + cps->scale = 1; + cps->dual = 0; + cps->price = 1; + cps->relax = 0.07; + cps->tol_bnd = 1e-7; + cps->tol_dj = 1e-7; + cps->tol_piv = 1e-9; + cps->round = 0; + cps->obj_ll = -DBL_MAX; + cps->obj_ul = +DBL_MAX; + cps->it_lim = -1; + cps->tm_lim = -1.0; + cps->out_frq = 200; + cps->out_dly = 0.0; + cps->branch = 2; + cps->btrack = 3; + cps->tol_int = 1e-5; + cps->tol_obj = 1e-7; + cps->mps_info = 1; + cps->mps_obj = 2; + cps->mps_orig = 0; + cps->mps_wide = 1; + cps->mps_free = 0; + cps->mps_skip = 0; + cps->lpt_orig = 0; + cps->presol = 0; + cps->binarize = 0; + cps->use_cuts = 0; + cps->mip_gap = 0.0; + return; +} + +LPX *lpx_create_prob(void) +{ /* create problem object */ + LPX *lp; + struct CPS *cps; + lp = glp_create_prob(); + cps = glp_alloc(1, sizeof(struct CPS)); + cps->lp = lp; + reset_cps(cps); + cps->link = cps_ptr; + cps_ptr = cps; + return lp; +} + +void lpx_set_prob_name(LPX *lp, const char *name) +{ /* assign (change) problem name */ + glp_set_prob_name(lp, name); + return; +} + +void lpx_set_obj_name(LPX *lp, const char *name) +{ /* assign (change) objective function name */ + glp_set_obj_name(lp, name); + return; +} + +void lpx_set_obj_dir(LPX *lp, int dir) +{ /* set (change) optimization direction flag */ + glp_set_obj_dir(lp, dir - LPX_MIN + GLP_MIN); + return; +} + +int lpx_add_rows(LPX *lp, int nrs) +{ /* add new rows to problem object */ + return glp_add_rows(lp, nrs); +} + +int lpx_add_cols(LPX *lp, int ncs) +{ /* add new columns to problem object */ + return glp_add_cols(lp, ncs); +} + +void lpx_set_row_name(LPX *lp, int i, const char *name) +{ /* assign (change) row name */ + glp_set_row_name(lp, i, name); + return; +} + +void lpx_set_col_name(LPX *lp, int j, const char *name) +{ /* assign (change) column name */ + glp_set_col_name(lp, j, name); + return; +} + +void lpx_set_row_bnds(LPX *lp, int i, int type, double lb, double ub) +{ /* set (change) row bounds */ + glp_set_row_bnds(lp, i, type - LPX_FR + GLP_FR, lb, ub); + return; +} + +void lpx_set_col_bnds(LPX *lp, int j, int type, double lb, double ub) +{ /* set (change) column bounds */ + glp_set_col_bnds(lp, j, type - LPX_FR + GLP_FR, lb, ub); + return; +} + +void lpx_set_obj_coef(glp_prob *lp, int j, double coef) +{ /* set (change) obj. coefficient or constant term */ + glp_set_obj_coef(lp, j, coef); + return; +} + +void lpx_set_mat_row(LPX *lp, int i, int len, const int ind[], + const double val[]) +{ /* set (replace) row of the constraint matrix */ + glp_set_mat_row(lp, i, len, ind, val); + return; +} + +void lpx_set_mat_col(LPX *lp, int j, int len, const int ind[], + const double val[]) +{ /* set (replace) column of the constraint matrix */ + glp_set_mat_col(lp, j, len, ind, val); + return; +} + +void lpx_load_matrix(LPX *lp, int ne, const int ia[], const int ja[], + const double ar[]) +{ /* load (replace) the whole constraint matrix */ + glp_load_matrix(lp, ne, ia, ja, ar); + return; +} + +void lpx_del_rows(LPX *lp, int nrs, const int num[]) +{ /* delete specified rows from problem object */ + glp_del_rows(lp, nrs, num); + return; +} + +void lpx_del_cols(LPX *lp, int ncs, const int num[]) +{ /* delete specified columns from problem object */ + glp_del_cols(lp, ncs, num); + return; +} + +void lpx_delete_prob(LPX *lp) +{ /* delete problem object */ + struct CPS *cps = find_cps(lp); + if (cps_ptr == cps) + cps_ptr = cps->link; + else + { struct CPS *prev; + for (prev = cps_ptr; prev != NULL; prev = prev->link) + if (prev->link == cps) break; + xassert(prev != NULL); + prev->link = cps->link; + } + glp_free(cps); + glp_delete_prob(lp); + return; +} + +const char *lpx_get_prob_name(LPX *lp) +{ /* retrieve problem name */ + return glp_get_prob_name(lp); +} + +const char *lpx_get_obj_name(LPX *lp) +{ /* retrieve objective function name */ + return glp_get_obj_name(lp); +} + +int lpx_get_obj_dir(LPX *lp) +{ /* retrieve optimization direction flag */ + return glp_get_obj_dir(lp) - GLP_MIN + LPX_MIN; +} + +int lpx_get_num_rows(LPX *lp) +{ /* retrieve number of rows */ + return glp_get_num_rows(lp); +} + +int lpx_get_num_cols(LPX *lp) +{ /* retrieve number of columns */ + return glp_get_num_cols(lp); +} + +const char *lpx_get_row_name(LPX *lp, int i) +{ /* retrieve row name */ + return glp_get_row_name(lp, i); +} + +const char *lpx_get_col_name(LPX *lp, int j) +{ /* retrieve column name */ + return glp_get_col_name(lp, j); +} + +int lpx_get_row_type(LPX *lp, int i) +{ /* retrieve row type */ + return glp_get_row_type(lp, i) - GLP_FR + LPX_FR; +} + +double lpx_get_row_lb(glp_prob *lp, int i) +{ /* retrieve row lower bound */ + double lb; + lb = glp_get_row_lb(lp, i); + if (lb == -DBL_MAX) lb = 0.0; + return lb; +} + +double lpx_get_row_ub(glp_prob *lp, int i) +{ /* retrieve row upper bound */ + double ub; + ub = glp_get_row_ub(lp, i); + if (ub == +DBL_MAX) ub = 0.0; + return ub; +} + +void lpx_get_row_bnds(glp_prob *lp, int i, int *typx, double *lb, + double *ub) +{ /* retrieve row bounds */ + if (typx != NULL) *typx = lpx_get_row_type(lp, i); + if (lb != NULL) *lb = lpx_get_row_lb(lp, i); + if (ub != NULL) *ub = lpx_get_row_ub(lp, i); + return; +} + +int lpx_get_col_type(LPX *lp, int j) +{ /* retrieve column type */ + return glp_get_col_type(lp, j) - GLP_FR + LPX_FR; +} + +double lpx_get_col_lb(glp_prob *lp, int j) +{ /* retrieve column lower bound */ + double lb; + lb = glp_get_col_lb(lp, j); + if (lb == -DBL_MAX) lb = 0.0; + return lb; +} + +double lpx_get_col_ub(glp_prob *lp, int j) +{ /* retrieve column upper bound */ + double ub; + ub = glp_get_col_ub(lp, j); + if (ub == +DBL_MAX) ub = 0.0; + return ub; +} + +void lpx_get_col_bnds(glp_prob *lp, int j, int *typx, double *lb, + double *ub) +{ /* retrieve column bounds */ + if (typx != NULL) *typx = lpx_get_col_type(lp, j); + if (lb != NULL) *lb = lpx_get_col_lb(lp, j); + if (ub != NULL) *ub = lpx_get_col_ub(lp, j); + return; +} + +double lpx_get_obj_coef(LPX *lp, int j) +{ /* retrieve obj. coefficient or constant term */ + return glp_get_obj_coef(lp, j); +} + +int lpx_get_num_nz(LPX *lp) +{ /* retrieve number of constraint coefficients */ + return glp_get_num_nz(lp); +} + +int lpx_get_mat_row(LPX *lp, int i, int ind[], double val[]) +{ /* retrieve row of the constraint matrix */ + return glp_get_mat_row(lp, i, ind, val); +} + +int lpx_get_mat_col(LPX *lp, int j, int ind[], double val[]) +{ /* retrieve column of the constraint matrix */ + return glp_get_mat_col(lp, j, ind, val); +} + +void lpx_create_index(LPX *lp) +{ /* create the name index */ + glp_create_index(lp); + return; +} + +int lpx_find_row(LPX *lp, const char *name) +{ /* find row by its name */ + return glp_find_row(lp, name); +} + +int lpx_find_col(LPX *lp, const char *name) +{ /* find column by its name */ + return glp_find_col(lp, name); +} + +void lpx_delete_index(LPX *lp) +{ /* delete the name index */ + glp_delete_index(lp); + return; +} + +void lpx_scale_prob(LPX *lp) +{ /* scale problem data */ + switch (lpx_get_int_parm(lp, LPX_K_SCALE)) + { case 0: + /* no scaling */ + glp_unscale_prob(lp); + break; + case 1: + /* equilibration scaling */ + glp_scale_prob(lp, GLP_SF_EQ); + break; + case 2: + /* geometric mean scaling */ + glp_scale_prob(lp, GLP_SF_GM); + break; + case 3: + /* geometric mean scaling, then equilibration scaling */ + glp_scale_prob(lp, GLP_SF_GM | GLP_SF_EQ); + break; + default: + xassert(lp != lp); + } + return; +} + +void lpx_unscale_prob(LPX *lp) +{ /* unscale problem data */ + glp_unscale_prob(lp); + return; +} + +void lpx_set_row_stat(LPX *lp, int i, int stat) +{ /* set (change) row status */ + glp_set_row_stat(lp, i, stat - LPX_BS + GLP_BS); + return; +} + +void lpx_set_col_stat(LPX *lp, int j, int stat) +{ /* set (change) column status */ + glp_set_col_stat(lp, j, stat - LPX_BS + GLP_BS); + return; +} + +void lpx_std_basis(LPX *lp) +{ /* construct standard initial LP basis */ + glp_std_basis(lp); + return; +} + +void lpx_adv_basis(LPX *lp) +{ /* construct advanced initial LP basis */ + glp_adv_basis(lp, 0); + return; +} + +void lpx_cpx_basis(LPX *lp) +{ /* construct Bixby's initial LP basis */ + glp_cpx_basis(lp); + return; +} + +static void fill_smcp(LPX *lp, glp_smcp *parm) +{ glp_init_smcp(parm); + switch (lpx_get_int_parm(lp, LPX_K_MSGLEV)) + { case 0: parm->msg_lev = GLP_MSG_OFF; break; + case 1: parm->msg_lev = GLP_MSG_ERR; break; + case 2: parm->msg_lev = GLP_MSG_ON; break; + case 3: parm->msg_lev = GLP_MSG_ALL; break; + default: xassert(lp != lp); + } + switch (lpx_get_int_parm(lp, LPX_K_DUAL)) + { case 0: parm->meth = GLP_PRIMAL; break; + case 1: parm->meth = GLP_DUAL; break; + default: xassert(lp != lp); + } + switch (lpx_get_int_parm(lp, LPX_K_PRICE)) + { case 0: parm->pricing = GLP_PT_STD; break; + case 1: parm->pricing = GLP_PT_PSE; break; + default: xassert(lp != lp); + } + if (lpx_get_real_parm(lp, LPX_K_RELAX) == 0.0) + parm->r_test = GLP_RT_STD; + else + parm->r_test = GLP_RT_HAR; + parm->tol_bnd = lpx_get_real_parm(lp, LPX_K_TOLBND); + parm->tol_dj = lpx_get_real_parm(lp, LPX_K_TOLDJ); + parm->tol_piv = lpx_get_real_parm(lp, LPX_K_TOLPIV); + parm->obj_ll = lpx_get_real_parm(lp, LPX_K_OBJLL); + parm->obj_ul = lpx_get_real_parm(lp, LPX_K_OBJUL); + if (lpx_get_int_parm(lp, LPX_K_ITLIM) < 0) + parm->it_lim = INT_MAX; + else + parm->it_lim = lpx_get_int_parm(lp, LPX_K_ITLIM); + if (lpx_get_real_parm(lp, LPX_K_TMLIM) < 0.0) + parm->tm_lim = INT_MAX; + else + parm->tm_lim = + (int)(1000.0 * lpx_get_real_parm(lp, LPX_K_TMLIM)); + parm->out_frq = lpx_get_int_parm(lp, LPX_K_OUTFRQ); + parm->out_dly = + (int)(1000.0 * lpx_get_real_parm(lp, LPX_K_OUTDLY)); + switch (lpx_get_int_parm(lp, LPX_K_PRESOL)) + { case 0: parm->presolve = GLP_OFF; break; + case 1: parm->presolve = GLP_ON; break; + default: xassert(lp != lp); + } + return; +} + +int lpx_simplex(LPX *lp) +{ /* easy-to-use driver to the simplex method */ + glp_smcp parm; + int ret; + fill_smcp(lp, &parm); + ret = glp_simplex(lp, &parm); + switch (ret) + { case 0: ret = LPX_E_OK; break; + case GLP_EBADB: + case GLP_ESING: + case GLP_ECOND: + case GLP_EBOUND: ret = LPX_E_FAULT; break; + case GLP_EFAIL: ret = LPX_E_SING; break; + case GLP_EOBJLL: ret = LPX_E_OBJLL; break; + case GLP_EOBJUL: ret = LPX_E_OBJUL; break; + case GLP_EITLIM: ret = LPX_E_ITLIM; break; + case GLP_ETMLIM: ret = LPX_E_TMLIM; break; + case GLP_ENOPFS: ret = LPX_E_NOPFS; break; + case GLP_ENODFS: ret = LPX_E_NODFS; break; + default: xassert(ret != ret); + } + return ret; +} + +int lpx_exact(LPX *lp) +{ /* easy-to-use driver to the exact simplex method */ + glp_smcp parm; + int ret; + fill_smcp(lp, &parm); + ret = glp_exact(lp, &parm); + switch (ret) + { case 0: ret = LPX_E_OK; break; + case GLP_EBADB: + case GLP_ESING: + case GLP_EBOUND: + case GLP_EFAIL: ret = LPX_E_FAULT; break; + case GLP_EITLIM: ret = LPX_E_ITLIM; break; + case GLP_ETMLIM: ret = LPX_E_TMLIM; break; + default: xassert(ret != ret); + } + return ret; +} + +int lpx_get_status(glp_prob *lp) +{ /* retrieve generic status of basic solution */ + int status; + switch (glp_get_status(lp)) + { case GLP_OPT: status = LPX_OPT; break; + case GLP_FEAS: status = LPX_FEAS; break; + case GLP_INFEAS: status = LPX_INFEAS; break; + case GLP_NOFEAS: status = LPX_NOFEAS; break; + case GLP_UNBND: status = LPX_UNBND; break; + case GLP_UNDEF: status = LPX_UNDEF; break; + default: xassert(lp != lp); + } + return status; +} + +int lpx_get_prim_stat(glp_prob *lp) +{ /* retrieve status of primal basic solution */ + return glp_get_prim_stat(lp) - GLP_UNDEF + LPX_P_UNDEF; +} + +int lpx_get_dual_stat(glp_prob *lp) +{ /* retrieve status of dual basic solution */ + return glp_get_dual_stat(lp) - GLP_UNDEF + LPX_D_UNDEF; +} + +double lpx_get_obj_val(LPX *lp) +{ /* retrieve objective value (basic solution) */ + return glp_get_obj_val(lp); +} + +int lpx_get_row_stat(LPX *lp, int i) +{ /* retrieve row status (basic solution) */ + return glp_get_row_stat(lp, i) - GLP_BS + LPX_BS; +} + +double lpx_get_row_prim(LPX *lp, int i) +{ /* retrieve row primal value (basic solution) */ + return glp_get_row_prim(lp, i); +} + +double lpx_get_row_dual(LPX *lp, int i) +{ /* retrieve row dual value (basic solution) */ + return glp_get_row_dual(lp, i); +} + +void lpx_get_row_info(glp_prob *lp, int i, int *tagx, double *vx, + double *dx) +{ /* obtain row solution information */ + if (tagx != NULL) *tagx = lpx_get_row_stat(lp, i); + if (vx != NULL) *vx = lpx_get_row_prim(lp, i); + if (dx != NULL) *dx = lpx_get_row_dual(lp, i); + return; +} + +int lpx_get_col_stat(LPX *lp, int j) +{ /* retrieve column status (basic solution) */ + return glp_get_col_stat(lp, j) - GLP_BS + LPX_BS; +} + +double lpx_get_col_prim(LPX *lp, int j) +{ /* retrieve column primal value (basic solution) */ + return glp_get_col_prim(lp, j); +} + +double lpx_get_col_dual(glp_prob *lp, int j) +{ /* retrieve column dual value (basic solution) */ + return glp_get_col_dual(lp, j); +} + +void lpx_get_col_info(glp_prob *lp, int j, int *tagx, double *vx, + double *dx) +{ /* obtain column solution information */ + if (tagx != NULL) *tagx = lpx_get_col_stat(lp, j); + if (vx != NULL) *vx = lpx_get_col_prim(lp, j); + if (dx != NULL) *dx = lpx_get_col_dual(lp, j); + return; +} + +int lpx_get_ray_info(LPX *lp) +{ /* determine what causes primal unboundness */ + return glp_get_unbnd_ray(lp); +} + +void lpx_check_kkt(LPX *lp, int scaled, LPXKKT *kkt) +{ /* check Karush-Kuhn-Tucker conditions */ + int m = glp_get_num_rows(lp); + int ae_ind, re_ind; + double ae_max, re_max; + xassert(scaled == scaled); + glp_check_kkt(lp, GLP_SOL, GLP_KKT_PE, &ae_max, &ae_ind, &re_max, + &re_ind); + kkt->pe_ae_max = ae_max; + kkt->pe_ae_row = ae_ind; + kkt->pe_re_max = re_max; + kkt->pe_re_row = re_ind; + if (re_max <= 1e-9) + kkt->pe_quality = 'H'; + else if (re_max <= 1e-6) + kkt->pe_quality = 'M'; + else if (re_max <= 1e-3) + kkt->pe_quality = 'L'; + else + kkt->pe_quality = '?'; + glp_check_kkt(lp, GLP_SOL, GLP_KKT_PB, &ae_max, &ae_ind, &re_max, + &re_ind); + kkt->pb_ae_max = ae_max; + kkt->pb_ae_ind = ae_ind; + kkt->pb_re_max = re_max; + kkt->pb_re_ind = re_ind; + if (re_max <= 1e-9) + kkt->pb_quality = 'H'; + else if (re_max <= 1e-6) + kkt->pb_quality = 'M'; + else if (re_max <= 1e-3) + kkt->pb_quality = 'L'; + else + kkt->pb_quality = '?'; + glp_check_kkt(lp, GLP_SOL, GLP_KKT_DE, &ae_max, &ae_ind, &re_max, + &re_ind); + kkt->de_ae_max = ae_max; + if (ae_ind == 0) + kkt->de_ae_col = 0; + else + kkt->de_ae_col = ae_ind - m; + kkt->de_re_max = re_max; + if (re_ind == 0) + kkt->de_re_col = 0; + else + kkt->de_re_col = ae_ind - m; + if (re_max <= 1e-9) + kkt->de_quality = 'H'; + else if (re_max <= 1e-6) + kkt->de_quality = 'M'; + else if (re_max <= 1e-3) + kkt->de_quality = 'L'; + else + kkt->de_quality = '?'; + glp_check_kkt(lp, GLP_SOL, GLP_KKT_DB, &ae_max, &ae_ind, &re_max, + &re_ind); + kkt->db_ae_max = ae_max; + kkt->db_ae_ind = ae_ind; + kkt->db_re_max = re_max; + kkt->db_re_ind = re_ind; + if (re_max <= 1e-9) + kkt->db_quality = 'H'; + else if (re_max <= 1e-6) + kkt->db_quality = 'M'; + else if (re_max <= 1e-3) + kkt->db_quality = 'L'; + else + kkt->db_quality = '?'; + kkt->cs_ae_max = 0.0, kkt->cs_ae_ind = 0; + kkt->cs_re_max = 0.0, kkt->cs_re_ind = 0; + kkt->cs_quality = 'H'; + return; +} + +int lpx_warm_up(LPX *lp) +{ /* "warm up" LP basis */ + int ret; + ret = glp_warm_up(lp); + if (ret == 0) + ret = LPX_E_OK; + else if (ret == GLP_EBADB) + ret = LPX_E_BADB; + else if (ret == GLP_ESING) + ret = LPX_E_SING; + else if (ret == GLP_ECOND) + ret = LPX_E_SING; + else + xassert(ret != ret); + return ret; +} + +int lpx_eval_tab_row(LPX *lp, int k, int ind[], double val[]) +{ /* compute row of the simplex tableau */ + return glp_eval_tab_row(lp, k, ind, val); +} + +int lpx_eval_tab_col(LPX *lp, int k, int ind[], double val[]) +{ /* compute column of the simplex tableau */ + return glp_eval_tab_col(lp, k, ind, val); +} + +int lpx_transform_row(LPX *lp, int len, int ind[], double val[]) +{ /* transform explicitly specified row */ + return glp_transform_row(lp, len, ind, val); +} + +int lpx_transform_col(LPX *lp, int len, int ind[], double val[]) +{ /* transform explicitly specified column */ + return glp_transform_col(lp, len, ind, val); +} + +int lpx_prim_ratio_test(LPX *lp, int len, const int ind[], + const double val[], int how, double tol) +{ /* perform primal ratio test */ + int piv; + piv = glp_prim_rtest(lp, len, ind, val, how, tol); + xassert(0 <= piv && piv <= len); + return piv == 0 ? 0 : ind[piv]; +} + +int lpx_dual_ratio_test(LPX *lp, int len, const int ind[], + const double val[], int how, double tol) +{ /* perform dual ratio test */ + int piv; + piv = glp_dual_rtest(lp, len, ind, val, how, tol); + xassert(0 <= piv && piv <= len); + return piv == 0 ? 0 : ind[piv]; +} + +int lpx_interior(LPX *lp) +{ /* easy-to-use driver to the interior-point method */ + int ret; + ret = glp_interior(lp, NULL); + switch (ret) + { case 0: ret = LPX_E_OK; break; + case GLP_EFAIL: ret = LPX_E_FAULT; break; + case GLP_ENOFEAS: ret = LPX_E_NOFEAS; break; + case GLP_ENOCVG: ret = LPX_E_NOCONV; break; + case GLP_EITLIM: ret = LPX_E_ITLIM; break; + case GLP_EINSTAB: ret = LPX_E_INSTAB; break; + default: xassert(ret != ret); + } + return ret; +} + +int lpx_ipt_status(glp_prob *lp) +{ /* retrieve status of interior-point solution */ + int status; + switch (glp_ipt_status(lp)) + { case GLP_UNDEF: status = LPX_T_UNDEF; break; + case GLP_OPT: status = LPX_T_OPT; break; + default: xassert(lp != lp); + } + return status; +} + +double lpx_ipt_obj_val(LPX *lp) +{ /* retrieve objective value (interior point) */ + return glp_ipt_obj_val(lp); +} + +double lpx_ipt_row_prim(LPX *lp, int i) +{ /* retrieve row primal value (interior point) */ + return glp_ipt_row_prim(lp, i); +} + +double lpx_ipt_row_dual(LPX *lp, int i) +{ /* retrieve row dual value (interior point) */ + return glp_ipt_row_dual(lp, i); +} + +double lpx_ipt_col_prim(LPX *lp, int j) +{ /* retrieve column primal value (interior point) */ + return glp_ipt_col_prim(lp, j); +} + +double lpx_ipt_col_dual(LPX *lp, int j) +{ /* retrieve column dual value (interior point) */ + return glp_ipt_col_dual(lp, j); +} + +void lpx_set_class(LPX *lp, int klass) +{ /* set problem class */ + xassert(lp == lp); + if (!(klass == LPX_LP || klass == LPX_MIP)) + xerror("lpx_set_class: invalid problem class\n"); + return; +} + +int lpx_get_class(LPX *lp) +{ /* determine problem klass */ + return glp_get_num_int(lp) == 0 ? LPX_LP : LPX_MIP; +} + +void lpx_set_col_kind(LPX *lp, int j, int kind) +{ /* set (change) column kind */ + glp_set_col_kind(lp, j, kind - LPX_CV + GLP_CV); + return; +} + +int lpx_get_col_kind(LPX *lp, int j) +{ /* retrieve column kind */ + return glp_get_col_kind(lp, j) == GLP_CV ? LPX_CV : LPX_IV; +} + +int lpx_get_num_int(LPX *lp) +{ /* retrieve number of integer columns */ + return glp_get_num_int(lp); +} + +int lpx_get_num_bin(LPX *lp) +{ /* retrieve number of binary columns */ + return glp_get_num_bin(lp); +} + +static int solve_mip(LPX *lp, int presolve) +{ glp_iocp parm; + int ret; + glp_init_iocp(&parm); + switch (lpx_get_int_parm(lp, LPX_K_MSGLEV)) + { case 0: parm.msg_lev = GLP_MSG_OFF; break; + case 1: parm.msg_lev = GLP_MSG_ERR; break; + case 2: parm.msg_lev = GLP_MSG_ON; break; + case 3: parm.msg_lev = GLP_MSG_ALL; break; + default: xassert(lp != lp); + } + switch (lpx_get_int_parm(lp, LPX_K_BRANCH)) + { case 0: parm.br_tech = GLP_BR_FFV; break; + case 1: parm.br_tech = GLP_BR_LFV; break; + case 2: parm.br_tech = GLP_BR_DTH; break; + case 3: parm.br_tech = GLP_BR_MFV; break; + default: xassert(lp != lp); + } + switch (lpx_get_int_parm(lp, LPX_K_BTRACK)) + { case 0: parm.bt_tech = GLP_BT_DFS; break; + case 1: parm.bt_tech = GLP_BT_BFS; break; + case 2: parm.bt_tech = GLP_BT_BPH; break; + case 3: parm.bt_tech = GLP_BT_BLB; break; + default: xassert(lp != lp); + } + parm.tol_int = lpx_get_real_parm(lp, LPX_K_TOLINT); + parm.tol_obj = lpx_get_real_parm(lp, LPX_K_TOLOBJ); + if (lpx_get_real_parm(lp, LPX_K_TMLIM) < 0.0 || + lpx_get_real_parm(lp, LPX_K_TMLIM) > 1e6) + parm.tm_lim = INT_MAX; + else + parm.tm_lim = + (int)(1000.0 * lpx_get_real_parm(lp, LPX_K_TMLIM)); + parm.mip_gap = lpx_get_real_parm(lp, LPX_K_MIPGAP); + if (lpx_get_int_parm(lp, LPX_K_USECUTS) & LPX_C_GOMORY) + parm.gmi_cuts = GLP_ON; + else + parm.gmi_cuts = GLP_OFF; + if (lpx_get_int_parm(lp, LPX_K_USECUTS) & LPX_C_MIR) + parm.mir_cuts = GLP_ON; + else + parm.mir_cuts = GLP_OFF; + if (lpx_get_int_parm(lp, LPX_K_USECUTS) & LPX_C_COVER) + parm.cov_cuts = GLP_ON; + else + parm.cov_cuts = GLP_OFF; + if (lpx_get_int_parm(lp, LPX_K_USECUTS) & LPX_C_CLIQUE) + parm.clq_cuts = GLP_ON; + else + parm.clq_cuts = GLP_OFF; + parm.presolve = presolve; + if (lpx_get_int_parm(lp, LPX_K_BINARIZE)) + parm.binarize = GLP_ON; + ret = glp_intopt(lp, &parm); + switch (ret) + { case 0: ret = LPX_E_OK; break; + case GLP_ENOPFS: ret = LPX_E_NOPFS; break; + case GLP_ENODFS: ret = LPX_E_NODFS; break; + case GLP_EBOUND: + case GLP_EROOT: ret = LPX_E_FAULT; break; + case GLP_EFAIL: ret = LPX_E_SING; break; + case GLP_EMIPGAP: ret = LPX_E_MIPGAP; break; + case GLP_ETMLIM: ret = LPX_E_TMLIM; break; + default: xassert(ret != ret); + } + return ret; +} + +int lpx_integer(LPX *lp) +{ /* easy-to-use driver to the branch-and-bound method */ + return solve_mip(lp, GLP_OFF); +} + +int lpx_intopt(LPX *lp) +{ /* easy-to-use driver to the branch-and-bound method */ + return solve_mip(lp, GLP_ON); +} + +int lpx_mip_status(glp_prob *lp) +{ /* retrieve status of MIP solution */ + int status; + switch (glp_mip_status(lp)) + { case GLP_UNDEF: status = LPX_I_UNDEF; break; + case GLP_OPT: status = LPX_I_OPT; break; + case GLP_FEAS: status = LPX_I_FEAS; break; + case GLP_NOFEAS: status = LPX_I_NOFEAS; break; + default: xassert(lp != lp); + } + return status; +} + +double lpx_mip_obj_val(LPX *lp) +{ /* retrieve objective value (MIP solution) */ + return glp_mip_obj_val(lp); +} + +double lpx_mip_row_val(LPX *lp, int i) +{ /* retrieve row value (MIP solution) */ + return glp_mip_row_val(lp, i); +} + +double lpx_mip_col_val(LPX *lp, int j) +{ /* retrieve column value (MIP solution) */ + return glp_mip_col_val(lp, j); +} + +void lpx_check_int(LPX *lp, LPXKKT *kkt) +{ /* check integer feasibility conditions */ + int ae_ind, re_ind; + double ae_max, re_max; + glp_check_kkt(lp, GLP_MIP, GLP_KKT_PE, &ae_max, &ae_ind, &re_max, + &re_ind); + kkt->pe_ae_max = ae_max; + kkt->pe_ae_row = ae_ind; + kkt->pe_re_max = re_max; + kkt->pe_re_row = re_ind; + if (re_max <= 1e-9) + kkt->pe_quality = 'H'; + else if (re_max <= 1e-6) + kkt->pe_quality = 'M'; + else if (re_max <= 1e-3) + kkt->pe_quality = 'L'; + else + kkt->pe_quality = '?'; + glp_check_kkt(lp, GLP_MIP, GLP_KKT_PB, &ae_max, &ae_ind, &re_max, + &re_ind); + kkt->pb_ae_max = ae_max; + kkt->pb_ae_ind = ae_ind; + kkt->pb_re_max = re_max; + kkt->pb_re_ind = re_ind; + if (re_max <= 1e-9) + kkt->pb_quality = 'H'; + else if (re_max <= 1e-6) + kkt->pb_quality = 'M'; + else if (re_max <= 1e-3) + kkt->pb_quality = 'L'; + else + kkt->pb_quality = '?'; + return; +} + +void lpx_reset_parms(LPX *lp) +{ /* reset control parameters to default values */ + struct CPS *cps = find_cps(lp); + reset_cps(cps); + return; +} + +void lpx_set_int_parm(LPX *lp, int parm, int val) +{ /* set (change) integer control parameter */ + struct CPS *cps = find_cps(lp); + switch (parm) + { case LPX_K_MSGLEV: + if (!(0 <= val && val <= 3)) + xerror("lpx_set_int_parm: MSGLEV = %d; invalid value\n", + val); + cps->msg_lev = val; + break; + case LPX_K_SCALE: + if (!(0 <= val && val <= 3)) + xerror("lpx_set_int_parm: SCALE = %d; invalid value\n", + val); + cps->scale = val; + break; + case LPX_K_DUAL: + if (!(val == 0 || val == 1)) + xerror("lpx_set_int_parm: DUAL = %d; invalid value\n", + val); + cps->dual = val; + break; + case LPX_K_PRICE: + if (!(val == 0 || val == 1)) + xerror("lpx_set_int_parm: PRICE = %d; invalid value\n", + val); + cps->price = val; + break; + case LPX_K_ROUND: + if (!(val == 0 || val == 1)) + xerror("lpx_set_int_parm: ROUND = %d; invalid value\n", + val); + cps->round = val; + break; + case LPX_K_ITLIM: + cps->it_lim = val; + break; + case LPX_K_ITCNT: + glp_set_it_cnt(lp, val); + break; + case LPX_K_OUTFRQ: + if (!(val > 0)) + xerror("lpx_set_int_parm: OUTFRQ = %d; invalid value\n", + val); + cps->out_frq = val; + break; + case LPX_K_BRANCH: + if (!(val == 0 || val == 1 || val == 2 || val == 3)) + xerror("lpx_set_int_parm: BRANCH = %d; invalid value\n", + val); + cps->branch = val; + break; + case LPX_K_BTRACK: + if (!(val == 0 || val == 1 || val == 2 || val == 3)) + xerror("lpx_set_int_parm: BTRACK = %d; invalid value\n", + val); + cps->btrack = val; + break; + case LPX_K_MPSINFO: + if (!(val == 0 || val == 1)) + xerror("lpx_set_int_parm: MPSINFO = %d; invalid value\n", + val); + cps->mps_info = val; + break; + case LPX_K_MPSOBJ: + if (!(val == 0 || val == 1 || val == 2)) + xerror("lpx_set_int_parm: MPSOBJ = %d; invalid value\n", + val); + cps->mps_obj = val; + break; + case LPX_K_MPSORIG: + if (!(val == 0 || val == 1)) + xerror("lpx_set_int_parm: MPSORIG = %d; invalid value\n", + val); + cps->mps_orig = val; + break; + case LPX_K_MPSWIDE: + if (!(val == 0 || val == 1)) + xerror("lpx_set_int_parm: MPSWIDE = %d; invalid value\n", + val); + cps->mps_wide = val; + break; + case LPX_K_MPSFREE: + if (!(val == 0 || val == 1)) + xerror("lpx_set_int_parm: MPSFREE = %d; invalid value\n", + val); + cps->mps_free = val; + break; + case LPX_K_MPSSKIP: + if (!(val == 0 || val == 1)) + xerror("lpx_set_int_parm: MPSSKIP = %d; invalid value\n", + val); + cps->mps_skip = val; + break; + case LPX_K_LPTORIG: + if (!(val == 0 || val == 1)) + xerror("lpx_set_int_parm: LPTORIG = %d; invalid value\n", + val); + cps->lpt_orig = val; + break; + case LPX_K_PRESOL: + if (!(val == 0 || val == 1)) + xerror("lpx_set_int_parm: PRESOL = %d; invalid value\n", + val); + cps->presol = val; + break; + case LPX_K_BINARIZE: + if (!(val == 0 || val == 1)) + xerror("lpx_set_int_parm: BINARIZE = %d; invalid value\n" + , val); + cps->binarize = val; + break; + case LPX_K_USECUTS: + if (val & ~LPX_C_ALL) + xerror("lpx_set_int_parm: USECUTS = 0x%X; invalid value\n", + val); + cps->use_cuts = val; + break; + case LPX_K_BFTYPE: + { glp_bfcp parm; + glp_get_bfcp(lp, &parm); + switch (val) + { case 1: + parm.type = GLP_BF_FT; break; + case 2: + parm.type = GLP_BF_BG; break; + case 3: + parm.type = GLP_BF_GR; break; + default: + xerror("lpx_set_int_parm: BFTYPE = %d; invalid val" + "ue\n", val); + } + glp_set_bfcp(lp, &parm); + } + break; + default: + xerror("lpx_set_int_parm: parm = %d; invalid parameter\n", + parm); + } + return; +} + +int lpx_get_int_parm(LPX *lp, int parm) +{ /* query integer control parameter */ + struct CPS *cps = find_cps(lp); + int val = 0; + switch (parm) + { case LPX_K_MSGLEV: + val = cps->msg_lev; break; + case LPX_K_SCALE: + val = cps->scale; break; + case LPX_K_DUAL: + val = cps->dual; break; + case LPX_K_PRICE: + val = cps->price; break; + case LPX_K_ROUND: + val = cps->round; break; + case LPX_K_ITLIM: + val = cps->it_lim; break; + case LPX_K_ITCNT: + val = glp_get_it_cnt(lp); break; + case LPX_K_OUTFRQ: + val = cps->out_frq; break; + case LPX_K_BRANCH: + val = cps->branch; break; + case LPX_K_BTRACK: + val = cps->btrack; break; + case LPX_K_MPSINFO: + val = cps->mps_info; break; + case LPX_K_MPSOBJ: + val = cps->mps_obj; break; + case LPX_K_MPSORIG: + val = cps->mps_orig; break; + case LPX_K_MPSWIDE: + val = cps->mps_wide; break; + case LPX_K_MPSFREE: + val = cps->mps_free; break; + case LPX_K_MPSSKIP: + val = cps->mps_skip; break; + case LPX_K_LPTORIG: + val = cps->lpt_orig; break; + case LPX_K_PRESOL: + val = cps->presol; break; + case LPX_K_BINARIZE: + val = cps->binarize; break; + case LPX_K_USECUTS: + val = cps->use_cuts; break; + case LPX_K_BFTYPE: + { glp_bfcp parm; + glp_get_bfcp(lp, &parm); + switch (parm.type) + { case GLP_BF_FT: + val = 1; break; + case GLP_BF_BG: + val = 2; break; + case GLP_BF_GR: + val = 3; break; + default: + xassert(lp != lp); + } + } + break; + default: + xerror("lpx_get_int_parm: parm = %d; invalid parameter\n", + parm); + } + return val; +} + +void lpx_set_real_parm(LPX *lp, int parm, double val) +{ /* set (change) real control parameter */ + struct CPS *cps = find_cps(lp); + switch (parm) + { case LPX_K_RELAX: + if (!(0.0 <= val && val <= 1.0)) + xerror("lpx_set_real_parm: RELAX = %g; invalid value\n", + val); + cps->relax = val; + break; + case LPX_K_TOLBND: + if (!(DBL_EPSILON <= val && val <= 0.001)) + xerror("lpx_set_real_parm: TOLBND = %g; invalid value\n", + val); + cps->tol_bnd = val; + break; + case LPX_K_TOLDJ: + if (!(DBL_EPSILON <= val && val <= 0.001)) + xerror("lpx_set_real_parm: TOLDJ = %g; invalid value\n", + val); + cps->tol_dj = val; + break; + case LPX_K_TOLPIV: + if (!(DBL_EPSILON <= val && val <= 0.001)) + xerror("lpx_set_real_parm: TOLPIV = %g; invalid value\n", + val); + cps->tol_piv = val; + break; + case LPX_K_OBJLL: + cps->obj_ll = val; + break; + case LPX_K_OBJUL: + cps->obj_ul = val; + break; + case LPX_K_TMLIM: + cps->tm_lim = val; + break; + case LPX_K_OUTDLY: + cps->out_dly = val; + break; + case LPX_K_TOLINT: + if (!(DBL_EPSILON <= val && val <= 0.001)) + xerror("lpx_set_real_parm: TOLINT = %g; invalid value\n", + val); + cps->tol_int = val; + break; + case LPX_K_TOLOBJ: + if (!(DBL_EPSILON <= val && val <= 0.001)) + xerror("lpx_set_real_parm: TOLOBJ = %g; invalid value\n", + val); + cps->tol_obj = val; + break; + case LPX_K_MIPGAP: + if (val < 0.0) + xerror("lpx_set_real_parm: MIPGAP = %g; invalid value\n", + val); + cps->mip_gap = val; + break; + default: + xerror("lpx_set_real_parm: parm = %d; invalid parameter\n", + parm); + } + return; +} + +double lpx_get_real_parm(LPX *lp, int parm) +{ /* query real control parameter */ + struct CPS *cps = find_cps(lp); + double val = 0.0; + switch (parm) + { case LPX_K_RELAX: + val = cps->relax; + break; + case LPX_K_TOLBND: + val = cps->tol_bnd; + break; + case LPX_K_TOLDJ: + val = cps->tol_dj; + break; + case LPX_K_TOLPIV: + val = cps->tol_piv; + break; + case LPX_K_OBJLL: + val = cps->obj_ll; + break; + case LPX_K_OBJUL: + val = cps->obj_ul; + break; + case LPX_K_TMLIM: + val = cps->tm_lim; + break; + case LPX_K_OUTDLY: + val = cps->out_dly; + break; + case LPX_K_TOLINT: + val = cps->tol_int; + break; + case LPX_K_TOLOBJ: + val = cps->tol_obj; + break; + case LPX_K_MIPGAP: + val = cps->mip_gap; + break; + default: + xerror("lpx_get_real_parm: parm = %d; invalid parameter\n", + parm); + } + return val; +} + +LPX *lpx_read_mps(const char *fname) +{ /* read problem data in fixed MPS format */ + LPX *lp = lpx_create_prob(); + if (glp_read_mps(lp, GLP_MPS_DECK, NULL, fname)) + lpx_delete_prob(lp), lp = NULL; + return lp; +} + +int lpx_write_mps(LPX *lp, const char *fname) +{ /* write problem data in fixed MPS format */ + return glp_write_mps(lp, GLP_MPS_DECK, NULL, fname); +} + +int lpx_read_bas(LPX *lp, const char *fname) +{ /* read LP basis in fixed MPS format */ + xassert(lp == lp); + xassert(fname == fname); + xerror("lpx_read_bas: operation not supported\n"); + return 0; +} + +int lpx_write_bas(LPX *lp, const char *fname) +{ /* write LP basis in fixed MPS format */ + xassert(lp == lp); + xassert(fname == fname); + xerror("lpx_write_bas: operation not supported\n"); + return 0; +} + +LPX *lpx_read_freemps(const char *fname) +{ /* read problem data in free MPS format */ + LPX *lp = lpx_create_prob(); + if (glp_read_mps(lp, GLP_MPS_FILE, NULL, fname)) + lpx_delete_prob(lp), lp = NULL; + return lp; +} + +int lpx_write_freemps(LPX *lp, const char *fname) +{ /* write problem data in free MPS format */ + return glp_write_mps(lp, GLP_MPS_FILE, NULL, fname); +} + +LPX *lpx_read_cpxlp(const char *fname) +{ /* read problem data in CPLEX LP format */ + LPX *lp; + lp = lpx_create_prob(); + if (glp_read_lp(lp, NULL, fname)) + lpx_delete_prob(lp), lp = NULL; + return lp; +} + +int lpx_write_cpxlp(LPX *lp, const char *fname) +{ /* write problem data in CPLEX LP format */ + return glp_write_lp(lp, NULL, fname); +} + +LPX *lpx_read_model(const char *model, const char *data, const char + *output) +{ /* read LP/MIP model written in GNU MathProg language */ + LPX *lp = NULL; + glp_tran *tran; + /* allocate the translator workspace */ + tran = glp_mpl_alloc_wksp(); + /* read model section and optional data section */ + if (glp_mpl_read_model(tran, model, data != NULL)) goto done; + /* read separate data section, if required */ + if (data != NULL) + if (glp_mpl_read_data(tran, data)) goto done; + /* generate the model */ + if (glp_mpl_generate(tran, output)) goto done; + /* build the problem instance from the model */ + lp = lpx_create_prob(); + glp_mpl_build_prob(tran, lp); +done: /* free the translator workspace */ + glp_mpl_free_wksp(tran); + /* bring the problem object to the calling program */ + return lp; +} + +int lpx_print_prob(LPX *lp, const char *fname) +{ /* write problem data in plain text format */ + return glp_write_lp(lp, NULL, fname); +} + +int lpx_print_sol(LPX *lp, const char *fname) +{ /* write LP problem solution in printable format */ + return glp_print_sol(lp, fname); +} + +int lpx_print_sens_bnds(LPX *lp, const char *fname) +{ /* write bounds sensitivity information */ + if (glp_get_status(lp) == GLP_OPT && !glp_bf_exists(lp)) + glp_factorize(lp); + return glp_print_ranges(lp, 0, NULL, 0, fname); +} + +int lpx_print_ips(LPX *lp, const char *fname) +{ /* write interior point solution in printable format */ + return glp_print_ipt(lp, fname); +} + +int lpx_print_mip(LPX *lp, const char *fname) +{ /* write MIP problem solution in printable format */ + return glp_print_mip(lp, fname); +} + +int lpx_is_b_avail(glp_prob *lp) +{ /* check if LP basis is available */ + return glp_bf_exists(lp); +} + +int lpx_main(int argc, const char *argv[]) +{ /* stand-alone LP/MIP solver */ + return glp_main(argc, argv); +} + +/* eof */ diff --git a/glpk-5.0/examples/oldapi/lpx.h b/glpk-5.0/examples/oldapi/lpx.h new file mode 100644 index 0000000..54af27e --- /dev/null +++ b/glpk-5.0/examples/oldapi/lpx.h @@ -0,0 +1,565 @@ +/* lpx.h (old GLPK API) */ + +/* Written by Andrew Makhorin <mao@gnu.org>, August 2013. */ + +#ifndef LPX_H +#define LPX_H + +#include <glpk.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define LPX glp_prob + +/* problem class: */ +#define LPX_LP 100 /* linear programming (LP) */ +#define LPX_MIP 101 /* mixed integer programming (MIP) */ + +/* type of auxiliary/structural variable: */ +#define LPX_FR 110 /* free variable */ +#define LPX_LO 111 /* variable with lower bound */ +#define LPX_UP 112 /* variable with upper bound */ +#define LPX_DB 113 /* double-bounded variable */ +#define LPX_FX 114 /* fixed variable */ + +/* optimization direction flag: */ +#define LPX_MIN 120 /* minimization */ +#define LPX_MAX 121 /* maximization */ + +/* status of primal basic solution: */ +#define LPX_P_UNDEF 132 /* primal solution is undefined */ +#define LPX_P_FEAS 133 /* solution is primal feasible */ +#define LPX_P_INFEAS 134 /* solution is primal infeasible */ +#define LPX_P_NOFEAS 135 /* no primal feasible solution exists */ + +/* status of dual basic solution: */ +#define LPX_D_UNDEF 136 /* dual solution is undefined */ +#define LPX_D_FEAS 137 /* solution is dual feasible */ +#define LPX_D_INFEAS 138 /* solution is dual infeasible */ +#define LPX_D_NOFEAS 139 /* no dual feasible solution exists */ + +/* status of auxiliary/structural variable: */ +#define LPX_BS 140 /* basic variable */ +#define LPX_NL 141 /* non-basic variable on lower bound */ +#define LPX_NU 142 /* non-basic variable on upper bound */ +#define LPX_NF 143 /* non-basic free variable */ +#define LPX_NS 144 /* non-basic fixed variable */ + +/* status of interior-point solution: */ +#define LPX_T_UNDEF 150 /* interior solution is undefined */ +#define LPX_T_OPT 151 /* interior solution is optimal */ + +/* kind of structural variable: */ +#define LPX_CV 160 /* continuous variable */ +#define LPX_IV 161 /* integer variable */ + +/* status of integer solution: */ +#define LPX_I_UNDEF 170 /* integer solution is undefined */ +#define LPX_I_OPT 171 /* integer solution is optimal */ +#define LPX_I_FEAS 172 /* integer solution is feasible */ +#define LPX_I_NOFEAS 173 /* no integer solution exists */ + +/* status codes reported by the routine lpx_get_status: */ +#define LPX_OPT 180 /* optimal */ +#define LPX_FEAS 181 /* feasible */ +#define LPX_INFEAS 182 /* infeasible */ +#define LPX_NOFEAS 183 /* no feasible */ +#define LPX_UNBND 184 /* unbounded */ +#define LPX_UNDEF 185 /* undefined */ + +/* exit codes returned by solver routines: */ +#define LPX_E_OK 200 /* success */ +#define LPX_E_EMPTY 201 /* empty problem */ +#define LPX_E_BADB 202 /* invalid initial basis */ +#define LPX_E_INFEAS 203 /* infeasible initial solution */ +#define LPX_E_FAULT 204 /* unable to start the search */ +#define LPX_E_OBJLL 205 /* objective lower limit reached */ +#define LPX_E_OBJUL 206 /* objective upper limit reached */ +#define LPX_E_ITLIM 207 /* iterations limit exhausted */ +#define LPX_E_TMLIM 208 /* time limit exhausted */ +#define LPX_E_NOFEAS 209 /* no feasible solution */ +#define LPX_E_INSTAB 210 /* numerical instability */ +#define LPX_E_SING 211 /* problems with basis matrix */ +#define LPX_E_NOCONV 212 /* no convergence (interior) */ +#define LPX_E_NOPFS 213 /* no primal feas. sol. (LP presolver) */ +#define LPX_E_NODFS 214 /* no dual feas. sol. (LP presolver) */ +#define LPX_E_MIPGAP 215 /* relative mip gap tolerance reached */ + +/* control parameter identifiers: */ +#define LPX_K_MSGLEV 300 /* lp->msg_lev */ +#define LPX_K_SCALE 301 /* lp->scale */ +#define LPX_K_DUAL 302 /* lp->dual */ +#define LPX_K_PRICE 303 /* lp->price */ +#define LPX_K_RELAX 304 /* lp->relax */ +#define LPX_K_TOLBND 305 /* lp->tol_bnd */ +#define LPX_K_TOLDJ 306 /* lp->tol_dj */ +#define LPX_K_TOLPIV 307 /* lp->tol_piv */ +#define LPX_K_ROUND 308 /* lp->round */ +#define LPX_K_OBJLL 309 /* lp->obj_ll */ +#define LPX_K_OBJUL 310 /* lp->obj_ul */ +#define LPX_K_ITLIM 311 /* lp->it_lim */ +#define LPX_K_ITCNT 312 /* lp->it_cnt */ +#define LPX_K_TMLIM 313 /* lp->tm_lim */ +#define LPX_K_OUTFRQ 314 /* lp->out_frq */ +#define LPX_K_OUTDLY 315 /* lp->out_dly */ +#define LPX_K_BRANCH 316 /* lp->branch */ +#define LPX_K_BTRACK 317 /* lp->btrack */ +#define LPX_K_TOLINT 318 /* lp->tol_int */ +#define LPX_K_TOLOBJ 319 /* lp->tol_obj */ +#define LPX_K_MPSINFO 320 /* lp->mps_info */ +#define LPX_K_MPSOBJ 321 /* lp->mps_obj */ +#define LPX_K_MPSORIG 322 /* lp->mps_orig */ +#define LPX_K_MPSWIDE 323 /* lp->mps_wide */ +#define LPX_K_MPSFREE 324 /* lp->mps_free */ +#define LPX_K_MPSSKIP 325 /* lp->mps_skip */ +#define LPX_K_LPTORIG 326 /* lp->lpt_orig */ +#define LPX_K_PRESOL 327 /* lp->presol */ +#define LPX_K_BINARIZE 328 /* lp->binarize */ +#define LPX_K_USECUTS 329 /* lp->use_cuts */ +#define LPX_K_BFTYPE 330 /* lp->bfcp->type */ +#define LPX_K_MIPGAP 331 /* lp->mip_gap */ + +#define LPX_C_COVER 0x01 /* mixed cover cuts */ +#define LPX_C_CLIQUE 0x02 /* clique cuts */ +#define LPX_C_GOMORY 0x04 /* Gomory's mixed integer cuts */ +#define LPX_C_MIR 0x08 /* mixed integer rounding cuts */ +#define LPX_C_ALL 0xFF /* all cuts */ + +typedef struct +{ /* this structure contains results reported by the routines which + checks Karush-Kuhn-Tucker conditions (for details see comments + to those routines) */ + /*--------------------------------------------------------------*/ + /* xR - A * xS = 0 (KKT.PE) */ + double pe_ae_max; + /* largest absolute error */ + int pe_ae_row; + /* number of row with largest absolute error */ + double pe_re_max; + /* largest relative error */ + int pe_re_row; + /* number of row with largest relative error */ + int pe_quality; + /* quality of primal solution: + 'H' - high + 'M' - medium + 'L' - low + '?' - primal solution is wrong */ + /*--------------------------------------------------------------*/ + /* l[k] <= x[k] <= u[k] (KKT.PB) */ + double pb_ae_max; + /* largest absolute error */ + int pb_ae_ind; + /* number of variable with largest absolute error */ + double pb_re_max; + /* largest relative error */ + int pb_re_ind; + /* number of variable with largest relative error */ + int pb_quality; + /* quality of primal feasibility: + 'H' - high + 'M' - medium + 'L' - low + '?' - primal solution is infeasible */ + /*--------------------------------------------------------------*/ + /* A' * (dR - cR) + (dS - cS) = 0 (KKT.DE) */ + double de_ae_max; + /* largest absolute error */ + int de_ae_col; + /* number of column with largest absolute error */ + double de_re_max; + /* largest relative error */ + int de_re_col; + /* number of column with largest relative error */ + int de_quality; + /* quality of dual solution: + 'H' - high + 'M' - medium + 'L' - low + '?' - dual solution is wrong */ + /*--------------------------------------------------------------*/ + /* d[k] >= 0 or d[k] <= 0 (KKT.DB) */ + double db_ae_max; + /* largest absolute error */ + int db_ae_ind; + /* number of variable with largest absolute error */ + double db_re_max; + /* largest relative error */ + int db_re_ind; + /* number of variable with largest relative error */ + int db_quality; + /* quality of dual feasibility: + 'H' - high + 'M' - medium + 'L' - low + '?' - dual solution is infeasible */ + /*--------------------------------------------------------------*/ + /* (x[k] - bound of x[k]) * d[k] = 0 (KKT.CS) */ + double cs_ae_max; + /* largest absolute error */ + int cs_ae_ind; + /* number of variable with largest absolute error */ + double cs_re_max; + /* largest relative error */ + int cs_re_ind; + /* number of variable with largest relative error */ + int cs_quality; + /* quality of complementary slackness: + 'H' - high + 'M' - medium + 'L' - low + '?' - primal and dual solutions are not complementary */ +} LPXKKT; + +LPX *lpx_create_prob(void); +/* create problem object */ + +void lpx_set_prob_name(LPX *lp, const char *name); +/* assign (change) problem name */ + +void lpx_set_obj_name(LPX *lp, const char *name); +/* assign (change) objective function name */ + +void lpx_set_obj_dir(LPX *lp, int dir); +/* set (change) optimization direction flag */ + +int lpx_add_rows(LPX *lp, int nrs); +/* add new rows to problem object */ + +int lpx_add_cols(LPX *lp, int ncs); +/* add new columns to problem object */ + +void lpx_set_row_name(LPX *lp, int i, const char *name); +/* assign (change) row name */ + +void lpx_set_col_name(LPX *lp, int j, const char *name); +/* assign (change) column name */ + +void lpx_set_row_bnds(LPX *lp, int i, int type, double lb, double ub); +/* set (change) row bounds */ + +void lpx_set_col_bnds(LPX *lp, int j, int type, double lb, double ub); +/* set (change) column bounds */ + +void lpx_set_obj_coef(glp_prob *lp, int j, double coef); +/* set (change) obj. coefficient or constant term */ + +void lpx_set_mat_row(LPX *lp, int i, int len, const int ind[], + const double val[]); +/* set (replace) row of the constraint matrix */ + +void lpx_set_mat_col(LPX *lp, int j, int len, const int ind[], + const double val[]); +/* set (replace) column of the constraint matrix */ + +void lpx_load_matrix(LPX *lp, int ne, const int ia[], const int ja[], + const double ar[]); +/* load (replace) the whole constraint matrix */ + +void lpx_del_rows(LPX *lp, int nrs, const int num[]); +/* delete specified rows from problem object */ + +void lpx_del_cols(LPX *lp, int ncs, const int num[]); +/* delete specified columns from problem object */ + +void lpx_delete_prob(LPX *lp); +/* delete problem object */ + +const char *lpx_get_prob_name(LPX *lp); +/* retrieve problem name */ + +const char *lpx_get_obj_name(LPX *lp); +/* retrieve objective function name */ + +int lpx_get_obj_dir(LPX *lp); +/* retrieve optimization direction flag */ + +int lpx_get_num_rows(LPX *lp); +/* retrieve number of rows */ + +int lpx_get_num_cols(LPX *lp); +/* retrieve number of columns */ + +const char *lpx_get_row_name(LPX *lp, int i); +/* retrieve row name */ + +const char *lpx_get_col_name(LPX *lp, int j); +/* retrieve column name */ + +int lpx_get_row_type(LPX *lp, int i); +/* retrieve row type */ + +double lpx_get_row_lb(LPX *lp, int i); +/* retrieve row lower bound */ + +double lpx_get_row_ub(LPX *lp, int i); +/* retrieve row upper bound */ + +void lpx_get_row_bnds(LPX *lp, int i, int *typx, double *lb, + double *ub); +/* retrieve row bounds */ + +int lpx_get_col_type(LPX *lp, int j); +/* retrieve column type */ + +double lpx_get_col_lb(LPX *lp, int j); +/* retrieve column lower bound */ + +double lpx_get_col_ub(LPX *lp, int j); +/* retrieve column upper bound */ + +void lpx_get_col_bnds(LPX *lp, int j, int *typx, double *lb, + double *ub); +/* retrieve column bounds */ + +double lpx_get_obj_coef(LPX *lp, int j); +/* retrieve obj. coefficient or constant term */ + +int lpx_get_num_nz(LPX *lp); +/* retrieve number of constraint coefficients */ + +int lpx_get_mat_row(LPX *lp, int i, int ind[], double val[]); +/* retrieve row of the constraint matrix */ + +int lpx_get_mat_col(LPX *lp, int j, int ind[], double val[]); +/* retrieve column of the constraint matrix */ + +void lpx_create_index(LPX *lp); +/* create the name index */ + +int lpx_find_row(LPX *lp, const char *name); +/* find row by its name */ + +int lpx_find_col(LPX *lp, const char *name); +/* find column by its name */ + +void lpx_delete_index(LPX *lp); +/* delete the name index */ + +void lpx_scale_prob(LPX *lp); +/* scale problem data */ + +void lpx_unscale_prob(LPX *lp); +/* unscale problem data */ + +void lpx_set_row_stat(LPX *lp, int i, int stat); +/* set (change) row status */ + +void lpx_set_col_stat(LPX *lp, int j, int stat); +/* set (change) column status */ + +void lpx_std_basis(LPX *lp); +/* construct standard initial LP basis */ + +void lpx_adv_basis(LPX *lp); +/* construct advanced initial LP basis */ + +void lpx_cpx_basis(LPX *lp); +/* construct Bixby's initial LP basis */ + +int lpx_simplex(LPX *lp); +/* easy-to-use driver to the simplex method */ + +int lpx_exact(LPX *lp); +/* easy-to-use driver to the exact simplex method */ + +int lpx_get_status(LPX *lp); +/* retrieve generic status of basic solution */ + +int lpx_get_prim_stat(LPX *lp); +/* retrieve primal status of basic solution */ + +int lpx_get_dual_stat(LPX *lp); +/* retrieve dual status of basic solution */ + +double lpx_get_obj_val(LPX *lp); +/* retrieve objective value (basic solution) */ + +int lpx_get_row_stat(LPX *lp, int i); +/* retrieve row status (basic solution) */ + +double lpx_get_row_prim(LPX *lp, int i); +/* retrieve row primal value (basic solution) */ + +double lpx_get_row_dual(LPX *lp, int i); +/* retrieve row dual value (basic solution) */ + +void lpx_get_row_info(LPX *lp, int i, int *tagx, double *vx, + double *dx); +/* obtain row solution information */ + +int lpx_get_col_stat(LPX *lp, int j); +/* retrieve column status (basic solution) */ + +double lpx_get_col_prim(LPX *lp, int j); +/* retrieve column primal value (basic solution) */ + +double lpx_get_col_dual(glp_prob *lp, int j); +/* retrieve column dual value (basic solution) */ + +void lpx_get_col_info(LPX *lp, int j, int *tagx, double *vx, + double *dx); +/* obtain column solution information (obsolete) */ + +int lpx_get_ray_info(LPX *lp); +/* determine what causes primal unboundness */ + +void lpx_check_kkt(LPX *lp, int scaled, LPXKKT *kkt); +/* check Karush-Kuhn-Tucker conditions */ + +int lpx_warm_up(LPX *lp); +/* "warm up" LP basis */ + +int lpx_eval_tab_row(LPX *lp, int k, int ind[], double val[]); +/* compute row of the simplex table */ + +int lpx_eval_tab_col(LPX *lp, int k, int ind[], double val[]); +/* compute column of the simplex table */ + +int lpx_transform_row(LPX *lp, int len, int ind[], double val[]); +/* transform explicitly specified row */ + +int lpx_transform_col(LPX *lp, int len, int ind[], double val[]); +/* transform explicitly specified column */ + +int lpx_prim_ratio_test(LPX *lp, int len, const int ind[], + const double val[], int how, double tol); +/* perform primal ratio test */ + +int lpx_dual_ratio_test(LPX *lp, int len, const int ind[], + const double val[], int how, double tol); +/* perform dual ratio test */ + +int lpx_interior(LPX *lp); +/* easy-to-use driver to the interior point method */ + +int lpx_ipt_status(LPX *lp); +/* retrieve status of interior-point solution */ + +double lpx_ipt_obj_val(LPX *lp); +/* retrieve objective value (interior point) */ + +double lpx_ipt_row_prim(LPX *lp, int i); +/* retrieve row primal value (interior point) */ + +double lpx_ipt_row_dual(LPX *lp, int i); +/* retrieve row dual value (interior point) */ + +double lpx_ipt_col_prim(LPX *lp, int j); +/* retrieve column primal value (interior point) */ + +double lpx_ipt_col_dual(LPX *lp, int j); +/* retrieve column dual value (interior point) */ + +void lpx_set_class(LPX *lp, int klass); +/* set problem class */ + +int lpx_get_class(LPX *lp); +/* determine problem klass */ + +void lpx_set_col_kind(LPX *lp, int j, int kind); +/* set (change) column kind */ + +int lpx_get_col_kind(LPX *lp, int j); +/* retrieve column kind */ + +int lpx_get_num_int(LPX *lp); +/* retrieve number of integer columns */ + +int lpx_get_num_bin(LPX *lp); +/* retrieve number of binary columns */ + +int lpx_integer(LPX *lp); +/* easy-to-use driver to the branch-and-bound method */ + +int lpx_intopt(LPX *lp); +/* easy-to-use driver to the branch-and-bound method */ + +int lpx_mip_status(LPX *lp); +/* retrieve status of MIP solution */ + +double lpx_mip_obj_val(LPX *lp); +/* retrieve objective value (MIP solution) */ + +double lpx_mip_row_val(LPX *lp, int i); +/* retrieve row value (MIP solution) */ + +double lpx_mip_col_val(LPX *lp, int j); +/* retrieve column value (MIP solution) */ + +void lpx_check_int(LPX *lp, LPXKKT *kkt); +/* check integer feasibility conditions */ + +void lpx_reset_parms(LPX *lp); +/* reset control parameters to default values */ + +void lpx_set_int_parm(LPX *lp, int parm, int val); +/* set (change) integer control parameter */ + +int lpx_get_int_parm(LPX *lp, int parm); +/* query integer control parameter */ + +void lpx_set_real_parm(LPX *lp, int parm, double val); +/* set (change) real control parameter */ + +double lpx_get_real_parm(LPX *lp, int parm); +/* query real control parameter */ + +LPX *lpx_read_mps(const char *fname); +/* read problem data in fixed MPS format */ + +int lpx_write_mps(LPX *lp, const char *fname); +/* write problem data in fixed MPS format */ + +int lpx_read_bas(LPX *lp, const char *fname); +/* read LP basis in fixed MPS format */ + +int lpx_write_bas(LPX *lp, const char *fname); +/* write LP basis in fixed MPS format */ + +LPX *lpx_read_freemps(const char *fname); +/* read problem data in free MPS format */ + +int lpx_write_freemps(LPX *lp, const char *fname); +/* write problem data in free MPS format */ + +LPX *lpx_read_cpxlp(const char *fname); +/* read problem data in CPLEX LP format */ + +int lpx_write_cpxlp(LPX *lp, const char *fname); +/* write problem data in CPLEX LP format */ + +LPX *lpx_read_model(const char *model, const char *data, + const char *output); +/* read LP/MIP model written in GNU MathProg language */ + +int lpx_print_prob(LPX *lp, const char *fname); +/* write problem data in plain text format */ + +int lpx_print_sol(LPX *lp, const char *fname); +/* write LP problem solution in printable format */ + +int lpx_print_sens_bnds(LPX *lp, const char *fname); +/* write bounds sensitivity information */ + +int lpx_print_ips(LPX *lp, const char *fname); +/* write interior point solution in printable format */ + +int lpx_print_mip(LPX *lp, const char *fname); +/* write MIP problem solution in printable format */ + +int lpx_is_b_avail(LPX *lp); +/* check if LP basis is available */ + +int lpx_main(int argc, const char *argv[]); +/* stand-alone LP/MIP solver */ + +#ifdef __cplusplus +} +#endif + +#endif + +/* eof */ diff --git a/glpk-5.0/examples/oldapi/lpxsamp.c b/glpk-5.0/examples/oldapi/lpxsamp.c new file mode 100644 index 0000000..dd08148 --- /dev/null +++ b/glpk-5.0/examples/oldapi/lpxsamp.c @@ -0,0 +1,51 @@ +/* lpxsamp.c */ + +#include <stdio.h> +#include <stdlib.h> +#include "lpx.h" + +int main(void) +{ LPX *lp; + int ia[1+1000], ja[1+1000]; + double ar[1+1000], Z, x1, x2, x3; +s1: lp = lpx_create_prob(); +s2: lpx_set_prob_name(lp, "sample"); +s3: lpx_set_obj_dir(lp, LPX_MAX); +s4: lpx_add_rows(lp, 3); +s5: lpx_set_row_name(lp, 1, "p"); +s6: lpx_set_row_bnds(lp, 1, LPX_UP, 0.0, 100.0); +s7: lpx_set_row_name(lp, 2, "q"); +s8: lpx_set_row_bnds(lp, 2, LPX_UP, 0.0, 600.0); +s9: lpx_set_row_name(lp, 3, "r"); +s10: lpx_set_row_bnds(lp, 3, LPX_UP, 0.0, 300.0); +s11: lpx_add_cols(lp, 3); +s12: lpx_set_col_name(lp, 1, "x1"); +s13: lpx_set_col_bnds(lp, 1, LPX_LO, 0.0, 0.0); +s14: lpx_set_obj_coef(lp, 1, 10.0); +s15: lpx_set_col_name(lp, 2, "x2"); +s16: lpx_set_col_bnds(lp, 2, LPX_LO, 0.0, 0.0); +s17: lpx_set_obj_coef(lp, 2, 6.0); +s18: lpx_set_col_name(lp, 3, "x3"); +s19: lpx_set_col_bnds(lp, 3, LPX_LO, 0.0, 0.0); +s20: lpx_set_obj_coef(lp, 3, 4.0); +s21: ia[1] = 1, ja[1] = 1, ar[1] = 1.0; /* a[1,1] = 1 */ +s22: ia[2] = 1, ja[2] = 2, ar[2] = 1.0; /* a[1,2] = 1 */ +s23: ia[3] = 1, ja[3] = 3, ar[3] = 1.0; /* a[1,3] = 1 */ +s24: ia[4] = 2, ja[4] = 1, ar[4] = 10.0; /* a[2,1] = 10 */ +s25: ia[5] = 3, ja[5] = 1, ar[5] = 2.0; /* a[3,1] = 2 */ +s26: ia[6] = 2, ja[6] = 2, ar[6] = 4.0; /* a[2,2] = 4 */ +s27: ia[7] = 3, ja[7] = 2, ar[7] = 2.0; /* a[3,2] = 2 */ +s28: ia[8] = 2, ja[8] = 3, ar[8] = 5.0; /* a[2,3] = 5 */ +s29: ia[9] = 3, ja[9] = 3, ar[9] = 6.0; /* a[3,3] = 6 */ +s30: lpx_load_matrix(lp, 9, ia, ja, ar); +s31: lpx_simplex(lp); +s32: Z = lpx_get_obj_val(lp); +s33: x1 = lpx_get_col_prim(lp, 1); +s34: x2 = lpx_get_col_prim(lp, 2); +s35: x3 = lpx_get_col_prim(lp, 3); +s36: printf("\nZ = %g; x1 = %g; x2 = %g; x3 = %g\n", Z, x1, x2, x3); +s37: lpx_delete_prob(lp); + return 0; +} + +/* eof */ diff --git a/glpk-5.0/examples/pbn/9dom.dat b/glpk-5.0/examples/pbn/9dom.dat new file mode 100644 index 0000000..80ece7a --- /dev/null +++ b/glpk-5.0/examples/pbn/9dom.dat @@ -0,0 +1,65 @@ +/* 9dom.dat */ + +/*********************************************************************** +* Web Paint-by-Number Puzzle #8098 from <www.webpbn.com>. +* Copyright (C) 2010 by Josh Greifer. Used by permission. +* +* Domino Logic III (Abstract pattern) +* +* created by Josh Greifer +* Apr 5, 2010 +* +* Encoded in GNU MathProg by Andrew Makhorin <mao@gnu.org>. +***********************************************************************/ + +data; + +param m := 19; + +param n := 19; + +param row : 1 2 := + 1 3 . + 2 1 . + 3 3 1 + 4 1 . + 5 3 1 + 6 1 . + 7 3 1 + 8 1 . + 9 3 1 + 10 1 . + 11 3 1 + 12 1 . + 13 3 1 + 14 1 . + 15 3 1 + 16 1 . + 17 3 1 + 18 1 . + 19 1 . +; + +param col : 1 2 := + 1 1 . + 2 1 . + 3 1 3 + 4 1 . + 5 1 3 + 6 1 . + 7 1 3 + 8 1 . + 9 1 3 + 10 1 . + 11 1 3 + 12 1 . + 13 1 3 + 14 1 . + 15 1 3 + 16 1 . + 17 1 3 + 18 1 . + 19 3 . +; + +end; diff --git a/glpk-5.0/examples/pbn/README b/glpk-5.0/examples/pbn/README new file mode 100644 index 0000000..43dc82c --- /dev/null +++ b/glpk-5.0/examples/pbn/README @@ -0,0 +1,6 @@ +This subdirectory contains examples, which illustrate how to use +GLPK and the GNU MathProg modeling language for practical solving the +paint-by-numbers puzzle. + +For details please see the document "Solving Paint-By-Numbers Puzzles +with GLPK" included in this subdirectory (file pbn.pdf). diff --git a/glpk-5.0/examples/pbn/bucks.dat b/glpk-5.0/examples/pbn/bucks.dat new file mode 100644 index 0000000..5dfc4f1 --- /dev/null +++ b/glpk-5.0/examples/pbn/bucks.dat @@ -0,0 +1,77 @@ +/* bucks.dat */ + +/*********************************************************************** +* Web Paint-by-Number Puzzle #27 from <www.webpbn.com>. +* Copyright (C) 2004 by Jan Wolter. Used by permission. +* +* Party at the Right [Political] +* +* created by Jan Wolter +* Apr 6, 2004 +* +* Encoded in GNU MathProg by Andrew Makhorin <mao@gnu.org>. +***********************************************************************/ + +data; + +param m := 23; + +param n := 27; + +param row : 1 2 3 4 5 6 7 8 := + 1 11 . . . . . . . + 2 17 . . . . . . . + 3 3 5 5 3 . . . . + 4 2 2 2 1 . . . . + 5 2 1 3 1 3 1 4 . + 6 3 3 3 3 . . . . + 7 5 1 3 1 3 1 3 . + 8 3 2 2 4 . . . . + 9 5 5 5 5 . . . . + 10 23 . . . . . . . + 11 . . . . . . . . + 12 23 . . . . . . . + 13 1 1 . . . . . . + 14 1 1 . . . . . . + 15 1 2 1 . . . . . + 16 1 1 1 1 . . . . + 17 1 1 1 1 . . . . + 18 1 10 1 2 1 . . . + 19 1 1 1 1 1 1 3 . + 20 1 1 1 1 1 1 1 1 + 21 1 1 1 1 1 1 1 . + 22 1 1 1 1 2 2 . . + 23 5 5 3 . . . . . +; + +param col : 1 2 3 4 5 6 := + 1 4 12 . . . . + 2 6 1 1 . . . + 3 8 1 1 . . . + 4 3 2 2 1 1 . + 5 2 1 1 2 1 6 + 6 1 1 1 1 . . + 7 3 1 1 2 1 1 + 8 3 2 3 1 1 . + 9 10 1 1 . . . + 10 4 2 2 1 1 . + 11 3 1 1 2 1 1 + 12 2 1 1 1 . . + 13 3 1 1 2 1 1 + 14 3 2 3 1 6 . + 15 10 1 1 . . . + 16 4 2 2 1 1 . + 17 3 1 1 2 1 1 + 18 1 1 1 9 . . + 19 2 1 1 2 1 1 + 20 2 2 3 1 3 . + 21 8 1 5 . . . + 22 6 1 1 . . . + 23 4 9 1 . . . + 24 1 1 . . . . + 25 2 1 . . . . + 26 1 1 . . . . + 27 4 . . . . . +; + +end; diff --git a/glpk-5.0/examples/pbn/cat.dat b/glpk-5.0/examples/pbn/cat.dat new file mode 100644 index 0000000..a655411 --- /dev/null +++ b/glpk-5.0/examples/pbn/cat.dat @@ -0,0 +1,67 @@ +/* cat.dat */ + +/*********************************************************************** +* Web Paint-by-Number Puzzle #6 from <www.webpbn.com>. +* Copyright (C) 2004 by Jan Wolter. Used by permission. +* +* Scardy Cat +* +* created by Jan Wolter +* Mar 24, 2004 +* +* Encoded in GNU MathProg by Andrew Makhorin <mao@gnu.org>. +***********************************************************************/ + +data; + +param m := 20; + +param n := 20; + +param row : 1 2 3 4 := + 1 2 . . . + 2 2 . . . + 3 1 . . . + 4 1 . . . + 5 1 3 . . + 6 2 5 . . + 7 1 7 1 1 + 8 1 8 2 2 + 9 1 9 5 . + 10 2 16 . . + 11 1 17 . . + 12 7 11 . . + 13 5 5 3 . + 14 5 4 . . + 15 3 3 . . + 16 2 2 . . + 17 2 1 . . + 18 1 1 . . + 19 2 2 . . + 20 2 2 . . +; + +param col : 1 2 3 := + 1 5 . . + 2 5 3 . + 3 2 3 4 + 4 1 7 2 + 5 8 . . + 6 9 . . + 7 9 . . + 8 8 . . + 9 7 . . + 10 8 . . + 11 9 . . + 12 10 . . + 13 13 . . + 14 6 2 . + 15 4 . . + 16 6 . . + 17 6 . . + 18 5 . . + 19 6 . . + 20 6 . . +; + +end; diff --git a/glpk-5.0/examples/pbn/dancer.dat b/glpk-5.0/examples/pbn/dancer.dat new file mode 100644 index 0000000..42e3057 --- /dev/null +++ b/glpk-5.0/examples/pbn/dancer.dat @@ -0,0 +1,42 @@ +/* dancer.dat */ + +/*********************************************************************** +* Web Paint-by-Number Puzzle #1 from <www.webpbn.com>. +* Copyright (C) 2004 by Jan Wolter. Used by permission. +* +* Demo Puzzle from Front Page +* +* created by Jan Wolter +* Mar 24, 2004 +* +* Encoded in GNU MathProg by Andrew Makhorin <mao@gnu.org>. +***********************************************************************/ + +data; + +param m := 10; + +param n := 5; + +param row : 1 2 3 := + 1 2 . . + 2 2 1 . + 3 1 1 . + 4 3 . . + 5 1 1 . + 6 1 1 . + 7 2 . . + 8 1 1 . + 9 1 2 . + 10 2 . . +; + +param col : 1 2 3 := + 1 2 1 . + 2 2 1 3 + 3 7 . . + 4 1 3 . + 5 2 1 . +; + +end; diff --git a/glpk-5.0/examples/pbn/disney.dat b/glpk-5.0/examples/pbn/disney.dat new file mode 100644 index 0000000..2eab1fe --- /dev/null +++ b/glpk-5.0/examples/pbn/disney.dat @@ -0,0 +1,115 @@ +/* disney.dat */ + +data; + +param m := 50; + +param n := 50; + +param row : 1 2 3 4 5 6 7 := + 1 8 . . . . . . + 2 7 15 . . . . . + 3 2 2 19 . . . . + 4 1 2 16 1 2 . . + 5 1 5 14 1 . . . + 6 2 4 13 1 1 . . + 7 6 12 5 . . . . + 8 1 5 6 11 . . . + 9 1 4 5 4 8 . . + 10 1 4 1 18 . . . + 11 1 5 2 11 4 . . + 12 1 8 2 6 3 . . + 13 1 7 1 3 2 . . + 14 1 13 2 . . . . + 15 1 12 1 . . . . + 16 1 2 7 4 2 . . + 17 2 3 4 2 . . . + 18 5 4 3 1 . . . + 19 8 4 3 1 . . . + 20 10 3 2 1 . . . + 21 12 1 1 . . . . + 22 13 1 1 1 . . . + 23 15 1 1 3 . . . + 24 3 5 5 1 2 1 . + 25 4 5 5 2 4 2 . + 26 3 3 5 1 1 2 1 + 27 3 3 2 4 2 2 . + 28 2 3 2 3 3 2 . + 29 2 4 3 3 5 . . + 30 2 7 4 1 4 3 . + 31 3 13 1 4 5 . . + 32 9 4 1 4 7 6 1 + 33 8 1 1 2 1 15 . + 34 6 6 3 1 1 6 6 + 35 6 3 8 1 2 6 6 + 36 2 5 13 3 1 . . + 37 5 1 11 3 4 . . + 38 9 8 4 3 . . . + 39 9 6 3 10 3 . . + 40 10 5 3 2 2 3 . + 41 10 6 3 2 10 . . + 42 10 4 2 1 9 . . + 43 11 3 2 2 4 . . + 44 11 2 2 1 1 2 3 + 45 8 2 2 2 8 . . + 46 5 1 2 2 4 4 . + 47 6 2 2 2 3 4 . + 48 8 2 2 2 3 3 . + 49 10 2 4 3 1 5 4 + 50 12 7 7 4 7 . . +; + +param col : 1 2 3 4 5 6 7 8 9 10 := + 1 14 . . . . . . . . . + 2 9 15 . . . . . . . . + 3 28 . . . . . . . . . + 4 7 5 14 . . . . . . . + 5 6 4 14 . . . . . . . + 6 5 5 8 4 . . . . . . + 7 7 6 8 3 . . . . . . + 8 19 8 3 . . . . . . . + 9 16 9 2 . . . . . . . + 10 15 2 5 2 . . . . . . + 11 8 3 1 3 1 . . . . . + 12 4 7 2 2 3 1 . . . . + 13 2 12 6 3 1 2 . . . . + 14 1 1 12 1 2 . . . . . + 15 1 4 9 2 1 2 . . . . + 16 1 6 5 6 1 . . . . . + 17 1 7 5 3 5 1 1 . . . + 18 1 8 8 6 2 1 . . . . + 19 2 1 7 5 9 1 . . . . + 20 2 2 7 6 9 1 . . . . + 21 6 15 9 2 . . . . . . + 22 7 5 4 14 1 . . . . . + 23 8 4 4 3 6 1 1 . . . + 24 9 5 2 7 3 2 3 . . . + 25 9 7 4 10 1 2 1 . . . + 26 8 2 4 2 5 2 2 2 1 . + 27 7 2 6 2 3 5 2 1 . . + 28 7 4 4 2 5 2 2 1 . . + 29 7 3 4 1 1 2 1 . . . + 30 7 3 4 1 2 2 2 . . . + 31 8 6 1 1 2 1 . . . . + 32 6 1 3 1 2 1 2 . . . + 33 4 1 3 2 2 1 2 2 . . + 34 4 1 3 1 3 1 2 2 2 . + 35 3 5 1 1 1 2 1 1 1 2 + 36 2 6 1 1 3 1 1 3 . . + 37 2 5 1 5 6 1 3 . . . + 38 2 6 2 6 3 2 . . . . + 39 1 4 2 6 2 2 1 . . . + 40 2 5 3 4 1 2 2 . . . + 41 3 7 3 1 10 . . . . . + 42 5 2 1 9 . . . . . . + 43 3 2 2 2 6 . . . . . + 44 2 1 1 2 3 2 . . . . + 45 4 2 2 2 1 . . . . . + 46 4 1 2 3 1 . . . . . + 47 4 1 1 2 3 2 . . . . + 48 6 4 6 . . . . . . . + 49 3 3 5 . . . . . . . + 50 3 2 3 . . . . . . . +; + +end; diff --git a/glpk-5.0/examples/pbn/dragon.dat b/glpk-5.0/examples/pbn/dragon.dat new file mode 100644 index 0000000..d2b8b14 --- /dev/null +++ b/glpk-5.0/examples/pbn/dragon.dat @@ -0,0 +1,61 @@ +/* dragon.dat */ + +/*********************************************************************** +* Hard 20x20 paint-by-numbers puzzle designed by Won Yoon Jo +* from the article "Painting by Numbers" by Robert A. Bosch (2000), +* <http://www.oberlin.edu/~math/faculty/bosch/pbn-page.html>. +* +* Encoded in GNU MathProg by Andrew Makhorin <mao@gnu.org>. +***********************************************************************/ + +data; + +param m := 20; + +param n := 20; + +param row : 1 2 3 4 5 := + 1 7 1 . . . + 2 1 1 2 . . + 3 2 1 2 . . + 4 1 2 2 . . + 5 4 2 3 . . + 6 3 1 4 . . + 7 3 1 3 . . + 8 2 1 4 . . + 9 2 9 . . . + 10 2 1 5 . . + 11 2 7 . . . + 12 14 . . . . + 13 8 2 . . . + 14 6 2 2 . . + 15 2 8 1 3 . + 16 1 5 5 2 . + 17 1 3 2 4 1 + 18 3 1 2 4 1 + 19 1 1 3 1 3 + 20 2 1 1 2 . ; + +param col : 1 2 3 4 5 := + 1 1 1 1 2 . + 2 3 1 2 1 1 + 3 1 4 2 1 1 + 4 1 3 2 4 . + 5 1 4 6 1 . + 6 1 11 1 . . + 7 5 1 6 2 . + 8 14 . . . . + 9 7 2 . . . + 10 7 2 . . . + 11 6 1 1 . . + 12 9 2 . . . + 13 3 1 1 1 . + 14 3 1 3 . . + 15 2 1 3 . . + 16 2 1 5 . . + 17 3 2 2 . . + 18 3 3 2 . . + 19 2 3 2 . . + 20 2 6 . . . ; + +end; diff --git a/glpk-5.0/examples/pbn/edge.dat b/glpk-5.0/examples/pbn/edge.dat new file mode 100644 index 0000000..cdd1864 --- /dev/null +++ b/glpk-5.0/examples/pbn/edge.dat @@ -0,0 +1,48 @@ +/* edge.dat */ + +/*********************************************************************** +* Web Paint-by-Number Puzzle #23 from <www.webpbn.com>. +* Copyright (C) 2004 by Jan Wolter. Used by permission. +* +* Nonrepresentational Test Pattern +* +* created by Jan Wolter +* Apr 5, 2004 +* +* Encoded in GNU MathProg by Andrew Makhorin <mao@gnu.org>. +***********************************************************************/ + +data; + +param m := 11; + +param n := 10; + +param row : 1 := + 1 1 + 2 3 + 3 1 + 4 2 + 5 1 + 6 3 + 7 3 + 8 1 + 9 2 + 10 2 + 11 4 +; + +param col : 1 2 := + 1 1 . + 2 3 . + 3 1 . + 4 2 2 + 5 2 . + 6 4 . + 7 1 . + 8 3 . + 9 3 . + 10 1 . +; + +end; diff --git a/glpk-5.0/examples/pbn/forever.dat b/glpk-5.0/examples/pbn/forever.dat new file mode 100644 index 0000000..e3bebf7 --- /dev/null +++ b/glpk-5.0/examples/pbn/forever.dat @@ -0,0 +1,77 @@ +/* forever.dat */ + +/*********************************************************************** +* Web Paint-by-Number Puzzle #6574 from <www.webpbn.com>. +* Copyright (C) 2009 by Gator. Used by permission. +* +* Lasts Forever +* +* created by Gator +* Aug 24, 2009 +* +* Encoded in GNU MathProg by Andrew Makhorin <mao@gnu.org>. +***********************************************************************/ + +data; + +param m := 25; + +param n := 25; + +param row : 1 2 3 4 5 6 7 8 := + 1 1 2 2 2 2 2 1 . + 2 1 2 2 2 2 2 1 1 + 3 1 1 . . . . . . + 4 1 1 . . . . . . + 5 1 3 1 . . . . . + 6 1 13 1 . . . . . + 7 1 13 1 . . . . . + 8 1 13 1 . . . . . + 9 1 4 4 1 . . . . + 10 1 4 3 4 1 . . . + 11 1 4 5 4 1 . . . + 12 1 7 1 . . . . . + 13 1 7 1 . . . . . + 14 1 7 1 . . . . . + 15 1 7 1 . . . . . + 16 1 1 5 1 . . . . + 17 1 2 6 1 . . . . + 18 1 4 6 1 . . . . + 19 1 6 6 1 . . . . + 20 1 3 1 . . . . . + 21 1 1 1 . . . . . + 22 1 1 . . . . . . + 23 1 1 . . . . . . + 24 1 1 2 2 2 2 2 1 + 25 1 2 2 2 2 2 1 . +; + +param col : 1 2 3 4 5 6 7 8 := + 1 1 2 2 2 2 2 1 . + 2 1 1 2 2 2 2 2 1 + 3 1 1 . . . . . . + 4 1 1 . . . . . . + 5 1 1 . . . . . . + 6 1 2 1 . . . . . + 7 1 6 1 1 . . . . + 8 1 6 2 1 . . . . + 9 1 6 3 1 . . . . + 10 1 4 8 1 . . . . + 11 1 3 5 2 1 . . . + 12 1 4 8 2 1 . . . + 13 1 4 9 2 1 . . . + 14 1 4 11 1 . . . . + 15 1 3 9 1 . . . . + 16 1 4 8 1 . . . . + 17 1 6 3 1 . . . . + 18 1 6 2 1 . . . . + 19 1 6 1 1 . . . . + 20 1 2 1 . . . . . + 21 1 1 . . . . . . + 22 1 1 . . . . . . + 23 1 1 . . . . . . + 24 1 2 2 2 2 2 1 1 + 25 1 2 2 2 2 2 1 . +; + +end; diff --git a/glpk-5.0/examples/pbn/knot.dat b/glpk-5.0/examples/pbn/knot.dat new file mode 100644 index 0000000..b9e12d7 --- /dev/null +++ b/glpk-5.0/examples/pbn/knot.dat @@ -0,0 +1,95 @@ +/* knot.dat */ + +/*********************************************************************** +* Web Paint-by-Number Puzzle #16 from <www.webpbn.com>. +* Copyright (C) 2004 by Jan Wolter. Used by permission. +* +* Probably Not +* +* created by Jan Wolter +* Mar 27, 2004 +* +* Encoded in GNU MathProg by Andrew Makhorin <mao@gnu.org>. +***********************************************************************/ + +data; + +param m := 34; + +param n := 34; + +param row : 1 2 3 4 5 6 7 8 := + 1 1 1 . . . . . . + 2 2 2 . . . . . . + 3 3 3 . . . . . . + 4 2 1 1 2 . . . . + 5 2 1 1 2 . . . . + 6 1 1 1 1 . . . . + 7 1 1 1 1 . . . . + 8 18 . . . . . . . + 9 2 1 1 1 1 2 . . + 10 1 1 1 1 1 1 . . + 11 1 1 1 1 1 1 . . + 12 26 . . . . . . . + 13 2 1 1 1 1 1 1 2 + 14 2 1 1 2 2 1 1 2 + 15 2 1 1 2 2 1 1 2 + 16 14 14 . . . . . . + 17 1 1 1 1 . . . . + 18 1 1 1 1 . . . . + 19 14 14 . . . . . . + 20 2 1 1 2 2 1 1 2 + 21 2 1 1 2 2 1 1 2 + 22 2 1 1 1 1 1 1 2 + 23 26 . . . . . . . + 24 1 1 1 1 1 1 . . + 25 1 1 1 1 1 1 . . + 26 2 1 1 1 1 2 . . + 27 18 . . . . . . . + 28 1 1 1 1 . . . . + 29 1 1 1 1 . . . . + 30 2 1 1 2 . . . . + 31 2 1 1 2 . . . . + 32 3 3 . . . . . . + 33 2 2 . . . . . . + 34 1 1 . . . . . . +; + +param col : 1 2 3 4 5 6 7 8 := + 1 1 1 . . . . . . + 2 2 2 . . . . . . + 3 3 3 . . . . . . + 4 2 1 1 2 . . . . + 5 2 1 1 2 . . . . + 6 1 1 1 1 . . . . + 7 1 1 1 1 . . . . + 8 18 . . . . . . . + 9 2 1 1 1 1 2 . . + 10 1 1 1 1 1 1 . . + 11 1 1 1 1 1 1 . . + 12 26 . . . . . . . + 13 2 1 1 1 1 1 1 2 + 14 2 1 1 2 2 1 1 2 + 15 2 1 1 2 2 1 1 2 + 16 14 14 . . . . . . + 17 1 1 1 1 . . . . + 18 1 1 1 1 . . . . + 19 14 14 . . . . . . + 20 2 1 1 2 2 1 1 2 + 21 2 1 1 2 2 1 1 2 + 22 2 1 1 1 1 1 1 2 + 23 26 . . . . . . . + 24 1 1 1 1 1 1 . . + 25 1 1 1 1 1 1 . . + 26 2 1 1 1 1 2 . . + 27 18 . . . . . . . + 28 1 1 1 1 . . . . + 29 1 1 1 1 . . . . + 30 2 1 1 2 . . . . + 31 2 1 1 2 . . . . + 32 3 3 . . . . . . + 33 2 2 . . . . . . + 34 1 1 . . . . . . +; + +end; diff --git a/glpk-5.0/examples/pbn/light.dat b/glpk-5.0/examples/pbn/light.dat new file mode 100644 index 0000000..1ffc5d4 --- /dev/null +++ b/glpk-5.0/examples/pbn/light.dat @@ -0,0 +1,122 @@ +/* light.dat */ + +/*********************************************************************** +* Web Paint-by-Number Puzzle #803 from <www.webpbn.com>. +* Copyright (C) 2007 by Robert Kummerfeldt. Used by permission. +* +* You light up my life +* +* created by Robert Kummerfeldt +* Mar 15, 2007 +* +* Encoded in GNU MathProg by Andrew Makhorin <mao@gnu.org>. +***********************************************************************/ + +data; + +param m := 45; + +param n := 50; + +param row : 1 2 3 4 := + 1 . . . . + 2 1 . . . + 3 1 . . . + 4 3 . . . + 5 2 2 . . + 6 1 1 . . + 7 7 . . . + 8 1 1 . . + 9 1 3 1 . + 10 1 3 1 . + 11 1 1 . . + 12 11 . . . + 13 1 1 . . + 14 1 1 . . + 15 2 2 . . + 16 1 1 . . + 17 1 1 . . + 18 1 1 . . + 19 1 1 . . + 20 2 2 . . + 21 1 1 . . + 22 1 1 . . + 23 1 1 . . + 24 1 1 . . + 25 1 1 . . + 26 1 1 . . + 27 1 1 . . + 28 1 1 . . + 29 1 1 . . + 30 1 1 . . + 31 2 2 . . + 32 1 1 . . + 33 1 1 . . + 34 1 1 . . + 35 1 1 . . + 36 1 1 . . + 37 1 4 1 . + 38 1 1 1 1 + 39 1 1 1 1 + 40 1 1 1 1 + 41 1 1 1 1 + 42 25 . . . + 43 6 5 . . + 44 5 6 . . + 45 4 5 . . +; + +param col : 1 2 3 4 5 := + 1 1 . . . . + 2 1 . . . . + 3 1 . . . . + 4 2 . . . . + 5 1 . . . . + 6 1 . . . . + 7 1 . . . . + 8 2 . . . . + 9 1 . . . . + 10 1 . . . . + 11 1 . . . . + 12 1 . . . . + 13 2 . . . . + 14 1 . . . . + 15 1 . . . . + 16 1 . . . . + 17 5 . . . . + 18 7 1 . . . + 19 6 1 . . . + 20 6 1 . . . + 21 1 6 1 . . + 22 4 1 . . . + 23 7 1 . . . + 24 1 1 1 1 . + 25 2 1 2 1 1 + 26 3 1 2 1 1 + 27 2 1 2 1 1 + 28 1 1 1 1 . + 29 7 6 . . . + 30 4 1 1 . . + 31 1 6 1 1 . + 32 6 6 . . . + 33 6 1 . . . + 34 5 1 . . . + 35 7 . . . . + 36 1 . . . . + 37 2 . . . . + 38 1 . . . . + 39 1 . . . . + 40 1 . . . . + 41 2 . . . . + 42 1 . . . . + 43 1 . . . . + 44 1 . . . . + 45 1 . . . . + 46 2 . . . . + 47 1 . . . . + 48 1 . . . . + 49 1 . . . . + 50 1 . . . . +; + +end; diff --git a/glpk-5.0/examples/pbn/mum.dat b/glpk-5.0/examples/pbn/mum.dat new file mode 100644 index 0000000..a1baf50 --- /dev/null +++ b/glpk-5.0/examples/pbn/mum.dat @@ -0,0 +1,101 @@ +/* mum.dat */ + +/*********************************************************************** +* Web Paint-by-Number Puzzle #65 from <www.webpbn.com>. +* Copyright (C) 2004 by Jan Wolter. Used by permission. +* +* Mum's the Word [has only one solution] +* +* created by Jan Wolter +* Jul 10, 2004 +* +* Encoded in GNU MathProg by Andrew Makhorin <mao@gnu.org>. +***********************************************************************/ + +data; + +param m := 40; + +param n := 34; + +param row : 1 2 3 4 5 6 7 8 9 := + 1 12 . . . . . . . . + 2 5 2 5 . . . . . . + 3 5 2 2 5 . . . . . + 4 1 2 2 2 2 2 1 . . + 5 4 2 2 4 2 2 4 . . + 6 4 2 2 4 2 2 4 . . + 7 1 2 2 2 2 2 1 . . + 8 6 2 2 2 2 2 6 . . + 9 6 2 2 2 2 2 6 . . + 10 1 14 1 . . . . . . + 11 10 10 . . . . . . . + 12 8 3 3 8 . . . . . + 13 1 1 2 1 1 2 1 1 . + 14 9 2 2 2 2 9 . . . + 15 9 9 . . . . . . . + 16 1 1 1 1 1 1 . . . + 17 12 2 12 . . . . . . + 18 12 12 . . . . . . . + 19 1 1 4 1 1 . . . . + 20 14 14 . . . . . . . + 21 12 12 . . . . . . . + 22 2 1 4 1 2 . . . . + 23 9 4 9 . . . . . . + 24 1 7 4 7 1 . . . . + 25 1 1 1 4 1 1 1 . . + 26 1 7 4 7 1 . . . . + 27 1 7 4 7 1 . . . . + 28 1 2 1 2 1 2 1 . . + 29 1 7 2 7 1 . . . . + 30 1 1 6 2 6 1 1 . . + 31 1 1 1 1 2 1 1 1 1 + 32 1 1 6 2 6 1 1 . . + 33 1 1 5 5 1 1 . . . + 34 1 1 1 8 1 1 1 . . + 35 1 1 4 4 1 1 . . . + 36 1 2 6 2 1 . . . . + 37 2 4 4 2 . . . . . + 38 2 6 2 . . . . . . + 39 4 4 . . . . . . . + 40 6 . . . . . . . . +; + +param col : 1 2 3 4 5 6 7 8 9 10 11 12 := + 1 5 . . . . . . . . . . . + 2 3 2 1 . . . . . . . . . + 3 3 2 2 1 . . . . . . . . + 4 3 2 2 2 2 . . . . . . . + 5 3 2 2 2 2 3 . . . . . . + 6 1 2 2 2 2 2 16 . . . . . + 7 1 2 2 2 2 2 2 1 2 . . . + 8 1 2 2 2 2 2 2 13 1 . . . + 9 3 2 2 2 2 2 2 4 1 1 . . + 10 6 5 2 2 2 2 6 1 1 . . . + 11 1 7 3 2 2 2 2 2 1 1 1 . + 12 3 4 1 2 2 2 2 2 2 1 1 1 + 13 6 1 2 3 2 2 2 2 1 1 1 . + 14 1 7 2 16 1 1 . . . . . . + 15 1 4 1 1 1 1 1 1 1 1 1 . + 16 1 2 1 3 1 1 6 1 1 1 1 . + 17 2 7 1 1 11 1 1 1 1 . . . + 18 2 7 1 1 11 1 1 1 1 . . . + 19 1 2 1 3 1 1 6 1 1 1 1 . + 20 1 4 1 1 1 1 1 1 1 1 1 . + 21 1 7 2 16 1 1 . . . . . . + 22 6 1 2 3 2 2 2 2 1 1 1 . + 23 3 4 1 2 2 2 2 2 2 1 1 1 + 24 1 7 3 2 2 2 2 2 1 1 1 . + 25 6 5 2 2 2 2 6 1 1 . . . + 26 3 2 2 2 2 2 2 4 1 1 . . + 27 1 2 2 2 2 2 2 13 1 . . . + 28 1 2 2 2 2 2 2 1 2 . . . + 29 1 2 2 2 2 2 16 . . . . . + 30 3 2 2 2 2 3 . . . . . . + 31 3 2 2 2 2 . . . . . . . + 32 3 2 2 1 . . . . . . . . + 33 3 2 1 . . . . . . . . . + 34 5 . . . . . . . . . . . +; + +end; diff --git a/glpk-5.0/examples/pbn/pbn.mod b/glpk-5.0/examples/pbn/pbn.mod new file mode 100644 index 0000000..c4a1b2c --- /dev/null +++ b/glpk-5.0/examples/pbn/pbn.mod @@ -0,0 +1,268 @@ +/* PBN, Paint-By-Numbers Puzzle */ + +/* Written in GNU MathProg by Andrew Makhorin <mao@gnu.org> */ + +/* NOTE: See also the document "Solving Paint-By-Numbers Puzzles with + GLPK", which is included in the GLPK distribution. */ + +/* A paint-by-numbers puzzle consists of an m*n grid of pixels (the + canvas) together with m+n cluster-size sequences, one for each row + and column. The goal is to paint the canvas with a picture that + satisfies the following constraints: + + 1. Each pixel must be blank or white. + + 2. If a row or column has cluster-size sequence s1, s2, ..., sk, + then it must contain k clusters of black pixels - the first with + s1 black pixels, the second with s2 black pixels, and so on. + + It should be noted that "first" means "leftmost" for rows and + "topmost" for columns, and that rows and columns need not begin or + end with black pixels. + + Example: + 1 1 + 1 1 + 2 1 1 1 1 1 2 3 + 3 2 1 2 1 2 3 4 8 9 + + 3 6 # # # . # # # # # # + 1 4 # . . . . . # # # # + 1 1 3 . . # . # . . # # # + 2 . . . . . . . . # # + 3 3 . . # # # . . # # # + 1 4 # . . . . . # # # # + 2 5 # # . . . # # # # # + 2 5 # # . . . # # # # # + 1 1 . . . # . . . . . # + 3 . . # # # . . . . . + + (In Russia such puzzles are known as "Japanese crosswords".) + + References: + Robert A. Bosch, "Painting by Numbers", 2000. + <http://www.oberlin.edu/~math/faculty/bosch/pbn-page.html> */ + +/*--------------------------------------------------------------------*/ +/* Main part based on the formulation proposed by Robert Bosch. */ + +param m, integer, >= 1; +/* the number of rows */ + +param n, integer, >= 1; +/* the number of columns */ + +param row{i in 1..m, 1..(n+1) div 2}, integer, >= 0, default 0; +/* the cluster-size sequence for row i (raw data) */ + +param col{j in 1..n, 1..(m+1) div 2}, integer, >= 0, default 0; +/* the cluster-size sequence for column j (raw data) */ + +param kr{i in 1..m} := sum{t in 1..(n+1) div 2: row[i,t] > 0} 1; +/* the number of clusters in row i */ + +param kc{j in 1..n} := sum{t in 1..(m+1) div 2: col[j,t] > 0} 1; +/* the number of clusters in column j */ + +param sr{i in 1..m, t in 1..kr[i]} := row[i,t], integer, >= 1; +/* the cluster-size sequence for row i */ + +param sc{j in 1..n, t in 1..kc[j]} := col[j,t], integer, >= 1; +/* the cluster-size sequence for column j */ + +check{i in 1..m}: sum{t in 1..kr[i]} sr[i,t] <= n - (kr[i] - 1); +/* check that the sum of the cluster sizes in each row is valid */ + +check{j in 1..n}: sum{t in 1..kc[j]} sc[j,t] <= m - (kc[j] - 1); +/* check that the sum of the cluster sizes in each column is valid */ + +check: sum{i in 1..m, t in 1..kr[i]} sr[i,t] = + sum{j in 1..n, t in 1..kc[j]} sc[j,t]; +/* check that the sum of the cluster sizes in all rows is equal to the + sum of the cluster sizes in all columns */ + +param er{i in 1..m, t in 1..kr[i]} := + if t = 1 then 1 else er[i,t-1] + sr[i,t-1] + 1; +/* the smallest value of j such that row i's t-th cluster can be + placed in row i with its leftmost pixel occupying pixel j */ + +param lr{i in 1..m, t in 1..kr[i]} := + if t = kr[i] then n + 1 - sr[i,t] else lr[i,t+1] - sr[i,t] - 1; +/* the largest value of j such that row i's t-th cluster can be + placed in row i with its leftmost pixel occupying pixel j */ + +param ec{j in 1..n, t in 1..kc[j]} := + if t = 1 then 1 else ec[j,t-1] + sc[j,t-1] + 1; +/* the smallest value of i such that column j's t-th cluster can be + placed in column j with its topmost pixel occupying pixel i */ + +param lc{j in 1..n, t in 1..kc[j]} := + if t = kc[j] then m + 1 - sc[j,t] else lc[j,t+1] - sc[j,t] - 1; +/* the largest value of i such that column j's t-th cluster can be + placed in column j with its topmost pixel occupying pixel i */ + +var z{i in 1..m, j in 1..n}, binary; +/* z[i,j] = 1, if row i's j-th pixel is painted black + z[i,j] = 0, if row i's j-th pixel is painted white */ + +var y{i in 1..m, t in 1..kr[i], j in er[i,t]..lr[i,t]}, binary; +/* y[i,t,j] = 1, if row i's t-th cluster is placed in row i with its + leftmost pixel occupying pixel j + y[i,t,j] = 0, if not */ + +var x{j in 1..n, t in 1..kc[j], i in ec[j,t]..lc[j,t]}, binary; +/* x[j,t,i] = 1, if column j's t-th cluster is placed in column j with + its topmost pixel occupying pixel i + x[j,t,i] = 0, if not */ + +s.t. fa{i in 1..m, t in 1..kr[i]}: + sum{j in er[i,t]..lr[i,t]} y[i,t,j] = 1; +/* row i's t-th cluster must appear in row i exactly once */ + +s.t. fb{i in 1..m, t in 1..kr[i]-1, j in er[i,t]..lr[i,t]}: + y[i,t,j] <= sum{jp in j+sr[i,t]+1..lr[i,t+1]} y[i,t+1,jp]; +/* row i's (t+1)-th cluster must be placed to the right of its t-th + cluster */ + +s.t. fc{j in 1..n, t in 1..kc[j]}: + sum{i in ec[j,t]..lc[j,t]} x[j,t,i] = 1; +/* column j's t-th cluster must appear in column j exactly once */ + +s.t. fd{j in 1..n, t in 1..kc[j]-1, i in ec[j,t]..lc[j,t]}: + x[j,t,i] <= sum{ip in i+sc[j,t]+1..lc[j,t+1]} x[j,t+1,ip]; +/* column j's (t+1)-th cluster must be placed below its t-th cluster */ + +s.t. fe{i in 1..m, j in 1..n}: + z[i,j] <= sum{t in 1..kr[i], jp in er[i,t]..lr[i,t]: + j-sr[i,t]+1 <= jp and jp <= j} y[i,t,jp]; +/* the double coverage constraint stating that if row i's j-th pixel + is painted black, then at least one of row i's clusters must be + placed in such a way that it covers row i's j-th pixel */ + +s.t. ff{i in 1..m, j in 1..n}: + z[i,j] <= sum{t in 1..kc[j], ip in ec[j,t]..lc[j,t]: + i-sc[j,t]+1 <= ip and ip <= i} x[j,t,ip]; +/* the double coverage constraint making sure that if row i's j-th + pixel is painted black, then at least one of column j's clusters + covers it */ + +s.t. fg{i in 1..m, j in 1..n, t in 1..kr[i], jp in er[i,t]..lr[i,t]: + j-sr[i,t]+1 <= jp and jp <= j}: z[i,j] >= y[i,t,jp]; +/* the constraint to prevent white pixels from being covered by the + row clusters */ + +s.t. fh{i in 1..m, j in 1..n, t in 1..kc[j], ip in ec[j,t]..lc[j,t]: + i-sc[j,t]+1 <= ip and ip <= i}: z[i,j] >= x[j,t,ip]; +/* the constraint to prevent white pixels from being covered by the + column clusters */ + +/* this is a feasibility problem, so no objective is needed */ + +/*--------------------------------------------------------------------*/ +/* The following part is used only to check for multiple solutions. */ + +param zz{i in 1..m, j in 1..n}, binary, default 0; +/* zz[i,j] is z[i,j] for a previously found solution */ + +s.t. fz{1..1 : sum{i in 1..m, j in 1..n} zz[i,j] > 0}: + sum{i in 1..m, j in 1..n} + (if zz[i,j] then (1 - z[i,j]) else z[i,j]) >= 1; +/* the constraint to forbid finding a solution, which is identical to + the previously found one; this constraint is included in the model + only if the previously found solution specified by the parameter zz + is provided in the data section */ + +solve; + +/*--------------------------------------------------------------------*/ +/* Print solution to the standard output. */ + +for {i in 1..m} +{ printf{j in 1..n} " %s", if z[i,j] then "#" else "."; + printf "\n"; +} + +/*--------------------------------------------------------------------*/ +/* Write solution to a text file in PostScript format. */ + +param ps, symbolic, default "solution.ps"; + +printf "%%!PS-Adobe-3.0\n" > ps; +printf "%%%%Creator: GLPK (pbn.mod)\n" >> ps; +printf "%%%%BoundingBox: 0 0 %d %d\n", + 6 * (n + 2), 6 * (m + 2) >> ps; +printf "%%%%EndComments\n" >> ps; +printf "<</PageSize [%d %d]>> setpagedevice\n", + 6 * (n + 2), 6 * (m + 2) >> ps; +printf "0.1 setlinewidth\n" >> ps; +printf "/A { 2 copy 2 copy 2 copy newpath moveto exch 6 add exch line" & + "to\n" >> ps; +printf "exch 6 add exch 6 add lineto 6 add lineto closepath } bind de" & + "f\n" >> ps; +printf "/W { A stroke } def\n" >> ps; +printf "/B { A fill } def\n" >> ps; +printf {i in 1..m, j in 1..n} "%d %d %s\n", + (j - 1) * 6 + 6, (m - i) * 6 + 6, + if z[i,j] then "B" else "W" >> ps; +printf "%%%%EOF\n" >> ps; + +printf "Solution has been written to file %s\n", ps; + +/*--------------------------------------------------------------------*/ +/* Write solution to a text file in the form of MathProg data section, + which can be used later to check for multiple solutions. */ + +param dat, symbolic, default "solution.dat"; + +printf "data;\n" > dat; +printf "\n" >> dat; +printf "param zz :" >> dat; +printf {j in 1..n} " %d", j >> dat; +printf " :=\n" >> dat; +for {i in 1..m} +{ printf " %2d", i >> dat; + printf {j in 1..n} " %s", if z[i,j] then "1" else "." >> dat; + printf "\n" >> dat; +} +printf ";\n" >> dat; +printf "\n" >> dat; +printf "end;\n" >> dat; + +printf "Solution has also been written to file %s\n", dat; + +/*--------------------------------------------------------------------*/ +/* The following data correspond to the example above. */ + +data; + +param m := 10; + +param n := 10; + +param row : 1 2 3 := + 1 3 6 . + 2 1 4 . + 3 1 1 3 + 4 2 . . + 5 3 3 . + 6 1 4 . + 7 2 5 . + 8 2 5 . + 9 1 1 . + 10 3 . . +; + +param col : 1 2 3 4 := + 1 2 3 . . + 2 1 2 . . + 3 1 1 1 1 + 4 1 2 . . + 5 1 1 1 1 + 6 1 2 . . + 7 2 3 . . + 8 3 4 . . + 9 8 . . . + 10 9 . . . +; + +end; diff --git a/glpk-5.0/examples/pbn/pbn.pdf b/glpk-5.0/examples/pbn/pbn.pdf Binary files differnew file mode 100644 index 0000000..8342189 --- /dev/null +++ b/glpk-5.0/examples/pbn/pbn.pdf diff --git a/glpk-5.0/examples/pbn/pbn.tex b/glpk-5.0/examples/pbn/pbn.tex new file mode 100644 index 0000000..c73a441 --- /dev/null +++ b/glpk-5.0/examples/pbn/pbn.tex @@ -0,0 +1,279 @@ +%* pbn.tex *% + +\documentclass[11pt,draft]{article} +\usepackage{amssymb} + +\begin{document} + +\title{Solving Paint-By-Numbers Puzzles with GLPK} + +\author{Andrew Makhorin {\tt<mao@gnu.org>}} + +\date{August 2011} + +\maketitle + +\section{Introduction$^1$} + +\footnotetext[1]{This section is based on the material from [1].} + +A {\it paint-by-numbers} puzzle consists of an $m\times n$ grid of +pixels (the {\it canvas}) together with $m+n$ {\it cluster-size +sequences}, one for each row and column. The goal is to paint the canvas +with a picture that satisfies the following constraints: + +1. Each pixel must be blank or white. + +2. If a row or column has cluster-size sequence $s_1$, $s_2$, \dots, +$s_k$, then it must contain $k$ clusters of black pixels---the first +with $s_1$ black pixels, the second with $s_2$ black pixels, and so on. + +It should be noted that ``first'' means ``leftmost'' for rows and +``topmost'' for columns, and that rows and columns need not begin or end +with black pixels. + +\subsubsection*{Example} + +\def\arraystretch{.8} + +\begin{center} +\begin{tabular}{*{3}{@{$\;\;$}c}c*{10}{@{\ }c}@{}} + & & && & &1& &1& & & & & \\ + & & && & &1& &1& & & & & \\ + & & &&2&1&1&1&1&1&2&3& & \\ + & & &&3&2&1&2&1&2&3&4&8&9\\ +\\ + &3&6&&$\blacksquare$&$\blacksquare$&$\blacksquare$&$\square$& +$\blacksquare$&$\blacksquare$&$\blacksquare$&$\blacksquare$& +$\blacksquare$&$\blacksquare$\\ + &1&4&&$\blacksquare$&$\square$&$\square$&$\square$&$\square$& +$\square$&$\blacksquare$&$\blacksquare$&$\blacksquare$&$\blacksquare$\\ +1&1&3&&$\square$&$\square$&$\blacksquare$&$\square$&$\blacksquare$& +$\square$&$\square$&$\blacksquare$&$\blacksquare$&$\blacksquare$\\ + & &2&&$\square$&$\square$&$\square$&$\square$&$\square$&$\square$& +$\square$&$\square$&$\blacksquare$&$\blacksquare$\\ + &3&3&&$\square$&$\square$&$\blacksquare$&$\blacksquare$&$\blacksquare$& +$\square$&$\square$&$\blacksquare$&$\blacksquare$&$\blacksquare$\\ + &1&4&&$\blacksquare$&$\square$&$\square$&$\square$&$\square$&$\square$& +$\blacksquare$&$\blacksquare$&$\blacksquare$&$\blacksquare$\\ + &2&5&&$\blacksquare$&$\blacksquare$&$\square$&$\square$&$\square$& +$\blacksquare$&$\blacksquare$&$\blacksquare$&$\blacksquare$& +$\blacksquare$\\ + &2&5&&$\blacksquare$&$\blacksquare$&$\square$&$\square$&$\square$& +$\blacksquare$&$\blacksquare$&$\blacksquare$&$\blacksquare$& +$\blacksquare$\\ + &1&1&&$\square$&$\square$&$\square$&$\blacksquare$&$\square$&$\square$& +$\square$&$\square$&$\square$&$\blacksquare$\\ + & &3&&$\square$&$\square$&$\blacksquare$&$\blacksquare$&$\blacksquare$& +$\square$&$\square$&$\square$&$\square$&$\square$\\ +\end{tabular} +\end{center} + +\def\arraystretch{1} + +\section{Solving a puzzle} + +The Paint-By-Numbers puzzle can be formulated as a 0-1 integer +feasibility problem. The formulation used in GLPK was proposed in [1]. + +For solving puzzles there are used two components, which both are +coded in the GNU MathProg modeling language [2]: the model section and +the data section. The model section is common for all puzzles and +placed in file \verb|pbn.mod|. This file is included in the GLPK +distribution and can be found in subdirectory \verb|examples/pbn|. + +To solve a particular puzzle the user only needs to prepare the data +section, which defines input data to the puzzle. The data section for +the example puzzle from the previous section may look like follows +(here \verb|m| is the number of rows, and \verb|n| is the number of +columns): + +\begin{footnotesize} +\begin{verbatim} +data; + +param m := 10; + +param n := 10; + +param row : 1 2 3 := + 1 3 6 . + 2 1 4 . + 3 1 1 3 + 4 2 . . + 5 3 3 . + 6 1 4 . + 7 2 5 . + 8 2 5 . + 9 1 1 . + 10 3 . . +; + +param col : 1 2 3 4 := + 1 2 3 . . + 2 1 2 . . + 3 1 1 1 1 + 4 1 2 . . + 5 1 1 1 1 + 6 1 2 . . + 7 2 3 . . + 8 3 4 . . + 9 8 . . . + 10 9 . . . +; + +end; +\end{verbatim} +\end{footnotesize} + +\newpage + +Let the data section for a puzzle be placed in file \verb|foo.dat|. +Then to solve the puzzle the user should enter the following command: + +\begin{verbatim} + glpsol --minisat -m pbn.mod -d foo.dat +\end{verbatim} + +\noindent +This command invokes \verb|glpsol|, the GLPK LP/MIP stand-alone solver, +which reads the model section from file \verb|pbn.mod|, the data section +from file \verb|foo.dat|, translates them to an internal representation, +and solves the resulting 0-1 integer feasibility problem. The option +\verb|--minisat| tells \verb|glpsol| to translate the feasibility +problem to a CNF satisfiability problem and then use the MiniSat solver +[3] to solve it. + +If a solution to the puzzle has been found, that is indicated by the +message \verb|SATISFIABLE|, \verb|glpsol| prints the solution to the +standard output (terminal), writes it to file \verb|solution.ps| in the +PostScript format, and also writes it to file \verb|solution.dat| in the +form of MathProg data section, which can be used later to check for +multiple solutions, if necessary (for details see the next section). +The message \verb|UNSATISFIABLE| means that the puzzle has no solution. + +Usually the time taken to solve a puzzle of moderate size (up to 50 rows +and columns) varies from several seconds to several minutes. However, +hard or large puzzles may require much more time. + +Data sections for some example puzzles included in the GLPK distribution +can be found in subdirectory \verb|examples/pbn|. + +\section{Checking for multiple solutions} + +Sometimes the user may be interested to know if the puzzle has exactly +one (unique) solution or it has multiple solutions. To check that the +user should solve the puzzle as explained above in the previous section +and then enter the following command: + +\begin{verbatim} + glpsol --minisat -m pbn.mod -d foo.dat -d solution.dat +\end{verbatim} + +\noindent +In this case \verb|glpsol| reads an additional data section from file +\verb|solution.dat|, which contains the previously found solution, +activates an additional constraint in the model section to forbid +finding the solution specified in the additional data section, and +attempts to find another solution. The message \verb|UNSATISFIABLE| +reported by \verb|glpsol| will mean that the puzzle has a unique +solution, while the message \verb|SATISFIABLE| will mean that the puzzle +has at least two different solutions. + +\newpage + +\section{Solution times} + +The table on the next page shows solution times on a sample set of +the paint-by-numbers puzzles from the \verb|<webpbn.com>| website. +This sample set was used in the survey [4] to compare efficiency of +existing PBN solvers. + +The authors of some puzzles from the sample set have given permission +for their puzzles to be freely redistributed as long as the original +attribution and copyright statement are retained. In the table these +puzzles are marked by an asterisk (*). The files containing the +MathProg data sections for these puzzles are included in the GLPK +distribution and can be found in subdirectory \verb|examples/pbn|. + +All runs were performed on Intel Pentium 4 (CPU 3GHz, 2GB of RAM). +The C compiler used was GCC 3.4.4 with default optimization options. + +The column `Sol.Time' shows the time, in seconds, taken by the +\verb|glpsol| solver to find a solution to corresponding puzzle. The +column `Chk.Time' shows the time, in seconds, taken by \verb|glpsol| to +check for multiple solutions, i.e. either to prove that the puzzle has +a unique solution or find another solution to the puzzle. Both these +times do not include the time used to translate the MathProg model and +data sections into an internal MIP representation, but include the time +used to translate the 0-1 feasibility problem to a CNF satisfiability +problem. + +\begin{thebibliography}{10} + +\bibitem{1} +Robert A. Bosch, ``Painting by Numbers'', 2000.\\ +\verb|<http://www.oberlin.edu/~math/faculty/bosch/pbn-page.html>|. + +\bibitem{2} +GLPK: Modeling Language GNU MathProg. Language Reference. (This +document is included in the GLPK distribution and can be found in +subdirectory \verb|doc|.) + +\bibitem{3} +Niklas E\'en, Niklas S\"orensson, ``An Extensible SAT-solver'', +Chalmers University of Technology, Sweden. \verb|<http://minisat.se/>|. + +\bibitem{4} +Jan Wolter, ``Survey of Paint-by-Number Puzzle Solvers''.\\ +\verb|<http://webpbn.com/survey/>|. + +\end{thebibliography} + +\newpage + +\begin{table} +\caption{Solution times on the sample set of puzzles from [4]} +\begin{center} +\begin{tabular}{@{}lllcrr@{}} +\hline +\multicolumn{2}{c}{Puzzle}&Size&Notes&Sol.Time, s&Chk.Time, s\\ +\hline +\#1&Dancer* &$10\times 5$&L&$<1$&$<1$\\ +\#6&Cat* &$20\times 20$&L&$<1$&$<1$\\ +\#21&Skid* &$25\times 14$&L, B&$<1$&$<1$\\ +\#27&Bucks* &$23\times 27$&B&$<1$&$<1$\\ +\#23&Edge* &$11\times 10$&&$<1$&$<1$\\ +\#2413&Smoke &$20\times 20$&&$<1$&$<1$\\ +\#16&Knot* &$34\times 34$&L&1&1\\ +\#529&Swing* &$45\times 45$&L&1&1\\ +\#65&Mum* &$40\times 34$&&1&1\\ +\#7604&DiCap &$55\times 55$&&10&10\\ +\#1694&Tragic &$50\times 45$&&3&3\\ +\#1611&Merka &$60\times 55$&B&4&4\\ +\#436&Petro* &$35\times 40$&&1&1\\ +\#4645&M\&M &$70\times 50$&B&5&6\\ +\#3541&Signed &$50\times 60$&&7&7\\ +\#803&Light* &$45\times 50$&B&1&1\\ +\#6574&Forever*&$25\times 25$&&1&1\\ +\#2040&Hot &$60\times 55$&&6&6\\ +\#6739&Karate &$40\times 40$&M&2&2\\ +\#8098&9-Dom* &$19\times 19$&&1&2\\ +\#2556&Flag &$45\times 65$&M, B&2&2\\ +\#2712&Lion &$47\times 47$&M&11&12\\ +\#10088&Marley &$63\times 52$&M&135&226\\ +\#9892&Nature &$40\times 50$&M&850&1053\\ +\hline +\end{tabular} + +\begin{tabular}{@{}lp{102mm}@{}} +*&Puzzle designer has given permission to redistribute the puzzle.\\ +L&Puzzle is line solvable. That is, it can be solved one line at a +time.\\ +B&Puzzle contains blank rows or columns.\\ +M&Puzzle has multiple solutions.\\ +\end{tabular} +\end{center} +\end{table} + +\end{document} diff --git a/glpk-5.0/examples/pbn/petro.dat b/glpk-5.0/examples/pbn/petro.dat new file mode 100644 index 0000000..15ccc4a --- /dev/null +++ b/glpk-5.0/examples/pbn/petro.dat @@ -0,0 +1,102 @@ +/* petro.dat */ + +/*********************************************************************** +* Web Paint-by-Number Puzzle #436 from <www.webpbn.com>. +* Copyright (C) 2006 by Jan Wolter. Used by permission. +* +* Old Stone Face +* +* created by Jan Wolter +* Jun 17, 2006 +* +* Encoded in GNU MathProg by Andrew Makhorin <mao@gnu.org>. +***********************************************************************/ + +data; + +param m := 35; + +param n := 40; + +param row : 1 2 3 4 5 6 7 8 9 := + 1 2 2 . . . . . . . + 2 2 3 2 . . . . . . + 3 3 3 3 2 . . . . . + 4 3 3 3 3 . . . . . + 5 2 3 3 3 3 2 . . . + 6 3 3 3 3 3 3 . . . + 7 4 2 3 2 2 4 . . . + 8 4 2 2 2 2 3 1 . . + 9 3 1 2 2 2 3 3 . . + 10 3 2 2 2 2 2 4 . . + 11 3 2 15 2 4 . . . . + 12 5 19 4 . . . . . . + 13 6 4 3 3 . . . . . + 14 6 4 4 . . . . . . + 15 2 4 6 2 . . . . . + 16 2 2 3 3 3 2 . . . + 17 9 2 2 2 3 9 . . . + 18 10 2 2 2 2 2 10 . . + 19 4 2 3 3 2 2 3 2 5 + 20 2 5 2 4 2 . . . . + 21 5 3 2 2 5 . . . . + 22 6 3 2 3 7 . . . . + 23 6 8 9 7 . . . . . + 24 4 8 7 5 . . . . . + 25 4 . . . . . . . . + 26 2 . . . . . . . . + 27 2 . . . . . . . . + 28 14 . . . . . . . . + 29 16 . . . . . . . . + 30 3 3 . . . . . . . + 31 2 2 . . . . . . . + 32 2 2 . . . . . . . + 33 4 4 . . . . . . . + 34 16 . . . . . . . . + 35 12 . . . . . . . . +; + +param col : 1 2 3 4 5 6 7 := + 1 1 . . . . . . + 2 3 2 . . . . . + 3 2 3 3 . . . . + 4 3 3 3 . . . . + 5 3 3 3 3 . . . + 6 4 2 2 2 . . . + 7 3 3 2 3 . . . + 8 3 2 2 2 . . . + 9 3 2 6 . . . . + 10 2 9 . . . . . + 11 2 3 3 . . . . + 12 4 4 3 2 4 . . + 13 7 2 5 2 6 . . + 14 12 2 3 2 3 2 . + 15 3 1 2 2 2 3 . + 16 2 2 3 2 2 2 . + 17 6 2 6 2 2 2 . + 18 12 4 3 2 2 . . + 19 12 2 2 2 . . . + 20 2 6 2 . . . . + 21 2 6 5 2 . . . + 22 10 9 2 2 . . . + 23 12 3 3 2 2 . . + 24 6 2 2 2 2 2 2 + 25 2 2 3 2 2 2 . + 26 4 3 2 2 2 3 . + 27 7 3 3 2 3 2 . + 28 5 3 5 2 6 . . + 29 4 3 3 3 4 . . + 30 3 5 3 . . . . + 31 3 9 . . . . . + 32 4 2 6 . . . . + 33 4 2 2 2 . . . + 34 4 2 2 3 . . . + 35 3 2 2 3 . . . + 36 3 3 3 . . . . + 37 3 3 3 . . . . + 38 4 3 3 . . . . + 39 2 3 3 . . . . + 40 2 1 . . . . . +; + +end; diff --git a/glpk-5.0/examples/pbn/skid.dat b/glpk-5.0/examples/pbn/skid.dat new file mode 100644 index 0000000..865c73b --- /dev/null +++ b/glpk-5.0/examples/pbn/skid.dat @@ -0,0 +1,66 @@ +/* skid.dat */ + +/*********************************************************************** +* Web Paint-by-Number Puzzle #21 from <www.webpbn.com>. +* Copyright (C) 2004 by Jan Wolter. Used by permission. +* +* Slippery Conditions +* +* created by Jan Wolter +* Apr 4, 2004 +* +* Encoded in GNU MathProg by Andrew Makhorin <mao@gnu.org>. +***********************************************************************/ + +data; + +param m := 25; + +param n := 14; + +param row : 1 2 3 := + 1 9 . . + 2 1 1 . + 3 1 1 1 + 4 1 3 1 + 5 13 . . + 6 13 . . + 7 13 . . + 8 13 . . + 9 2 2 . + 10 2 2 . + 11 . . . + 12 2 2 . + 13 2 2 . + 14 2 2 . + 15 2 2 . + 16 2 2 . + 17 2 2 . + 18 2 2 . + 19 2 2 . + 20 2 2 . + 21 2 2 . + 22 2 2 . + 23 2 2 . + 24 2 2 . + 25 2 2 . +; + +param col : 1 2 3 4 5 := + 1 2 . . . . + 2 4 6 . . . + 3 9 4 4 2 . + 4 1 6 2 6 . + 5 1 5 2 . . + 6 1 6 . . . + 7 1 5 . . . + 8 1 4 . . . + 9 1 4 . . . + 10 1 4 2 . . + 11 1 4 6 . . + 12 1 6 4 4 2 + 13 9 2 6 . . + 14 4 2 . . . +; + +end; diff --git a/glpk-5.0/examples/pbn/swing.dat b/glpk-5.0/examples/pbn/swing.dat new file mode 100644 index 0000000..547e0db --- /dev/null +++ b/glpk-5.0/examples/pbn/swing.dat @@ -0,0 +1,117 @@ +/* swing.dat */ + +/*********************************************************************** +* Web Paint-by-Number Puzzle #529 from <www.webpbn.com>. +* Copyright (C) 2006 by Jan Wolter. Used by permission. +* +* Swing +* +* created by Jan Wolter +* Sep 28, 2006 +* +* Encoded in GNU MathProg by Andrew Makhorin <mao@gnu.org>. +***********************************************************************/ + +data; + +param m := 45; + +param n := 45; + +param row : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 := + 1 7 1 1 1 1 1 . . . . . . . . + 2 3 1 3 1 4 1 4 1 5 1 5 1 2 . + 3 1 1 1 3 1 4 1 4 1 5 1 5 1 2 + 4 2 1 2 1 1 1 1 6 2 . . . . . + 5 3 30 1 5 . . . . . . . . . . + 6 1 5 8 1 1 7 1 1 3 . . . . . + 7 3 4 8 1 5 1 2 . . . . . . . + 8 3 20 6 6 . . . . . . . . . . + 9 3 3 7 2 5 1 . . . . . . . . + 10 3 3 1 1 9 1 1 5 6 . . . . . + 11 2 3 8 1 3 4 2 . . . . . . . + 12 5 3 1 10 4 5 2 . . . . . . . + 13 1 2 3 8 4 6 . . . . . . . . + 14 2 2 3 11 10 . . . . . . . . . + 15 2 2 3 10 7 . . . . . . . . . + 16 2 3 1 7 12 2 . . . . . . . . + 17 2 3 1 4 11 2 . . . . . . . . + 18 4 1 2 1 11 2 . . . . . . . . + 19 9 1 2 9 . . . . . . . . . . + 20 6 2 1 4 11 . . . . . . . . . + 21 2 5 1 2 6 6 . . . . . . . . + 22 6 2 4 8 4 . . . . . . . . . + 23 4 2 16 1 . . . . . . . . . . + 24 2 2 15 2 . . . . . . . . . . + 25 3 2 15 4 . . . . . . . . . . + 26 3 3 13 4 . . . . . . . . . . + 27 4 12 9 . . . . . . . . . . . + 28 1 9 10 . . . . . . . . . . . + 29 2 1 17 7 2 . . . . . . . . . + 30 2 2 8 3 8 2 . . . . . . . . + 31 2 3 6 3 8 2 . . . . . . . . + 32 2 4 5 4 7 2 . . . . . . . . + 33 2 5 5 4 6 . . . . . . . . . + 34 4 4 5 4 9 . . . . . . . . . + 35 1 4 6 4 4 . . . . . . . . . + 36 4 3 6 4 3 2 . . . . . . . . + 37 2 1 2 7 4 4 2 . . . . . . . + 38 2 2 2 9 5 5 2 . . . . . . . + 39 2 2 2 10 6 6 . . . . . . . . + 40 3 2 1 9 18 . . . . . . . . . + 41 8 4 23 . . . . . . . . . . . + 42 1 2 1 2 2 1 1 1 2 . . . . . + 43 2 1 4 2 1 4 1 5 1 3 1 2 . . + 44 2 1 5 4 4 1 5 1 3 1 2 . . . + 45 1 10 1 1 1 . . . . . . . . . +; + +param col : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 := + 1 7 1 1 1 1 1 . . . . . . . . + 2 2 2 4 1 4 1 5 1 4 1 4 1 2 . + 3 3 1 4 1 4 1 14 4 1 2 . . . . + 4 1 1 5 1 2 3 4 1 . . . . . . + 5 3 13 1 10 . . . . . . . . . . + 6 1 9 4 . . . . . . . . . . . + 7 6 7 2 2 . . . . . . . . . . + 8 8 4 1 4 . . . . . . . . . . + 9 2 8 3 2 5 3 . . . . . . . . + 10 10 1 3 7 2 . . . . . . . . . + 11 8 6 2 8 1 2 . . . . . . . . + 12 1 1 2 2 8 1 1 . . . . . . . + 13 2 1 1 1 2 1 3 1 3 3 1 . . . + 14 2 1 1 1 5 4 2 1 . . . . . . + 15 2 1 1 1 1 7 2 1 . . . . . . + 16 2 1 1 2 9 1 2 1 . . . . . . + 17 4 6 12 1 3 . . . . . . . . . + 18 16 13 3 2 . . . . . . . . . . + 19 12 21 2 . . . . . . . . . . . + 20 2 13 23 . . . . . . . . . . . + 21 2 14 19 . . . . . . . . . . . + 22 2 14 20 2 . . . . . . . . . . + 23 2 13 7 2 8 2 . . . . . . . . + 24 12 8 1 7 2 . . . . . . . . . + 25 5 1 1 1 2 8 1 5 2 . . . . . + 26 2 1 1 1 9 1 1 4 . . . . . . + 27 2 1 1 1 6 1 3 5 . . . . . . + 28 2 2 1 5 6 2 . . . . . . . . + 29 2 1 3 1 3 7 3 2 . . . . . . + 30 2 3 2 1 1 2 4 4 2 . . . . . + 31 2 2 1 1 2 3 1 8 2 . . . . . + 32 9 3 1 7 2 . . . . . . . . . + 33 12 4 1 6 2 . . . . . . . . . + 34 7 4 1 2 5 . . . . . . . . . + 35 2 6 6 5 6 . . . . . . . . . + 36 8 8 6 3 . . . . . . . . . . + 37 3 10 8 4 2 . . . . . . . . . + 38 5 11 9 5 2 . . . . . . . . . + 39 3 1 12 16 2 . . . . . . . . . + 40 3 1 12 16 . . . . . . . . . . + 41 5 2 13 21 . . . . . . . . . . + 42 6 1 3 3 1 1 . . . . . . . . + 43 5 1 3 1 3 1 1 2 1 4 1 3 1 3 + 44 5 1 3 1 3 1 4 1 4 1 3 1 3 . + 45 1 1 1 1 1 1 . . . . . . . . +; + +end; diff --git a/glpk-5.0/examples/pentomino.mod b/glpk-5.0/examples/pentomino.mod new file mode 100644 index 0000000..56aca7e --- /dev/null +++ b/glpk-5.0/examples/pentomino.mod @@ -0,0 +1,460 @@ +/* PENTOMINO, a geometric placement puzzle */ + +/* Written in GNU MathProg by Andrew Makhorin <mao@gnu.org> */ + +/* A pentomino is a plane geometric figure by joining five equal + squares edge to edge. It is a polyomino with five cells. Pentominoes + were defined by Prof. Solomon W. Golomb in his book "Polyominoes: + Puzzles, Patterns, Problems, and Packings." + + There are twelve pentominoes, not counting rotations and reflections + as distinct: + + +---+ + | | + +---+ +---+ +---+ + | | | | | | + +---+---+ +---+ +---+ +---+ + | | | | | | | | | + +---+---+---+ +---+ +---+ +---+---+ + | | | | | | | | | | + +---+---+ +---+ +---+---+ +---+---+ + | | | | | | | | | + +---+ +---+ +---+---+ +---+ + F I L N + + +---+---+ +---+---+---+ +---+ + | | | | | | | | | + +---+---+ +---+---+---+ +---+ +---+ +---+ + | | | | | | | | | | | + +---+---+ +---+ +---+---+---+ +---+---+---+ + | | | | | | | | | | | | + +---+ +---+ +---+---+---+ +---+---+---+ + P T U V + + +---+ + | | + +---+ +---+ +---+---+ +---+---+ + | | | | | | | | | | + +---+---+ +---+---+---+ +---+---+ +---+---+ + | | | | | | | | | | | + +---+---+---+ +---+---+---+ +---+ +---+---+ + | | | | | | | | | | + +---+---+ +---+ +---+ +---+---+ + W X Y Z + + + A classic pentomino puzzle is to tile a given outline, i.e. cover + it without overlap and without gaps. Each of 12 pentominoes has an + area of 5 unit squares, so the outline must have area of 60 units. + Note that it is allowed to rotate and reflect the pentominoes. + + (From Wikipedia, the free encyclopedia.) */ + +set A; +check card(A) = 12; +/* basic set of pentominoes */ + +set B{a in A}; +/* B[a] is a set of distinct versions of pentomino a obtained by its + rotations and reflections */ + +set C := setof{a in A, b in B[a]} b; +check card(C) = 63; +/* set of distinct versions of all pentominoes */ + +set D{c in C}, within {0..4} cross {0..4}; +/* D[c] is a set of squares (i,j), relative to (0,0), that constitute + a distinct version of pentomino c */ + +param m, default 6; +/* number of rows in the outline */ + +param n, default 10; +/* number of columns in the outline */ + +set R, default {1..m} cross {1..n}; +/* set of squares (i,j), relative to (1,1), of the outline to be tiled + with the pentominoes */ + +check card(R) = 60; +/* the outline must have exactly 60 squares */ + +set S := setof{c in C, i in 1..m, j in 1..n: + forall{(ii,jj) in D[c]} ((i+ii,j+jj) in R)} (c,i,j); +/* set of all possible placements, where triplet (c,i,j) means that + the base square (0,0) of a distinct version of pentomino c is placed + at square (i,j) of the outline */ + +var x{(c,i,j) in S}, binary; +/* x[c,i,j] = 1 means that placement (c,i,j) is used in the tiling */ + +s.t. use{a in A}: sum{(c,i,j) in S: substr(c,1,1) = a} x[c,i,j] = 1; +/* every pentomino must be used exactly once */ + +s.t. cov{(i,j) in R}: + sum{(c,ii,jj) in S: (i-ii, j-jj) in D[c]} x[c,ii,jj] = 1; +/* every square of the outline must be covered exactly once */ + +/* this is a feasibility problem, so no objective is needed */ + +solve; + +for {i in 1..m} +{ for {j in 1..n} + { for {0..0: (i,j) in R} + { for {(c,ii,jj) in S: (i-ii,j-jj) in D[c] and x[c,ii,jj]} + printf " %s", substr(c,1,1); + } + for {0..0: (i,j) not in R} + printf " ."; + } + printf "\n"; +} + +data; + +/* These data correspond to a puzzle from the book "Pentominoes" by + Jon Millington */ + +param m := 8; + +param n := 15; + +set R : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 := + 1 - - - - - - - + - - - - - - - + 2 - - - - - - + + + - - - - - - + 3 - - - - - + + + + + - - - - - + 4 - - - - + + + - + + + - - - - + 5 - - - + + + + - + + + + - - - + 6 - - + + + + + - + + + + + - - + 7 - + + + + + + - + + + + + + - + 8 + + + + + + + + + + + + + + + ; + +/* DO NOT CHANGE ANY DATA BELOW! */ + +set A := F, I, L, N, P, T, U, V, W, X, Y, Z; + +set B[F] := F1, F2, F3, F4, F5, F6, F7, F8; +set B[I] := I1, I2; +set B[L] := L1, L2, L3, L4, L5, L6, L7, L8; +set B[N] := N1, N2, N3, N4, N5, N6, N7, N8; +set B[P] := P1, P2, P3, P4, P5, P6, P7, P8; +set B[T] := T1, T2, T3, T4; +set B[U] := U1, U2, U3, U4; +set B[V] := V1, V2, V3, V4; +set B[W] := W1, W2, W3, W4; +set B[X] := X; +set B[Y] := Y1, Y2, Y3, Y4, Y5, Y6, Y7, Y8; +set B[Z] := Z1, Z2, Z3, Z4; + +set D[F1] : 0 1 2 := + 0 - + + + 1 + + - + 2 - + - ; + +set D[F2] : 0 1 2 := + 0 - + - + 1 + + + + 2 - - + ; + +set D[F3] : 0 1 2 := + 0 - + - + 1 - + + + 2 + + - ; + +set D[F4] : 0 1 2 := + 0 + - - + 1 + + + + 2 - + - ; + +set D[F5] : 0 1 2 := + 0 + + - + 1 - + + + 2 - + - ; + +set D[F6] : 0 1 2 := + 0 - - + + 1 + + + + 2 - + - ; + +set D[F7] : 0 1 2 := + 0 - + - + 1 + + - + 2 - + + ; + +set D[F8] : 0 1 2 := + 0 - + - + 1 + + + + 2 + - - ; + +set D[I1] : 0 := + 0 + + 1 + + 2 + + 3 + + 4 + ; + +set D[I2] : 0 1 2 3 4 := + 0 + + + + + ; + +set D[L1] : 0 1 := + 0 + - + 1 + - + 2 + - + 3 + + ; + +set D[L2] : 0 1 2 3 := + 0 + + + + + 1 + - - - ; + +set D[L3] : 0 1 := + 0 + + + 1 - + + 2 - + + 3 - + ; + +set D[L4] : 0 1 2 3 := + 0 - - - + + 1 + + + + ; + +set D[L5] : 0 1 := + 0 - + + 1 - + + 2 - + + 3 + + ; + +set D[L6] : 0 1 2 3 := + 0 + - - - + 1 + + + + ; + +set D[L7] : 0 1 := + 0 + + + 1 + - + 2 + - + 3 + - ; + +set D[L8] : 0 1 2 3 := + 0 + + + + + 1 - - - + ; + +set D[N1] : 0 1 := + 0 + - + 1 + - + 2 + + + 3 - + ; + +set D[N2] : 0 1 2 3 := + 0 - + + + + 1 + + - - ; + +set D[N3] : 0 1 := + 0 + - + 1 + + + 2 - + + 3 - + ; + +set D[N4] : 0 1 2 3 := + 0 - - + + + 1 + + + - ; + +set D[N5] : 0 1 := + 0 - + + 1 - + + 2 + + + 3 + - ; + +set D[N6] : 0 1 2 3 := + 0 + + - - + 1 - + + + ; + +set D[N7] : 0 1 := + 0 - + + 1 + + + 2 + - + 3 + - ; + +set D[N8] : 0 1 2 3 := + 0 + + + - + 1 - - + + ; + +set D[P1] : 0 1 := + 0 + + + 1 + + + 2 + - ; + +set D[P2] : 0 1 2 := + 0 + + + + 1 - + + ; + +set D[P3] : 0 1 := + 0 - + + 1 + + + 2 + + ; + +set D[P4] : 0 1 2 := + 0 + + - + 1 + + + ; + +set D[P5] : 0 1 := + 0 + + + 1 + + + 2 - + ; + +set D[P6] : 0 1 2 := + 0 - + + + 1 + + + ; + +set D[P7] : 0 1 := + 0 + - + 1 + + + 2 + + ; + +set D[P8] : 0 1 2 := + 0 + + + + 1 + + - ; + +set D[T1] : 0 1 2 := + 0 + + + + 1 - + - + 2 - + - ; + +set D[T2] : 0 1 2 := + 0 - - + + 1 + + + + 2 - - + ; + +set D[T3] : 0 1 2 := + 0 - + - + 1 - + - + 2 + + + ; + +set D[T4] : 0 1 2 := + 0 + - - + 1 + + + + 2 + - - ; + +set D[U1] : 0 1 2 := + 0 + - + + 1 + + + ; + +set D[U2] : 0 1 := + 0 + + + 1 + - + 2 + + ; + +set D[U3] : 0 1 2 := + 0 + + + + 1 + - + ; + +set D[U4] : 0 1 := + 0 + + + 1 - + + 2 + + ; + +set D[V1] : 0 1 2 := + 0 - - + + 1 - - + + 2 + + + ; + +set D[V2] : 0 1 2 := + 0 + - - + 1 + - - + 2 + + + ; + +set D[V3] : 0 1 2 := + 0 + + + + 1 + - - + 2 + - - ; + +set D[V4] : 0 1 2 := + 0 + + + + 1 - - + + 2 - - + ; + +set D[W1] : 0 1 2 := + 0 - - + + 1 - + + + 2 + + - ; + +set D[W2] : 0 1 2 := + 0 + - - + 1 + + - + 2 - + + ; + +set D[W3] : 0 1 2 := + 0 - + + + 1 + + - + 2 + - - ; + +set D[W4] : 0 1 2 := + 0 + + - + 1 - + + + 2 - - + ; + +set D[X] : 0 1 2 := + 0 - + - + 1 + + + + 2 - + - ; + +set D[Y1] : 0 1 := + 0 + - + 1 + - + 2 + + + 3 + - ; + +set D[Y2] : 0 1 2 3 := + 0 + + + + + 1 - + - - ; + +set D[Y3] : 0 1 := + 0 - + + 1 + + + 2 - + + 3 - + ; + +set D[Y4] : 0 1 2 3 := + 0 - - + - + 1 + + + + ; + +set D[Y5] : 0 1 := + 0 - + + 1 - + + 2 + + + 3 - + ; + +set D[Y6] : 0 1 2 3 := + 0 - + - - + 1 + + + + ; + +set D[Y7] : 0 1 := + 0 + - + 1 + + + 2 + - + 3 + - ; + +set D[Y8] : 0 1 2 3 := + 0 + + + + + 1 - - + - ; + +set D[Z1] : 0 1 2 := + 0 - + + + 1 - + - + 2 + + - ; + +set D[Z2] : 0 1 2 := + 0 + - - + 1 + + + + 2 - - + ; + +set D[Z3] : 0 1 2 := + 0 + + - + 1 - + - + 2 - + + ; + +set D[Z4] : 0 1 2 := + 0 - - + + 1 + + + + 2 + - - ; + +end; diff --git a/glpk-5.0/examples/plan.lp b/glpk-5.0/examples/plan.lp new file mode 100644 index 0000000..cab6494 --- /dev/null +++ b/glpk-5.0/examples/plan.lp @@ -0,0 +1,39 @@ +\* plan.lp *\ + +Minimize + value: .03 bin1 + .08 bin2 + .17 bin3 + .12 bin4 + .15 bin5 + + .21 alum + .38 silicon + +Subject To + yield: bin1 + bin2 + bin3 + bin4 + bin5 + + alum + silicon = 2000 + + fe: .15 bin1 + .04 bin2 + .02 bin3 + .04 bin4 + .02 bin5 + + .01 alum + .03 silicon <= 60 + + cu: .03 bin1 + .05 bin2 + .08 bin3 + .02 bin4 + .06 bin5 + + .01 alum <= 100 + + mn: .02 bin1 + .04 bin2 + .01 bin3 + .02 bin4 + .02 bin5 <= 40 + + mg: .02 bin1 + .03 bin2 + .01 bin5 <= 30 + + al: .70 bin1 + .75 bin2 + .80 bin3 + .75 bin4 + .80 bin5 + + .97 alum >= 1500 + + si1: .02 bin1 + .06 bin2 + .08 bin3 + .12 bin4 + .02 bin5 + + .01 alum + .97 silicon >= 250 + + si2: .02 bin1 + .06 bin2 + .08 bin3 + .12 bin4 + .02 bin5 + + .01 alum + .97 silicon <= 300 + +Bounds + bin1 <= 200 + bin2 <= 2500 + 400 <= bin3 <= 800 + 100 <= bin4 <= 700 + bin5 <= 1500 + +End + +\* eof *\ diff --git a/glpk-5.0/examples/plan.mod b/glpk-5.0/examples/plan.mod new file mode 100644 index 0000000..effe838 --- /dev/null +++ b/glpk-5.0/examples/plan.mod @@ -0,0 +1,39 @@ +/* plan.mod */ + +var bin1, >= 0, <= 200; +var bin2, >= 0, <= 2500; +var bin3, >= 400, <= 800; +var bin4, >= 100, <= 700; +var bin5, >= 0, <= 1500; +var alum, >= 0; +var silicon, >= 0; + +minimize + +value: .03 * bin1 + .08 * bin2 + .17 * bin3 + .12 * bin4 + .15 * bin5 + + .21 * alum + .38 * silicon; + +subject to + +yield: bin1 + bin2 + bin3 + bin4 + bin5 + alum + silicon = 2000; + +fe: .15 * bin1 + .04 * bin2 + .02 * bin3 + .04 * bin4 + .02 * bin5 + + .01 * alum + .03 * silicon <= 60; + +cu: .03 * bin1 + .05 * bin2 + .08 * bin3 + .02 * bin4 + .06 * bin5 + + .01 * alum <= 100; + +mn: .02 * bin1 + .04 * bin2 + .01 * bin3 + .02 * bin4 + .02 * bin5 + <= 40; + +mg: .02 * bin1 + .03 * bin2 + .01 * bin5 <= 30; + +al: .70 * bin1 + .75 * bin2 + .80 * bin3 + .75 * bin4 + .80 * bin5 + + .97 * alum >= 1500; + +si: 250 <= .02 * bin1 + .06 * bin2 + .08 * bin3 + .12 * bin4 + + .02 * bin5 + .01 * alum + .97 * silicon <= 300; + +end; + +/* eof */ diff --git a/glpk-5.0/examples/plan.mps b/glpk-5.0/examples/plan.mps new file mode 100644 index 0000000..b6bb094 --- /dev/null +++ b/glpk-5.0/examples/plan.mps @@ -0,0 +1,54 @@ +*000000001111111111222222222233333333334444444444555555555566 +*234567890123456789012345678901234567890123456789012345678901 +NAME PLAN +ROWS + N VALUE + E YIELD + L FE + L CU + L MN + L MG + G AL + L SI +COLUMNS + BIN1 VALUE .03000 YIELD 1.00000 + FE .15000 CU .03000 + MN .02000 MG .02000 + AL .70000 SI .02000 + BIN2 VALUE .08000 YIELD 1.00000 + FE .04000 CU .05000 + MN .04000 MG .03000 + AL .75000 SI .06000 + BIN3 VALUE .17000 YIELD 1.00000 + FE .02000 CU .08000 + MN .01000 AL .80000 + SI .08000 + BIN4 VALUE .12000 YIELD 1.00000 + FE .04000 CU .02000 + MN .02000 AL .75000 + SI .12000 + BIN5 VALUE .15000 YIELD 1.00000 + FE .02000 CU .06000 + MN .02000 MG .01000 + AL .80000 SI .02000 + ALUM VALUE .21000 YIELD 1.00000 + FE .01000 CU .01000 + AL .97000 SI .01000 + SILICON VALUE .38000 YIELD 1.00000 + FE .03000 SI .97000 +RHS + RHS1 YIELD 2000.00000 FE 60.00000 + CU 100.00000 MN 40.00000 + SI 300.00000 + MG 30.00000 AL 1500.00000 +RANGES + RNG1 SI 50.00000 +BOUNDS + UP BND1 BIN1 200.00000 + UP BIN2 2500.00000 + LO BIN3 400.00000 + UP BIN3 800.00000 + LO BIN4 100.00000 + UP BIN4 700.00000 + UP BIN5 1500.00000 +ENDATA diff --git a/glpk-5.0/examples/planarity.mod b/glpk-5.0/examples/planarity.mod new file mode 100644 index 0000000..28d608e --- /dev/null +++ b/glpk-5.0/examples/planarity.mod @@ -0,0 +1,109 @@ +/* PLANARITY, Graph Planarity Testing */ + +/* Written in GNU MathProg by Andrew Makhorin <mao@gnu.org> */ + +/* Given a graph G = (V, E), where V is a set of vertices and E is + a set of edges (unordered pairs of vertices), this model tests if + G is planar, and if it is, finds its faces for some embedding. + It is assumed that G is loopless and the degree of any its vertex + is at least 2. + + Though there exist linear-time algorithms to test graph planarity, + this MIP feasibility model may be used, for example, to find + an embedding subject to some additional constraints or an "optimal" + embedding. + + This model is based on Mac Lane's planarity characterization that + states that a finite undirected graph is planar iff the cycle space + of the graph (in GF(2)) has a cycle basis in which each edge of the + graph participates in at most two basis vectors. */ + +param nv; +/* number of vertices */ + +set V := 1..nv; +/* set of vertices */ + +set E, within V cross V; +/* set of edges */ + +check{(i,j) in E} i <> j; +/* graph must have no loops */ + +set A := E union setof{(i,j) in E} (j,i); +/* set of arcs, where every edge (i,j) gives two arcs i->j and j->i */ + +check{i in V} sum{(i,j) in A} 1 >= 2; +/* degree of any vertex must be at least 2 */ + +param nf := 2 - nv + card(E); +/* number of faces (including outer face) */ + +set F := 1..nf; +/* set of faces = set of vertices of dual graph */ + +/* Let every face be assigned a unique color. Below we say that arc + i->j has color f if on moving from vertex i to vertex j face f is + located on the left to that arc. (Note that every face is defined + by a cycle mentioned in Mac Lane's characterization. In this model + cycles are constructed explicitly from arcs.) */ + +var x{(i,j) in A, f in F}, binary; +/* x[i,j,f] = 1 means that arc i->j has color f */ + +s.t. r1{(i,j) in A}: sum{f in F} x[i,j,f] = 1; +/* every arc must have exactly one color */ + +s.t. r2{j in V, f in F}: sum{(i,j) in A} x[i,j,f] <= 1; +/* two or more arcs of the same color must not enter the same vertex */ + +s.t. r3{j in V, f in F}: + sum{(i,j) in A} x[i,j,f] = sum{(j,i) in A} x[j,i,f]; +/* if arc of color f enters some vertex, exactly one arc of the same + color must leave that vertex */ + +s.t. r4{(i,j) in E, f in F}: x[i,j,f] + x[j,i,f] <= 1; +/* arcs that correspond to the same edge must have different colors + (to avoid invalid faces i->j->i) */ + +s.t. r5{f in F}: sum{(i,j) in A} x[i,j,f] >= 1; +/* every color must be used at least once */ + +/* this is a feasibility problem, so no objective is needed */ + +solve; + +printf "number of vertices = %d\n", nv; +printf "number of edges = %d\n", card(A) / 2; +printf "number of faces = %d\n", nf; + +for {f in F} +{ printf "face %d:", f; + printf {(i,j) in A: x[i,j,f] = 1} " %d->%d", i, j; + printf "\n"; +} + +data; + +/* The data below correspond to the following (planar) graph: + + 1 - 2 - - 3 - - 4 + | | | + | | | + 5 - 6 | | + | \ | | + | \ | | + 7 - - - - 8 - - 9 - - - - 10- - -11 + | / | \ | | + | / | \ | | + | / | \ | | + | / | \ | | + 12 - - - -13 - - - - - - - 14- - -15 */ + +param nv := 15; + +set E := (1,2) (1,5) (2,3) (3,4) (3,8) (4,9) (5,6) (5,7) (6,8) + (7,8) (7,12) (8,9) (8,12) (8,13) (9,10) (9,14) (10,11) + (10,14) (11,15) (12,13) (13,14) (14,15) ; + +end; diff --git a/glpk-5.0/examples/powpl25h.mod b/glpk-5.0/examples/powpl25h.mod new file mode 100644 index 0000000..bdeefb9 --- /dev/null +++ b/glpk-5.0/examples/powpl25h.mod @@ -0,0 +1,203 @@ +/* Power plant LP scheduler, example data with 25hrs for daylightsavings */ + +/* Implemented, inspected, written and converted to GNU MathProg + by NASZVADI, Peter, 199x-2017 <vuk@cs.elte.hu> */ + +/* + Fast electric power plant scheduler implementation based on new + results in author's Thesis. + + The base problem is: + * given some power plants + * a short time scale partitioned to equidistant intervals + * the task is to yielding the cheapest schedule for the plants + * the daily demand forecast is usually accurate and part of the input + + The power plants has technical limitations: + * upper and lower bounds of produced energy + * and also a gradient barrier in both directions + (can depend on time, but this GMPL implementation is simplified) + * Also units with same properties (technical and price) should be + scheduled together usually with near same performance values + * Assumed a simplified network topology, which is contractive, so + keeping Kirchhoff's laws is a necessary constraint too + * All solutions must be integer + + The LP relaxation is equivalent with the MIP problem due to the + model's matrix interesting property: it is Totally Unimodular + (proven in 2004 by author) and also a Network Matrix (2006, + presented at OTDK 2016, Szeged, Hungary) so: + * it is strictly polynomial if it is solved by most simplex algs + * all base solutions become integer if the RHS vector is integer + (it is in real life, so this is an acceptable assumption) + * The transposed matrix is NOT a Network Matrix in most cases! + + However, adding several other constraints easily turns the problem + to be NP-hard, which is also pinpointed and discussed in the Thesis. + + See more about electric power plants' scheduling in the + author's Thesis (in Hungarian): + http://www.cs.elte.hu/matdiploma/vuk.pdf + + It is possible to run with custom parameters, what is needed + to define is: + * TIME set (daylightsaving cases or other than hour intervals) + * PLANTS set (the 'Demand' is mandatory and usually negative) + * PRICE parameter (can be negative if energy is sold to a consumer) + * BOUND parameter (technical bounds) + * MAXGRAD parameter (technical bounds) + + Then generate a pretty-printed solution by typing: + glpsol --math powpl25h.mod +*/ + +set TIME, default { + '00:00', '01:00', '02:00', '03:00', '04:00', + '05:00', '06:00', '07:00', '08:00', '09:00', + '10:00', '11:00', '12:00', '13:00', '14:00', + '15:00', '16:00', '17:00', '18:00', '19:00', + '20:00', '21:00', '22:00', '23:00', '24:00' +}; +/* Time labels, assumed natural ordering. daylightsaving's bias + can be inserted p.ex. in Central Europe like: + ... '01:00', '02:00', '02:00b', '03:00', ... */ + +set TADJ := setof{(r, s) in TIME cross TIME: r < s}(r, s) diff + setof{(t, u, v) in TIME cross TIME cross TIME: t < u and u < v}(t, v); +/* Tricky adjacent time label generator because GMPL lacks order determination + of set elements (except intervals composed of equidistant numbers) */ + +set PLANTS, default {'Demand'}; +/* Demand is a promoted, mandatory one, usually filled + with negative MW values in data section */ + +set DIRECTION, default {'Up', 'Down'}; +/* All possible directions of gradients, do not touch */ + +param MAXINT, default 10000; +/* A "macro" for bounding absolute value of all used numbers + and used as default value */ + +param PRICE{PLANTS}, default MAXINT; +/* Should be specified in data section, self-explanatory. + can be negative if there are energy buyers */ + +param BOUND{(p, t, d) in PLANTS cross TIME cross DIRECTION}, + default if t = '00:00' then if d = 'Down' then BOUND[p, t, 'Up'] else 0 else + if p <> 'Demand' or d = 'Up' then sum{(u, v) in TADJ: v = t} BOUND[p, u, d] + else BOUND[p, t, 'Up']; +/* Obvious, technical bounds of each power plant unit (real or virtual like + 'Demand'). If some parts are not given in data section, calculated + from preceeding values. Also for time '00:00', its 'Down' values by + default are the same as denoted with 'Up' */ + +param MAXGRAD{(p, d) in PLANTS cross DIRECTION}, default MAXINT; +/* Usually nonnegative integer, might differ in distinct directions per unit + in the cited thesis, it is allowed to gradient bounds to depend on time, + but this is a simplified model */ + +var x{(t, p) in TIME cross PLANTS}, <= BOUND[p, t, 'Up'], >= BOUND[p, t, 'Down']; +/* The schedule, dimension is MW */ + +s.t. kirchhoff{t in TIME: t <> '00:00'}: sum{p in PLANTS} x[t, p] = 0; +/* Conservative property */ + +s.t. gradient{(p, t, u) in PLANTS cross TADJ}: + -MAXGRAD[p, 'Down'] <= x[t, p] - x[u, p] <= MAXGRAD[p, 'Up']; +/* Technical limitations, each unit usually cannot change performance + arbitrarily in a short time, so limited in both directions per time unit*/ + +minimize obj: sum{(t, p) in TIME cross PLANTS}(x[t, p] * PRICE[p]); +/* The objective is the cost of the schedule */ + +solve; + +/* Pretty print solution in table */ + +printf '+--------+'; +for{p in PLANTS}{ + printf '-% 6s-+', '------'; +} +printf '\n'; +printf '|%7s |', ' '; +for{p in PLANTS}{ + printf ' % 6s |', p; +} +printf '\n'; +printf '+--------+'; +for{p in PLANTS}{ + printf '-% 6s-+', '------'; +} +printf '\n'; +for{t in TIME}{ + printf '|%7s |', t; + for{p in PLANTS}{ + printf ' % 6s |', x[t, p].val; + } + printf '\n'; +} +printf '+--------+'; +for{p in PLANTS}{ + printf '-% 6s-+', '------'; +} +printf '\n'; + +data; + +set TIME := + '00:00', '01:00', '02:00', '02:00b', '03:00', '04:00', + '05:00', '06:00', '07:00', '08:00', '09:00', + '10:00', '11:00', '12:00', '13:00', '14:00', + '15:00', '16:00', '17:00', '18:00', '19:00', + '20:00', '21:00', '22:00', '23:00', '24:00'; + +/* + Generated random default values and names, the demand is the sum of + 2 sinewaves. + Also specified a treshold for nuclear plants from 15:00 till 19:00 + The sun is shining only morning and in the afternoon: 07:00-18:00, so + solar plant cannot produce electric energy after sunset. + + Only touch this section, or export it to a data file! +*/ + +set PLANTS 'Demand', 'Atom1', 'Atom2', 'Coal', 'Gas1', 'Gas2', 'Green', 'Oil', 'Solar', 'Dam'; + +param PRICE := + 'Demand' 0 + 'Atom1' 2 + 'Atom2' 2 + 'Coal' 15.6 + 'Gas1' 12 + 'Gas2' 11.5 + 'Green' 8.8 + 'Oil' 23.3 + 'Solar' 7.6 + 'Dam' 3; +/* price per MW */ + +param BOUND := + [*, *, 'Up'] (tr): 'Atom1' 'Atom2' 'Coal' 'Gas1' 'Gas2' 'Green' 'Oil' 'Solar' 'Dam' := + '00:00' 240 240 100 150 150 20 90 0 20 + '01:00' 240 240 155 192 208 35 230 0 20 + [*, *, 'Up'] (tr): 'Atom1' 'Atom2' := + '15:00' 200 200 + '19:00' 235 235 + [*, *, 'Up'] (tr): 'Solar' := + '07:00' 20 + '18:00' 0 + [*, *, 'Down'] (tr): 'Atom1' 'Atom2' 'Coal' 'Gas1' 'Gas2' 'Green' 'Oil' 'Solar' 'Dam' := + '01:00' 100 100 50 62 68 0 75 0 20 + [*, *, 'Up'] : '01:00' '02:00' '02:00b' '03:00' '04:00' '05:00' '06:00' '07:00' '08:00' := + 'Demand' -868 -851 -842 -837 -791 -887 -912 -1046 -1155 + [*, *, 'Up'] : '09:00' '10:00' '11:00' '12:00' '13:00' '14:00' '15:00' '16:00' := + 'Demand' -945 -873 -797 -990 -1241 -1134 -815 -782 + [*, *, 'Up'] : '17:00' '18:00' '19:00' '20:00' '21:00' '22:00' '23:00' '24:00' := + 'Demand' -772 -827 -931 -1105 -1215 -1249 -1183 -952; + +param MAXGRAD (tr) + : 'Atom1' 'Atom2' 'Coal' 'Gas1' 'Gas2' 'Green' 'Oil' 'Solar' 'Dam' := + 'Up' 30 30 35 89 95 5 56 2 4 + 'Down' 30 30 45 96 102 5 56 2 4; + +end; diff --git a/glpk-5.0/examples/powplant.mod b/glpk-5.0/examples/powplant.mod new file mode 100644 index 0000000..3b5d73e --- /dev/null +++ b/glpk-5.0/examples/powplant.mod @@ -0,0 +1,200 @@ +/* Power plant LP scheduler */ + +/* Implemented, inspected, written and converted to GNU MathProg + by NASZVADI, Peter, 199x-2017 <vuk@cs.elte.hu> */ + +/* + Fast electric power plant scheduler implementation based on new + results in author's Thesis. + + The base problem is: + * given some power plants + * a short time scale partitioned to equidistant intervals + * the task is to yielding the cheapest schedule for the plants + * the daily demand forecast is usually accurate and part of the input + + The power plants has technical limitations: + * upper and lower bounds of produced energy + * and also a gradient barrier in both directions + (can depend on time, but this GMPL implementation is simplified) + * Also units with same properties (technical and price) should be + scheduled together usually with near same performance values + * Assumed a simplified network topology, which is contractive, so + keeping Kirchhoff's laws is a necessary constraint too + * All solutions must be integer + + The LP relaxation is equivalent with the MIP problem due to the + model's matrix interesting property: it is Totally Unimodular + (proven in 2004 by author) and also a Network Matrix (2006, + presented at OTDK 2016, Szeged, Hungary) so: + * it is strictly polynomial if it is solved by most simplex algs + * all base solutions become integer if the RHS vector is integer + (it is in real life, so this is an acceptable assumption) + * The transposed matrix is NOT a Network Matrix in most cases! + + However, adding several other constraints easily turns the problem + to be NP-hard, which is also pinpointed and discussed in the Thesis. + + See more about electric power plants' scheduling in the + author's Thesis (in Hungarian): + http://www.cs.elte.hu/matdiploma/vuk.pdf + + It is possible to run with custom parameters, what is needed + to define is: + * TIME set (daylightsaving cases or other than hour intervals) + * PLANTS set (the 'Demand' is mandatory and usually negative) + * PRICE parameter (can be negative if energy is sold to a consumer) + * BOUND parameter (technical bounds) + * MAXGRAD parameter (technical bounds) + + Then generate a pretty-printed solution by typing: + glpsol --math powplant.mod [--data NEW_DATA.dat] + + where "NEW_DATA.dat" should contain the above 5 structures filled + with custom data. Square brackets shoudn't be entered, and specifying + custom data file is optional. +*/ + +set TIME, default { + '00:00', '01:00', '02:00', '03:00', '04:00', + '05:00', '06:00', '07:00', '08:00', '09:00', + '10:00', '11:00', '12:00', '13:00', '14:00', + '15:00', '16:00', '17:00', '18:00', '19:00', + '20:00', '21:00', '22:00', '23:00', '24:00' +}; +/* Time labels, assumed natural ordering. daylightsaving's bias + can be inserted p.ex. in Central Europe like: + ... '01:00', '02:00', '02:00b', '03:00', ... */ + +set TADJ := setof{(r, s) in TIME cross TIME: r < s}(r, s) diff + setof{(t, u, v) in TIME cross TIME cross TIME: t < u and u < v}(t, v); +/* Tricky adjacent time label generator because GMPL lacks order determination + of set elements (except intervals composed of equidistant numbers) */ + +set PLANTS, default {'Demand'}; +/* Demand is a promoted, mandatory one, usually filled + with negative MW values in data section */ + +set DIRECTION, default {'Up', 'Down'}; +/* All possible directions of gradients, do not touch */ + +param MAXINT, default 10000; +/* A "macro" for bounding absolute value of all used numbers + and used as default value */ + +param PRICE{PLANTS}, default MAXINT; +/* Should be specified in data section, self-explanatory. + can be negative if there are energy buyers */ + +param BOUND{(p, t, d) in PLANTS cross TIME cross DIRECTION}, + default if t = '00:00' then if d = 'Down' then BOUND[p, t, 'Up'] else 0 else + if p <> 'Demand' or d = 'Up' then sum{(u, v) in TADJ: v = t} BOUND[p, u, d] + else BOUND[p, t, 'Up']; +/* Obvious, technical bounds of each power plant unit (real or virtual like + 'Demand'). If some parts are not given in data section, calculated + from preceeding values. Also for time '00:00', its 'Down' values by + default are the same as denoted with 'Up' */ + +param MAXGRAD{(p, d) in PLANTS cross DIRECTION}, default MAXINT; +/* Usually nonnegative integer, might differ in distinct directions per unit + in the cited thesis, it is allowed to gradient bounds to depend on time, + but this is a simplified model */ + +var x{(t, p) in TIME cross PLANTS}, <= BOUND[p, t, 'Up'], >= BOUND[p, t, 'Down']; +/* The schedule, dimension is MW */ + +s.t. kirchhoff{t in TIME: t <> '00:00'}: sum{p in PLANTS} x[t, p] = 0; +/* Conservative property */ + +s.t. gradient{(p, t, u) in PLANTS cross TADJ}: + -MAXGRAD[p, 'Down'] <= x[t, p] - x[u, p] <= MAXGRAD[p, 'Up']; +/* Technical limitations, each unit usually cannot change performance + arbitrarily in a short time, so limited in both directions per time unit*/ + +minimize obj: sum{(t, p) in TIME cross PLANTS}(x[t, p] * PRICE[p]); +/* The objective is the cost of the schedule */ + +solve; + +/* Pretty print solution in table */ + +printf '+--------+'; +for{p in PLANTS}{ + printf '-% 6s-+', '------'; +} +printf '\n'; +printf '|%7s |', ' '; +for{p in PLANTS}{ + printf ' % 6s |', p; +} +printf '\n'; +printf '+--------+'; +for{p in PLANTS}{ + printf '-% 6s-+', '------'; +} +printf '\n'; +for{t in TIME}{ + printf '|%7s |', t; + for{p in PLANTS}{ + printf ' % 6s |', x[t, p].val; + } + printf '\n'; +} +printf '+--------+'; +for{p in PLANTS}{ + printf '-% 6s-+', '------'; +} +printf '\n'; + +data; + +/* + Generated random default values and names, the demand is the sum of + 2 sinewaves. + Also specified a treshold for nuclear plants from 15:00 till 19:00 + The sun is shining only morning and in the afternoon: 07:00-18:00, so + solar plant cannot produce electric energy after sunset. + + Only touch this section, or export it to a data file! +*/ + +set PLANTS 'Demand', 'Atom1', 'Atom2', 'Coal', 'Gas1', 'Gas2', 'Green', 'Oil', 'Solar', 'Dam'; + +param PRICE := + 'Demand' 0 + 'Atom1' 2 + 'Atom2' 2 + 'Coal' 15.6 + 'Gas1' 12 + 'Gas2' 11.5 + 'Green' 8.8 + 'Oil' 23.3 + 'Solar' 7.6 + 'Dam' 3; +/* price per MW */ + +param BOUND := + [*, *, 'Up'] (tr): 'Atom1' 'Atom2' 'Coal' 'Gas1' 'Gas2' 'Green' 'Oil' 'Solar' 'Dam' := + '00:00' 240 240 100 150 150 20 90 0 20 + '01:00' 240 240 155 192 208 35 230 0 20 + [*, *, 'Up'] (tr): 'Atom1' 'Atom2' := + '15:00' 200 200 + '19:00' 235 235 + [*, *, 'Up'] (tr): 'Solar' := + '07:00' 20 + '18:00' 0 + [*, *, 'Down'] (tr): 'Atom1' 'Atom2' 'Coal' 'Gas1' 'Gas2' 'Green' 'Oil' 'Solar' 'Dam' := + '01:00' 100 100 50 62 68 0 75 0 20 + [*, *, 'Up'] : '01:00' '02:00' '03:00' '04:00' '05:00' '06:00' '07:00' '08:00' := + 'Demand' -868 -851 -837 -791 -887 -912 -1046 -1155 + [*, *, 'Up'] : '09:00' '10:00' '11:00' '12:00' '13:00' '14:00' '15:00' '16:00' := + 'Demand' -945 -873 -797 -990 -1241 -1134 -815 -782 + [*, *, 'Up'] : '17:00' '18:00' '19:00' '20:00' '21:00' '22:00' '23:00' '24:00' := + 'Demand' -772 -827 -931 -1105 -1215 -1249 -1183 -952; + +param MAXGRAD (tr) + : 'Atom1' 'Atom2' 'Coal' 'Gas1' 'Gas2' 'Green' 'Oil' 'Solar' 'Dam' := + 'Up' 30 30 35 89 95 5 56 2 4 + 'Down' 30 30 45 96 102 5 56 2 4; + +end; diff --git a/glpk-5.0/examples/prod.mod b/glpk-5.0/examples/prod.mod new file mode 100644 index 0000000..aa793f7 --- /dev/null +++ b/glpk-5.0/examples/prod.mod @@ -0,0 +1,331 @@ +# PROD, a multiperiod production model +# +# References: +# Robert Fourer, David M. Gay and Brian W. Kernighan, "A Modeling Language +# for Mathematical Programming." Management Science 36 (1990) 519-554. + +### PRODUCTION SETS AND PARAMETERS ### + +set prd 'products'; # Members of the product group + +param pt 'production time' {prd} > 0; + + # Crew-hours to produce 1000 units + +param pc 'production cost' {prd} > 0; + + # Nominal production cost per 1000, used + # to compute inventory and shortage costs + +### TIME PERIOD SETS AND PARAMETERS ### + +param first > 0 integer; + # Index of first production period to be modeled + +param last > first integer; + + # Index of last production period to be modeled + +set time 'planning horizon' := first..last; + +### EMPLOYMENT PARAMETERS ### + +param cs 'crew size' > 0 integer; + + # Workers per crew + +param sl 'shift length' > 0; + + # Regular-time hours per shift + +param rtr 'regular time rate' > 0; + + # Wage per hour for regular-time labor + +param otr 'overtime rate' > rtr; + + # Wage per hour for overtime labor + +param iw 'initial workforce' >= 0 integer; + + # Crews employed at start of first period + +param dpp 'days per period' {time} > 0; + + # Regular working days in a production period + +param ol 'overtime limit' {time} >= 0; + + # Maximum crew-hours of overtime in a period + +param cmin 'crew minimum' {time} >= 0; + + # Lower limit on average employment in a period + +param cmax 'crew maximum' {t in time} >= cmin[t]; + + # Upper limit on average employment in a period + +param hc 'hiring cost' {time} >= 0; + + # Penalty cost of hiring a crew + +param lc 'layoff cost' {time} >= 0; + + # Penalty cost of laying off a crew + +### DEMAND PARAMETERS ### + +param dem 'demand' {prd,first..last+1} >= 0; + + # Requirements (in 1000s) + # to be met from current production and inventory + +param pro 'promoted' {prd,first..last+1} logical; + + # true if product will be the subject + # of a special promotion in the period + +### INVENTORY AND SHORTAGE PARAMETERS ### + +param rir 'regular inventory ratio' >= 0; + + # Proportion of non-promoted demand + # that must be in inventory the previous period + +param pir 'promotional inventory ratio' >= 0; + + # Proportion of promoted demand + # that must be in inventory the previous period + +param life 'inventory lifetime' > 0 integer; + + # Upper limit on number of periods that + # any product may sit in inventory + +param cri 'inventory cost ratio' {prd} > 0; + + # Inventory cost per 1000 units is + # cri times nominal production cost + +param crs 'shortage cost ratio' {prd} > 0; + + # Shortage cost per 1000 units is + # crs times nominal production cost + +param iinv 'initial inventory' {prd} >= 0; + + # Inventory at start of first period; age unknown + +param iil 'initial inventory left' {p in prd, t in time} + := iinv[p] less sum {v in first..t} dem[p,v]; + + # Initial inventory still available for allocation + # at end of period t + +param minv 'minimum inventory' {p in prd, t in time} + := dem[p,t+1] * (if pro[p,t+1] then pir else rir); + + # Lower limit on inventory at end of period t + +### VARIABLES ### + +var Crews{first-1..last} >= 0; + + # Average number of crews employed in each period + +var Hire{time} >= 0; # Crews hired from previous to current period + +var Layoff{time} >= 0; # Crews laid off from previous to current period + +var Rprd 'regular production' {prd,time} >= 0; + + # Production using regular-time labor, in 1000s + +var Oprd 'overtime production' {prd,time} >= 0; + + # Production using overtime labor, in 1000s + +var Inv 'inventory' {prd,time,1..life} >= 0; + + # Inv[p,t,a] is the amount of product p that is + # a periods old -- produced in period (t+1)-a -- + # and still in storage at the end of period t + +var Short 'shortage' {prd,time} >= 0; + + # Accumulated unsatisfied demand at the end of period t + +### OBJECTIVE ### + +minimize cost: + + sum {t in time} rtr * sl * dpp[t] * cs * Crews[t] + + sum {t in time} hc[t] * Hire[t] + + sum {t in time} lc[t] * Layoff[t] + + sum {t in time, p in prd} otr * cs * pt[p] * Oprd[p,t] + + sum {t in time, p in prd, a in 1..life} cri[p] * pc[p] * Inv[p,t,a] + + sum {t in time, p in prd} crs[p] * pc[p] * Short[p,t]; + + # Full regular wages for all crews employed, plus + # penalties for hiring and layoffs, plus + # wages for any overtime worked, plus + # inventory and shortage costs + + # (All other production costs are assumed + # to depend on initial inventory and on demands, + # and so are not included explicitly.) + +### CONSTRAINTS ### + +rlim 'regular-time limit' {t in time}: + + sum {p in prd} pt[p] * Rprd[p,t] <= sl * dpp[t] * Crews[t]; + + # Hours needed to accomplish all regular-time + # production in a period must not exceed + # hours available on all shifts + +olim 'overtime limit' {t in time}: + + sum {p in prd} pt[p] * Oprd[p,t] <= ol[t]; + + # Hours needed to accomplish all overtime + # production in a period must not exceed + # the specified overtime limit + +empl0 'initial crew level': Crews[first-1] = iw; + + # Use given initial workforce + +empl 'crew levels' {t in time}: Crews[t] = Crews[t-1] + Hire[t] - Layoff[t]; + + # Workforce changes by hiring or layoffs + +emplbnd 'crew limits' {t in time}: cmin[t] <= Crews[t] <= cmax[t]; + + # Workforce must remain within specified bounds + +dreq1 'first demand requirement' {p in prd}: + + Rprd[p,first] + Oprd[p,first] + Short[p,first] + - Inv[p,first,1] = dem[p,first] less iinv[p]; + +dreq 'demand requirements' {p in prd, t in first+1..last}: + + Rprd[p,t] + Oprd[p,t] + Short[p,t] - Short[p,t-1] + + sum {a in 1..life} (Inv[p,t-1,a] - Inv[p,t,a]) + = dem[p,t] less iil[p,t-1]; + + # Production plus increase in shortage plus + # decrease in inventory must equal demand + +ireq 'inventory requirements' {p in prd, t in time}: + + sum {a in 1..life} Inv[p,t,a] + iil[p,t] >= minv[p,t]; + + # Inventory in storage at end of period t + # must meet specified minimum + +izero 'impossible inventories' {p in prd, v in 1..life-1, a in v+1..life}: + + Inv[p,first+v-1,a] = 0; + + # In the vth period (starting from first) + # no inventory may be more than v periods old + # (initial inventories are handled separately) + +ilim1 'new-inventory limits' {p in prd, t in time}: + + Inv[p,t,1] <= Rprd[p,t] + Oprd[p,t]; + + # New inventory cannot exceed + # production in the most recent period + +ilim 'inventory limits' {p in prd, t in first+1..last, a in 2..life}: + + Inv[p,t,a] <= Inv[p,t-1,a-1]; + + # Inventory left from period (t+1)-p + # can only decrease as time goes on + +### DATA ### + +data; + +set prd := 18REG 24REG 24PRO ; + +param first := 1 ; +param last := 13 ; +param life := 2 ; + +param cs := 18 ; +param sl := 8 ; +param iw := 8 ; + +param rtr := 16.00 ; +param otr := 43.85 ; +param rir := 0.75 ; +param pir := 0.80 ; + +param : pt pc cri crs iinv := + + 18REG 1.194 2304. 0.015 1.100 82.0 + 24REG 1.509 2920. 0.015 1.100 792.2 + 24PRO 1.509 2910. 0.015 1.100 0.0 ; + +param : dpp ol cmin cmax hc lc := + + 1 19.5 96.0 0.0 8.0 7500 7500 + 2 19.0 96.0 0.0 8.0 7500 7500 + 3 20.0 96.0 0.0 8.0 7500 7500 + 4 19.0 96.0 0.0 8.0 7500 7500 + 5 19.5 96.0 0.0 8.0 15000 15000 + 6 19.0 96.0 0.0 8.0 15000 15000 + 7 19.0 96.0 0.0 8.0 15000 15000 + 8 20.0 96.0 0.0 8.0 15000 15000 + 9 19.0 96.0 0.0 8.0 15000 15000 + 10 20.0 96.0 0.0 8.0 15000 15000 + 11 20.0 96.0 0.0 8.0 7500 7500 + 12 18.0 96.0 0.0 8.0 7500 7500 + 13 18.0 96.0 0.0 8.0 7500 7500 ; + +param dem (tr) : + + 18REG 24REG 24PRO := + + 1 63.8 1212.0 0.0 + 2 76.0 306.2 0.0 + 3 88.4 319.0 0.0 + 4 913.8 208.4 0.0 + 5 115.0 298.0 0.0 + 6 133.8 328.2 0.0 + 7 79.6 959.6 0.0 + 8 111.0 257.6 0.0 + 9 121.6 335.6 0.0 + 10 470.0 118.0 1102.0 + 11 78.4 284.8 0.0 + 12 99.4 970.0 0.0 + 13 140.4 343.8 0.0 + 14 63.8 1212.0 0.0 ; + +param pro (tr) : + + 18REG 24REG 24PRO := + + 1 0 1 0 + 2 0 0 0 + 3 0 0 0 + 4 1 0 0 + 5 0 0 0 + 6 0 0 0 + 7 0 1 0 + 8 0 0 0 + 9 0 0 0 + 10 1 0 1 + 11 0 0 0 + 12 0 0 0 + 13 0 1 0 + 14 0 1 0 ; + +end; diff --git a/glpk-5.0/examples/qfit.mod b/glpk-5.0/examples/qfit.mod new file mode 100644 index 0000000..f168c4b --- /dev/null +++ b/glpk-5.0/examples/qfit.mod @@ -0,0 +1,49 @@ +/*Quadratic Curve Fitting Solution + + Find a plausable quadratic fit to a sample of points + + Nigel_Galloway@operamail.com + February 1st., 2009 +*/ +set Sample; +param Sx {z in Sample}; +param Sy {z in Sample}; + +var a; +var b; +var c; + +equalz1 :sum{z in Sample} a*Sx[z]*Sx[z]*Sx[z]*Sx[z] + sum{z in Sample} b*Sx[z]*Sx[z]*Sx[z] + sum{z in Sample} c*Sx[z]*Sx[z] = sum{z in Sample} Sy[z]*Sx[z]*Sx[z]; +equalz2 :sum{z in Sample} a*Sx[z]*Sx[z]*Sx[z] + sum{z in Sample} b*Sx[z]*Sx[z] + sum{z in Sample} c*Sx[z] = sum{z in Sample} Sy[z]*Sx[z]; +equalz3 :sum{z in Sample} a*Sx[z]*Sx[z] + sum{z in Sample} b*Sx[z] + sum{z in Sample} c = sum{z in Sample} Sy[z]; + +solve; + +printf "\nbest quadratic fit is:\n\ty = %f %s %fx %s %fx^2\n\n", c, if b < 0 then "-" else "+", abs(b), if a < 0 then "-" else "+", abs(a); + +data; + +param: +Sample: Sx Sy := + 1 0 1 + 2 0.5 0.9 + 3 1 0.7 + 4 1.5 1.5 + 5 1.9 2 + 6 2.5 2.4 + 7 3 3.2 + 8 3.5 2 + 9 4 2.7 + 10 4.5 3.5 + 11 5 1 + 12 5.5 4 + 13 6 3.6 + 14 6.6 2.7 + 15 7 5.7 + 16 7.6 4.6 + 17 8.5 6 + 18 9 6.8 + 19 10 7.3 +; + +end; diff --git a/glpk-5.0/examples/queens.mod b/glpk-5.0/examples/queens.mod new file mode 100644 index 0000000..3f446ce --- /dev/null +++ b/glpk-5.0/examples/queens.mod @@ -0,0 +1,41 @@ +/* QUEENS, a classic combinatorial optimization problem */ + +/* Written in GNU MathProg by Andrew Makhorin <mao@gnu.org> */ + +/* The Queens Problem is to place as many queens as possible on the 8x8 + (or more generally, nxn) chess board in a way that they do not fight + each other. This problem is probably as old as the chess game itself, + and thus its origin is not known, but it is known that Gauss studied + this problem. */ + +param n, integer, > 0, default 8; +/* size of the chess board */ + +var x{1..n, 1..n}, binary; +/* x[i,j] = 1 means that a queen is placed in square [i,j] */ + +s.t. a{i in 1..n}: sum{j in 1..n} x[i,j] <= 1; +/* at most one queen can be placed in each row */ + +s.t. b{j in 1..n}: sum{i in 1..n} x[i,j] <= 1; +/* at most one queen can be placed in each column */ + +s.t. c{k in 2-n..n-2}: sum{i in 1..n, j in 1..n: i-j == k} x[i,j] <= 1; +/* at most one queen can be placed in each "\"-diagonal */ + +s.t. d{k in 3..n+n-1}: sum{i in 1..n, j in 1..n: i+j == k} x[i,j] <= 1; +/* at most one queen can be placed in each "/"-diagonal */ + +maximize obj: sum{i in 1..n, j in 1..n} x[i,j]; +/* objective is to place as many queens as possible */ + +/* solve the problem */ +solve; + +/* and print its optimal solution */ +for {i in 1..n} +{ for {j in 1..n} printf " %s", if x[i,j] then "Q" else "."; + printf("\n"); +} + +end; diff --git a/glpk-5.0/examples/samp1.mps b/glpk-5.0/examples/samp1.mps new file mode 100644 index 0000000..dd60d18 --- /dev/null +++ b/glpk-5.0/examples/samp1.mps @@ -0,0 +1,29 @@ +NAME SAMP1 +ROWS + N Z + G R1 + G R2 + G R3 +COLUMNS + X1 R1 2.0 R2 1.0 + X1 R3 5.0 Z 3.0 + MARK0001 'MARKER' 'INTORG' + X2 R1 -1.0 R2 -1.0 + X2 R3 3.0 Z 7.0 + X3 R1 1.0 R2 -6.0 + X3 Z -1.0 + MARK0002 'MARKER' 'INTEND' + X4 R1 -1.0 R2 4.0 + X4 R3 1.0 Z 1.0 +RHS + RHS1 R1 1.0 + RHS1 R2 8.0 + RHS1 R3 5.0 +BOUNDS + UP BND1 X1 4.0 + LO BND1 X2 2.0 + UP BND1 X2 5.0 + UP BND1 X3 1.0 + LO BND1 X4 3.0 + UP BND1 X4 8.0 +ENDATA diff --git a/glpk-5.0/examples/samp2.mps b/glpk-5.0/examples/samp2.mps new file mode 100644 index 0000000..d2da1a3 --- /dev/null +++ b/glpk-5.0/examples/samp2.mps @@ -0,0 +1,27 @@ +NAME SAMP2 +ROWS + N Z + G R1 + G R2 + G R3 +COLUMNS + X1 R1 2.0 R2 1.0 + X1 R3 5.0 Z 3.0 + X2 R1 -1.0 R2 -1.0 + X2 R3 3.0 Z 7.0 + X3 R1 1.0 R2 -6.0 + X3 Z -1.0 + X4 R1 -1.0 R2 4.0 + X4 R3 1.0 Z 1.0 +RHS + RHS1 R1 1.0 + RHS1 R2 8.0 + RHS1 R3 5.0 +BOUNDS + UP BND1 X1 4.0 + LO BND1 X2 2.0 + UI BND1 X2 5.0 + BV BND1 X3 + LO BND1 X4 3.0 + UP BND1 X4 8.0 +ENDATA diff --git a/glpk-5.0/examples/sample.asn b/glpk-5.0/examples/sample.asn new file mode 100644 index 0000000..edb0aaf --- /dev/null +++ b/glpk-5.0/examples/sample.asn @@ -0,0 +1,40 @@ +c sample.asn +c +c This is an example of the assignment problem data +c in DIMACS format. +c +p asn 17 22 +c +n 1 +n 2 +n 3 +n 4 +n 5 +n 6 +n 7 +n 8 +c +a 1 9 13 +a 1 10 21 +a 1 12 20 +a 2 10 12 +a 2 12 8 +a 2 13 26 +a 3 11 22 +a 3 13 11 +a 4 9 12 +a 4 12 36 +a 4 14 25 +a 5 11 41 +a 5 12 40 +a 5 13 11 +a 5 14 4 +a 5 15 8 +a 5 16 35 +a 5 17 32 +a 6 9 13 +a 7 10 19 +a 8 10 39 +a 8 11 15 +c +c eof diff --git a/glpk-5.0/examples/sample.c b/glpk-5.0/examples/sample.c new file mode 100644 index 0000000..468a6a3 --- /dev/null +++ b/glpk-5.0/examples/sample.c @@ -0,0 +1,52 @@ +/* sample.c */ + +#include <stdio.h> +#include <stdlib.h> +#include <glpk.h> + +int main(void) +{ glp_prob *lp; + int ia[1+1000], ja[1+1000]; + double ar[1+1000], z, x1, x2, x3; +s1: lp = glp_create_prob(); +s2: glp_set_prob_name(lp, "sample"); +s3: glp_set_obj_dir(lp, GLP_MAX); +s4: glp_add_rows(lp, 3); +s5: glp_set_row_name(lp, 1, "p"); +s6: glp_set_row_bnds(lp, 1, GLP_UP, 0.0, 100.0); +s7: glp_set_row_name(lp, 2, "q"); +s8: glp_set_row_bnds(lp, 2, GLP_UP, 0.0, 600.0); +s9: glp_set_row_name(lp, 3, "r"); +s10: glp_set_row_bnds(lp, 3, GLP_UP, 0.0, 300.0); +s11: glp_add_cols(lp, 3); +s12: glp_set_col_name(lp, 1, "x1"); +s13: glp_set_col_bnds(lp, 1, GLP_LO, 0.0, 0.0); +s14: glp_set_obj_coef(lp, 1, 10.0); +s15: glp_set_col_name(lp, 2, "x2"); +s16: glp_set_col_bnds(lp, 2, GLP_LO, 0.0, 0.0); +s17: glp_set_obj_coef(lp, 2, 6.0); +s18: glp_set_col_name(lp, 3, "x3"); +s19: glp_set_col_bnds(lp, 3, GLP_LO, 0.0, 0.0); +s20: glp_set_obj_coef(lp, 3, 4.0); +s21: ia[1] = 1, ja[1] = 1, ar[1] = 1.0; /* a[1,1] = 1 */ +s22: ia[2] = 1, ja[2] = 2, ar[2] = 1.0; /* a[1,2] = 1 */ +s23: ia[3] = 1, ja[3] = 3, ar[3] = 1.0; /* a[1,3] = 1 */ +s24: ia[4] = 2, ja[4] = 1, ar[4] = 10.0; /* a[2,1] = 10 */ +s25: ia[5] = 3, ja[5] = 1, ar[5] = 2.0; /* a[3,1] = 2 */ +s26: ia[6] = 2, ja[6] = 2, ar[6] = 4.0; /* a[2,2] = 4 */ +s27: ia[7] = 3, ja[7] = 2, ar[7] = 2.0; /* a[3,2] = 2 */ +s28: ia[8] = 2, ja[8] = 3, ar[8] = 5.0; /* a[2,3] = 5 */ +s29: ia[9] = 3, ja[9] = 3, ar[9] = 6.0; /* a[3,3] = 6 */ +s30: glp_load_matrix(lp, 9, ia, ja, ar); +s31: glp_simplex(lp, NULL); +s32: z = glp_get_obj_val(lp); +s33: x1 = glp_get_col_prim(lp, 1); +s34: x2 = glp_get_col_prim(lp, 2); +s35: x3 = glp_get_col_prim(lp, 3); +s36: printf("\nz = %g; x1 = %g; x2 = %g; x3 = %g\n", + z, x1, x2, x3); +s37: glp_delete_prob(lp); + return 0; +} + +/* eof */ diff --git a/glpk-5.0/examples/sample.clq b/glpk-5.0/examples/sample.clq new file mode 100644 index 0000000..741f712 --- /dev/null +++ b/glpk-5.0/examples/sample.clq @@ -0,0 +1,30 @@ +c sample.clq +c +c This is an example of the Maximum Weight Clique +c Problem in DIMACS clique/coloring format. +c +p edge 8 16 +n 1 3 +n 2 4 +n 3 8 +n 5 5 +n 6 2 +n 8 3 +e 1 4 +e 1 5 +e 1 6 +e 1 8 +e 2 3 +e 2 6 +e 2 7 +e 2 8 +e 3 4 +e 3 6 +e 3 7 +e 4 5 +e 4 8 +e 5 7 +e 5 8 +e 6 7 +c +c eof diff --git a/glpk-5.0/examples/sample.cnf b/glpk-5.0/examples/sample.cnf new file mode 100644 index 0000000..508f150 --- /dev/null +++ b/glpk-5.0/examples/sample.cnf @@ -0,0 +1,12 @@ +c sample.cnf +c +c This is an example of the CNF-SAT problem data +c in DIMACS format. +c +p cnf 4 3 +1 2 0 +-4 3 +-2 0 +-1 4 0 +c +c eof diff --git a/glpk-5.0/examples/sample.col b/glpk-5.0/examples/sample.col new file mode 100644 index 0000000..132f6e5 --- /dev/null +++ b/glpk-5.0/examples/sample.col @@ -0,0 +1,30 @@ +c sample.col +c +c This is an example of the vertex coloring problem data +c in DIMACS format. +c +p edge 10 21 +c +e 1 2 +e 1 6 +e 1 7 +e 1 10 +e 2 3 +e 2 7 +e 2 8 +e 3 4 +e 3 8 +e 4 5 +e 4 8 +e 4 9 +e 5 6 +e 5 9 +e 5 10 +e 6 10 +e 7 8 +e 7 10 +e 8 9 +e 8 10 +e 9 10 +c +c eof diff --git a/glpk-5.0/examples/sample.max b/glpk-5.0/examples/sample.max new file mode 100644 index 0000000..6b80422 --- /dev/null +++ b/glpk-5.0/examples/sample.max @@ -0,0 +1,26 @@ +c sample.max +c +c This is an example of the maximum flow problem data +c in DIMACS format. +c +p max 9 14 +c +n 1 s +n 9 t +c +a 1 2 14 +a 1 4 23 +a 2 3 10 +a 2 4 9 +a 3 5 12 +a 3 8 18 +a 4 5 26 +a 5 2 11 +a 5 6 25 +a 5 7 4 +a 6 7 7 +a 6 8 8 +a 7 9 15 +a 8 9 20 +c +c eof diff --git a/glpk-5.0/examples/sample.min b/glpk-5.0/examples/sample.min new file mode 100644 index 0000000..5ebf58b --- /dev/null +++ b/glpk-5.0/examples/sample.min @@ -0,0 +1,26 @@ +c sample.min +c +c This is an example of the minimum cost flow problem data +c in DIMACS format. +c +p min 9 14 +c +n 1 20 +n 9 -20 +c +a 1 2 0 14 0 +a 1 4 0 23 0 +a 2 3 0 10 2 +a 2 4 0 9 3 +a 3 5 2 12 1 +a 3 8 0 18 0 +a 4 5 0 26 0 +a 5 2 0 11 1 +a 5 6 0 25 5 +a 5 7 0 4 7 +a 6 7 0 7 0 +a 6 8 4 8 0 +a 7 9 0 15 3 +a 8 9 0 20 9 +c +c eof diff --git a/glpk-5.0/examples/sat.mod b/glpk-5.0/examples/sat.mod new file mode 100644 index 0000000..84ba952 --- /dev/null +++ b/glpk-5.0/examples/sat.mod @@ -0,0 +1,201 @@ +/* SAT, Satisfiability Problem */ + +/* Written in GNU MathProg by Andrew Makhorin <mao@gnu.org> */ + +param m, integer, > 0; +/* number of clauses */ + +param n, integer, > 0; +/* number of variables */ + +set C{1..m}; +/* clauses; each clause C[i], i = 1, ..., m, is disjunction of some + variables or their negations; in the data section each clause is + coded as a set of indices of corresponding variables, where negative + indices mean negation; for example, the clause (x3 or not x7 or x11) + is coded as the set { 3, -7, 11 } */ + +var x{1..n}, binary; +/* main variables */ + +/* To solve the satisfiability problem means to determine all variables + x[j] such that conjunction of all clauses C[1] and ... and C[m] takes + on the value true, i.e. all clauses are satisfied. + + Let the clause C[i] be (t or t' or ... or t''), where t, t', ..., t'' + are either variables or their negations. The condition of satisfying + C[i] can be most naturally written as: + + t + t' + ... + t'' >= 1, (1) + + where t, t', t'' have to be replaced by either x[j] or (1 - x[j]). + The formulation (1) leads to the mip problem with no objective, i.e. + to a feasibility problem. + + Another, more practical way is to write the condition for C[i] as: + + t + t' + ... + t'' + y[i] >= 1, (2) + + where y[i] is an auxiliary binary variable, and minimize the sum of + y[i]. If the sum is zero, all y[i] are also zero, and therefore all + clauses are satisfied. If the sum is minimal but non-zero, its value + shows the number of clauses which cannot be satisfied. */ + +var y{1..m}, binary, >= 0; +/* auxiliary variables */ + +s.t. c{i in 1..m}: + sum{j in C[i]} (if j > 0 then x[j] else (1 - x[-j])) + y[i] >= 1; +/* the condition (2) */ + +minimize unsat: sum{i in 1..m} y[i]; +/* number of unsatisfied clauses */ + +data; + +/* These data correspond to the instance hole6 (pigeon hole problem for + 6 holes) from SATLIB, the Satisfiability Library, which is part of + the collection at the Forschungsinstitut fuer anwendungsorientierte + Wissensverarbeitung in Ulm Germany */ + +/* The optimal solution is 1 (one clause cannot be satisfied) */ + +param m := 133; + +param n := 42; + +set C[1] := -1 -7; +set C[2] := -1 -13; +set C[3] := -1 -19; +set C[4] := -1 -25; +set C[5] := -1 -31; +set C[6] := -1 -37; +set C[7] := -7 -13; +set C[8] := -7 -19; +set C[9] := -7 -25; +set C[10] := -7 -31; +set C[11] := -7 -37; +set C[12] := -13 -19; +set C[13] := -13 -25; +set C[14] := -13 -31; +set C[15] := -13 -37; +set C[16] := -19 -25; +set C[17] := -19 -31; +set C[18] := -19 -37; +set C[19] := -25 -31; +set C[20] := -25 -37; +set C[21] := -31 -37; +set C[22] := -2 -8; +set C[23] := -2 -14; +set C[24] := -2 -20; +set C[25] := -2 -26; +set C[26] := -2 -32; +set C[27] := -2 -38; +set C[28] := -8 -14; +set C[29] := -8 -20; +set C[30] := -8 -26; +set C[31] := -8 -32; +set C[32] := -8 -38; +set C[33] := -14 -20; +set C[34] := -14 -26; +set C[35] := -14 -32; +set C[36] := -14 -38; +set C[37] := -20 -26; +set C[38] := -20 -32; +set C[39] := -20 -38; +set C[40] := -26 -32; +set C[41] := -26 -38; +set C[42] := -32 -38; +set C[43] := -3 -9; +set C[44] := -3 -15; +set C[45] := -3 -21; +set C[46] := -3 -27; +set C[47] := -3 -33; +set C[48] := -3 -39; +set C[49] := -9 -15; +set C[50] := -9 -21; +set C[51] := -9 -27; +set C[52] := -9 -33; +set C[53] := -9 -39; +set C[54] := -15 -21; +set C[55] := -15 -27; +set C[56] := -15 -33; +set C[57] := -15 -39; +set C[58] := -21 -27; +set C[59] := -21 -33; +set C[60] := -21 -39; +set C[61] := -27 -33; +set C[62] := -27 -39; +set C[63] := -33 -39; +set C[64] := -4 -10; +set C[65] := -4 -16; +set C[66] := -4 -22; +set C[67] := -4 -28; +set C[68] := -4 -34; +set C[69] := -4 -40; +set C[70] := -10 -16; +set C[71] := -10 -22; +set C[72] := -10 -28; +set C[73] := -10 -34; +set C[74] := -10 -40; +set C[75] := -16 -22; +set C[76] := -16 -28; +set C[77] := -16 -34; +set C[78] := -16 -40; +set C[79] := -22 -28; +set C[80] := -22 -34; +set C[81] := -22 -40; +set C[82] := -28 -34; +set C[83] := -28 -40; +set C[84] := -34 -40; +set C[85] := -5 -11; +set C[86] := -5 -17; +set C[87] := -5 -23; +set C[88] := -5 -29; +set C[89] := -5 -35; +set C[90] := -5 -41; +set C[91] := -11 -17; +set C[92] := -11 -23; +set C[93] := -11 -29; +set C[94] := -11 -35; +set C[95] := -11 -41; +set C[96] := -17 -23; +set C[97] := -17 -29; +set C[98] := -17 -35; +set C[99] := -17 -41; +set C[100] := -23 -29; +set C[101] := -23 -35; +set C[102] := -23 -41; +set C[103] := -29 -35; +set C[104] := -29 -41; +set C[105] := -35 -41; +set C[106] := -6 -12; +set C[107] := -6 -18; +set C[108] := -6 -24; +set C[109] := -6 -30; +set C[110] := -6 -36; +set C[111] := -6 -42; +set C[112] := -12 -18; +set C[113] := -12 -24; +set C[114] := -12 -30; +set C[115] := -12 -36; +set C[116] := -12 -42; +set C[117] := -18 -24; +set C[118] := -18 -30; +set C[119] := -18 -36; +set C[120] := -18 -42; +set C[121] := -24 -30; +set C[122] := -24 -36; +set C[123] := -24 -42; +set C[124] := -30 -36; +set C[125] := -30 -42; +set C[126] := -36 -42; +set C[127] := 6 5 4 3 2 1; +set C[128] := 12 11 10 9 8 7; +set C[129] := 18 17 16 15 14 13; +set C[130] := 24 23 22 21 20 19; +set C[131] := 30 29 28 27 26 25; +set C[132] := 36 35 34 33 32 31; +set C[133] := 42 41 40 39 38 37; + +end; diff --git a/glpk-5.0/examples/shiftcov.mod b/glpk-5.0/examples/shiftcov.mod new file mode 100644 index 0000000..1e036c8 --- /dev/null +++ b/glpk-5.0/examples/shiftcov.mod @@ -0,0 +1,244 @@ +/* File: shiftcover.mod */ + +/* WORKFORCE SHIFT COVERAGE assignment problem */ + +/* Written by Larry D'Agostino <larrydag -at- sbcglobal -dot- com> + + Maximize Productivity with Industrial Engineer and Operations Research Tools + http://industrialengineertools.blogspot.com + + +/* The WORKFORCE SHIFT COVERAGE is an assigment problem that determines + the schedule of crew given available time and shifts. + + The objective is to cover the available time given hourly demand with the minimum + number of crew members. + + This is a set covering problem that is very common among finding crew + and shift allocations. Notice in the data section the workforce shift allocation + per day of the week.*/ + + +/* ----- Model PARAMTERS and SETS -----*/ + +param numhrs; +/* number of hours of operations in a given day */ + +param dys; +/* number of days in a week */ + +set S; +/* set of crew shifts */ + +set H := 1..numhrs; +/* set of hours of a day*/ + +set D; +/* set of days of a week*/ + +param dmnd{h in H, d in D}; +/* demand for crew members given h hour and d day */ + +param shifts{d in D, h in H, s in S}; +/* shifts to assign to crew members given d day, h hour, and s shift schedule + +/*----- Model VARIABLES -----*/ + +var crew{s in S}, integer, >=0; +/* number of crew assigned to shift S */ + + +/*----- Model CONSTRAINTS -----*/ + +s.t. Coverage{h in H, d in D}: sum{s in S} crew[s]*shifts[d,h,s] >= dmnd[h,d]; +/* number of crew to cover with a shift given hourly demand and day */ + + +/*----- Model OBJECTIVE -----*/ + +minimize obj: sum{s in S} crew[s]; +/* minimize number of crew to cover demand*/ + +solve; +display crew; + +printf "\n"; +printf "Total Crew: %3d\n\n", sum{s in S} crew[s]; + + + +printf "\n\n"; +printf "Weekly Crew Schedule\n\n"; +printf "Hour "; +printf{d in D} " %s ", d; +printf "\n"; +for {h in H} { + printf " %2s ",h; + printf{d in D} " %3d ", sum{s in S} crew[s]*shifts[d,h,s]; + printf "\n"; +} +printf"\n"; + + + +data; + +param numhrs := 16; + +set D := SUN, MON, TUE, WED, THU, FRI, SAT; + +set S := Sh1, Sh2, Sh3, Sh4, Sh5, Sh6, Sh7, Sh8, Sh9; + +param dmnd : SUN MON TUE WED THU FRI SAT := +1 0 3 3 4 3 2 0 +2 0 14 14 16 14 12 12 +3 0 24 24 27 24 20 15 +4 0 28 28 32 28 23 15 +5 0 33 33 37 33 24 16 +6 0 34 34 38 34 24 15 +7 0 35 35 39 35 25 11 +8 0 35 35 40 35 27 0 +9 0 34 34 39 34 25 0 +10 0 31 31 35 31 24 0 +11 2 24 24 27 24 25 0 +12 3 19 19 21 19 21 0 +13 2 24 24 27 24 13 0 +14 2 16 16 18 16 0 0 +15 0 7 7 7 7 0 0 +16 0 5 5 5 5 0 0; + + +param shifts := +['SUN',*,*]: + Sh1 Sh2 Sh3 Sh4 Sh5 Sh6 Sh7 Sh8 Sh9 := +1 0 0 0 0 0 0 0 0 0 +2 0 0 0 0 0 0 0 0 0 +3 0 0 0 0 0 0 0 0 0 +4 0 0 0 0 0 0 0 0 0 +5 0 0 0 0 0 0 0 0 0 +6 0 0 0 0 0 0 0 0 0 +7 0 0 0 0 0 0 0 0 0 +8 0 0 0 0 0 0 0 0 0 +9 0 0 0 0 0 0 0 0 0 +10 0 0 0 0 0 0 0 0 0 +11 0 0 0 0 0 0 0 0 1 +12 0 0 0 0 0 0 0 0 1 +13 0 0 0 0 0 0 0 0 1 +14 0 0 0 0 0 0 0 0 1 +15 0 0 0 0 0 0 0 0 0 +16 0 0 0 0 0 0 0 0 0 + + +['MON',*,*]: + Sh1 Sh2 Sh3 Sh4 Sh5 Sh6 Sh7 Sh8 Sh9 := +1 1 0 0 0 0 0 0 0 0 +2 1 1 0 0 0 0 0 0 0 +3 1 1 1 0 0 0 0 0 0 +4 1 1 1 1 0 0 0 0 0 +5 0 1 1 1 1 0 0 0 0 +6 1 0 1 1 1 1 0 0 1 +7 1 1 0 1 1 1 1 0 1 +8 1 1 1 0 1 1 1 1 1 +9 1 1 1 1 0 1 1 1 1 +10 0 1 1 1 1 0 1 1 1 +11 0 0 1 1 1 1 0 1 0 +12 0 0 0 1 1 1 1 0 1 +13 0 0 0 0 1 1 1 1 1 +14 0 0 0 0 0 1 1 1 1 +15 0 0 0 0 0 0 1 1 1 +16 0 0 0 0 0 0 0 1 1 + +['TUE',*,*]: + Sh1 Sh2 Sh3 Sh4 Sh5 Sh6 Sh7 Sh8 Sh9 := +1 1 0 0 0 0 0 0 0 0 +2 1 1 0 0 0 0 0 0 0 +3 1 1 1 0 0 0 0 0 0 +4 1 1 1 1 0 0 0 0 0 +5 0 1 1 1 1 0 0 0 0 +6 1 0 1 1 1 1 0 0 1 +7 1 1 0 1 1 1 1 0 1 +8 1 1 1 0 1 1 1 1 1 +9 1 1 1 1 0 1 1 1 1 +10 0 1 1 1 1 0 1 1 1 +11 0 0 1 1 1 1 0 1 0 +12 0 0 0 1 1 1 1 0 1 +13 0 0 0 0 1 1 1 1 1 +14 0 0 0 0 0 1 1 1 1 +15 0 0 0 0 0 0 1 1 1 +16 0 0 0 0 0 0 0 1 1 + +['WED',*,*]: + Sh1 Sh2 Sh3 Sh4 Sh5 Sh6 Sh7 Sh8 Sh9 := +1 1 0 0 0 0 0 0 0 0 +2 1 1 0 0 0 0 0 0 0 +3 1 1 1 0 0 0 0 0 0 +4 1 1 1 1 0 0 0 0 0 +5 0 1 1 1 1 0 0 0 0 +6 1 0 1 1 1 1 0 0 1 +7 1 1 0 1 1 1 1 0 1 +8 1 1 1 0 1 1 1 1 1 +9 1 1 1 1 0 1 1 1 1 +10 0 1 1 1 1 0 1 1 1 +11 0 0 1 1 1 1 0 1 0 +12 0 0 0 1 1 1 1 0 1 +13 0 0 0 0 1 1 1 1 1 +14 0 0 0 0 0 1 1 1 1 +15 0 0 0 0 0 0 1 1 1 +16 0 0 0 0 0 0 0 1 1 + +['THU',*,*]: + Sh1 Sh2 Sh3 Sh4 Sh5 Sh6 Sh7 Sh8 Sh9 := +1 1 0 0 0 0 0 0 0 0 +2 1 1 0 0 0 0 0 0 0 +3 1 1 1 0 0 0 0 0 0 +4 1 1 1 1 0 0 0 0 0 +5 0 1 1 1 1 0 0 0 0 +6 1 0 1 1 1 1 0 0 0 +7 1 1 0 1 1 1 1 0 0 +8 1 1 1 0 1 1 1 1 0 +9 1 1 1 1 0 1 1 1 0 +10 0 1 1 1 1 0 1 1 0 +11 0 0 1 1 1 1 0 1 0 +12 0 0 0 1 1 1 1 0 0 +13 0 0 0 0 1 1 1 1 0 +14 0 0 0 0 0 1 1 1 0 +15 0 0 0 0 0 0 1 1 0 +16 0 0 0 0 0 0 0 1 0 + +['FRI',*,*]: + Sh1 Sh2 Sh3 Sh4 Sh5 Sh6 Sh7 Sh8 Sh9 := +1 1 0 0 0 0 0 0 0 0 +2 1 1 0 0 0 0 0 0 0 +3 1 1 1 0 0 0 0 0 0 +4 1 1 1 1 0 0 0 0 0 +5 0 1 1 1 1 0 0 0 0 +6 1 0 1 1 1 1 0 0 0 +7 1 1 0 1 1 1 1 0 0 +8 1 1 1 0 1 1 1 1 0 +9 1 1 1 1 0 1 1 1 0 +10 0 1 1 1 1 0 1 1 0 +11 0 0 1 1 1 1 0 1 0 +12 0 0 0 1 1 1 1 0 0 +13 0 0 0 0 1 1 1 1 0 +14 0 0 0 0 0 1 1 1 0 +15 0 0 0 0 0 0 1 1 0 +16 0 0 0 0 0 0 0 1 0 + +['SAT',*,*]: + Sh1 Sh2 Sh3 Sh4 Sh5 Sh6 Sh7 Sh8 Sh9 := +1 0 0 0 0 0 0 0 0 0 +2 0 0 0 0 0 0 0 0 1 +3 0 0 0 0 0 0 0 0 1 +4 0 0 0 0 0 0 0 0 1 +5 0 0 0 0 0 0 0 0 1 +6 0 0 0 0 0 0 0 0 1 +7 0 0 0 0 0 0 0 0 1 +8 0 0 0 0 0 0 0 0 0 +9 0 0 0 0 0 0 0 0 0 +10 0 0 0 0 0 0 0 0 0 +11 0 0 0 0 0 0 0 0 0 +12 0 0 0 0 0 0 0 0 0 +13 0 0 0 0 0 0 0 0 0 +14 0 0 0 0 0 0 0 0 0 +15 0 0 0 0 0 0 0 0 0 +16 0 0 0 0 0 0 0 0 0; diff --git a/glpk-5.0/examples/shikaku.mod b/glpk-5.0/examples/shikaku.mod new file mode 100644 index 0000000..19cf5dd --- /dev/null +++ b/glpk-5.0/examples/shikaku.mod @@ -0,0 +1,107 @@ +/* A solver for the Japanese number-puzzle Shikaku + * http://en.wikipedia.org/wiki/Shikaku + * + * Sebastian Nowozin <nowozin@gmail.com>, 27th January 2009 + */ + +param ndim := 10; +set rows := 1..ndim; +set rows1 := 1..(ndim+1); +set cols := 1..ndim; +set cols1 := 1..(ndim+1); +param givens{rows, cols}, integer, >= 0, default 0; + +/* Set of vertices as (row,col) coordinates */ +set V := { (i,j) in { rows, cols }: givens[i,j] != 0 }; + +/* Set of all feasible boxes of the right size: only this boxes are possible. + * The box contains (i,j) and ranges from (k,l) to (m,n) + */ +set B := { (i,j,k,l,m,n) in { V, rows, cols, rows1, cols1 }: + i >= k and i < m and j >= l and j < n and /* Contains (i,j) */ + ((m-k)*(n-l)) = givens[i,j] and /* Right size */ + card({ (s,t) in V: s >= k and s < m and t >= l and t < n }) = 1 + /* Contains only (i,j), no other number */ +}; + +var x{B}, binary; + +/* Cover each square exactly once */ +s.t. cover_once{ (s,t) in { rows, cols } }: + sum{(i,j,k,l,m,n) in B: s >= k and s < m and t >= l and t < n} + x[i,j,k,l,m,n] = 1; + +minimize cost: 0; + +solve; + +/* Output solution graphically */ +printf "\nSolution:\n"; +for { row in rows1 } { + for { col in cols1 } { + printf{0..0: card({(i,j,k,l,m,n) in B: + col >= l and col <= n and (row = k or row = m) and + x[i,j,k,l,m,n] = 1}) > 0 and + card({(i,j,k,l,m,n) in B: + row >= k and row <= m and (col = l or col = n) and + x[i,j,k,l,m,n] = 1}) > 0} "+"; + printf{0..0: card({(i,j,k,l,m,n) in B: + col >= l and col <= n and (row = k or row = m) and + x[i,j,k,l,m,n] = 1}) = 0 and + card({(i,j,k,l,m,n) in B: + row >= k and row <= m and (col = l or col = n) and + x[i,j,k,l,m,n] = 1}) > 0} "|"; + printf{0..0: card({(i,j,k,l,m,n) in B: + row >= k and row <= m and (col = l or col = n) and + x[i,j,k,l,m,n] = 1}) = 0 and + card({(i,j,k,l,m,n) in B: + col >= l and col <= n and (row = k or row = m) and + x[i,j,k,l,m,n] = 1}) > 0} "-"; + printf{0..0: card({(i,j,k,l,m,n) in B: + row >= k and row <= m and (col = l or col = n) and + x[i,j,k,l,m,n] = 1}) = 0 and + card({(i,j,k,l,m,n) in B: + col >= l and col <= n and (row = k or row = m) and + x[i,j,k,l,m,n] = 1}) = 0} " "; + + printf{0..0: card({(i,j,k,l,m,n) in B: + col >= l and col < n and (row = k or row = m) and + x[i,j,k,l,m,n] = 1}) > 0} "---"; + printf{0..0: card({(i,j,k,l,m,n) in B: + col >= l and col < n and (row = k or row = m) and + x[i,j,k,l,m,n] = 1}) = 0} " "; + } + printf "\n"; + + for { (col,p) in { cols, 1 }: card({ s in rows: s = row }) = 1 } { + printf{0..0: card({(i,j,k,l,m,n) in B: + row >= k and row < m and (col = l or col = n) and + x[i,j,k,l,m,n] = 1}) > 0} "|"; + printf{0..0: card({(i,j,k,l,m,n) in B: + row >= k and row < m and (col = l or col = n) and + x[i,j,k,l,m,n] = 1}) = 0} " "; + printf{0..0: card({ (i,j) in V: i = row and j = col}) > 0} " %2d", givens[row,col]; + printf{0..0: card({ (i,j) in V: i = row and j = col}) = 0} " ."; + } + printf{0..0: card({ r in rows: r = row }) = 1} "|\n"; +} + +data; + +/* This Shikaku is from + * http://www.emn.fr/x-info/sdemasse/gccat/KShikaku.html#uid5449 + */ +param givens : 1 2 3 4 5 6 7 8 9 10 := + 1 9 . . . 12 . . 5 . . + 2 . . . . . . . . . . + 3 . . . . . . . . . 6 + 4 8 . 6 . 8 . . . . . + 5 . . . . . . . . . . + 6 . . . . . . . . . . + 7 . . . . . 6 . 8 . 12 + 8 4 . . . . . . . . . + 9 . . . . . . . . . . + 10 . . 3 . . 9 . . . 4 + ; + +end; diff --git a/glpk-5.0/examples/sorting.mod b/glpk-5.0/examples/sorting.mod new file mode 100644 index 0000000..8f82b1f --- /dev/null +++ b/glpk-5.0/examples/sorting.mod @@ -0,0 +1,67 @@ +/* sorting.mod - how to sort arrays in MathProg */ + +/* Written in GNU MathProg by Andrew Makhorin <mao@gnu.org> */ + +# Sometimes it is necessary to print parameters or variables in the +# order of ascending or descending their values. Suppose, for example, +# that we have the following subscripted parameter: + +set I := 1..12; + +param a{i in I} := Uniform(2, 7); + +# If we print all its members: + +printf{i in I} "a[%d] = %g\n", i, a[i]; + +# the output may look like follows: +# +# a[1] = 2.64156 +# a[2] = 2.04798 +# a[3] = 2.14843 +# a[4] = 4.76896 +# a[5] = 6.09132 +# a[6] = 3.27780 +# a[7] = 4.06113 +# a[8] = 4.05898 +# a[9] = 6.63120 +# a[10] = 6.50318 +# a[11] = 3.46065 +# a[12] = 4.69845 +# +# However, we would like the parameter members to appear in the order +# of ascending their values. +# +# Introduce the following auxiliary parameter: + +param pos{i in I} := + 1 + card({j in I: a[j] < a[i] or a[j] = a[i] and j < i}); + +# where pos[i] = k means that in the sorted list member a[i] would +# have k-th position, 1 <= k <= |I|. Then introduce another auxiliary +# parameter: + +param ind{k in 1..card(I)} := sum{i in I: pos[i] = k} i; + +# where ind[k] = i iff pos[k] = i. +# +# Now, the following statement: + +printf{k in 1..card(I)} "a[%d] = %g\n", ind[k], a[ind[k]]; + +# prints the parameter members in the desired order: +# +# a[2] = 2.04798 +# a[3] = 2.14843 +# a[1] = 2.64156 +# a[6] = 3.27780 +# a[11] = 3.46065 +# a[8] = 4.05898 +# a[7] = 4.06113 +# a[12] = 4.69845 +# a[4] = 4.76896 +# a[5] = 6.09132 +# a[10] = 6.50318 +# a[9] = 6.63120 + +end; diff --git a/glpk-5.0/examples/spp.mod b/glpk-5.0/examples/spp.mod new file mode 100644 index 0000000..53008f6 --- /dev/null +++ b/glpk-5.0/examples/spp.mod @@ -0,0 +1,67 @@ +/* SPP, Shortest Path Problem */ + +/* Written in GNU MathProg by Andrew Makhorin <mao@gnu.org> */ + +/* Given a directed graph G = (V,E), its edge lengths c(i,j) for all + (i,j) in E, and two nodes s, t in V, the Shortest Path Problem (SPP) + is to find a directed path from s to t whose length is minimal. */ + +param n, integer, > 0; +/* number of nodes */ + +set E, within {i in 1..n, j in 1..n}; +/* set of edges */ + +param c{(i,j) in E}; +/* c[i,j] is length of edge (i,j); note that edge lengths are allowed + to be of any sign (positive, negative, or zero) */ + +param s, in {1..n}; +/* source node */ + +param t, in {1..n}; +/* target node */ + +var x{(i,j) in E}, >= 0; +/* x[i,j] = 1 means that edge (i,j) belong to shortest path; + x[i,j] = 0 means that edge (i,j) does not belong to shortest path; + note that variables x[i,j] are binary, however, there is no need to + declare them so due to the totally unimodular constraint matrix */ + +s.t. r{i in 1..n}: sum{(j,i) in E} x[j,i] + (if i = s then 1) = + sum{(i,j) in E} x[i,j] + (if i = t then 1); +/* conservation conditions for unity flow from s to t; every feasible + solution is a path from s to t */ + +minimize Z: sum{(i,j) in E} c[i,j] * x[i,j]; +/* objective function is the path length to be minimized */ + +data; + +/* Optimal solution is 20 that corresponds to the following shortest + path: s = 1 -> 2 -> 4 -> 8 -> 6 = t */ + +param n := 8; + +param s := 1; + +param t := 6; + +param : E : c := + 1 2 1 + 1 4 8 + 1 7 6 + 2 4 2 + 3 2 14 + 3 4 10 + 3 5 6 + 3 6 19 + 4 5 8 + 4 8 13 + 5 8 12 + 6 5 7 + 7 4 5 + 8 6 4 + 8 7 10; + +end; diff --git a/glpk-5.0/examples/spxsamp1.c b/glpk-5.0/examples/spxsamp1.c new file mode 100644 index 0000000..7156423 --- /dev/null +++ b/glpk-5.0/examples/spxsamp1.c @@ -0,0 +1,18 @@ +/* spxsamp1.c */ + +#include <stdio.h> +#include <stdlib.h> +#include <glpk.h> + +int main(void) +{ glp_prob *P; + P = glp_create_prob(); + glp_read_mps(P, GLP_MPS_DECK, NULL, "25fv47.mps"); + glp_adv_basis(P, 0); + glp_simplex(P, NULL); + glp_print_sol(P, "25fv47.txt"); + glp_delete_prob(P); + return 0; +} + +/* eof */ diff --git a/glpk-5.0/examples/spxsamp2.c b/glpk-5.0/examples/spxsamp2.c new file mode 100644 index 0000000..f952e74 --- /dev/null +++ b/glpk-5.0/examples/spxsamp2.c @@ -0,0 +1,20 @@ +/* spxsamp2.c */ + +#include <stdio.h> +#include <stdlib.h> +#include <glpk.h> + +int main(void) +{ glp_prob *P; + glp_smcp parm; + P = glp_create_prob(); + glp_read_mps(P, GLP_MPS_DECK, NULL, "25fv47.mps"); + glp_init_smcp(&parm); + parm.meth = GLP_DUAL; + glp_simplex(P, &parm); + glp_print_sol(P, "25fv47.txt"); + glp_delete_prob(P); + return 0; +} + +/* eof */ diff --git a/glpk-5.0/examples/sql/README b/glpk-5.0/examples/sql/README new file mode 100644 index 0000000..f78ec15 --- /dev/null +++ b/glpk-5.0/examples/sql/README @@ -0,0 +1,5 @@ +This subdirectory contains files which demonstrate using data tables +in MathProg models for MySQL and iODBC. + +Script mysql_setup.sh is used to load the data from the *.sql files to +a MySQL database. Change the username, if necessary. diff --git a/glpk-5.0/examples/sql/mysql_setup.sh b/glpk-5.0/examples/sql/mysql_setup.sh new file mode 100755 index 0000000..1dce8ed --- /dev/null +++ b/glpk-5.0/examples/sql/mysql_setup.sh @@ -0,0 +1,6 @@ +#!/bin/sh +# This file can be used to create database glpk in MySQL. +echo MySQL is called for user root. +mysql -f -u root -p < sudoku.sql +echo MySQL is called for user root. +mysql -f -u root -p < transp.sql diff --git a/glpk-5.0/examples/sql/sudoku.sql b/glpk-5.0/examples/sql/sudoku.sql new file mode 100644 index 0000000..2fe40d7 --- /dev/null +++ b/glpk-5.0/examples/sql/sudoku.sql @@ -0,0 +1,101 @@ +CREATE DATABASE glpk; +CREATE USER glpk@localhost IDENTIFIED BY 'gnu'; +GRANT ALL PRIVILEGES ON glpk.* TO glpk@localhost; +USE glpk; +DROP TABLE sudoku; +CREATE TABLE sudoku ( + ID INT , + COL INT , + LIN INT , + VAL INT , + PRIMARY KEY ( ID, COL, LIN ) + ); +DROP TABLE sudoku_solution; +CREATE TABLE sudoku_solution ( + ID INT , + COL INT , + LIN INT , + VAL INT , + PRIMARY KEY ( ID, COL, LIN ) + ); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 1, 1, 5); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 1, 2, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 1, 3, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 1, 4, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 1, 5, 4); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 1, 6, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 1, 7, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 1, 8, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 1, 9, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 2, 1, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 2, 2, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 2, 3, 3); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 2, 4, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 2, 5, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 2, 6, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 2, 7, 6); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 2, 8, 2); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 2, 9, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 3, 1, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 3, 2, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 3, 3, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 3, 4, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 3, 5, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 3, 6, 9); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 3, 7, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 3, 8, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 3, 9, 4); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 4, 1, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 4, 2, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 4, 3, 6); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 4, 4, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 4, 5, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 4, 6, 7); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 4, 7, 2); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 4, 8, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 4, 9, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 5, 1, 8); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 5, 2, 1); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 5, 3, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 5, 4, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 5, 5, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 5, 6, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 5, 7, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 5, 8, 4); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 5, 9, 3); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 6, 1, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 6, 2, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 6, 3, 9); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 6, 4, 1); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 6, 5, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 6, 6, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 6, 7, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 6, 8, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 6, 9, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 7, 1, 7); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 7, 2, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 7, 3, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 7, 4, 5); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 7, 5, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 7, 6, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 7, 7, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 7, 8, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 7, 9, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 8, 1, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 8, 2, 9); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 8, 3, 2); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 8, 4, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 8, 5, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 8, 6, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 8, 7, 8); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 8, 8, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 8, 9, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 9, 1, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 9, 2, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 9, 3, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 9, 4, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 9, 5, 3); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 9, 6, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 9, 7, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 9, 8, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 9, 9, 6); diff --git a/glpk-5.0/examples/sql/sudoku_mysql.mod b/glpk-5.0/examples/sql/sudoku_mysql.mod new file mode 100644 index 0000000..6e56f2c --- /dev/null +++ b/glpk-5.0/examples/sql/sudoku_mysql.mod @@ -0,0 +1,113 @@ +/* SUDOKU, Number Placement Puzzle */ + +/* Written in GNU MathProg by Andrew Makhorin <mao@mai2.rcnet.ru> */ + +/* This example shows how to use the table statement. + The sudoku to be solves is read from file sudoku_in.csv. + The solution is written to sudoku_out.csv. + The file format is CSV as defined in + RFC 4180 - Common Format and MIME Type for + Comma-Separated Values (CSV) Files */ + +/* Sudoku, also known as Number Place, is a logic-based placement + puzzle. The aim of the canonical puzzle is to enter a numerical + digit from 1 through 9 in each cell of a 9x9 grid made up of 3x3 + subgrids (called "regions"), starting with various digits given in + some cells (the "givens"). Each row, column, and region must contain + only one instance of each numeral. + + Example: + + +-------+-------+-------+ + | 5 3 . | . 7 . | . . . | + | 6 . . | 1 9 5 | . . . | + | . 9 8 | . . . | . 6 . | + +-------+-------+-------+ + | 8 . . | . 6 . | . . 3 | + | 4 . . | 8 . 3 | . . 1 | + | 7 . . | . 2 . | . . 6 | + +-------+-------+-------+ + | . 6 . | . . . | 2 8 . | + | . . . | 4 1 9 | . . 5 | + | . . . | . 8 . | . 7 9 | + +-------+-------+-------+ + + (From Wikipedia, the free encyclopedia.) */ +set fields dimen 2; + +param id; + +param givens{1..9, 1..9}, integer, >= 0, <= 9, default 0; +/* the "givens" */ + +/* +table ti IN 'MySQL' 'Database=glpk;UID=glpk;PWD=gnu' + 'sudoku' : + fields <- [COL, LIN], givens ~ VAL; +*/ +table ti IN 'MySQL' 'Database=glpk;UID=glpk;PWD=gnu' + 'SELECT * FROM sudoku WHERE ID = ' & id : + fields <- [COL, LIN], givens ~ VAL; + +var x{i in 1..9, j in 1..9, k in 1..9}, binary; +/* x[i,j,k] = 1 means cell [i,j] is assigned number k */ + +s.t. fa{i in 1..9, j in 1..9, k in 1..9: givens[i,j] != 0}: + x[i,j,k] = (if givens[i,j] = k then 1 else 0); +/* assign pre-defined numbers using the "givens" */ + +s.t. fb{i in 1..9, j in 1..9}: sum{k in 1..9} x[i,j,k] = 1; +/* each cell must be assigned exactly one number */ + +s.t. fc{i in 1..9, k in 1..9}: sum{j in 1..9} x[i,j,k] = 1; +/* cells in the same row must be assigned distinct numbers */ + +s.t. fd{j in 1..9, k in 1..9}: sum{i in 1..9} x[i,j,k] = 1; +/* cells in the same column must be assigned distinct numbers */ + +s.t. fe{I in 1..9 by 3, J in 1..9 by 3, k in 1..9}: + sum{i in I..I+2, j in J..J+2} x[i,j,k] = 1; +/* cells in the same region must be assigned distinct numbers */ + +/* there is no need for an objective function here */ + +solve; + +table ta{(i,j) in fields} OUT + 'MySQL' 'Database=glpk;UID=glpk;PWD=gnu' + 'DELETE FROM sudoku_solution' + 'WHERE ID = ' & id & ';' + 'INSERT INTO sudoku_solution' + '(ID, COL, LIN, VAL)' + 'VALUES(?, ?, ?, ?);' : + id ~ ID, i ~ COL, j ~ LIN, (sum{k in 1..9} x[i,j,k] * k) ~ VAL; + +printf "\nSudoku to be solved\n"; +for {i in 1..9} +{ for {0..0: i = 1 or i = 4 or i = 7} + printf " +-------+-------+-------+\n"; + for {j in 1..9} + { for {0..0: j = 1 or j = 4 or j = 7} printf(" |"); + printf " %d", givens[i,j]; + for {0..0: j = 9} printf(" |\n"); + } + for {0..0: i = 9} + printf " +-------+-------+-------+\n"; + } +printf "\nSolution\n"; +for {i in 1..9} +{ for {0..0: i = 1 or i = 4 or i = 7} + printf " +-------+-------+-------+\n"; + for {j in 1..9} + { for {0..0: j = 1 or j = 4 or j = 7} printf(" |"); + printf " %d", sum{k in 1..9} x[i,j,k] * k; + for {0..0: j = 9} printf(" |\n"); + } + for {0..0: i = 9} + printf " +-------+-------+-------+\n"; +} + +data; + +param id := 1; +end; diff --git a/glpk-5.0/examples/sql/sudoku_odbc.mod b/glpk-5.0/examples/sql/sudoku_odbc.mod new file mode 100644 index 0000000..9ffa3ab --- /dev/null +++ b/glpk-5.0/examples/sql/sudoku_odbc.mod @@ -0,0 +1,111 @@ +/* SUDOKU, Number Placement Puzzle */ + +/* Written in GNU MathProg by Andrew Makhorin <mao@mai2.rcnet.ru> */ + +/* This example shows how to use the table statement. + The sudoku to be solves is read from file sudoku_in.csv. + The solution is written to sudoku_out.csv. + The file format is CSV as defined in + RFC 4180 - Common Format and MIME Type for + Comma-Separated Values (CSV) Files */ + +/* Sudoku, also known as Number Place, is a logic-based placement + puzzle. The aim of the canonical puzzle is to enter a numerical + digit from 1 through 9 in each cell of a 9x9 grid made up of 3x3 + subgrids (called "regions"), starting with various digits given in + some cells (the "givens"). Each row, column, and region must contain + only one instance of each numeral. + + Example: + + +-------+-------+-------+ + | 5 3 . | . 7 . | . . . | + | 6 . . | 1 9 5 | . . . | + | . 9 8 | . . . | . 6 . | + +-------+-------+-------+ + | 8 . . | . 6 . | . . 3 | + | 4 . . | 8 . 3 | . . 1 | + | 7 . . | . 2 . | . . 6 | + +-------+-------+-------+ + | . 6 . | . . . | 2 8 . | + | . . . | 4 1 9 | . . 5 | + | . . . | . 8 . | . 7 9 | + +-------+-------+-------+ + + (From Wikipedia, the free encyclopedia.) */ +set fields dimen 2; + +param id; + +param givens{1..9, 1..9}, integer, >= 0, <= 9, default 0; +/* the "givens" */ + +table ti IN 'iODBC' + 'DSN=glpk;UID=glpk;PWD=gnu' + 'SELECT * FROM sudoku' + 'WHERE ID = ' & id : + fields <- [COL, LIN], givens ~ VAL; + +var x{i in 1..9, j in 1..9, k in 1..9}, binary; +/* x[i,j,k] = 1 means cell [i,j] is assigned number k */ + +s.t. fa{i in 1..9, j in 1..9, k in 1..9: givens[i,j] != 0}: + x[i,j,k] = (if givens[i,j] = k then 1 else 0); +/* assign pre-defined numbers using the "givens" */ + +s.t. fb{i in 1..9, j in 1..9}: sum{k in 1..9} x[i,j,k] = 1; +/* each cell must be assigned exactly one number */ + +s.t. fc{i in 1..9, k in 1..9}: sum{j in 1..9} x[i,j,k] = 1; +/* cells in the same row must be assigned distinct numbers */ + +s.t. fd{j in 1..9, k in 1..9}: sum{i in 1..9} x[i,j,k] = 1; +/* cells in the same column must be assigned distinct numbers */ + +s.t. fe{I in 1..9 by 3, J in 1..9 by 3, k in 1..9}: + sum{i in I..I+2, j in J..J+2} x[i,j,k] = 1; +/* cells in the same region must be assigned distinct numbers */ + +/* there is no need for an objective function here */ + + +solve; + +table ta {(i, j) in {i1 in 1..9} cross {i2 in 1..9}} OUT + 'iODBC' 'DSN=glpk;UID=glpk;PWD=gnu' + 'DELETE FROM sudoku_solution' + 'WHERE ID = ' & id & ';' + 'INSERT INTO sudoku_solution' + '(ID, COL, LIN, VAL)' + 'VALUES(?, ?, ?, ?);' : + id ~ ID, i ~ COL, j ~ LIN, (sum{k in 1..9} x[i,j,k] * k) ~ VAL; + +printf "\nSudoku to be solved\n"; +for {i in 1..9} +{ for {0..0: i = 1 or i = 4 or i = 7} + printf " +-------+-------+-------+\n"; + for {j in 1..9} + { for {0..0: j = 1 or j = 4 or j = 7} printf(" |"); + printf " %d", givens[i,j]; + for {0..0: j = 9} printf(" |\n"); + } + for {0..0: i = 9} + printf " +-------+-------+-------+\n"; + } +printf "\nSolution\n"; +for {i in 1..9} +{ for {0..0: i = 1 or i = 4 or i = 7} + printf " +-------+-------+-------+\n"; + for {j in 1..9} + { for {0..0: j = 1 or j = 4 or j = 7} printf(" |"); + printf " %d", sum{k in 1..9} x[i,j,k] * k; + for {0..0: j = 9} printf(" |\n"); + } + for {0..0: i = 9} + printf " +-------+-------+-------+\n"; +} + +data; + +param id := 1; +end; diff --git a/glpk-5.0/examples/sql/transp.sql b/glpk-5.0/examples/sql/transp.sql new file mode 100644 index 0000000..8737333 --- /dev/null +++ b/glpk-5.0/examples/sql/transp.sql @@ -0,0 +1,45 @@ +CREATE DATABASE glpk; +CREATE USER glpk@localhost IDENTIFIED BY 'gnu'; +GRANT ALL PRIVILEGES ON glpk.* TO glpk@localhost; +USE glpk; +# production capacity +DROP TABLE transp_capa; +CREATE TABLE transp_capa ( + PLANT TEXT(127), + CAPA REAL, + PRIMARY KEY ( PLANT(127) ) + ); +INSERT INTO transp_capa ( PLANT, CAPA ) VALUES ( 'Seattle', 350 ); +INSERT INTO transp_capa ( PLANT, CAPA ) VALUES ( 'San Diego', 600 ); +# demand +DROP TABLE transp_demand; +CREATE TABLE transp_demand ( + MARKET TEXT(127), + DEMAND REAL, + PRIMARY KEY ( MARKET(127) ) + ); +INSERT INTO transp_demand ( MARKET, DEMAND ) VALUES ( 'New York', 325 ); +INSERT INTO transp_demand ( MARKET, DEMAND ) VALUES ( 'Chicago', 300 ); +INSERT INTO transp_demand ( MARKET, DEMAND ) VALUES ( 'Topeka', 275 ); +# distance +DROP TABLE transp_dist; +CREATE TABLE transp_dist ( + LOC1 TEXT(127), + LOC2 TEXT(127), + DIST REAL, + PRIMARY KEY ( LOC1(127), LOC2(127) ) + ); +INSERT INTO transp_dist ( LOC1, LOC2, DIST ) VALUES ( 'Seattle', 'New York', 2.5 ); +INSERT INTO transp_dist ( LOC1, LOC2, DIST ) VALUES ( 'Seattle', 'Chicago', 1.7 ); +INSERT INTO transp_dist ( LOC1, LOC2, DIST ) VALUES ( 'Seattle', 'Topeka', 1.8 ); +INSERT INTO transp_dist ( LOC1, LOC2, DIST ) VALUES ( 'San Diego', 'New York', 2.5 ); +INSERT INTO transp_dist ( LOC1, LOC2, DIST ) VALUES ( 'San Diego', 'Chicago', 1.8 ); +INSERT INTO transp_dist ( LOC1, LOC2, DIST ) VALUES ( 'San Diego', 'Topeka', 1.4 ); +# result +DROP TABLE transp_result; +CREATE TABLE transp_result ( + LOC1 TEXT(127), + LOC2 TEXT(127), + QUANTITY REAL, + PRIMARY KEY ( LOC1(127), LOC2(127) ) + ); diff --git a/glpk-5.0/examples/sql/transp_mysql.mod b/glpk-5.0/examples/sql/transp_mysql.mod new file mode 100644 index 0000000..f375fa3 --- /dev/null +++ b/glpk-5.0/examples/sql/transp_mysql.mod @@ -0,0 +1,71 @@ +# A TRANSPORTATION PROBLEM +# +# This problem finds a least cost shipping schedule that meets +# requirements at markets and supplies at factories. +# +# References: +# Dantzig G B, "Linear Programming and Extensions." +# Princeton University Press, Princeton, New Jersey, 1963, +# Chapter 3-3. + +set I; +/* canning plants */ + +param a{i in I}; +/* capacity of plant i in cases */ + +table plants IN "MySQL" + 'Database=glpk;UID=glpk;PWD=gnu' + 'SELECT PLANT, CAPA AS CAPACITY FROM transp_capa' : + I <- [ PLANT ], a ~ CAPACITY; + +set J; +/* markets */ + +param b{j in J}; +/* demand at market j in cases */ + +table markets IN "MySQL" + 'Database=glpk;UID=glpk;PWD=gnu' + 'transp_demand' : + J <- [ MARKET ], b ~ DEMAND; + +param d{i in I, j in J}; +/* distance in thousands of miles */ + +table dist IN "MySQL" + 'Database=glpk;UID=glpk;PWD=gnu' + 'transp_dist' : + [ LOC1, LOC2 ], d ~ DIST; + +param f; +/* freight in dollars per case per thousand miles */ + +param c{i in I, j in J} := f * d[i,j] / 1000; +/* transport cost in thousands of dollars per case */ + +var x{i in I, j in J} >= 0; +/* shipment quantities in cases */ + +minimize cost: sum{i in I, j in J} c[i,j] * x[i,j]; +/* total transportation costs in thousands of dollars */ + +s.t. supply{i in I}: sum{j in J} x[i,j] <= a[i]; +/* observe supply limit at plant i */ + +s.t. demand{j in J}: sum{i in I} x[i,j] >= b[j]; +/* satisfy demand at market j */ + +solve; + +table result{i in I, j in J: x[i,j]} OUT "MySQL" + 'Database=glpk;UID=glpk;PWD=gnu' + 'DELETE FROM transp_result;' + 'INSERT INTO transp_result VALUES (?,?,?)' : + i ~ LOC1, j ~ LOC2, x[i,j] ~ QUANTITY; + +data; + +param f := 90; + +end; diff --git a/glpk-5.0/examples/sql/transp_odbc.mod b/glpk-5.0/examples/sql/transp_odbc.mod new file mode 100644 index 0000000..36d807e --- /dev/null +++ b/glpk-5.0/examples/sql/transp_odbc.mod @@ -0,0 +1,72 @@ +# A TRANSPORTATION PROBLEM +# +# This problem finds a least cost shipping schedule that meets +# requirements at markets and supplies at factories. +# +# References: +# Dantzig G B, "Linear Programming and Extensions." +# Princeton University Press, Princeton, New Jersey, 1963, +# Chapter 3-3. + +set I; +/* canning plants */ + +param a{i in I}; +/* capacity of plant i in cases */ + +table plants IN "iODBC" + 'DSN=glpk;UID=glpk;PWD=gnu' + 'SELECT PLANT, CAPA AS CAPACITY' + 'FROM transp_capa' : + I <- [ PLANT ], a ~ CAPACITY; + +set J; +/* markets */ + +param b{j in J}; +/* demand at market j in cases */ + +table markets IN "iODBC" + 'DSN=glpk;UID=glpk;PWD=gnu' + 'transp_demand' : + J <- [ MARKET ], b ~ DEMAND; + +param d{i in I, j in J}; +/* distance in thousands of miles */ + +table dist IN "iODBC" + 'DSN=glpk;UID=glpk;PWD=gnu' + 'transp_dist' : + [ LOC1, LOC2 ], d ~ DIST; + +param f; +/* freight in dollars per case per thousand miles */ + +param c{i in I, j in J} := f * d[i,j] / 1000; +/* transport cost in thousands of dollars per case */ + +var x{i in I, j in J} >= 0; +/* shipment quantities in cases */ + +minimize cost: sum{i in I, j in J} c[i,j] * x[i,j]; +/* total transportation costs in thousands of dollars */ + +s.t. supply{i in I}: sum{j in J} x[i,j] <= a[i]; +/* observe supply limit at plant i */ + +s.t. demand{j in J}: sum{i in I} x[i,j] >= b[j]; +/* satisfy demand at market j */ + +solve; + +table result{i in I, j in J: x[i,j]} OUT "iODBC" + 'DSN=glpk;UID=glpk;PWD=gnu' + 'DELETE FROM transp_result;' + 'INSERT INTO transp_result VALUES (?,?,?)' : + i ~ LOC1, j ~ LOC2, x[i,j] ~ QUANTITY; + +data; + +param f := 90; + +end; diff --git a/glpk-5.0/examples/stigler.mod b/glpk-5.0/examples/stigler.mod new file mode 100644 index 0000000..20c5d9d --- /dev/null +++ b/glpk-5.0/examples/stigler.mod @@ -0,0 +1,411 @@ +/* STIGLER, original Stigler's 1939 diet problem */ + +/* The Stigler Diet is an optimization problem named for George Stigler, + a 1982 Nobel Laureate in economics, who posed the following problem: + For a moderately active man weighing 154 pounds, how much of each of + 77 foods should be eaten on a daily basis so that the man's intake of + nine nutrients will be at least equal to the recommended dietary + allowances (RDSs) suggested by the National Research Council in 1943, + with the cost of the diet being minimal? + + The nutrient RDAs required to be met in Stigler's experiment were + calories, protein, calcium, iron, vitamin A, thiamine, riboflavin, + niacin, and ascorbic acid. The result was an annual budget allocated + to foods such as evaporated milk, cabbage, dried navy beans, and beef + liver at a cost of approximately $0.11 a day in 1939 U.S. dollars. + + While the name "Stigler Diet" was applied after the experiment by + outsiders, according to Stigler, "No one recommends these diets for + anyone, let alone everyone." The Stigler diet has been much ridiculed + for its lack of variety and palatability, however his methodology has + received praise and is considered to be some of the earliest work in + linear programming. + + The Stigler diet question is a linear programming problem. Lacking + any sophisticated method of solving such a problem, Stigler was + forced to utilize heuristic methods in order to find a solution. The + diet question originally asked in which quantities a 154 pound male + would have to consume 77 different foods in order to fulfill the + recommended intake of 9 different nutrients while keeping expense at + a minimum. Through "trial and error, mathematical insight and + agility," Stigler was able to eliminate 62 of the foods from the + original 77 (these foods were removed based because they lacked + nutrients in comparison to the remaining 15). From the reduced list, + Stigler calculated the required amounts of each of the remaining 15 + foods to arrive at a cost-minimizing solution to his question. + According to Stigler's calculations, the annual cost of his solution + was $39.93 in 1939 dollars. When corrected for inflation using the + consumer price index, the cost of the diet in 2005 dollars is + $561.43. The specific combination of foods and quantities is as + follows: + + Stigler's 1939 Diet + + Food Annual Quantities Annual Cost + ---------------- ----------------- ----------- + Wheat Flour 370 lb. $13.33 + Evaporated Milk 57 cans 3.84 + Cabbage 111 lb. 4.11 + Spinach 23 lb. 1.85 + Dried Navy Beans 285 lb. 16.80 + ---------------------------------------------- + Total Annual Cost $39.93 + + The 9 nutrients that Stigler's diet took into consideration and their + respective recommended daily amounts were: + + Table of nutrients considered in Stigler's diet + + Nutrient Daily Recommended Intake + ------------------------- ------------------------ + Calories 3,000 Calories + Protein 70 grams + Calcium .8 grams + Iron 12 milligrams + Vitamin A 5,000 IU + Thiamine (Vitamin B1) 1.8 milligrams + Riboflavin (Vitamin B2) 2.7 milligrams + Niacin 18 milligrams + Ascorbic Acid (Vitamin C) 75 milligrams + + Seven years after Stigler made his initial estimates, the development + of George Dantzig's Simplex algorithm made it possible to solve the + problem without relying on heuristic methods. The exact value was + determined to be $39.69 (using the original 1939 data). Dantzig's + algorithm describes a method of traversing the vertices of a polytope + of N+1 dimensions in order to find the optimal solution to a specific + situation. + + (From Wikipedia, the free encyclopedia.) */ + +/* Translated from GAMS by Andrew Makhorin <mao@gnu.org>. + + For the original GAMS model stigler1939.gms see [3]. + + References: + + 1. George J. Stigler, "The Cost of Subsistence," J. Farm Econ. 27, + 1945, pp. 303-14. + + 2. National Research Council, "Recommended Daily Allowances," Reprint + and Circular Series No. 115, January, 1943. + + 3. Erwin Kalvelagen, "Model building with GAMS," Chapter 2, "Building + linear programming models," pp. 128-34. */ + +set C; +/* commodities */ + +check card(C) = 77; +/* there must be 77 commodities */ + +set N; +/* nutrients */ + +param data{c in C, {"price", "weight"} union N}; +/* nutritive values per dollar of expenditure */ + +param allowance{n in N}; +/* recommended daily allowance for a moderately active man */ + +var x{c in C}, >= 0; +/* dollars of food to be purchased daily */ + +s.t. nb{n in N}: sum{c in C} data[c,n] * x[c] >= allowance[n]; +/* nutrient balance */ + +minimize cost: sum{c in C} x[c]; +/* total food bill */ + +solve; + +param days := 365.25; +/* days in a year */ + +param commodity{c in C}, symbolic; + +param unit{c in C}, symbolic; + +printf "\n"; +printf "MINIMUM COST ANNUAL DIET\n"; +printf "\n"; +printf " Commodity Unit Quantity Cost \n"; +printf "------------------------- ---------- ---------- ----------\n"; +printf{c in C: x[c] != 0} "%-25s %10s %10.2f $%7.2f\n", commodity[c], + unit[c], 100 * days * x[c] / data[c,"price"], days * x[c]; +printf " -----------------\n"; +printf " Total: $%7.2f\n", + days * sum{c in C} x[c]; +printf "\n"; + +data; + +param : C : commodity unit := +flour "Wheat Flour (Enriched)" "10 lb." +macaroni "Macaroni" "1 lb." +cereal "Wheat Cereal (Enriched)" "28 oz." +cornflakes "Corn Flakes" "8 oz." +cornmeal "Corn Meal" "1 lb." +grits "Hominy Grits" "24 oz." +rice "Rice" "1 lb." +oats "Rolled Oats" "1 lb." +whitebread "White Bread (Enriched)" "1 lb." +wheatbread "Whole Wheat Bread" "1 lb." +ryebread "Rye Bread" "1 lb." +poundcake "Pound Cake" "1 lb." +crackers "Soda Crackers" "1 lb." +milk "Milk" "1 qt." +evapmild "Evaporated Milk (can)" "14.5 oz." +butter "Butter" "1 lb." +margarine "Oleomargarine" "1 lb." +eggs "Eggs" "1 doz." +cheese "Cheese (Cheddar)" "1 lb." +cream "Cream" "1/2 pt." +peanutbutter "Peanut Butter" "1 lb." +mayonnaise "Mayonnaise" "1/2 pt." +crisco "Crisco" "1 lb." +lard "Lard" "1 lb." +sirloinsteak "Sirloin Steak" "1 lb." +roundsteak "Round Steak" "1 lb." +ribroast "Rib Roast" "1 lb." +chuckroast "Chuck Roast" "1 lb." +plate "Plate" "1 lb." +liver "Liver (Beef)" "1 lb." +lambleg "Leg of Lamb" "1 lb." +lambchops "Lamb Chops (Rib)" "1 lb." +porkchops "Pork Chops" "1 lb." +porkroast "Pork Loin Roast" "1 lb." +bacon "Bacon" "1 lb." +ham "Ham - smoked" "1 lb." +saltpork "Salt Pork" "1 lb." +chicken "Roasting Chicken" "1 lb." +veal "Veal Cutlets" "1 lb." +salmon "Salmon, Pink (can)" "16 oz." +apples "Apples" "1 lb." +bananas "Bananas" "1 lb." +lemons "Lemons" "1 doz." +oranges "Oranges" "1 doz." +greenbeans "Green Beans" "1 lb." +cabbage "Cabbage" "1 lb." +carrots "Carrots" "1 bunch" +celery "Celery" "1 stalk" +lettuce "Lettuce" "1 head" +onions "Onions" "1 lb." +potatoes "Potatoes" "15 lb." +spinach "Spinach" "1 lb." +sweetpotato "Sweet Potatoes" "1 lb." +peaches "Peaches (can)" "No. 2 1/2" +pears "Pears (can)" "No. 2 1/2" +pineapple "Pineapple (can)" "No. 2 1/2" +asparagus "Asparagus (can)" "No. 2" +cannedgrbn "Grean Beans (can)" "No. 2" +porkbeans "Pork and Beans (can)" "16 oz." +corn "Corn (can)" "No. 2" +peas "Peas (can)" "No. 2" +tomatoes "Tomatoes (can)" "No. 2" +tomatosoup "Tomato Soup (can)" "10 1/2 oz." +driedpeach "Peaches, Dried" "1 lb." +prunes "Prunes, Dried" "1 lb." +raisins "Raisins, Dried" "15 oz." +driedpeas "Peas, Dried" "1 lb." +limabeans "Lima Beans, Dried" "1 lb." +navybeans "Navy Beans, Dried" "1 lb." +coffee "Coffee" "1 lb." +tea "Tea" "1/4 lb." +cocoa "Cocoa" "8 oz." +chocolate "Chocolate" "8 oz." +sugar "Sugar" "10 lb." +cornsirup "Corn Sirup" "24 oz." +molasses "Molasses" "18 oz." +strawberry "Strawberry Preserve" "1 lb." +; + +set N := +calories /* Calories, unit = 1000 */ +protein /* Protein, unit = grams */ +calcium /* Calcium, unit = grams */ +iron /* Iron, unit = milligrams */ +vitaminA /* Vitamin A, unit = 1000 International Units */ +thiamine /* Thiamine, Vit. B1, unit = milligrams */ +riboflavin /* Riboflavin, Vit. B2, unit = milligrams */ +niacin /* Niacin (Nicotinic Acid), unit = milligrams */ +ascorbicAcid /* Ascorbic Acid, Vit. C, unit = milligrams */ +; + +param data +: price weight calories protein calcium iron := +# aug. 15 edible +# 1939 per $1 +# (cents) (grams) (1000) (grams) (grams) (mg.) +flour 36.0 12600 44.7 1411 2.0 365 +macaroni 14.1 3217 11.6 418 .7 54 +cereal 24.2 3280 11.8 377 14.4 175 +cornflakes 7.1 3194 11.4 252 .1 56 +cornmeal 4.6 9861 36.0 897 1.7 99 +grits 8.5 8005 28.6 680 .8 80 +rice 7.5 6048 21.2 460 .6 41 +oats 7.1 6389 25.3 907 5.1 341 +whitebread 7.9 5742 15.6 488 2.5 115 +wheatbread 9.1 4985 12.2 484 2.7 125 +ryebread 9.2 4930 12.4 439 1.1 82 +poundcake 24.8 1829 8.0 130 .4 31 +crackers 15.1 3004 12.5 288 .5 50 +milk 11.0 8867 6.1 310 10.5 18 +evapmild 6.7 6035 8.4 422 15.1 9 +butter 20.8 1473 10.8 9 .2 3 +margarine 16.1 2817 20.6 17 .6 6 +eggs 32.6 1857 2.9 238 1.0 52 +cheese 24.2 1874 7.4 448 16.4 19 +cream 14.1 1689 3.5 49 1.7 3 +peanutbutter 17.9 2534 15.7 661 1.0 48 +mayonnaise 16.7 1198 8.6 18 .2 8 +crisco 20.3 2234 20.1 0 .0 0 +lard 9.8 4628 41.7 0 .0 0 +sirloinsteak 39.6 1145 2.9 166 .1 34 +roundsteak 36.4 1246 2.2 214 .1 32 +ribroast 29.2 1553 3.4 213 .1 33 +chuckroast 22.6 2007 3.6 309 .2 46 +plate 14.6 3107 8.5 404 .2 62 +liver 26.8 1692 2.2 333 .2 139 +lambleg 27.6 1643 3.1 245 .1 20 +lambchops 36.6 1239 3.3 140 .1 15 +porkchops 30.7 1477 3.5 196 .2 80 +porkroast 24.2 1874 4.4 249 .3 37 +bacon 25.6 1772 10.4 152 .2 23 +ham 27.4 1655 6.7 212 .2 31 +saltpork 16.0 2835 18.8 164 .1 26 +chicken 30.3 1497 1.8 184 .1 30 +veal 42.3 1072 1.7 156 .1 24 +salmon 13.0 3489 5.8 705 6.8 45 +apples 4.4 9072 5.8 27 .5 36 +bananas 6.1 4982 4.9 60 .4 30 +lemons 26.0 2380 1.0 21 .5 14 +oranges 30.9 4439 2.2 40 1.1 18 +greenbeans 7.1 5750 2.4 138 3.7 80 +cabbage 3.7 8949 2.6 125 4.0 36 +carrots 4.7 6080 2.7 73 2.8 43 +celery 7.3 3915 .9 51 3.0 23 +lettuce 8.2 2247 .4 27 1.1 22 +onions 3.6 11844 5.8 166 3.8 59 +potatoes 34.0 16810 14.3 336 1.8 118 +spinach 8.1 4592 1.1 106 .0 138 +sweetpotato 5.1 7649 9.6 138 2.7 54 +peaches 16.8 4894 3.7 20 .4 10 +pears 20.4 4030 3.0 8 .3 8 +pineapple 21.3 3993 2.4 16 .4 8 +asparagus 27.7 1945 .4 33 .3 12 +cannedgrbn 10.0 5386 1.0 54 2.0 65 +porkbeans 7.1 6389 7.5 364 4.0 134 +corn 10.4 5452 5.2 136 .2 16 +peas 13.8 4109 2.3 136 .6 45 +tomatoes 8.6 6263 1.3 63 .7 38 +tomatosoup 7.6 3917 1.6 71 .6 43 +driedpeach 15.7 2889 8.5 87 1.7 173 +prunes 9.0 4284 12.8 99 2.5 154 +raisins 9.4 4524 13.5 104 2.5 136 +driedpeas 7.9 5742 20.0 1367 4.2 345 +limabeans 8.9 5097 17.4 1055 3.7 459 +navybeans 5.9 7688 26.9 1691 11.4 792 +coffee 22.4 2025 .0 0 .0 0 +tea 17.4 652 .0 0 .0 0 +cocoa 8.6 2637 8.7 237 3.0 72 +chocolate 16.2 1400 8.0 77 1.3 39 +sugar 51.7 8773 34.9 0 .0 0 +cornsirup 13.7 4996 14.7 0 .5 74 +molasses 13.6 3752 9.0 0 10.3 244 +strawberry 20.5 2213 6.4 11 .4 7 + +: vitaminA thiamine riboflavin niacin ascorbicAcid := +# (1000 IU) (mg.) (mg.) (mg.) (mg.) +flour .0 55.4 33.3 441 0 +macaroni .0 3.2 1.9 68 0 +cereal .0 14.4 8.8 114 0 +cornflakes .0 13.5 2.3 68 0 +cornmeal 30.9 17.4 7.9 106 0 +grits .0 10.6 1.6 110 0 +rice .0 2.0 4.8 60 0 +oats .0 37.1 8.9 64 0 +whitebread .0 13.8 8.5 126 0 +wheatbread .0 13.9 6.4 160 0 +ryebread .0 9.9 3.0 66 0 +poundcake 18.9 2.8 3.0 17 0 +crackers .0 .0 .0 0 0 +milk 16.8 4.0 16.0 7 177 +evapmild 26.0 3.0 23.5 11 60 +butter 44.2 .0 .2 2 0 +margarine 55.8 .2 .0 0 0 +eggs 18.6 2.8 6.5 1 0 +cheese 28.1 .8 10.3 4 0 +cream 16.9 .6 2.5 0 17 +peanutbutter .0 9.6 8.1 471 0 +mayonnaise 2.7 .4 .5 0 0 +crisco .0 .0 .0 0 0 +lard .2 .0 .5 5 0 +sirloinsteak .2 2.1 2.9 69 0 +roundsteak .4 2.5 2.4 87 0 +ribroast .0 .0 2.0 0 0 +chuckroast .4 1.0 4.0 120 0 +plate .0 .9 .0 0 0 +liver 169.2 6.4 50.8 316 525 +lambleg .0 2.8 3.0 86 0 +lambchops .0 1.7 2.7 54 0 +porkchops .0 17.4 2.7 60 0 +porkroast .0 18.2 3.6 79 0 +bacon .0 1.8 1.8 71 0 +ham .0 9.9 3.3 50 0 +saltpork .0 1.4 1.8 0 0 +chicken .1 .9 1.8 68 46 +veal .0 1.4 2.4 57 0 +salmon 3.5 1.0 4.9 209 0 +apples 7.3 3.6 2.7 5 544 +bananas 17.4 2.5 3.5 28 498 +lemons .0 .5 .0 4 952 +oranges 11.1 3.6 1.3 10 1993 +greenbeans 69.0 4.3 5.8 37 862 +cabbage 7.2 9.0 4.5 26 5369 +carrots 188.5 6.1 4.3 89 608 +celery .9 1.4 1.4 9 313 +lettuce 112.4 1.8 3.4 11 449 +onions 16.6 4.7 5.9 21 1184 +potatoes 6.7 29.4 7.1 198 2522 +spinach 918.4 5.7 13.8 33 2755 +sweetpotato 290.7 8.4 5.4 83 1912 +peaches 21.5 .5 1.0 31 196 +pears .8 .8 .8 5 81 +pineapple 2.0 2.8 .8 7 399 +asparagus 16.3 1.4 2.1 17 272 +cannedgrbn 53.9 1.6 4.3 32 431 +porkbeans 3.5 8.3 7.7 56 0 +corn 12.0 1.6 2.7 42 218 +peas 34.9 4.9 2.5 37 370 +tomatoes 53.2 3.4 2.5 36 1253 +tomatosoup 57.9 3.5 2.4 67 862 +driedpeach 86.8 1.2 4.3 55 57 +prunes 85.7 3.9 4.3 65 257 +raisins 4.5 6.3 1.4 24 136 +driedpeas 2.9 28.7 18.4 162 0 +limabeans 5.1 26.9 38.2 93 0 +navybeans .0 38.4 24.6 217 0 +coffee .0 4.0 5.1 50 0 +tea .0 .0 2.3 42 0 +cocoa .0 2.0 11.9 40 0 +chocolate .0 .9 3.4 14 0 +sugar .0 .0 .0 0 0 +cornsirup .0 .0 .0 5 0 +molasses .0 1.9 7.5 146 0 +strawberry .2 .2 .4 3 0 +; + +param allowance := +calories 3 +protein 70 +calcium .8 +iron 12 +vitaminA 5 +thiamine 1.8 +riboflavin 2.7 +niacin 18 +ascorbicAcid 75 +; + +end; diff --git a/glpk-5.0/examples/sudoku.dat b/glpk-5.0/examples/sudoku.dat new file mode 100644 index 0000000..074ff4f --- /dev/null +++ b/glpk-5.0/examples/sudoku.dat @@ -0,0 +1,16 @@ +/* sudoku.dat, a hard Sudoku puzzle which causes branching */ + +data; + +param givens : 1 2 3 4 5 6 7 8 9 := + 1 1 . . . . . 7 . . + 2 . 2 . . . . 5 . . + 3 6 . . 3 8 . . . . + 4 . 7 8 . . . . . . + 5 . . . 6 . 9 . . . + 6 . . . . . . 1 4 . + 7 . . . . 2 5 . . 9 + 8 . . 3 . . . . 6 . + 9 . . 4 . . . . . 2 ; + +end; diff --git a/glpk-5.0/examples/sudoku.mod b/glpk-5.0/examples/sudoku.mod new file mode 100644 index 0000000..61f2fe2 --- /dev/null +++ b/glpk-5.0/examples/sudoku.mod @@ -0,0 +1,84 @@ +/* SUDOKU, Number Placement Puzzle */ + +/* Written in GNU MathProg by Andrew Makhorin <mao@gnu.org> */ + +/* Sudoku, also known as Number Place, is a logic-based placement + puzzle. The aim of the canonical puzzle is to enter a numerical + digit from 1 through 9 in each cell of a 9x9 grid made up of 3x3 + subgrids (called "regions"), starting with various digits given in + some cells (the "givens"). Each row, column, and region must contain + only one instance of each numeral. + + Example: + + +-------+-------+-------+ + | 5 3 . | . 7 . | . . . | + | 6 . . | 1 9 5 | . . . | + | . 9 8 | . . . | . 6 . | + +-------+-------+-------+ + | 8 . . | . 6 . | . . 3 | + | 4 . . | 8 . 3 | . . 1 | + | 7 . . | . 2 . | . . 6 | + +-------+-------+-------+ + | . 6 . | . . . | 2 8 . | + | . . . | 4 1 9 | . . 5 | + | . . . | . 8 . | . 7 9 | + +-------+-------+-------+ + + (From Wikipedia, the free encyclopedia.) */ + +param givens{1..9, 1..9}, integer, >= 0, <= 9, default 0; +/* the "givens" */ + +var x{i in 1..9, j in 1..9, k in 1..9}, binary; +/* x[i,j,k] = 1 means cell [i,j] is assigned number k */ + +s.t. fa{i in 1..9, j in 1..9, k in 1..9: givens[i,j] != 0}: + x[i,j,k] = (if givens[i,j] = k then 1 else 0); +/* assign pre-defined numbers using the "givens" */ + +s.t. fb{i in 1..9, j in 1..9}: sum{k in 1..9} x[i,j,k] = 1; +/* each cell must be assigned exactly one number */ + +s.t. fc{i in 1..9, k in 1..9}: sum{j in 1..9} x[i,j,k] = 1; +/* cells in the same row must be assigned distinct numbers */ + +s.t. fd{j in 1..9, k in 1..9}: sum{i in 1..9} x[i,j,k] = 1; +/* cells in the same column must be assigned distinct numbers */ + +s.t. fe{I in 1..9 by 3, J in 1..9 by 3, k in 1..9}: + sum{i in I..I+2, j in J..J+2} x[i,j,k] = 1; +/* cells in the same region must be assigned distinct numbers */ + +/* there is no need for an objective function here */ + +solve; + +for {i in 1..9} +{ for {0..0: i = 1 or i = 4 or i = 7} + printf " +-------+-------+-------+\n"; + for {j in 1..9} + { for {0..0: j = 1 or j = 4 or j = 7} printf(" |"); + printf " %d", sum{k in 1..9} x[i,j,k] * k; + for {0..0: j = 9} printf(" |\n"); + } + for {0..0: i = 9} + printf " +-------+-------+-------+\n"; +} + +data; + +/* These data correspond to the example above. */ + +param givens : 1 2 3 4 5 6 7 8 9 := + 1 5 3 . . 7 . . . . + 2 6 . . 1 9 5 . . . + 3 . 9 8 . . . . 6 . + 4 8 . . . 6 . . . 3 + 5 4 . . 8 . 3 . . 1 + 6 7 . . . 2 . . . 6 + 7 . 6 . . . . 2 8 . + 8 . . . 4 1 9 . . 5 + 9 . . . . 8 . . 7 9 ; + +end; diff --git a/glpk-5.0/examples/t1.cs b/glpk-5.0/examples/t1.cs new file mode 100644 index 0000000..d07780f --- /dev/null +++ b/glpk-5.0/examples/t1.cs @@ -0,0 +1,99 @@ +/*Find the minimum value which satisfies the linear inequality: + a*x + b*y >= 1 {a,b,x,y Integers} {a,b > 0} {a,b entered on command line} + + Nigel_Galloway@operamail.com + February 2008 +*/ +using System; +using System.Runtime.InteropServices; + +unsafe class GLPK{ + double *lp; + public int a; + public int b; + + const string glpkLibrary = "libglpk.so"; + readonly int GLP_FR = 1; + readonly int GLP_IV = 2; + readonly int GLP_DB = 4; + struct ConstraintMatrix{ + public fixed int ia[3]; + public fixed int ja[3]; + public fixed double ar[3]; + } + [DllImport(glpkLibrary, SetLastError=true)] + static extern double* glp_create_prob(); + [DllImport(glpkLibrary, SetLastError=true)] + static extern void glp_add_rows(double* lp, int rows); + [DllImport(glpkLibrary, SetLastError=true)] + static extern void glp_add_cols(double* lp, int cols); + [DllImport(glpkLibrary, SetLastError=true)] + static extern void glp_set_col_bnds(double* lp, int col, int bound_type, double lower_bound, double upper_bound); + [DllImport(glpkLibrary, SetLastError=true)] + static extern void glp_set_col_kind(double* lp, int col, int kind); + [DllImport(glpkLibrary, SetLastError=true)] + static extern void glp_load_matrix(double* lp, int elements, int* ia, int* ja, double* ar); + public GLPK(int a, int b){ + this.a = a; + this.b = b; + lp = glp_create_prob(); + //Col 1 is x, Col 2 is y + glp_add_rows(lp, 1); + glp_add_cols(lp, 2); + glp_set_col_bnds(lp, 1, GLP_FR, 0.0, 0.0); + glp_set_col_bnds(lp, 2, GLP_FR, 0.0, 0.0); + glp_set_col_kind(lp, 1, GLP_IV); + glp_set_col_kind(lp, 2, GLP_IV); + //Row 1 is a*x + b*y + ConstraintMatrix CM = new ConstraintMatrix(); + CM.ia[1]=1; CM.ja[1]=1; CM.ar[1]=a; + CM.ia[2]=1; CM.ja[2]=2; CM.ar[2]=b; + glp_load_matrix(lp, 2, CM.ia, CM.ja, CM.ar); + Console.WriteLine("Hello Nigel"); + } + + [DllImport(glpkLibrary, SetLastError=true)] + static extern void glp_set_row_bnds(double* lp, int row, int bound_type, double lower_bound, double upper_bound); + [DllImport(glpkLibrary, SetLastError=true)] + static extern void glp_simplex(double* lp, void* options); + [DllImport(glpkLibrary, SetLastError=true)] + static extern void glp_intopt(double* lp, void* options); + [DllImport(glpkLibrary, SetLastError=true)] + static extern double glp_mip_col_val(double* lp, int col); + public int betterGuess(int upper_bound){ + //Find a new guess less than the old guess: 1 <= (a*x + b*y) <= (old guess - 1) + glp_set_row_bnds(lp, 1, GLP_DB, 1.0, ((double)upper_bound)-0.5); + glp_simplex(lp, null); + glp_intopt(lp, null); + int x = (int)glp_mip_col_val(lp, 1); + int y = (int)glp_mip_col_val(lp, 2); + int nextGuess = a*x + b*y; + Console.WriteLine("x = {0}, y = {1}, a*x + b*y = {2}",x,y,nextGuess); + return nextGuess; + } + + [DllImport(glpkLibrary, SetLastError=true)] + static extern void glp_delete_prob(double* lp); + ~GLPK(){ + glp_delete_prob(lp); + Console.WriteLine("Goodbye Nigel"); + } + +} + +class test{ + static bool isMinimum(int a, int b, int guess){ + Console.WriteLine("Trying {0}",guess); + if (a%guess > 0) return false; + if (b%guess > 0) return false; + Console.WriteLine("Solution is {0}",guess); + return true; + } + + public static void Main(string[] args){ + Console.WriteLine("a = {0}, b = {1}",args[0], args[1]); + GLPK lp = new GLPK(Int32.Parse(args[0]),Int32.Parse(args[1])); + int guess = (lp.a > lp.b) ? lp.b : lp.a; + while (!isMinimum(lp.a,lp.b,guess)) guess = lp.betterGuess(guess); + } +} diff --git a/glpk-5.0/examples/tas.mod b/glpk-5.0/examples/tas.mod new file mode 100644 index 0000000..dbb5ac2 --- /dev/null +++ b/glpk-5.0/examples/tas.mod @@ -0,0 +1,486 @@ +/* TAS, Tail Assignment Problem */ + +/* Written in GNU MathProg by Andrew Makhorin <mao@gnu.org> */ + +/* The Tail Assignment Problem (TAS) is to construct rosters for a set + of aircrafts (tails), which cover all flights for a given scheduling + period. + + This model includes only flight connection constraints while other + constraints (for example, maintenance constraints) are ignored. Such + simplification allows using a single commodity network to model the + problem, where commodity corresponds to the set of aircrafts. + + Nodes of the network are activities. They include all flights plus + two dummy nodes (activities): source node, s, corresponding to + initial activity of each aircraft, and sink node t, corresponding to + final activity of each aircraft. Arc v->v' exists in the network if + and only if the same aircraft is able to operate activity v and then + immediately activity v'. In partucular, arcs s->f and f->t exist for + all flights f. Arcs f->f', where f and f' are some flights, exist + only if the connection time (which is the difference between the + departure time of f' and the arrival time of f) is not less than a + given minimal connection time. + + Reference: + M. Groenkvist, "The Tail Assignment Problem," Dept. of Comp. Sci. + and Eng., Chalmers University of Technology and Goeteborg University, + Goeteborg, Sweden, August 2005. */ + +######################################################################## + +param nf, integer, > 0; +/* number of flights */ + +set F := 1..nf; +/* set of flights (for a given period from timetable) */ + +param hub{f in F}, in {1, 2}; +/* hub[f] = 1: Sheremetyevo-1 + hub[f] = 2: Sheremetyevo-2 */ + +param dest{f in F}, symbolic; +/* destination airport (IATA code) */ + +param fno1{f in F}, integer; +/* first leg flight number */ + +param dep1{f in F}, integer, >= 0; +/* departure time from Sheremetyevo airport, in minutes */ + +check{f in F: f < nf}: dep1[f] <= dep1[f+1]; +/* all flights must be ordered by ascending of the departure time */ + +param arr1{f in F}, integer, >= 0; +/* arrival time to destination airport, in minutes */ + +param fno2{f in F}, integer; +/* second leg flight number */ + +param dep2{f in F}, integer, >= 0; +/* departure time from destination airport, in minutes */ + +param arr2{f in F}, integer, >= 0; +/* arrival time to Sheremetyevo airport, in minutes */ + +param mct1, integer, >= 0, default 80; +/* minimal connection time (within SVO1 or SVO2), in minutes */ + +param mct2, integer, >= 0, default 150; +/* minimal connection time (between SVO1 and SVO2), in minutes */ + +set E := setof{f in F, ff in F: arr2[f] + (if hub[f] = hub[ff] then + mct1 else mct2) <= dep1[ff]} (f, ff); +/* connection network; arc f->ff is in E, iff the same aircraft can be + assigned to flight f and then immediately to flight ff */ + +var s{f in F}, >= 0; +/* s[f] is a flow from source node to node f */ + +var x{(f,ff) in E}, >= 0; +/* x[f,ff] is a flow from node f to node ff */ + +var t{f in F}, >= 0; +/* t[f] is a flow from node f to sink node */ + +s.t. into{f in F}: s[f] + sum{(ff,f) in E} x[ff,f] = 1; +/* exactly one aircraft must come into each node f */ + +s.t. from{f in F}: t[f] + sum{(f,ff) in E} x[f,ff] = 1; +/* exactly one aircraft must come from each node f */ + +minimize obj: sum{f in F} s[f]; +/* minimize the number aircrafts sufficient to cover all flights */ + +solve; + +######################################################################## + +param na := floor(sum{f in F} s[f] + .5); +/* minimal number of aircrafts found */ + +printf "At least %d aircrafts needed\n", na; + +set A := 1..na; +/* set of aircrafts */ + +printf "Building rosters...\n"; + +param tail{f in F}, in A, := +/* tail[f] is the number of an aircraft assigned to flight f */ + + if f = 1 then 1 + /* assign aircraft 1 to the earliest flight */ + + else if s[f] >= 0.9 then (max{ff in 1..f-1} tail[ff]) + 1 + /* if f is the first flight in a roster, assign to it a next + aircraft */ + + else sum{(ff,f) in E} tail[ff] * (if x[ff,f] >= 0.9 then 1); + /* otherwise, assign to flight f the same aircraft, which is + assigned to a preceding flight in the roster */ + +######################################################################## + +param file, symbolic, default "tas.ps"; +/* file to output the assignment chart in postscript format */ + +param title, symbolic, default "(no title)"; +/* chart title */ + +param left, default 25; +/* left margin, in mm */ + +param top, default 25; +/* top margin, in mm */ + +param right, default 20; +/* right margin, in mm */ + +param bottom, default 15; +/* bottom margin, in mm */ + +param sx := 297 - left - right; +/* chart area horizontal size, in mm */ + +param sy := 210 - top - bottom; +/* chart area vertical size, in mm */ + +param gap, default sy / (na - 1); +/* gap between rosters, in mm */ + +printf "Writing assignment chart to %s...\n", file; + +printf "%%!PS-Adobe-3.0\n" > file; +printf "%%%%Title: Tail Assignment Chart\n" >> file; +printf "%%%%Creator: GLPK MathProg\n" >> file; +printf "%%%%BoundingBox: 0 0 595 842\n" >> file; +printf "%%%%EndComments\n" >> file; +printf "<</PageSize [595 842]>> setpagedevice\n" >> file; +printf "72 25.4 div dup scale\n" >> file; +printf "210 %.3f sub %.3f translate\n", bottom, left >> file; +printf "90 rotate\n" >> file; + +printf "/HelveticaBold findfont 5 scalefont setfont\n" >> file; +printf "%.3f %.3f moveto (%s) dup show\n", 0, sy + 5, title >> file; + +param period := floor((max{f in F} arr2[f]) / 60. + .5); +/* period duration, in hours */ + +/* vertical bars */ +printf ".8 .8 .8 setrgbcolor\n" >> file; +for {tt in 0..period} +{ printf "%s setlinewidth\n", + if tt mod 24 = 0 then ".5" else "0" >> file; + printf "newpath %.3f %.3f moveto %.3f %.3f lineto stroke\n", + tt * (sx / period), 0, tt * (sx / period), + sy + (if tt mod 24 = 0 then 2) >> file; +} + +/* rosters */ +for {a in A} +{ printf "0 0 0 setrgbcolor\n" >> file; + printf "0 setlinewidth\n" >> file; + printf "newpath %.3f %.3f moveto %.3f %.3f lineto stroke\n", + 0, sy - gap * (a - 1), sx, sy - gap * (a - 1) >> file; + printf "/Dingbats findfont 4 scalefont setfont\n" >> file; + printf "%.3f %.3f moveto <28> dup show\n", + -4, sy - gap * (a - 1) - 1.4, a >> file; + printf "/Helvetica findfont 3 scalefont setfont\n" >> file; + printf "%.3f %.3f moveto (%2d) dup show\n", + -9, sy - gap * (a - 1) - 1.2, a >> file; + for {f in F: tail[f] == a} + { printf "0 0 %s setrgbcolor\n", + if hub[f] = 1 then "0" else ".8" >> file; + printf "1 setlinewidth\n" >> file; + printf "newpath %.3f %.3f moveto %.3f %.3f lineto stroke\n", + dep1[f] / 60 * (sx / period), sy - gap * (a - 1), + arr2[f] / 60 * (sx / period), sy - gap * (a - 1) >> file; + printf "/Helvetica findfont 1.8 scalefont setfont\n" >> file; + printf "%.3f %.3f moveto (%02d:%02d %s) dup show\n", + dep1[f] / 60 * (sx / period), sy - gap * (a - 1) + .8, + (dep1[f] mod 1440) div 60, (dep1[f] mod 1440) mod 60, + dest[f] >> file; + printf "%.3f %.3f moveto (%d %02d:%02d) dup show\n", + dep1[f] / 60 * (sx / period), sy - gap * (a - 1) - 2.1, + fno1[f], + (arr2[f] mod 1440) div 60, (arr2[f] mod 1440) mod 60 >> file; + } +} + +printf "showpage\n" >> file; +printf "%%%%EOF\n" >> file; + +######################################################################## + +data; + +param title := "Tu-154 [from 2008-08-18 to 2008-08-24]"; + +param nf := 261; + +param : hub dest fno1 dep1 arr1 fno2 dep2 arr2 := + 1 1 IKT 743 195 520 744 610 970 + 2 1 OMS 815 205 405 816 485 700 + 3 1 CEK 897 205 360 898 430 595 + 4 1 KRR 763 260 400 764 480 610 + 5 2 SIP 133 280 420 134 500 620 + 6 2 BUD 131 290 450 132 520 675 + 7 1 AAQ 701 305 440 702 510 640 + 8 1 MRV 785 310 440 786 520 650 + 9 2 WAW 101 355 475 102 540 660 + 10 2 GYD 147 370 550 148 675 860 + 11 1 AER 869 385 530 870 655 795 + 12 1 KRR 765 430 560 766 630 760 + 13 1 AAQ 703 520 660 704 740 850 + 14 1 LED 845 530 620 846 690 775 + 15 1 KRR 767 540 675 768 765 895 + 16 2 KBP 183 665 760 184 850 940 + 17 1 MRV 787 755 905 788 985 1135 + 18 1 KRR 771 810 940 772 1030 1165 + 19 1 LED 849 825 900 850 960 1095 + 20 2 IST 209 880 1050 210 1120 1280 + 21 1 AER 873 885 1030 874 1760 1900 + 22 1 ASF 711 995 1145 712 1640 1795 + 23 2 ULN 563 995 1335 564 1415 1815 + 24 2 OTP 151 1020 1175 152 1800 1940 + 25 2 BEY 509 1025 1265 510 1350 1580 + 26 2 OSL 211 1060 1220 212 1860 2015 + 27 1 IKT 739 1085 1420 740 1510 1870 + 28 1 KRR 773 1095 1240 774 1620 1765 + 29 1 SGC 877 1120 1315 878 1395 1625 + 30 1 LED 857 1150 1230 858 1610 1690 + 31 1 CEK 899 1230 1385 900 1455 1620 + 32 1 PEE 821 1235 1390 822 1450 1600 + 33 2 TBS 197 1240 1405 198 1560 1715 + 34 1 UFA 891 1275 1405 892 1475 1610 + 35 1 KJA 781 1300 1570 782 1680 1990 + 36 1 IKT 743 1635 1960 744 2050 2410 + 37 1 OMS 815 1645 1845 816 1925 2140 + 38 1 CEK 897 1645 1800 898 1870 2035 + 39 1 KRR 763 1700 1840 764 1920 2050 + 40 2 SIP 133 1720 1860 134 1940 2060 + 41 2 BUD 131 1730 1890 132 1960 2115 + 42 1 AAQ 701 1745 1880 702 1950 2080 + 43 1 MRV 785 1750 1880 786 1960 2090 + 44 2 WAW 101 1795 1915 102 1980 2100 + 45 2 GYD 147 1810 1990 148 2115 2300 + 46 1 AER 869 1825 1970 870 2095 2235 + 47 2 EVN 193 1850 2030 194 2105 2275 + 48 1 KRR 765 1870 2000 766 2070 2200 + 49 1 AAQ 703 1960 2100 704 2180 2290 + 50 1 LED 845 1970 2060 846 2130 2215 + 51 1 KRR 767 1980 2115 768 2205 2335 + 52 2 KBP 183 2105 2200 184 2290 2380 + 53 1 MRV 787 2195 2345 788 2425 2575 + 54 1 KRR 771 2250 2380 772 2470 2605 + 55 1 LED 849 2265 2340 850 2400 2535 + 56 2 IST 209 2320 2490 210 2560 2720 + 57 1 AER 873 2325 2470 874 3200 3340 + 58 2 ULN 563 2435 2775 564 2855 3255 + 59 1 ASF 711 2435 2585 712 3080 3235 + 60 2 DAM 517 2465 2705 518 2790 3020 + 61 2 OSL 211 2500 2660 212 3300 3455 + 62 2 KBP 185 2510 2610 186 3160 3250 + 63 1 IKT 739 2525 2860 740 2950 3310 + 64 1 KRR 773 2535 2680 774 3060 3205 + 65 1 SGC 877 2560 2755 878 2835 3065 + 66 1 LED 857 2590 2670 858 3050 3130 + 67 1 CEK 899 2670 2825 900 2895 3060 + 68 1 PEE 821 2675 2830 822 2890 3040 + 69 2 TBS 197 2680 2845 198 3000 3155 + 70 1 UFA 891 2715 2845 892 2915 3050 + 71 1 KJA 781 2740 3010 782 3120 3430 + 72 1 IKT 743 3075 3400 744 3490 3850 + 73 1 CEK 897 3085 3240 898 3310 3475 + 74 1 OMS 815 3085 3285 816 3365 3580 + 75 1 KRR 763 3140 3280 764 3360 3490 + 76 2 SIP 133 3160 3300 134 3380 3500 + 77 2 BUD 131 3170 3330 132 3400 3555 + 78 1 AAQ 701 3185 3320 702 3390 3520 + 79 1 MRV 785 3190 3320 786 3400 3530 + 80 2 WAW 101 3235 3355 102 3420 3540 + 81 2 FRU 181 3245 3495 182 3590 3860 + 82 2 GYD 147 3250 3430 148 3555 3740 + 83 1 AER 869 3265 3410 870 3535 3675 + 84 1 KRR 765 3310 3440 766 3510 3640 + 85 1 AAQ 703 3400 3540 704 3620 3730 + 86 1 LED 845 3410 3500 846 3570 3655 + 87 1 KRR 767 3420 3555 768 3645 3775 + 88 2 KBP 183 3545 3640 184 3730 3820 + 89 1 MRV 787 3635 3785 788 3865 4015 + 90 1 KRR 771 3690 3820 772 3910 4045 + 91 1 LED 849 3705 3780 850 3840 3975 + 92 2 IST 209 3760 3930 210 4000 4160 + 93 1 AER 873 3765 3910 874 4640 4780 + 94 2 ULN 563 3875 4215 564 4295 4695 + 95 1 ASF 711 3875 4025 712 4520 4675 + 96 2 OTP 151 3900 4055 152 4680 4820 + 97 2 BEY 509 3905 4145 510 4230 4460 + 98 2 OSL 211 3940 4100 212 4740 4895 + 99 2 KBP 185 3950 4050 186 4600 4690 + 100 1 IKT 739 3965 4300 740 4390 4750 + 101 1 KRR 773 3975 4120 774 4500 4645 + 102 1 SGC 877 4000 4195 878 4275 4505 + 103 1 LED 857 4030 4110 858 4490 4570 + 104 1 CEK 899 4110 4265 900 4335 4500 + 105 1 PEE 821 4115 4270 822 4330 4480 + 106 2 TBS 197 4120 4285 198 4440 4595 + 107 1 UFA 891 4155 4285 892 4355 4490 + 108 1 KJA 781 4180 4450 782 4560 4870 + 109 1 IKT 743 4515 4840 744 4930 5290 + 110 1 OMS 815 4525 4725 816 4805 5020 + 111 1 CEK 897 4525 4680 898 4750 4915 + 112 1 KRR 763 4580 4720 764 4800 4930 + 113 2 SIP 133 4600 4740 134 4820 4940 + 114 2 BUD 131 4610 4770 132 4840 4995 + 115 1 AAQ 701 4625 4760 702 4830 4960 + 116 1 MRV 785 4630 4760 786 4840 4970 + 117 2 WAW 101 4675 4795 102 4860 4980 + 118 2 GYD 147 4690 4870 148 4995 5180 + 119 1 AER 869 4705 4850 870 4975 5115 + 120 2 EVN 193 4730 4910 194 4985 5155 + 121 1 KRR 765 4750 4880 766 4950 5080 + 122 1 AAQ 703 4840 4980 704 5060 5170 + 123 1 LED 845 4850 4940 846 5010 5095 + 124 1 KRR 767 4860 4995 768 5085 5215 + 125 2 KBP 183 4985 5080 184 5170 5260 + 126 1 MRV 787 5075 5225 788 5305 5455 + 127 1 KRR 771 5130 5260 772 5350 5485 + 128 1 LED 849 5145 5220 850 5280 5415 + 129 2 IST 209 5200 5370 210 5440 5600 + 130 1 AER 873 5205 5350 874 6080 6220 + 131 1 ASF 711 5315 5465 712 5960 6115 + 132 2 ULN 563 5315 5655 564 5735 6135 + 133 2 DAM 517 5345 5585 518 5670 5900 + 134 2 OSL 211 5380 5540 212 6180 6335 + 135 2 KBP 185 5390 5490 186 6040 6130 + 136 1 IKT 739 5405 5740 740 5830 6190 + 137 1 KRR 773 5415 5560 774 5940 6085 + 138 1 SGC 877 5440 5635 878 5715 5945 + 139 1 LED 857 5470 5550 858 5930 6010 + 140 1 CEK 899 5550 5705 900 5775 5940 + 141 1 PEE 821 5555 5710 822 5770 5920 + 142 2 TBS 197 5560 5725 198 5880 6035 + 143 1 UFA 891 5595 5725 892 5795 5930 + 144 1 KJA 781 5620 5890 782 6000 6310 + 145 1 IKT 743 5955 6280 744 6370 6730 + 146 1 OMS 815 5965 6165 816 6245 6460 + 147 1 CEK 897 5965 6120 898 6190 6355 + 148 1 KRR 763 6020 6160 764 6240 6370 + 149 2 SIP 133 6040 6180 134 6260 6380 + 150 2 BUD 131 6050 6210 132 6280 6435 + 151 1 AAQ 701 6065 6200 702 6270 6400 + 152 1 MRV 785 6070 6200 786 6280 6410 + 153 2 WAW 101 6115 6235 102 6300 6420 + 154 2 FRU 181 6125 6375 182 6470 6740 + 155 2 GYD 147 6130 6310 148 6435 6620 + 156 1 AER 869 6145 6290 870 6415 6555 + 157 2 EVN 193 6170 6350 194 6425 6595 + 158 1 KRR 765 6190 6320 766 6390 6520 + 159 1 AAQ 703 6280 6420 704 6500 6610 + 160 1 LED 845 6290 6380 846 6450 6535 + 161 1 KRR 767 6300 6435 768 6525 6655 + 162 2 KBP 183 6425 6520 184 6610 6700 + 163 2 AYT 223 6500 6690 224 6750 6940 + 164 1 AER 867 6510 6660 868 6730 6880 + 165 1 MRV 787 6515 6665 788 6745 6895 + 166 1 KRR 771 6570 6700 772 6790 6925 + 167 1 LED 849 6585 6660 850 6720 6855 + 168 2 IST 209 6640 6810 210 6880 7040 + 169 1 AER 873 6645 6790 874 7520 7660 + 170 1 ASF 711 6755 6905 712 7400 7555 + 171 2 ULN 563 6755 7095 564 7175 7575 + 172 2 OTP 151 6780 6935 152 7560 7700 + 173 2 BEY 509 6785 7025 510 7110 7340 + 174 2 OSL 211 6820 6980 212 7620 7775 + 175 2 KBP 185 6830 6930 186 7480 7570 + 176 1 IKT 739 6845 7180 740 7270 7630 + 177 1 KRR 773 6855 7000 774 7380 7525 + 178 1 SGC 877 6880 7075 878 7155 7385 + 179 1 LED 857 6910 6990 858 7370 7450 + 180 1 CEK 899 6990 7145 900 7215 7380 + 181 1 PEE 821 6995 7150 822 7210 7360 + 182 2 TBS 197 7000 7165 198 7320 7475 + 183 1 UFA 891 7035 7165 892 7235 7370 + 184 1 KJA 781 7060 7330 782 7440 7750 + 185 1 IKT 743 7395 7720 744 7810 8170 + 186 1 CEK 897 7405 7560 898 7630 7795 + 187 1 KRR 763 7460 7600 764 7680 7810 + 188 2 SIP 133 7480 7620 134 7700 7820 + 189 2 BUD 131 7490 7650 132 7720 7875 + 190 1 AAQ 701 7505 7640 702 7710 7840 + 191 1 MRV 785 7510 7640 786 7720 7850 + 192 2 IST 207 7545 7720 208 7795 7985 + 193 2 WAW 101 7555 7675 102 7740 7860 + 194 2 GYD 147 7570 7750 148 7875 8060 + 195 1 AER 869 7585 7730 870 7855 7995 + 196 2 AYT 221 7610 7800 222 7895 8085 + 197 2 EVN 193 7610 7790 194 7865 8035 + 198 1 KRR 765 7630 7760 766 7830 7960 + 199 1 AAQ 703 7720 7860 704 7940 8050 + 200 1 LED 845 7730 7820 846 7890 7975 + 201 1 KRR 767 7740 7875 768 7965 8095 + 202 2 KBP 183 7865 7960 184 8050 8140 + 203 2 AYT 223 7940 8130 224 8190 8380 + 204 1 MRV 787 7955 8105 788 8185 8335 + 205 1 KRR 771 8010 8140 772 8230 8365 + 206 1 LED 849 8025 8100 850 8160 8295 + 207 2 IST 209 8080 8250 210 8320 8480 + 208 1 AER 873 8085 8230 874 8960 9100 + 209 1 ASF 711 8195 8345 712 8840 8995 + 210 2 ULN 563 8195 8535 564 8615 9015 + 211 1 KJA 779 8230 8500 780 8575 8870 + 212 2 OSL 211 8260 8420 212 9060 9215 + 213 2 KBP 185 8270 8370 186 8920 9010 + 214 1 IKT 739 8285 8620 740 8710 9070 + 215 1 KRR 773 8295 8440 774 8820 8965 + 216 1 SGC 877 8320 8515 878 8595 8825 + 217 1 LED 857 8350 8430 858 8810 8890 + 218 1 CEK 899 8430 8585 900 8655 8820 + 219 1 PEE 821 8435 8590 822 8650 8800 + 220 2 TBS 197 8440 8605 198 8760 8915 + 221 1 UFA 891 8475 8605 892 8675 8810 + 222 1 KJA 781 8500 8770 782 8880 9190 + 223 1 IKT 743 8835 9160 744 9250 9610 + 224 1 OMS 815 8845 9045 816 9125 9340 + 225 1 CEK 897 8845 9000 898 9070 9235 + 226 1 KRR 763 8900 9040 764 9120 9250 + 227 2 SIP 133 8920 9060 134 9140 9260 + 228 2 BUD 131 8930 9090 132 9160 9315 + 229 1 AAQ 701 8945 9080 702 9150 9280 + 230 1 MRV 785 8950 9080 786 9160 9290 + 231 2 IST 207 8985 9160 208 9235 9425 + 232 2 WAW 101 8995 9115 102 9180 9300 + 233 2 FRU 181 9005 9255 182 9350 9620 + 234 2 GYD 147 9010 9190 148 9315 9500 + 235 1 AER 869 9025 9170 870 9295 9435 + 236 2 EVN 193 9050 9230 194 9305 9475 + 237 1 KRR 765 9070 9200 766 9270 9400 + 238 1 AAQ 703 9160 9300 704 9380 9490 + 239 1 LED 845 9170 9260 846 9330 9415 + 240 1 KRR 767 9180 9315 768 9405 9535 + 241 2 KBP 183 9305 9400 184 9490 9580 + 242 2 AYT 223 9380 9570 224 9630 9820 + 243 1 MRV 787 9395 9545 788 9625 9775 + 244 1 KRR 771 9450 9580 772 9670 9805 + 245 1 LED 849 9465 9540 850 9600 9735 + 246 2 IST 209 9520 9690 210 9760 9920 + 247 1 AER 873 9525 9670 874 10400 10540 + 248 1 ASF 711 9635 9785 712 10280 10435 + 249 2 ULN 563 9635 9975 564 10055 10455 + 250 2 OTP 151 9660 9815 152 10440 10580 + 251 2 DAM 517 9665 9905 518 9990 10220 + 252 2 OSL 211 9700 9860 212 10500 10655 + 253 2 KBP 185 9710 9810 186 10360 10450 + 254 1 IKT 739 9725 10060 740 10150 10510 + 255 1 KRR 773 9735 9880 774 10260 10405 + 256 1 SGC 877 9760 9955 878 10035 10265 + 257 1 LED 857 9790 9870 858 10250 10330 + 258 1 CEK 899 9870 10025 900 10095 10260 + 259 1 PEE 821 9875 10030 822 10090 10240 + 260 1 UFA 891 9915 10045 892 10115 10250 + 261 1 KJA 781 9940 10210 782 10320 10630 +; + +end; diff --git a/glpk-5.0/examples/threads/Build_Multiseed.bat b/glpk-5.0/examples/threads/Build_Multiseed.bat new file mode 100644 index 0000000..34dd95f --- /dev/null +++ b/glpk-5.0/examples/threads/Build_Multiseed.bat @@ -0,0 +1,12 @@ +rem Build GLPK DLL with Microsoft Visual Studio Community 2015 + +rem NOTE: Make sure that HOME variable specifies correct path +set HOME="C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC" + +call %HOME%\vcvarsall.bat x64 +copy config_VC config.h +%HOME%\bin\nmake.exe /f Makefile_VC +set PATH=..\..\w64\ +%HOME%\bin\nmake.exe /f Makefile_VC check + +pause diff --git a/glpk-5.0/examples/threads/Makefile b/glpk-5.0/examples/threads/Makefile new file mode 100644 index 0000000..61063d3 --- /dev/null +++ b/glpk-5.0/examples/threads/Makefile @@ -0,0 +1,5 @@ +all: + gcc multiseed.c -I. -lglpk -pthread -o multiseed + +check: + ./multiseed clustering.mod 20 diff --git a/glpk-5.0/examples/threads/Makefile_VC b/glpk-5.0/examples/threads/Makefile_VC new file mode 100644 index 0000000..5bb8179 --- /dev/null +++ b/glpk-5.0/examples/threads/Makefile_VC @@ -0,0 +1,26 @@ +## Build multiseed example with Microsoft Visual Studio Express ## + +CFLAGS = \ +/I. \ +/I..\..\src \ +/I..\..\w64 \ +/DHAVE_CONFIG_H=1 \ +/D_CRT_SECURE_NO_WARNINGS=1 \ +/nologo \ +/W3 \ +/O2 \ +/Zi + +.c.obj: + cl.exe $(CFLAGS) /Fo$*.obj /c $*.c + +all: multiseed.exe + +multiseed.exe: multiseed.obj ..\..\w64\glpk_4_61.dll + cl.exe $(CFLAGS) /Fmultiseed.exe \ + multiseed.obj ..\..\w64\glpk_4_61.lib + +check: multiseed.exe + .\multiseed.exe clustering.mod 20 + +## eof ## diff --git a/glpk-5.0/examples/threads/README b/glpk-5.0/examples/threads/README new file mode 100644 index 0000000..cb547f0 --- /dev/null +++ b/glpk-5.0/examples/threads/README @@ -0,0 +1,66 @@ +Thread local memory example +=========================== + +The GLPK library, when compiled with default options, uses a separate environment +for each thread that is executed. So each thread is isolated. The only exeption +is error handling. An error in any of the library functions will not only +terminate the active thread but the complete process. + +This can be circumvented by defining an error handling routine with +glp_error_hook(). This directory contains an example demonstrating running a +multithreaded application with error handling. + + +The example code +---------------- + +The program multiseed solves a MathProg model multiple times in separate parallel +threads. Each threads uses a different seed for the MathProg pseudo random number +generator. + +The MathProg model clustering.mod generates 50 randomly distributed "towns". Out +of the towns it selects 3 to be cluster centers and assign the other towns to the +clusters such that the sum of the population weighted euclidian distances between +towns and centers is minimized. + +The solution is written to a Scalable Vector File which can be viewed with a web +browser. + +For demonstration purposes at the end of every third thread the error handling +routine is triggered by calling glp_error(). This results in output like + + 18-00086 Model has been successfully processed + 18-00087 Voluntarily throwing an error in multiseed.c at line 147 + 18-00088 Error detected in file multiseed.c at line 146 + 18-00089 Error caught + +Terminal output is preceeded by numbers indicating the thread index and the +output line. You can pipe it through sort to get a better overiew, e.g. + + multiseed clustering.mod 20 | sort + + +Building and running the example code +------------------------------------- + +On Linux multiseed can be compiled with gcc by calling + + make + +The code can be executed with + + make check + +For compiling the example on 64bit Windows with Microsoft Visual Studio C++ run + + Build_Multiseed.bat + +You may have to adust the variable HOME in the batch file depending on the +installation path of Visual Studio. + +You can run multiseed with + + multiseed <filename> <count> + +Where filename is the path to the model file and count is the number of parallel +threads. diff --git a/glpk-5.0/examples/threads/clustering.mod b/glpk-5.0/examples/threads/clustering.mod new file mode 100644 index 0000000..cd8cd37 --- /dev/null +++ b/glpk-5.0/examples/threads/clustering.mod @@ -0,0 +1,109 @@ +/* + * Author: Heinrich Schuchardt <xypron.glpk@gmx.de> + * + * This model solves a clustering problem: + * + * Out of 50 towns select 3 to be cluster centers and assign the other + * towns to the clusters such that the sum of the population weighted + * euclidian distances between towns and centers is minimized. + * + * The solution is saved as a scalable vector graphic file with a + * pseudo-random file name. + */ + +# Output file +param fn, symbolic := "00000" & 100000 * Uniform01(); +param f, symbolic := "ct" & substr(fn, length(fn) - 4) & ".svg"; + +# Centers +param nc := 3; +set C := {1 .. nc}; + +# Towns +param nt := 50; +set T := {1 .. nt}; +param xt{T} := Uniform01(); +param yt{T} := Uniform01(); +param pt{T} := ceil(1000 * Uniform01()); + +# Image size +param scale := 1000; + +# Colors +# saturation [0, 255] +param sat := 192; +param hue{c in C} := 6 * (c - 1) / nc; +param red{c in C} := + if hue[c] <= 1 or hue[c] >= 5 then 255 + else (if hue[c] >=2 and hue[c] <= 4 then 255 - sat + else (if hue[c] <=2 then 255 - sat + sat * (2-hue[c]) + else 255 - sat + sat * (hue[c]-4) )); +param green{c in C} := + if hue[c] >= 1 and hue[c] <= 3 then 255 + else (if hue[c] >= 4 then 255 - sat + else (if hue[c] <=1 then 255 - sat + sat * hue[c] + else 255 - sat + sat * (4-hue[c]) )); +param blue{c in C} := + if hue[c] >= 3 and hue[c] <= 5 then 255 + else (if hue[c] <=2 then 255 - sat + else (if hue[c] <=3 then 255 - sat + sat * (hue[c]-2) + else 255 - sat + sat * (6-hue[c]) )); + +var x{T}; +var y{T,T}, binary; + +minimize obj : sum{c in T, t in T} y[c,t] * pt[t] + * sqrt((xt[c] - xt[t])^2 + (yt[c] - yt[t])^2); + +s.t. sumx : sum{c in T} x[c] = nc; +s.t. cxy{c in T, t in T} : y[c,t] <= x[c]; +s.t. sumy{t in T} : sum{c in T} y[c,t] = 1; + +solve; + +for {c in T : x[c] > .5} { + printf "Center %5.4f %5.4f\n", xt[c], yt[c]; + for {t in T : y[c,t] > .5} { + printf " Town %5.4f %5.4f (%5.0f)\n", xt[t], yt[t], pt[t]; + } +} + +# Output the solution as scalable vector graphic + +# header +printf "<?xml version=""1.0"" standalone=""no""?>\n" > f; +printf "<!DOCTYPE svg PUBLIC ""-//W3C//DTD SVG 1.1//EN"" \n" >> f; +printf """http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"">\n" >> f; +printf "<svg width=""%d"" height=""%d"" version=""1.0"" \n", + 1.2 * scale, 1.2 * scale >> f; +printf "xmlns=""http://www.w3.org/2000/svg"">\n" >> f; + +# background +printf "<rect x=""0"" y=""0"" width=""%d"" height=""%d""" & + " stroke=""none"" fill=""white""/>\n", + 1.2 * scale, 1.2 * scale>> f; + +# border +printf "<rect x=""%d"" y=""%d"" width=""%d"" height=""%d""" & + " stroke=""black"" stroke-width="".5"" fill=""white""/>\n", + .1 * scale, .1 * scale, scale, scale >> f; + +# circles for towns +for {t in T} + printf {s in T, c in C : y[s,t] > .5 + && c = floor( .5 + sum{u in T : u <= s} x[u])} + "<circle cx=""%f"" cy=""%f"" r=""%f"" stroke=""black"" " & + "stroke-width=""1"" fill=""rgb(%d,%d,%d)""/>\n", + (.1 + xt[t]) * scale, (.1 + yt[t]) * scale, .001 * sqrt(pt[t]) * scale, + red[c], green[c] , blue[c] >> f; + +# lines from towns to assigned centers +for {t in T, c in T : y[c,t] > .5} + printf "<line x1=""%f"" y1=""%f"" x2=""%f"" y2=""%f""" & + " style=""stroke:black;stroke-width:.5""/>\n", + (.1 + xt[c]) * scale, (.1 + yt[c]) * scale, + (.1 + xt[t]) * scale, (.1 + yt[t]) * scale >> f; + +printf "</svg>\n" >> f; + +end; diff --git a/glpk-5.0/examples/threads/multiseed.c b/glpk-5.0/examples/threads/multiseed.c new file mode 100644 index 0000000..eb5d215 --- /dev/null +++ b/glpk-5.0/examples/threads/multiseed.c @@ -0,0 +1,255 @@ +/* multiseed.c (multithreading demo) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* Copyright (C) 2017 Free Software Foundation, Inc. +* Written by Heinrich Schuchardt <xypron.glpk@gmx.de>. +* +* 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 3 of the License, 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. If not, see <http://www.gnu.org/licenses/>. +***********************************************************************/ + +/* + * This program demonstrates running the GLPK library with multiple threads. + * + * When called the program requires two arguments: + * + * filename - the name of the MathProg model to be solved + * threads - the count of parallel threads to be run. + * + * Each thread is run with a different seed for the random number generator + * provided by the GLPK library. + */ + +#include <glpk.h> +#include <malloc.h> +#include <setjmp.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "thread.h" + +#define BUFLEN 256 + +/* Task descriptor */ +struct task { + pthread_t tid; + char *filename; + int seed; + size_t pos; + char buf[BUFLEN + 1]; + int line; + jmp_buf jmp; +}; + +/* Mutex for console output */ +pthread_mutex_t mutex; + +/* Console output handler */ +int term_hook(void *info, const char *text) +{ + struct task *task = (struct task *) info; + size_t len = strlen(text); + + /* Lock mutex so this is the only task creating console output. */ + pthread_mutex_lock(&mutex); + + /* Append the new text to the buffer. */ + if (task->pos + len > BUFLEN) { + printf("%02d-%05d %s%s", task->seed, ++task->line, task->buf, text); + task->pos = 0; + task->buf[0] = 0; + } else { + strcpy(task->buf + task->pos, text); + task->pos += len; + } + + /* If a complete line is available, send it to the console. */ + if (strchr(task->buf, '\n')) { + printf("%02d-%05d %s", task->seed, ++task->line, task->buf); + task->pos = 0; + task->buf[0] = 0; + } + + /* Unlock the mutex. */ + pthread_mutex_unlock(&mutex); + + /* Disable default output. */ + return -1; +} + +/* Error handler */ +void error_hook(void *info) +{ + struct task *task = (struct task *) info; + + term_hook(task, "Error caught\n"); + glp_free_env(); + longjmp(task->jmp, 1); +} + +void worker(void *arg) +{ + struct task *task = (struct task *) arg; + int ret; + glp_prob *lp; + glp_tran *tran; + glp_iocp iocp; + + if (setjmp(task->jmp)) { + /* If an error is caught leave the function. */ + return; + } + + /* Set the error handler. */ + glp_error_hook(error_hook, task); + + /* Set the console output handler. */ + glp_term_hook(term_hook, arg); + + glp_printf("Seed %02d\n", task->seed); + + /* Create the problem object. */ + lp = glp_create_prob(); + if (!lp) { + glp_error("Out of memory\n"); + } + + /* Create the MathProg translator workspace. */ + tran = glp_mpl_alloc_wksp(); + if (!lp) { + glp_error("Out of memory\n"); + } + + /* Set the pseudo random number generator seed. */ + glp_mpl_init_rand(tran, task->seed); + + /* Read the model file. */ + ret = glp_mpl_read_model (tran, task->filename, GLP_OFF); + if (ret != 0) { + glp_error("Model %s is not valid\n", task->filename); + } + + /* Generate the model. */ + ret = glp_mpl_generate(tran, NULL); + if (ret != 0) { + glp_error("Cannot generate model %s\n", task->filename); + } + + /* Build the problem. */ + glp_mpl_build_prob(tran, lp); + + /* Solve the problem. */ + glp_init_iocp(&iocp); + iocp.presolve = GLP_ON; + ret = glp_intopt(lp, &iocp); + if (ret == 0) { + /* Execute the post solve part of the model. */ + glp_mpl_postsolve(tran, lp, GLP_MIP); + } + + /* Release the memory. */ + glp_mpl_free_wksp (tran); + glp_delete_prob(lp); + + if (0 == task->seed % 3) { + glp_error("Voluntarily throwing an error in %s at line %d\n", + __FILE__, __LINE__); + } + + glp_term_hook(NULL, NULL); + + glp_error_hook(NULL, NULL); + + glp_free_env(); +} + +#ifdef __WOE__ +DWORD run(void *arg) +{ +#else +void *run(void *arg) +{ +#endif + worker(arg); + pthread_exit(NULL); +} + +int main(int argc, char *argv[]) +{ + int i, n, rc; + struct task *tasks; + + /* Make sure thread local memory is used by the GLPK library. */ + if (!glp_config("TLS")) { + printf("The loaded GLPK library does not support thread local memory.\n" + "You need a version of the library configured with " + "--enable-reentrant=yes to run this program.\n"); + exit(EXIT_FAILURE); + } + + /* Check program arguments. */ + if (argc != 3) { + printf("Usage %s filename threads\n" + " filename - MathProg model file\n" + " threads - number of threads\n", + argv[0]); + exit(EXIT_FAILURE); + } + + /* Parse the arguments. */ + n = atoi(argv[2]); + if (n > 50) { + printf("Number of threads is to high (> 50).\n"); + exit(EXIT_FAILURE); + } + if (n <= 1) { + printf("Need positive number of threads\n"); + exit(EXIT_FAILURE); + } + + /* Allocate memory for the task descriptors. */ + tasks = calloc(n, sizeof(struct task)); + if (!tasks) { + printf("Out of memory"); + exit(EXIT_FAILURE); + } + + /* Create a mutex for console output. */ + pthread_mutex_init(&mutex, NULL); + + /* Create the threads. */ + for (i = 0; i < n; ++i) { + tasks[i].filename = argv[1]; + tasks[i].seed = i + 1; + tasks[i].pos = 0; + tasks[i].buf[0] = 0; + tasks[i].line = 0; + rc = pthread_create(&tasks[i].tid, NULL, run, &tasks[i]); + if (rc) { + printf("ERROR; return code from pthread_create() is %d\n", rc); + exit(EXIT_FAILURE); + } + } + + /* Wait for all threads to complete. */ + for (i = 0; i < n; ++i) { + pthread_join(tasks[i].tid, NULL); + } + + /* Destroy the mutex. */ + pthread_mutex_destroy(&mutex); + + return EXIT_SUCCESS; +} diff --git a/glpk-5.0/examples/threads/thread.h b/glpk-5.0/examples/threads/thread.h new file mode 100644 index 0000000..79c3dde --- /dev/null +++ b/glpk-5.0/examples/threads/thread.h @@ -0,0 +1,50 @@ +/* thread.h (pthread emulation for Windows) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* Copyright (C) 2011-2017 Free Software Foundation, Inc. +* Written by Heinrich Schuchardt <xypron.glpk@gmx.de>. +* +* 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 3 of the License, 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. If not, see <http://www.gnu.org/licenses/>. +***********************************************************************/ + +#ifndef THREAD_H + +#define THREAD_H 1 + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif // HAVE_CONFIG_H + +#ifdef __WOE__ +#include <windows.h> +typedef CRITICAL_SECTION pthread_mutex_t; +typedef HANDLE pthread_t; +// @todo The return type of routine C is "DWORD" for Windows and +// "void *" for Posix. +#define pthread_create(A,B,C,D) \ + (int)((*A = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)&C,D,0,NULL))==NULL) +#define pthread_exit(A) ExitThread(0) +#define pthread_mutex_destroy(A) DeleteCriticalSection(A) +#define pthread_mutex_init(A,B) (InitializeCriticalSection(A),0) +#define pthread_mutex_lock(A) (EnterCriticalSection(A),0) +#define pthread_mutex_unlock(A) (LeaveCriticalSection(A),0) +#define pthread_self() GetCurrentThreadId() +#define pthread_join(A, B) \ + (WaitForSingleObject(A, INFINITE),CloseHandle(A),0) +#else +#include <pthread.h> +#endif + +#endif // THREAD_H diff --git a/glpk-5.0/examples/tiling.mod b/glpk-5.0/examples/tiling.mod new file mode 100644 index 0000000..6e0cabd --- /dev/null +++ b/glpk-5.0/examples/tiling.mod @@ -0,0 +1,118 @@ +/* Rectifiable polyomino tilings generator */ + +/* Written and converted to GNU MathProg by NASZVADI, Peter, 2007-2017 + <vuk@cs.elte.hu> */ + +/* + This model searches for a maximal packing of a given polyomino + composed of unit squares in a given rectangle. In a feasible packing, a + placed polyomino and its intersection of a unit square's inner part in + the rectangle must be the square or empty. If there exists a packing + that covers totally the rectangle, then the polyomino is called + "rectifiable" + + Summary: + Decides if an Im * Jm rectangle could be tiled with given pattern + and prints a (sub)optimal solution if found + + Generated magic numbers are implicit tables, check them: + + # for magic in 3248 688 1660 3260 + do printf "Magic % 5d:" "$magic" + for e in 0 1 2 3 4 5 6 7 + do printf "% 3d" "$((-1 + ((magic / (3**e)) % 3)))" + done + echo + done + Magic 3248: 1 1 -1 -1 0 0 0 0 + Magic 688: 0 0 0 0 1 1 -1 -1 + Magic 1660: 0 0 0 0 1 -1 1 -1 + Magic 3260: 1 -1 1 -1 0 0 0 0 + # +*/ + +param Im, default 3; +/* vertical edge length of the box */ + +param Jm, default 3; +/* horizontal edge length of the box */ + +set S, default {(0, 0), (1, 0), (2, 0), (0, 1), (1, 1), (2, 1), (0, 2)}; +/* P-heptomino is the default shape. More info on this heptomino: + http://www.cflmath.com/Polyomino/7omino4_rect.html */ + +set I := 1..Im; +/* rows of rectangle */ + +set J := 1..Jm; +/* columns of rectangle */ + +set IJ := I cross J; +/* the rectangle itself */ + +set E := 0..7; +/* helper set to allow iterating on all transformations of the S shape */ + +set Shifts := setof{(i, j, e) in IJ cross E: + setof{(x, y) in S} + ((x * (-1 + floor(3248 / 3^e) mod 3)) + + (y * (-1 + floor(688 / 3^e) mod 3)) + i, + (x * (-1 + floor(1660 / 3^e) mod 3)) + + (y * (-1 + floor(3260 / 3^e) mod 3)) + j) within IJ}(i, j, e); +/* all shifted, flipped, rotated, mirrored mappings of polyomino that + contained by the rectangle */ + +var cell{IJ}, binary; +/* booleans denoting if a cell is covered in the rectangle */ + +var tile{Shifts}, binary; +/* booleans denoting usage of a shift */ + +var objvalue; + +s.t. covers{(i, j) in IJ}: sum{(k, l, e, a, b) in Shifts cross S: + i = k + a * (-1 + floor(3248 / 3^e) mod 3) + + b * (-1 + floor(688 / 3^e) mod 3) + and + j = l + a * (-1 + floor(1660 / 3^e) mod 3) + + b * (-1 + floor(3260 / 3^e) mod 3) + }tile[k, l, e] = cell[i, j]; + +s.t. objeval: sum{(i, j) in IJ}cell[i, j] - objvalue = 0; + +maximize obj: objvalue; + +solve; + +printf '\nCovered cells/all cells = %d/%d\n\n', objvalue.val, Im * Jm; +printf '\nA tiling:\n\n'; +for{i in I}{ + for{j in J}{ + printf '%s', if cell[i, j].val then '' else ' *** '; + for{(k, l, e, a, b) in Shifts cross S: + cell[i, j].val + and i = k + a * (-1 + floor(3248 / 3^e) mod 3) + + b * (-1 + floor(688 / 3^e) mod 3) + and j = l + a * (-1 + floor(1660 / 3^e) mod 3) + + b * (-1 + floor(3260 / 3^e) mod 3) + and tile[k, l, e].val + }{ + printf '% 5d', (k * Jm + l) * 8 + e; + } + } + printf '\n'; +} +printf '\n'; + +data; + +param Im := 14; +/* here can be set rectangle's one side */ + +param Jm := 14; +/* here can be set rectangle's other side */ + +set S := (0,0),(1,0),(2,0),(0,1),(1,1),(2,1),(0,2); +/* here you can specify arbitrary polyomino */ + +end; diff --git a/glpk-5.0/examples/todd.mod b/glpk-5.0/examples/todd.mod new file mode 100644 index 0000000..c0ef44b --- /dev/null +++ b/glpk-5.0/examples/todd.mod @@ -0,0 +1,36 @@ +/* TODD, a class of hard instances of zero-one knapsack problems */ + +/* Written in GNU MathProg by Andrew Makhorin <mao@gnu.org> */ + +/* Chvatal describes a class of instances of zero-one knapsack problems + due to Todd. He shows that a wide class of algorithms - including all + based on branch and bound or dynamic programming - find it difficult + to solve problems in the Todd class. More exactly, the time required + by these algorithms to solve instances of problems that belong to the + Todd class grows as an exponential function of the problem size. + + Reference: + Chvatal V. (1980), Hard knapsack problems, Op. Res. 28, 1402-1411. */ + +param n > 0 integer; + +param log2_n := log(n) / log(2); + +param k := floor(log2_n); + +param a{j in 1..n} := 2 ** (k + n + 1) + 2 ** (k + n + 1 - j) + 1; + +param b := 0.5 * floor(sum{j in 1..n} a[j]); + +var x{1..n} binary; + +maximize obj: sum{j in 1..n} a[j] * x[j]; + +s.t. cap: sum{j in 1..n} a[j] * x[j] <= b; + +data; + +param n := 15; +/* change this parameter to choose a particular instance */ + +end; diff --git a/glpk-5.0/examples/toto.mod b/glpk-5.0/examples/toto.mod new file mode 100644 index 0000000..6b4318e --- /dev/null +++ b/glpk-5.0/examples/toto.mod @@ -0,0 +1,135 @@ +/* Covering code generator, especially for football pool systems */ + +/* Written and converted to GNU MathProg by NASZVADI, Peter, 199x-2017 + <vuk@cs.elte.hu> */ + +/* + Looks up for minimal covering codes in the specified Hamming-space. + Without specifying model data, by default it looks up for covering + for a mixed covering code in Hamming-space {X, 1, 2, 3}*{X, 1}^4 + with one layer. + + Hamming space is a set of finite words with all the same length over + a finite alphabet: the space could be decomposed to Cartesian + products of subsets of the alphabet, e.g. the first letter of an + element can be chosen from a 2-element set, the next from 6 letters, + and so on. + + There is a natural metric function in these spaces: the + Hamming-distance (hence the name, from now referred as: distance). + The distance of two (equal-length) words is the number of different + letter pairs in the corresponding positions. + + Covering Hamming-spaces with minimal number of spheres with given + radius - usually difficult problem excluding special cases. + + Relationship with sports: + Football pool system in Hungarian: "Toto'kulcs", so Toto, totogol and + other football pool systems are usually need mixed ternary/binary + code coverings in order to minimize loss of the gambler. + + See more at: + https://en.wikipedia.org/wiki/Covering_code + + A tricky workaround is used: + floor(), abs() and cosine() magic are used at 'coverings' constraints, + because GMPL lacks proper boolean<->integer evaluation/casting. +*/ + +param ArgNum1, >= 1, default 1; +param ArgNum2, >= 1, default 1; +param ArgNum3, >= 1, default 1; +param ArgNum4, >= 1, default 1; +param ArgNum5, >= 1, default 1; +param ArgNum6, >= 1, default 1; +param ArgNum7, >= 1, default 1; +param ArgNum8, >= 1, default 1; +param ArgNum9, >= 1, default 1; +param ArgNum10, >= 1, default 1; +param ArgNum11, >= 1, default 1; +param ArgNum12, >= 1, default 1; +param ArgNum13, >= 1, default 1; +/* at most 13 matches' outcomes */ + +param Radius, >= 1, default 1; +/* covering radius */ + +param Layer, >= 1, default 1; +/* each point of space must be covered at least Layer times */ + +set X := 0..ArgNum1 - 1 cross 0..ArgNum2 - 1 cross 0..ArgNum3 - 1 cross + 0..ArgNum4 - 1 cross 0..ArgNum5 - 1 cross 0..ArgNum6 - 1 cross + 0..ArgNum7 - 1 cross 0..ArgNum8 - 1 cross 0..ArgNum9 - 1 cross + 0..ArgNum10 - 1 cross 0..ArgNum11 - 1 cross 0..ArgNum12 - 1 cross + 0..ArgNum13 - 1; +/* the Hamming-space generated by the Cartesian-products of sets + with elements ArgNum[n] */ + +var x{X}, integer, >=0; +/* denotes each point's amount of containing covering sets */ + +var objvalue; + +s.t. coverings{(i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13) in X}: + sum{(j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13) in X: + floor(abs(cos(i1 - j1))) + floor(abs(cos(i2 - j2))) + + floor(abs(cos(i3 - j3))) + floor(abs(cos(i4 - j4))) + + floor(abs(cos(i5 - j5))) + floor(abs(cos(i6 - j6))) + + floor(abs(cos(i7 - j7))) + floor(abs(cos(i8 - j8))) + + floor(abs(cos(i9 - j9))) + floor(abs(cos(i10 - j10))) + + floor(abs(cos(i11 - j11))) + floor(abs(cos(i12 - j12))) + + floor(abs(cos(i13 - j13))) >= 13 - Radius + } x[j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13] >= Layer; +/* covering constraints, select at least 'Layer' amount of spheres that cover + (i1,i2,...) and has radius 'Radius' */ + +s.t. oneisset: x[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] >= 1; +/* this does not violate symmetry nor excludes important solutions but + boosts the solving process */ + +s.t. objc: sum{(i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13) in X} + x[i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13] = objvalue; +/* the total number of pools (covering sets) */ + +minimize obj: objvalue; +/* Also 'objc' could be used directly instead of 'obj', but for + experiments, it is useful to set up additional constraints for + introduced objvalue variable */ + +solve; + +printf 'Solution: %s\nRadius: %s\nLayer: %s\n', + objvalue.val, Radius, Layer; +/* report important scalars */ + +printf 'Selected bets:\n'; +for{(i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13) in X: + x[i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13]}{ + printf ' Times %s:', + x[i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13].val; + printf '%s', if ArgNum1 == 1 then '' else ' ' & if i1 then i1 else 'X'; + printf '%s', if ArgNum2 == 1 then '' else '-' & if i2 then i2 else 'X'; + printf '%s', if ArgNum3 == 1 then '' else '-' & if i3 then i3 else 'X'; + printf '%s', if ArgNum4 == 1 then '' else '-' & if i4 then i4 else 'X'; + printf '%s', if ArgNum5 == 1 then '' else '-' & if i5 then i5 else 'X'; + printf '%s', if ArgNum6 == 1 then '' else '-' & if i6 then i6 else 'X'; + printf '%s', if ArgNum7 == 1 then '' else '-' & if i7 then i7 else 'X'; + printf '%s', if ArgNum8 == 1 then '' else '-' & if i8 then i8 else 'X'; + printf '%s', if ArgNum9 == 1 then '' else '-' & if i9 then i9 else 'X'; + printf '%s', if ArgNum10 == 1 then '' else '-' & if i10 then i10 else 'X'; + printf '%s', if ArgNum11 == 1 then '' else '-' & if i11 then i11 else 'X'; + printf '%s', if ArgNum12 == 1 then '' else '-' & if i12 then i12 else 'X'; + printf '%s', if ArgNum13 == 1 then '' else '-' & if i13 then i13 else 'X'; + printf '\n'; +} +/* pretty-print a generated football pool system (covering code) */ + +data; + +param ArgNum1 := 4; +param ArgNum2 := 2; +param ArgNum3 := 2; +param ArgNum4 := 2; +param ArgNum5 := 2; + +end; diff --git a/glpk-5.0/examples/train.mod b/glpk-5.0/examples/train.mod new file mode 100644 index 0000000..a17520e --- /dev/null +++ b/glpk-5.0/examples/train.mod @@ -0,0 +1,281 @@ +# TRAIN, a model of railroad passenger car allocation +# +# References: +# Robert Fourer, David M. Gay and Brian W. Kernighan, "A Modeling Language +# for Mathematical Programming." Management Science 36 (1990) 519-554. + +### SCHEDULE SETS AND PARAMETERS ### + +set cities; + +set links within {c1 in cities, c2 in cities: c1 <> c2}; + + # Set of cities, and set of intercity links + +param last > 0 integer; # Number of time intervals in a day + +set times := 1..last; # Set of time intervals in a day + +set schedule within + {c1 in cities, t1 in times, + c2 in cities, t2 in times: (c1,c2) in links}; + + # Member (c1,t1,c2,t2) of this set represents + # a train that leaves city c1 at time t1 + # and arrives in city c2 at time t2 + +### DEMAND PARAMETERS ### + +param section > 0 integer; + + # Maximum number of cars in one section of a train + +param demand {schedule} > 0; + + # For each scheduled train: + # the smallest number of cars that + # can meet demand for the train + +param low {(c1,t1,c2,t2) in schedule} := ceil(demand[c1,t1,c2,t2]); + + # Minimum number of cars needed to meet demand + +param high {(c1,t1,c2,t2) in schedule} + + := max (2, min (ceil(2*demand[c1,t1,c2,t2]), + section*ceil(demand[c1,t1,c2,t2]/section) )); + + # Maximum number of cars allowed on a train: + # 2 if demand is for less than one car; + # otherwise, lesser of + # number of cars needed to hold twice the demand, and + # number of cars in minimum number of sections needed + +### DISTANCE PARAMETERS ### + +param dist_table {links} >= 0 default 0.0; + +param distance {(c1,c2) in links} > 0 + := if dist_table[c1,c2] > 0 then dist_table[c1,c2] else dist_table[c2,c1]; + + # Inter-city distances: distance[c1,c2] is miles + # between city c1 and city c2 + +### VARIABLES ### + +var U 'cars stored' {cities,times} >= 0; + + # u[c,t] is the number of unused cars stored + # at city c in the interval beginning at time t + +var X 'cars in train' {schedule} >= 0; + + # x[c1,t1,c2,t2] is the number of cars assigned to + # the scheduled train that leaves c1 at t1 and + # arrives in c2 at t2 + +### OBJECTIVES ### + +minimize cars: + sum {c in cities} U[c,last] + + sum {(c1,t1,c2,t2) in schedule: t2 < t1} X[c1,t1,c2,t2]; + + # Number of cars in the system: + # sum of unused cars and cars in trains during + # the last time interval of the day + +minimize miles: + sum {(c1,t1,c2,t2) in schedule} distance[c1,c2] * X[c1,t1,c2,t2]; + + # Total car-miles run by all scheduled trains in a day + +### CONSTRAINTS ### + +account {c in cities, t in times}: + + U[c,t] = U[c, if t > 1 then t-1 else last] + + + sum {(c1,t1,c,t) in schedule} X[c1,t1,c,t] - + sum {(c,t,c2,t2) in schedule} X[c,t,c2,t2]; + + # For every city and time: + # unused cars in the present interval must equal + # unused cars in the previous interval, + # plus cars just arriving in trains, + # minus cars just leaving in trains + +satisfy {(c1,t1,c2,t2) in schedule}: + + low[c1,t1,c2,t2] <= X[c1,t1,c2,t2] <= high[c1,t1,c2,t2]; + + # For each scheduled train: + # number of cars must meet demand, + # but must not be so great that unnecessary + # sections are run + +### DATA ### + +data; + +set cities := BO NY PH WA ; + +set links := (BO,NY) (NY,PH) (PH,WA) + (NY,BO) (PH,NY) (WA,PH) ; + +param dist_table := [*,*] BO NY 232 + NY PH 90 + PH WA 135 ; + +param last := 48 ; + +param section := 14 ; + +set schedule := + + (WA,*,PH,*) 2 5 6 9 8 11 10 13 + 12 15 13 16 14 17 15 18 + 16 19 17 20 18 21 19 22 + 20 23 21 24 22 25 23 26 + 24 27 25 28 26 29 27 30 + 28 31 29 32 30 33 31 34 + 32 35 33 36 34 37 35 38 + 36 39 37 40 38 41 39 42 + 40 43 41 44 42 45 44 47 + 46 1 + + (PH,*,NY,*) 1 3 5 7 9 11 11 13 + 13 15 14 16 15 17 16 18 + 17 19 18 20 19 21 20 22 + 21 23 22 24 23 25 24 26 + 25 27 26 28 27 29 28 30 + 29 31 30 32 31 33 32 34 + 33 35 34 36 35 37 36 38 + 37 39 38 40 39 41 40 42 + 41 43 42 44 43 45 44 46 + 45 47 47 1 + + (NY,*,BO,*) 10 16 12 18 14 20 15 21 + 16 22 17 23 18 24 19 25 + 20 26 21 27 22 28 23 29 + 24 30 25 31 26 32 27 33 + 28 34 29 35 30 36 31 37 + 32 38 33 39 34 40 35 41 + 36 42 37 43 38 44 39 45 + 40 46 41 47 42 48 43 1 + 44 2 45 3 46 4 48 6 + + (BO,*,NY,*) 7 13 9 15 11 17 12 18 + 13 19 14 20 15 21 16 22 + 17 23 18 24 19 25 20 26 + 21 27 22 28 23 29 24 30 + 25 31 26 32 27 33 28 34 + 29 35 30 36 31 37 32 38 + 33 39 34 40 35 41 36 42 + 37 43 38 44 39 45 40 46 + 41 47 43 1 45 3 47 5 + + (NY,*,PH,*) 1 3 12 14 13 15 14 16 + 15 17 16 18 17 19 18 20 + 19 21 20 22 21 23 22 24 + 23 25 24 26 25 27 26 28 + 27 29 28 30 29 31 30 32 + 31 33 32 34 33 35 34 36 + 35 37 36 38 37 39 38 40 + 39 41 40 42 41 43 42 44 + 43 45 44 46 45 47 46 48 + 47 1 + + (PH,*,WA,*) 1 4 14 17 15 18 16 19 + 17 20 18 21 19 22 20 23 + 21 24 22 25 23 26 24 27 + 25 28 26 29 27 30 28 31 + 29 32 30 33 31 34 32 35 + 33 36 34 37 35 38 36 39 + 37 40 38 41 39 42 40 43 + 41 44 42 45 43 46 44 47 + 45 48 46 1 47 2 ; + +param demand := + + [WA,*,PH,*] 2 5 .55 6 9 .01 8 11 .01 + 10 13 .13 12 15 1.59 13 16 1.69 + 14 17 5.19 15 18 3.55 16 19 6.29 + 17 20 4.00 18 21 5.80 19 22 3.40 + 20 23 4.88 21 24 2.92 22 25 4.37 + 23 26 2.80 24 27 4.23 25 28 2.88 + 26 29 4.33 27 30 3.11 28 31 4.64 + 29 32 3.44 30 33 4.95 31 34 3.73 + 32 35 5.27 33 36 3.77 34 37 4.80 + 35 38 3.31 36 39 3.89 37 40 2.65 + 38 41 3.01 39 42 2.04 40 43 2.31 + 41 44 1.52 42 45 1.75 44 47 1.88 + 46 1 1.05 + + [PH,*,NY,*] 1 3 1.05 5 7 .43 9 11 .20 + 11 13 .21 13 15 .40 14 16 6.49 + 15 17 16.40 16 18 9.48 17 19 17.15 + 18 20 9.31 19 21 15.20 20 22 8.21 + 21 23 13.32 22 24 7.35 23 25 11.83 + 24 26 6.61 25 27 10.61 26 28 6.05 + 27 29 9.65 28 30 5.61 29 31 9.25 + 30 32 5.40 31 33 8.24 32 34 4.84 + 33 35 7.44 34 36 4.44 35 37 6.80 + 36 38 4.11 37 39 6.25 38 40 3.69 + 39 41 5.55 40 42 3.29 41 43 4.77 + 42 44 2.91 43 45 4.19 44 46 2.53 + 45 47 4.00 47 1 1.65 + + [NY,*,BO,*] 10 16 1.23 12 18 3.84 14 20 4.08 + 15 21 1.47 16 22 2.96 17 23 1.60 + 18 24 2.95 19 25 1.71 20 26 2.81 + 21 27 1.77 22 28 2.87 23 29 1.84 + 24 30 2.95 25 31 1.91 26 32 3.12 + 27 33 1.93 28 34 3.31 29 35 2.00 + 30 36 3.40 31 37 2.08 32 38 3.41 + 33 39 2.69 34 40 4.45 35 41 2.32 + 36 42 3.40 37 43 1.80 38 44 2.63 + 39 45 1.52 40 46 2.23 41 47 1.25 + 42 48 1.79 43 1 .97 44 2 1.28 + 45 3 .48 46 4 .68 48 6 .08 + + [BO,*,NY,*] 7 13 .03 9 15 1.29 11 17 4.59 + 12 18 2.56 13 19 3.92 14 20 2.37 + 15 21 3.81 16 22 2.24 17 23 3.51 + 18 24 2.13 19 25 3.28 20 26 2.05 + 21 27 3.15 22 28 1.99 23 29 3.09 + 24 30 1.93 25 31 3.19 26 32 1.91 + 27 33 3.21 28 34 1.85 29 35 3.21 + 30 36 1.71 31 37 3.04 32 38 2.08 + 33 39 3.13 34 40 1.96 35 41 2.53 + 36 42 1.43 37 43 2.04 38 44 1.12 + 39 45 1.71 40 46 .91 41 47 1.32 + 43 1 1.80 45 3 1.13 47 5 .23 + + [NY,*,PH,*] 1 3 .04 12 14 4.68 13 15 5.61 + 14 16 3.56 15 17 5.81 16 18 3.81 + 17 19 6.31 18 20 4.07 19 21 7.33 + 20 22 4.55 21 23 7.37 22 24 4.73 + 23 25 7.61 24 26 4.92 25 27 7.91 + 26 28 5.19 27 29 8.40 28 30 5.53 + 29 31 9.32 30 32 5.51 31 33 10.33 + 32 34 9.21 33 35 18.95 34 36 11.23 + 35 37 16.85 36 38 7.29 37 39 10.89 + 38 40 5.41 39 41 8.21 40 42 4.52 + 41 43 6.99 42 44 3.92 43 45 6.21 + 44 46 3.44 45 47 5.17 46 48 2.55 + 47 1 1.24 + + [PH,*,WA,*] 1 4 .20 14 17 4.49 15 18 3.53 + 16 19 2.67 17 20 3.83 18 21 3.01 + 19 22 4.12 20 23 3.15 21 24 4.67 + 22 25 3.20 23 26 4.23 24 27 2.87 + 25 28 3.84 26 29 2.60 27 30 3.80 + 28 31 2.77 29 32 4.31 30 33 3.16 + 31 34 4.88 32 35 3.45 33 36 5.55 + 34 37 3.52 35 38 6.11 36 39 3.32 + 37 40 5.53 38 41 3.03 39 42 4.51 + 40 43 2.53 41 44 3.39 42 45 1.93 + 43 46 2.52 44 47 1.20 45 48 1.75 + 46 1 .88 47 2 .87 ; + +end; diff --git a/glpk-5.0/examples/transp.mod b/glpk-5.0/examples/transp.mod new file mode 100644 index 0000000..a7cb939 --- /dev/null +++ b/glpk-5.0/examples/transp.mod @@ -0,0 +1,63 @@ +# A TRANSPORTATION PROBLEM +# +# This problem finds a least cost shipping schedule that meets +# requirements at markets and supplies at factories. +# +# References: +# Dantzig G B, "Linear Programming and Extensions." +# Princeton University Press, Princeton, New Jersey, 1963, +# Chapter 3-3. + +set I; +/* canning plants */ + +set J; +/* markets */ + +param a{i in I}; +/* capacity of plant i in cases */ + +param b{j in J}; +/* demand at market j in cases */ + +param d{i in I, j in J}; +/* distance in thousands of miles */ + +param f; +/* freight in dollars per case per thousand miles */ + +param c{i in I, j in J} := f * d[i,j] / 1000; +/* transport cost in thousands of dollars per case */ + +var x{i in I, j in J} >= 0; +/* shipment quantities in cases */ + +minimize cost: sum{i in I, j in J} c[i,j] * x[i,j]; +/* total transportation costs in thousands of dollars */ + +s.t. supply{i in I}: sum{j in J} x[i,j] <= a[i]; +/* observe supply limit at plant i */ + +s.t. demand{j in J}: sum{i in I} x[i,j] >= b[j]; +/* satisfy demand at market j */ + +data; + +set I := Seattle San-Diego; + +set J := New-York Chicago Topeka; + +param a := Seattle 350 + San-Diego 600; + +param b := New-York 325 + Chicago 300 + Topeka 275; + +param d : New-York Chicago Topeka := + Seattle 2.5 1.7 1.8 + San-Diego 2.5 1.8 1.4 ; + +param f := 90; + +end; diff --git a/glpk-5.0/examples/trick.mod b/glpk-5.0/examples/trick.mod new file mode 100644 index 0000000..df5717b --- /dev/null +++ b/glpk-5.0/examples/trick.mod @@ -0,0 +1,72 @@ +/* TRICK, A Transportation Design Problem */ + +/* Translated from the Mosel modeling language to GNU MathProg by + Andrew Makhorin <mao@gnu.org> */ + +/* This example model is described in the article "Formulations and + Reformulations in Integer Programming" by Michael Trick (it is + publicly available at http://mat.gsia.cmu.edu/trick/formul04.pdf). + + This model demonstrates an amazing effect when including in the + formulation an additional constraint, which is redundant even for + LP relaxation, makes the model easy for solving with the B&B. */ + +set TRUCKS := 1..10; + +set PACKAGES := 1..20; + +param capacity{TRUCKS}; + +param size{PACKAGES}; + +param cost{TRUCKS}; + +param can_use{PACKAGES, TRUCKS}; + +var x{PACKAGES, TRUCKS}, binary; + +var y{TRUCKS}, binary; + +minimize total: sum{i in TRUCKS} cost[i] * y[i]; + +f1{i in TRUCKS}: + sum{j in PACKAGES} size[j] * x[j,i] <= capacity[i] * y[i]; + +f2{i in TRUCKS, j in PACKAGES}: + x[j,i] <= y[i]; + +f3{j in PACKAGES}: + sum{i in TRUCKS} can_use[j,i] * x[j,i] = 1; + +redundant_constraint: + sum{i in TRUCKS} capacity[i] * y[i] >= sum{j in PACKAGES} size[j]; + +data; + +param capacity := + [1] 100 [2] 200 [3] 100 [4] 200 [5] 100 [6] 200 [7] 100 [8] 200 + [9] 100 [10] 200; + +param size := + [1] 17 [2] 21 [3] 54 [4] 45 [5] 87 [6] 34 [7] 23 [8] 45 [9] 12 + [10] 43 [11] 54 [12] 39 [13] 31 [14] 26 [15] 75 [16] 48 [17] 16 + [18] 32 [19] 45 [20] 55; + +param cost := + [1] 1 [2] 1.8 [3] 1 [4] 1.8 [5] 1 [6] 1.8 [7] 1 [8] 1.8 [9] 1 + [10] 1.8; + +param can_use (tr): + 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 := + 1 1 1 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 0 0 + 2 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 0 0 0 + 3 0 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 + 4 0 0 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 0 0 + 5 0 0 1 1 1 1 0 0 0 0 0 0 0 1 1 1 1 1 1 0 + 6 0 0 0 1 1 1 1 0 0 0 0 0 0 1 1 1 0 0 0 0 + 7 0 0 0 0 1 1 1 1 1 0 0 0 0 0 1 1 1 1 0 0 + 8 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 1 1 1 1 1 + 9 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 1 1 1 1 + 10 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 1 1; + +end; diff --git a/glpk-5.0/examples/tsp.mod b/glpk-5.0/examples/tsp.mod new file mode 100644 index 0000000..358245d --- /dev/null +++ b/glpk-5.0/examples/tsp.mod @@ -0,0 +1,335 @@ +/* TSP, Traveling Salesman Problem */ + +/* Written in GNU MathProg by Andrew Makhorin <mao@gnu.org> */ + +/* The Traveling Salesman Problem (TSP) is stated as follows. + Let a directed graph G = (V, E) be given, where V = {1, ..., n} is + a set of nodes, E <= V x V is a set of arcs. Let also each arc + e = (i,j) be assigned a number c[i,j], which is the length of the + arc e. The problem is to find a closed path of minimal length going + through each node of G exactly once. */ + +param n, integer, >= 3; +/* number of nodes */ + +set V := 1..n; +/* set of nodes */ + +set E, within V cross V; +/* set of arcs */ + +param c{(i,j) in E}; +/* distance from node i to node j */ + +var x{(i,j) in E}, binary; +/* x[i,j] = 1 means that the salesman goes from node i to node j */ + +minimize total: sum{(i,j) in E} c[i,j] * x[i,j]; +/* the objective is to make the path length as small as possible */ + +s.t. leave{i in V}: sum{(i,j) in E} x[i,j] = 1; +/* the salesman leaves each node i exactly once */ + +s.t. enter{j in V}: sum{(i,j) in E} x[i,j] = 1; +/* the salesman enters each node j exactly once */ + +/* Constraints above are not sufficient to describe valid tours, so we + need to add constraints to eliminate subtours, i.e. tours which have + disconnected components. Although there are many known ways to do + that, I invented yet another way. The general idea is the following. + Let the salesman sell, say, cars, starting the travel from node 1, + where he has n cars. If we require the salesman to sell exactly one + car in each node, he will need to go through all nodes to satisfy + this requirement, thus, all subtours will be eliminated. */ + +var y{(i,j) in E}, >= 0; +/* y[i,j] is the number of cars, which the salesman has after leaving + node i and before entering node j; in terms of the network analysis, + y[i,j] is a flow through arc (i,j) */ + +s.t. cap{(i,j) in E}: y[i,j] <= (n-1) * x[i,j]; +/* if arc (i,j) does not belong to the salesman's tour, its capacity + must be zero; it is obvious that on leaving a node, it is sufficient + to have not more than n-1 cars */ + +s.t. node{i in V}: +/* node[i] is a conservation constraint for node i */ + + sum{(j,i) in E} y[j,i] + /* summary flow into node i through all ingoing arcs */ + + + (if i = 1 then n) + /* plus n cars which the salesman has at starting node */ + + = /* must be equal to */ + + sum{(i,j) in E} y[i,j] + /* summary flow from node i through all outgoing arcs */ + + + 1; + /* plus one car which the salesman sells at node i */ + +solve; + +printf "Optimal tour has length %d\n", + sum{(i,j) in E} c[i,j] * x[i,j]; +printf("From node To node Distance\n"); +printf{(i,j) in E: x[i,j]} " %3d %3d %8g\n", + i, j, c[i,j]; + +data; + +/* These data correspond to the symmetric instance ulysses16 from: + + Reinelt, G.: TSPLIB - A travelling salesman problem library. + ORSA-Journal of the Computing 3 (1991) 376-84; + http://elib.zib.de/pub/Packages/mp-testdata/tsp/tsplib */ + +/* The optimal solution is 6859 */ + +param n := 16; + +param : E : c := + 1 2 509 + 1 3 501 + 1 4 312 + 1 5 1019 + 1 6 736 + 1 7 656 + 1 8 60 + 1 9 1039 + 1 10 726 + 1 11 2314 + 1 12 479 + 1 13 448 + 1 14 479 + 1 15 619 + 1 16 150 + 2 1 509 + 2 3 126 + 2 4 474 + 2 5 1526 + 2 6 1226 + 2 7 1133 + 2 8 532 + 2 9 1449 + 2 10 1122 + 2 11 2789 + 2 12 958 + 2 13 941 + 2 14 978 + 2 15 1127 + 2 16 542 + 3 1 501 + 3 2 126 + 3 4 541 + 3 5 1516 + 3 6 1184 + 3 7 1084 + 3 8 536 + 3 9 1371 + 3 10 1045 + 3 11 2728 + 3 12 913 + 3 13 904 + 3 14 946 + 3 15 1115 + 3 16 499 + 4 1 312 + 4 2 474 + 4 3 541 + 4 5 1157 + 4 6 980 + 4 7 919 + 4 8 271 + 4 9 1333 + 4 10 1029 + 4 11 2553 + 4 12 751 + 4 13 704 + 4 14 720 + 4 15 783 + 4 16 455 + 5 1 1019 + 5 2 1526 + 5 3 1516 + 5 4 1157 + 5 6 478 + 5 7 583 + 5 8 996 + 5 9 858 + 5 10 855 + 5 11 1504 + 5 12 677 + 5 13 651 + 5 14 600 + 5 15 401 + 5 16 1033 + 6 1 736 + 6 2 1226 + 6 3 1184 + 6 4 980 + 6 5 478 + 6 7 115 + 6 8 740 + 6 9 470 + 6 10 379 + 6 11 1581 + 6 12 271 + 6 13 289 + 6 14 261 + 6 15 308 + 6 16 687 + 7 1 656 + 7 2 1133 + 7 3 1084 + 7 4 919 + 7 5 583 + 7 6 115 + 7 8 667 + 7 9 455 + 7 10 288 + 7 11 1661 + 7 12 177 + 7 13 216 + 7 14 207 + 7 15 343 + 7 16 592 + 8 1 60 + 8 2 532 + 8 3 536 + 8 4 271 + 8 5 996 + 8 6 740 + 8 7 667 + 8 9 1066 + 8 10 759 + 8 11 2320 + 8 12 493 + 8 13 454 + 8 14 479 + 8 15 598 + 8 16 206 + 9 1 1039 + 9 2 1449 + 9 3 1371 + 9 4 1333 + 9 5 858 + 9 6 470 + 9 7 455 + 9 8 1066 + 9 10 328 + 9 11 1387 + 9 12 591 + 9 13 650 + 9 14 656 + 9 15 776 + 9 16 933 + 10 1 726 + 10 2 1122 + 10 3 1045 + 10 4 1029 + 10 5 855 + 10 6 379 + 10 7 288 + 10 8 759 + 10 9 328 + 10 11 1697 + 10 12 333 + 10 13 400 + 10 14 427 + 10 15 622 + 10 16 610 + 11 1 2314 + 11 2 2789 + 11 3 2728 + 11 4 2553 + 11 5 1504 + 11 6 1581 + 11 7 1661 + 11 8 2320 + 11 9 1387 + 11 10 1697 + 11 12 1838 + 11 13 1868 + 11 14 1841 + 11 15 1789 + 11 16 2248 + 12 1 479 + 12 2 958 + 12 3 913 + 12 4 751 + 12 5 677 + 12 6 271 + 12 7 177 + 12 8 493 + 12 9 591 + 12 10 333 + 12 11 1838 + 12 13 68 + 12 14 105 + 12 15 336 + 12 16 417 + 13 1 448 + 13 2 941 + 13 3 904 + 13 4 704 + 13 5 651 + 13 6 289 + 13 7 216 + 13 8 454 + 13 9 650 + 13 10 400 + 13 11 1868 + 13 12 68 + 13 14 52 + 13 15 287 + 13 16 406 + 14 1 479 + 14 2 978 + 14 3 946 + 14 4 720 + 14 5 600 + 14 6 261 + 14 7 207 + 14 8 479 + 14 9 656 + 14 10 427 + 14 11 1841 + 14 12 105 + 14 13 52 + 14 15 237 + 14 16 449 + 15 1 619 + 15 2 1127 + 15 3 1115 + 15 4 783 + 15 5 401 + 15 6 308 + 15 7 343 + 15 8 598 + 15 9 776 + 15 10 622 + 15 11 1789 + 15 12 336 + 15 13 287 + 15 14 237 + 15 16 636 + 16 1 150 + 16 2 542 + 16 3 499 + 16 4 455 + 16 5 1033 + 16 6 687 + 16 7 592 + 16 8 206 + 16 9 933 + 16 10 610 + 16 11 2248 + 16 12 417 + 16 13 406 + 16 14 449 + 16 15 636 +; + +end; diff --git a/glpk-5.0/examples/tsp/README b/glpk-5.0/examples/tsp/README new file mode 100644 index 0000000..7d497e5 --- /dev/null +++ b/glpk-5.0/examples/tsp/README @@ -0,0 +1,37 @@ +This subdirectory contains an example application program, TSPSOL, +which is a stand-alone solver intended to solve the Symmetric Traveling +Salesman Problem (TSP) with the GLPK integer optimizer. + +Please note that this program is only an illustrative example that +illustrates generating "lazy" constraints during the branch-and-bound +search. It is *not* a state-of-the-art code, so only small-sized TSP +instances (perhaps, having up to 150-200 nodes) can be solved with this +program in a reasonable time. For more details see comments in the +source code. + +To build TSPSOL executable you need to run 'build.sh' script. Note that +you should have the GLPK library properly installed. + +To run the TSPSOL program use the following command: + + tspsol tsp-file + +where tsp-file specifies an input text file containing TSP data in +TSPLIB 95 format. + +Detailed description of the input format recognized by TSPSOL is given +in the report: Gerhard Reinelt, "TSPLIB 95". This report as well as +TSPLIB, a library of sample TSP instances, are freely available for +research purposes; see: +<http://www.iwr.uni-heidelberg.de/groups/comopt/software/TSPLIB95/>. + +This subdirectory also includes the following example TSP instances: + +dantzig42.tsp 42 cities (Dantzig) [from TSPLIB] +gr120.tsp 120 cities in Germany (Groetschel) [from TSPLIB] +moscow.tsp 68 cities in Moscow region (Makhorin) +sample.tsp small example from D.Phillips and A.Garcia-Diaz +ulysses16.tsp Odyssey of Ulysses (Groetschel/Padberg) [from TSPLIB] +ulysses22.tsp Odyssey of Ulysses (Groetschel/Padberg) [from TSPLIB] + +Please send comments to the <help-glpk@gnu.org> mailing list. diff --git a/glpk-5.0/examples/tsp/bench.txt b/glpk-5.0/examples/tsp/bench.txt new file mode 100644 index 0000000..4596b2e --- /dev/null +++ b/glpk-5.0/examples/tsp/bench.txt @@ -0,0 +1,56 @@ +Solver: TSPSOL for GLPK 4.56 +Computer: Intel Celeron J1800 2.41 GHz +OS: Debian GNU/Linux 8.1.0 "Jessie" +Compiler: GCC 4.7.2 (options used: -O2) +Test set: TSPLIB 95 <http://www.iwr.uni-heidelberg.de/groups/comopt/software/TSPLIB95/> + +Instance N Solution Lower Bound Nodes Iters Time,s Mem,MB +------------ --- ------------ ------------ -------- ------- ------ ------ +att48 48 10628 opt 1 336 < 1 1.2 +bayg29 29 1610 opt 1 173 < 1 0.3 +bays29 29 2020 opt 1 166 < 1 0.3 +berlin52 52 7542 opt 1 253 < 1 0.7 +bier127 127 118282 opt 29 1330 14 19.1 +brazil58 58 25395 opt 1 458 1 2.0 +brg180 180 1950 opt 131 20012 83 52.0 +burma14 14 3323 opt 1 55 < 1 0.1 +ch130 130 6110 opt 45 2212 38 24.2 +ch150 150 6528 opt 271 4967 138 27.5 +d198 98 15780 opt 259 11371 719 92.3 +dantzig42 42 699 opt 1 171 < 1 0.8 +eil51 51 426 opt 115 1368 2 2.4 +eil76 76 538 opt 1 517 < 1 2.2 +eil101 101 629 opt 1 838 4 9.9 +fri26 26 937 opt 1 125 < 1 0.2 +gr17 17 2085 opt 1 93 < 1 0.1 +gr21 21 2707 opt 1 82 < 1 0.1 +gr24 24 1272 opt 1 137 < 1 0.2 +gr48 48 5046 opt 3 407 1 2.3 +gr96 96 55209 opt 367 5564 63 12.4 +gr120 120 6942 opt 121 2940 46 14.7 +gr137 137 69853 opt 97 1934 27 16.2 +gr202 202 40160 opt 183 4176 287 88.4 +hk48 48 11461 opt 1 322 < 1 1.1 +kroA100 100 21282 opt 57 2227 23 13.2 +kroB100 100 22141 opt 71 1891 27 15.6 +kroC100 100 20749 opt 9 1035 5 9.4 +kroD100 100 21294 opt 9 1203 10 12.3 +kroE100 100 22068 opt 323 5055 100 13.4 +kroA150 150 26524 opt 431 8069 487 50.2 +kroB150 150 26130 opt 309 12599 610 43.1 +lin105 105 14379 opt 5 910 4 7.3 +lin318 318 42029 opt 1527 25885 4972 286.4 +pr76 76 108159 opt 20537 636616 9218 128.7 * +pr107 107 44303 opt 1 3692 38 33.2 +pr124 124 59030 opt 19 1306 23 25.6 +pr136 136 96772 opt 93 2799 60 27.7 +pr144 144 58537 opt 11 1948 37 32.2 +pr152 152 73682 opt 125 3269 99 46.0 +pr226 226 80369 opt 1 6699 240 163.8 +rat99 99 1211 opt 11 467 2 5,6 +rd100 100 7910 opt 1 868 3 7.2 +st70 70 675 opt 1 688 1 3.2 +swiss42 42 1273 opt 1 231 < 1 0.8 +u159 159 42080 opt 9 1356 15 30.0 +ulysses16 16 6859 opt 1 72 < 1 0.1 +ulysses22 22 7013 opt 1 110 < 1 0.2 diff --git a/glpk-5.0/examples/tsp/build.sh b/glpk-5.0/examples/tsp/build.sh new file mode 100755 index 0000000..ab6abc1 --- /dev/null +++ b/glpk-5.0/examples/tsp/build.sh @@ -0,0 +1,8 @@ +#!/bin/sh +# +# Run this script to build TSPSOL executable. +# +# NOTE: you need to have GLPK properly installed. +# +gcc -O2 -otspsol main.c maxflow.c mincut.c misc.c tsplib.c -lglpk -lm +./tspsol sample.tsp diff --git a/glpk-5.0/examples/tsp/dantzig42.tsp b/glpk-5.0/examples/tsp/dantzig42.tsp new file mode 100644 index 0000000..15567bf --- /dev/null +++ b/glpk-5.0/examples/tsp/dantzig42.tsp @@ -0,0 +1,103 @@ +NAME : dantzig42 +TYPE : TSP +COMMENT : 42 cities (Dantzig) +DIMENSION : 42 +EDGE_WEIGHT_TYPE : EXPLICIT +EDGE_WEIGHT_FORMAT : LOWER_DIAG_ROW +DISPLAY_DATA_TYPE : TWOD_DISPLAY +EDGE_WEIGHT_SECTION + 0 8 0 39 45 0 37 47 9 0 50 49 21 15 0 61 62 21 + 20 17 0 58 60 16 17 18 6 0 59 60 15 20 26 17 10 0 + 62 66 20 25 31 22 15 5 0 81 81 40 44 50 41 35 24 20 + 0 103 107 62 67 72 63 57 46 41 23 0 108 117 66 71 77 68 + 61 51 46 26 11 0 145 149 104 108 114 106 99 88 84 63 49 40 + 0 181 185 140 144 150 142 135 124 120 99 85 76 35 0 187 191 146 + 150 156 142 137 130 125 105 90 81 41 10 0 161 170 120 124 130 115 + 110 104 105 90 72 62 34 31 27 0 142 146 101 104 111 97 91 85 + 86 75 51 59 29 53 48 21 0 174 178 133 138 143 129 123 117 118 + 107 83 84 54 46 35 26 31 0 185 186 142 143 140 130 126 124 128 + 118 93 101 72 69 58 58 43 26 0 164 165 120 123 124 106 106 105 + 110 104 86 97 71 93 82 62 42 45 22 0 137 139 94 96 94 80 + 78 77 84 77 56 64 65 90 87 58 36 68 50 30 0 117 122 77 + 80 83 68 62 60 61 50 34 42 49 82 77 60 30 62 70 49 21 + 0 114 118 73 78 84 69 63 57 59 48 28 36 43 77 72 45 27 + 59 69 55 27 5 0 85 89 44 48 53 41 34 28 29 22 23 35 + 69 105 102 74 56 88 99 81 54 32 29 0 77 80 36 40 46 34 + 27 19 21 14 29 40 77 114 111 84 64 96 107 87 60 40 37 8 + 0 87 89 44 46 46 30 28 29 32 27 36 47 78 116 112 84 66 + 98 95 75 47 36 39 12 11 0 91 93 48 50 48 34 32 33 36 + 30 34 45 77 115 110 83 63 97 91 72 44 32 36 9 15 3 0 + 105 106 62 63 64 47 46 49 54 48 46 59 85 119 115 88 66 98 + 79 59 31 36 42 28 33 21 20 0 111 113 69 71 66 51 53 56 + 61 57 59 71 96 130 126 98 75 98 85 62 38 47 53 39 42 29 + 30 12 0 91 92 50 51 46 30 34 38 43 49 60 71 103 141 136 + 109 90 115 99 81 53 61 62 36 34 24 28 20 20 0 83 85 42 + 43 38 22 26 32 36 51 63 75 106 142 140 112 93 126 108 88 60 + 64 66 39 36 27 31 28 28 8 0 89 91 55 55 50 34 39 44 + 49 63 76 87 120 155 150 123 100 123 109 86 62 71 78 52 49 39 + 44 35 24 15 12 0 95 97 64 63 56 42 49 56 60 75 86 97 + 126 160 155 128 104 128 113 90 67 76 82 62 59 49 53 40 29 25 + 23 11 0 74 81 44 43 35 23 30 39 44 62 78 89 121 159 155 + 127 108 136 124 101 75 79 81 54 50 42 46 43 39 23 14 14 21 + 0 67 69 42 41 31 25 32 41 46 64 83 90 130 164 160 133 114 + 146 134 111 85 84 86 59 52 47 51 53 49 32 24 24 30 9 0 + 74 76 61 60 42 44 51 60 66 83 102 110 147 185 179 155 133 159 + 146 122 98 105 107 79 71 66 70 70 60 48 40 36 33 25 18 0 + 57 59 46 41 25 30 36 47 52 71 93 98 136 172 172 148 126 158 + 147 124 121 97 99 71 65 59 63 67 62 46 38 37 43 23 13 17 + 0 45 46 41 34 20 34 38 48 53 73 96 99 137 176 178 151 131 + 163 159 135 108 102 103 73 67 64 69 75 72 54 46 49 54 34 24 + 29 12 0 35 37 35 26 18 34 36 46 51 70 93 97 134 171 176 + 151 129 161 163 139 118 102 101 71 65 65 70 84 78 58 50 56 62 + 41 32 38 21 9 0 29 33 30 21 18 35 33 40 45 65 87 91 + 117 166 171 144 125 157 156 139 113 95 97 67 60 62 67 79 82 62 + 53 59 66 45 38 45 27 15 6 0 3 11 41 37 47 57 55 58 + 63 83 105 109 147 186 188 164 144 176 182 161 134 119 116 86 78 84 + 88 101 108 88 80 86 92 71 64 71 54 41 32 25 0 5 12 55 + 41 53 64 61 61 66 84 111 113 150 186 192 166 147 180 188 167 140 + 124 119 90 87 90 94 107 114 77 86 92 98 80 74 77 60 48 38 + 32 6 0 +DISPLAY_DATA_SECTION + 1 170.0 85.0 + 2 166.0 88.0 + 3 133.0 73.0 + 4 140.0 70.0 + 5 142.0 55.0 + 6 126.0 53.0 + 7 125.0 60.0 + 8 119.0 68.0 + 9 117.0 74.0 + 10 99.0 83.0 + 11 73.0 79.0 + 12 72.0 91.0 + 13 37.0 94.0 + 14 6.0 106.0 + 15 3.0 97.0 + 16 21.0 82.0 + 17 33.0 67.0 + 18 4.0 66.0 + 19 3.0 42.0 + 20 27.0 33.0 + 21 52.0 41.0 + 22 57.0 59.0 + 23 58.0 66.0 + 24 88.0 65.0 + 25 99.0 67.0 + 26 95.0 55.0 + 27 89.0 55.0 + 28 83.0 38.0 + 29 85.0 25.0 + 30 104.0 35.0 + 31 112.0 37.0 + 32 112.0 24.0 + 33 113.0 13.0 + 34 125.0 30.0 + 35 135.0 32.0 + 36 147.0 18.0 + 37 147.5 36.0 + 38 154.5 45.0 + 39 157.0 54.0 + 40 158.0 61.0 + 41 172.0 82.0 + 42 174.0 87.0 +EOF diff --git a/glpk-5.0/examples/tsp/gr120.tsp b/glpk-5.0/examples/tsp/gr120.tsp new file mode 100644 index 0000000..6322489 --- /dev/null +++ b/glpk-5.0/examples/tsp/gr120.tsp @@ -0,0 +1,534 @@ +NAME: gr120 +TYPE: TSP +COMMENT: 120 cities in Germany (Groetschel) +DIMENSION: 120 +EDGE_WEIGHT_TYPE: EXPLICIT +EDGE_WEIGHT_FORMAT: LOWER_DIAG_ROW +DISPLAY_DATA_TYPE: TWOD_DISPLAY +EDGE_WEIGHT_SECTION + 0 534 0 434 107 0 294 241 148 0 593 190 137 374 0 409 351 240 + 190 258 0 332 320 232 139 494 310 0 232 354 261 113 372 188 208 0 + 464 124 88 171 202 328 188 284 0 566 508 397 347 331 171 467 345 485 + 0 552 80 127 259 234 365 249 372 61 522 0 802 316 336 509 222 470 + 588 584 392 502 386 0 633 432 479 552 586 723 417 621 411 874 354 738 + 0 257 641 541 407 706 522 184 391 372 679 433 915 390 0 187 577 477 + 337 636 452 375 321 507 609 595 845 572 196 0 91 450 357 210 509 325 + 248 141 380 482 468 718 661 228 158 0 412 624 531 384 690 506 210 408 + 398 663 459 892 227 169 351 383 0 400 752 659 512 818 634 338 536 526 + 791 587 1020 524 151 270 371 167 0 472 805 712 565 871 687 391 589 579 + 844 640 1073 413 257 342 443 220 57 0 389 665 572 425 731 547 251 449 + 439 704 500 933 274 146 328 360 53 112 165 0 610 76 183 317 192 442 + 396 430 202 515 141 233 492 723 653 526 700 828 881 741 0 340 730 630 + 490 789 605 394 474 582 762 643 998 444 125 185 311 223 67 139 168 806 + 0 510 152 134 217 248 370 175 330 46 527 72 438 380 359 553 426 385 + 513 566 426 213 569 0 153 447 354 207 470 280 246 113 377 437 465 715 + 659 345 275 98 500 488 560 477 523 428 423 0 511 844 751 604 910 726 + 430 628 618 883 679 1112 407 296 381 482 259 96 39 204 920 178 605 599 + 0 269 283 190 42 332 148 169 63 213 305 301 544 582 382 312 185 365 + 493 546 406 359 465 259 170 585 0 525 157 95 232 42 257 316 355 160 + 330 167 254 521 638 568 441 615 743 796 656 188 721 206 438 835 274 0 + 150 539 446 299 598 414 279 283 469 571 557 807 488 112 96 120 267 255 + 327 244 615 195 515 237 366 274 530 0 80 507 414 267 566 382 305 251 + 437 539 525 775 572 196 88 77 351 339 411 328 583 279 483 205 450 242 + 498 63 0 130 520 427 280 579 395 318 264 450 552 538 788 543 167 59 + 101 322 310 382 299 596 250 496 218 412 255 511 56 25 0 401 791 691 + 551 850 666 474 535 662 823 723 1059 524 238 238 372 303 138 126 248 867 + 101 649 489 165 526 782 256 340 311 0 134 524 431 284 583 399 314 268 + 454 556 542 792 530 154 63 105 309 297 369 286 600 237 500 222 408 259 + 515 34 29 22 298 0 666 942 849 702 1008 824 528 726 716 981 777 1210 + 446 423 605 637 357 280 217 279 1018 336 703 754 194 683 933 521 605 576 + 416 563 0 259 281 188 40 364 180 142 72 211 337 299 549 555 372 302 + 175 338 466 519 379 357 455 257 172 558 27 272 264 232 245 516 249 656 + 0 505 447 336 286 354 110 406 284 424 70 461 566 819 618 548 421 602 + 730 783 643 538 701 466 376 822 244 353 509 478 491 762 494 920 276 0 + 453 358 247 234 265 59 354 232 335 182 372 477 767 566 496 369 550 678 + 731 591 449 649 377 324 770 192 264 458 426 439 710 443 868 224 95 0 + 627 334 251 408 168 239 528 406 300 166 348 331 700 740 670 504 724 852 + 905 765 360 823 346 504 944 366 179 632 600 613 884 617 1042 398 162 177 + 0 339 275 187 94 313 281 45 184 143 438 204 543 458 229 382 250 255 + 350 436 296 351 439 130 248 475 136 271 286 312 325 519 321 573 102 377 + 325 425 0 710 283 254 491 117 375 611 489 319 354 351 202 679 823 753 + 626 807 935 988 848 272 906 365 587 1027 449 159 715 683 696 967 700 1125 + 481 345 337 183 430 0 243 353 260 113 419 235 89 133 283 392 368 621 + 502 209 286 159 285 413 466 326 429 439 226 157 505 94 344 190 216 229 + 500 225 603 67 331 279 453 96 536 0 376 520 427 280 586 402 106 300 + 294 559 355 788 340 146 322 306 112 240 293 153 596 296 281 338 332 261 + 511 220 322 293 376 253 430 234 498 446 620 151 703 181 0 449 594 501 + 354 660 476 180 378 368 633 429 862 256 206 388 420 45 204 257 101 670 + 260 355 537 296 335 585 304 388 359 340 346 394 308 572 520 694 225 777 + 255 82 0 505 781 688 541 847 663 367 565 555 820 616 1049 289 262 444 + 476 196 119 136 118 857 175 542 593 129 522 772 360 444 415 255 402 161 + 495 759 707 881 412 964 442 269 233 0 322 611 518 371 677 493 197 395 + 372 650 446 879 359 69 261 293 94 142 224 84 687 146 372 410 263 352 + 602 177 261 232 247 219 361 325 589 537 711 242 794 272 99 106 200 0 + 185 575 482 335 634 450 231 319 419 607 480 843 462 86 124 156 241 226 + 298 218 651 166 406 273 337 310 566 40 124 95 227 82 495 300 546 494 + 668 276 751 207 212 278 334 151 0 353 638 545 398 704 520 224 422 412 + 677 473 906 282 110 292 324 61 125 178 38 714 181 399 441 217 379 629 + 208 292 263 261 250 315 352 616 564 738 269 821 299 126 82 154 46 182 + 0 324 314 191 106 275 91 225 104 244 248 332 487 638 437 367 240 421 + 549 602 462 390 520 290 238 641 64 227 329 297 310 581 314 739 95 187 + 135 309 196 392 150 317 391 578 408 365 435 0 388 234 127 124 219 113 + 289 168 215 270 254 431 606 501 431 304 485 613 666 526 310 584 232 302 + 705 128 163 393 361 374 645 378 803 159 209 120 219 229 336 214 381 455 + 642 472 429 499 64 0 447 664 571 424 730 546 250 448 438 703 499 932 + 188 204 386 418 36 202 255 88 740 258 425 535 294 405 655 302 386 357 + 338 344 392 378 642 590 764 295 847 325 152 68 231 130 276 96 461 525 + 0 360 606 513 366 672 488 192 390 380 645 441 874 273 117 299 331 46 + 150 203 63 682 206 367 448 242 347 597 215 299 270 286 257 340 320 584 + 532 706 237 789 267 94 58 179 48 189 31 403 467 82 0 605 133 180 + 312 287 418 264 425 112 575 55 439 313 448 648 520 474 602 655 515 193 + 658 89 517 694 354 220 610 577 591 738 595 792 352 514 425 401 219 404 + 421 370 444 631 461 495 488 385 307 514 456 0 656 932 839 692 998 814 + 518 716 706 971 767 1200 444 413 595 627 347 270 200 269 1008 326 693 744 + 177 673 923 511 595 566 406 553 42 646 910 858 1032 563 1115 593 420 384 + 151 351 485 305 729 793 382 330 782 0 573 113 101 280 79 329 359 403 + 163 402 157 235 509 686 616 489 663 791 844 704 131 769 209 486 883 322 + 57 578 546 559 830 563 981 320 425 336 236 314 176 392 559 633 820 650 + 614 677 353 220 603 645 210 971 0 293 384 274 143 319 129 262 60 314 + 286 402 531 675 451 381 201 458 586 639 499 460 534 360 151 678 101 318 + 343 311 324 595 328 776 132 225 173 353 233 436 187 354 428 615 445 379 + 472 83 147 498 440 455 766 375 0 372 283 199 153 229 39 273 151 324 + 196 324 441 686 485 415 288 469 597 650 510 413 568 370 241 689 111 228 + 377 345 358 629 362 787 143 135 83 263 244 346 198 365 439 626 456 413 + 483 54 72 509 451 377 777 300 90 0 330 479 386 239 545 361 65 259 + 253 518 314 747 378 119 276 260 150 278 331 191 555 334 240 297 370 220 + 470 174 276 247 414 207 468 193 457 405 579 110 662 140 46 120 307 126 + 166 164 276 340 190 132 329 458 518 313 324 0 610 297 234 391 107 275 + 511 389 322 248 331 254 693 723 653 526 707 835 888 748 302 806 368 487 + 927 349 149 615 583 596 867 600 1025 381 239 231 77 408 106 436 603 677 + 864 694 651 721 292 236 747 689 384 1015 186 336 246 562 0 598 874 781 + 634 940 756 460 658 648 913 709 1142 370 355 537 569 289 212 197 211 950 + 268 635 686 157 615 865 453 537 508 348 495 84 588 852 800 974 505 1057 + 535 362 326 93 293 427 247 671 735 324 272 724 85 913 708 719 400 957 + 0 214 604 504 364 663 479 402 348 534 636 622 872 599 223 49 185 378 + 319 391 355 680 234 580 302 430 339 595 123 115 86 287 90 632 329 575 + 523 697 409 780 313 349 415 471 288 151 319 394 458 413 326 675 622 643 + 408 442 303 680 564 0 154 401 308 161 460 276 199 78 331 433 419 669 + 612 298 228 63 453 441 513 430 477 381 377 47 552 136 392 190 158 171 + 442 175 707 126 372 320 494 201 577 110 291 490 546 363 226 396 191 255 + 488 401 471 697 440 138 239 250 477 639 255 0 70 464 371 224 523 339 + 262 208 394 496 482 732 567 191 121 27 346 334 406 323 540 274 440 162 + 445 199 455 83 47 64 335 68 600 189 435 383 557 269 640 173 295 383 + 439 256 119 287 254 378 381 294 534 590 503 268 302 249 540 532 148 115 + 0 606 349 266 387 183 216 507 385 354 147 363 357 715 719 649 522 703 + 831 884 744 375 802 400 483 923 345 194 611 579 592 863 596 1021 377 139 + 154 22 447 209 432 599 673 860 690 647 717 288 232 743 685 416 1011 262 + 332 242 558 103 953 676 473 536 0 631 228 175 412 38 296 532 410 240 + 306 272 210 640 744 674 547 728 856 909 769 233 827 286 508 948 370 80 + 636 604 617 888 621 1046 402 293 261 138 351 79 457 624 698 885 715 672 + 742 313 257 768 710 325 1036 117 357 267 583 69 978 701 498 561 153 0 + 642 129 176 349 121 369 428 472 232 428 226 187 578 755 685 558 732 860 + 913 773 98 838 278 555 952 391 132 647 615 628 899 632 1050 389 465 376 + 260 383 161 461 628 702 889 719 683 746 422 330 772 714 279 1040 75 430 + 340 587 191 982 712 509 572 275 122 0 503 779 686 539 845 661 365 563 + 553 818 614 1047 245 260 442 474 141 151 168 116 855 207 540 591 162 520 + 770 358 442 413 287 400 201 493 757 705 879 410 962 440 267 231 44 198 + 332 152 576 640 174 177 629 199 818 613 624 305 862 125 469 544 437 858 + 883 887 0 372 762 662 522 821 637 456 506 644 794 705 1030 506 209 209 + 343 285 120 108 230 838 72 631 460 147 497 753 227 311 282 29 269 398 + 487 733 681 855 501 938 471 354 322 237 218 198 243 552 616 320 268 720 + 388 801 566 600 396 838 330 258 413 306 834 859 870 269 0 641 348 265 + 422 152 262 542 420 314 189 362 313 714 754 684 557 738 866 919 779 344 + 837 360 518 958 380 193 646 614 627 898 631 1056 412 185 200 23 439 165 + 467 634 708 895 725 682 752 323 233 778 720 415 1046 231 367 277 593 59 + 988 711 508 571 45 122 244 893 869 0 561 837 744 597 903 719 423 621 + 611 876 672 1105 311 318 500 532 252 175 192 174 913 231 598 649 186 578 + 828 416 500 471 311 458 154 551 815 763 937 468 1020 498 325 289 65 256 + 390 210 634 698 287 235 687 152 876 671 682 363 920 77 527 602 495 916 + 941 945 66 293 951 0 478 754 661 514 820 636 340 538 528 793 589 1022 + 261 235 417 449 116 132 149 91 830 188 515 566 159 495 745 333 417 388 + 268 375 226 468 732 680 854 385 937 415 242 206 55 173 307 127 551 615 + 149 152 604 224 793 588 599 280 837 150 444 519 412 833 858 862 25 250 + 868 91 0 247 316 223 76 360 176 170 39 246 333 334 572 583 360 290 + 163 366 494 547 407 392 443 292 133 586 37 307 252 220 233 504 237 684 + 34 272 220 394 146 477 95 262 336 523 353 288 380 92 156 406 348 387 + 674 355 83 139 221 377 616 317 92 177 373 398 424 521 475 408 579 496 + 0 317 336 212 95 289 105 218 79 266 262 354 501 631 430 360 233 414 + 542 595 455 412 513 312 213 634 53 248 397 290 378 574 382 732 88 201 + 149 323 189 406 143 310 384 571 401 358 428 21 85 454 396 407 722 375 + 62 68 269 306 664 387 184 247 302 327 444 569 545 337 627 544 70 0 + 272 382 289 142 448 264 84 162 234 421 295 650 497 180 315 188 280 408 + 461 321 458 464 221 186 500 123 373 193 245 258 544 228 598 96 360 308 + 482 91 565 29 142 250 437 267 159 294 179 243 320 262 310 588 421 216 + 227 96 465 530 342 139 209 461 486 490 435 526 496 493 410 124 172 0 + 575 276 199 356 86 240 476 354 287 250 296 266 672 688 618 491 672 800 + 853 713 289 771 333 452 892 314 127 580 548 561 832 565 990 346 237 205 + 82 373 141 401 568 642 829 659 616 686 257 201 712 654 349 980 165 301 + 211 527 35 922 645 442 505 97 56 178 827 803 66 885 802 342 271 430 + 0 219 479 386 239 545 361 167 259 317 518 378 747 474 83 172 149 253 + 235 339 230 555 228 304 263 378 220 470 79 139 134 289 112 507 193 457 + 405 579 174 662 126 154 290 346 136 621 194 276 340 288 201 393 497 518 + 313 324 108 562 439 199 216 153 558 583 587 344 260 593 402 319 221 269 + 97 527 0 293 683 583 443 742 558 238 427 426 715 487 951 352 50 232 + 264 131 101 174 108 759 105 413 381 213 418 674 148 232 203 206 190 385 + 408 654 602 776 283 859 248 140 168 224 41 122 72 473 537 166 89 502 + 375 722 487 521 167 759 317 259 334 227 755 780 791 222 177 790 280 197 + 396 466 219 724 134 0 54 529 429 289 588 404 327 273 459 561 547 797 + 595 219 92 82 374 362 434 351 605 302 505 227 473 264 520 119 31 43 + 363 58 628 254 500 448 622 334 705 238 327 411 467 284 147 315 319 383 + 409 322 600 618 568 333 367 281 605 560 84 180 53 601 626 637 465 334 + 636 523 440 242 312 267 570 170 255 0 648 188 182 355 68 316 434 430 + 238 362 232 154 584 761 691 564 738 866 919 779 177 844 284 561 958 390 + 100 653 621 634 905 638 1056 395 412 323 194 389 95 467 634 708 895 725 + 689 752 333 277 778 720 285 1046 81 377 287 593 125 988 718 515 578 209 + 56 66 893 876 178 951 868 418 347 496 112 593 797 643 0 211 601 501 + 361 660 476 231 345 479 633 480 869 466 74 81 182 243 189 261 220 677 + 129 406 299 300 336 592 105 150 121 190 108 497 326 572 520 694 276 777 + 310 204 280 336 143 37 184 391 455 278 191 495 487 640 405 439 166 677 + 429 160 252 145 673 698 709 334 161 708 392 309 314 384 196 642 99 125 + 173 715 0 568 844 751 604 910 726 430 628 618 883 679 1112 348 325 507 + 539 259 182 150 181 920 238 605 656 127 585 835 423 507 478 318 465 98 + 558 822 770 944 475 1027 505 332 296 63 263 397 217 641 705 294 242 694 + 96 883 678 689 370 927 30 534 609 502 923 948 952 103 300 958 56 120 + 586 634 500 892 409 287 530 958 399 0 497 150 67 204 70 257 288 327 + 155 335 164 282 516 610 540 413 587 715 768 628 216 693 201 410 807 246 + 28 502 470 483 754 487 905 244 353 264 184 243 187 316 483 557 744 574 + 538 601 199 135 627 569 217 895 85 292 228 442 167 837 567 364 427 199 + 108 160 742 725 198 800 717 279 220 345 132 442 646 492 128 564 807 0 + 290 680 580 440 739 555 317 424 505 712 566 948 506 139 98 261 285 155 + 227 229 756 88 492 378 266 415 671 144 176 164 140 136 424 405 651 599 + 773 362 856 389 290 322 263 195 116 226 470 534 320 243 581 414 719 484 + 518 252 756 356 147 331 224 752 777 788 295 111 787 319 276 393 463 275 + 721 178 154 190 794 79 326 643 0 475 65 42 182 137 282 261 295 65 + 439 85 321 437 588 518 391 565 693 746 606 141 671 111 388 785 224 95 + 480 448 461 732 465 883 222 378 289 272 216 254 294 461 535 722 552 516 + 579 255 169 605 547 138 873 92 325 241 420 255 815 545 342 405 287 175 + 161 720 703 286 778 695 257 277 323 220 420 624 470 167 542 785 88 621 + 0 654 341 278 435 151 319 555 433 366 266 375 298 755 767 697 570 751 + 879 932 792 346 850 412 531 971 393 193 659 627 640 911 644 1069 425 262 + 254 100 452 103 480 647 721 908 738 695 765 336 280 791 733 428 1059 230 + 380 290 606 44 1001 724 521 584 122 113 235 906 882 77 964 881 421 350 + 509 79 606 803 649 169 721 971 211 800 299 0 445 387 276 226 294 50 + 346 224 364 125 410 506 759 558 488 361 542 670 723 583 478 641 406 316 + 762 184 293 450 418 431 702 435 860 216 64 57 193 317 411 271 438 512 + 699 529 486 556 127 149 582 524 454 850 365 165 75 397 311 792 515 312 + 375 170 332 405 697 673 216 755 672 212 141 300 276 397 594 440 352 512 + 762 293 591 318 355 0 375 765 665 525 824 640 384 509 572 797 633 1033 + 434 160 245 346 213 48 59 158 841 42 559 463 98 500 756 230 314 285 + 90 272 326 490 736 684 858 429 941 474 286 250 165 169 201 171 555 619 + 248 196 648 316 804 569 603 324 841 258 294 416 309 837 862 873 197 72 + 872 221 178 478 548 454 832 263 128 337 879 164 228 728 130 706 885 676 + 0 268 658 558 418 717 533 231 402 419 690 480 926 420 53 138 239 199 + 132 204 202 734 72 406 356 243 393 649 123 207 178 185 165 401 383 629 + 577 751 276 834 367 204 236 240 109 86 140 448 512 234 157 495 391 697 + 462 496 166 734 333 187 309 202 730 755 766 272 156 765 296 253 371 441 + 227 699 130 68 230 772 57 303 627 86 599 778 569 107 0 261 519 426 + 279 585 401 141 299 329 558 390 787 422 43 200 232 211 183 294 178 595 + 162 316 342 333 260 510 98 200 171 275 131 455 233 497 445 619 186 702 + 166 114 248 294 67 90 142 316 380 246 159 405 445 558 353 364 76 602 + 387 227 295 195 598 623 627 292 246 633 350 267 261 309 137 567 69 82 + 223 633 90 357 482 176 460 646 437 197 90 0 710 184 271 417 239 487 + 496 530 300 546 249 168 616 823 753 626 800 928 981 841 108 906 321 623 +1020 459 241 715 683 696 967 700 1118 457 583 494 378 451 279 529 696 770 + 957 787 751 814 490 448 840 782 310 1108 184 560 458 655 309 1050 780 577 + 640 393 240 118 955 938 362 1013 930 492 512 558 296 655 859 705 179 777 +1020 269 856 229 353 523 941 834 695 0 396 291 180 177 198 53 297 175 + 268 218 305 410 710 509 439 312 493 621 674 534 382 592 310 273 713 135 + 197 401 369 382 653 386 811 167 157 67 215 268 315 222 389 463 650 480 + 437 507 78 53 533 475 358 801 269 122 32 348 215 743 466 263 326 206 + 236 309 648 624 238 706 623 163 92 251 180 348 545 391 256 463 713 197 + 542 222 259 97 627 520 388 427 0 295 424 278 183 308 118 302 100 354 + 275 442 520 715 491 421 241 498 626 679 539 500 574 400 191 718 141 307 + 383 351 364 635 368 816 172 214 162 342 273 425 227 394 468 655 485 419 + 512 114 151 538 480 495 806 364 40 79 353 325 748 448 178 308 321 346 + 419 653 606 356 711 628 123 93 256 290 353 527 373 366 445 718 281 524 + 365 369 154 609 502 393 537 111 0 651 927 834 687 993 809 513 711 701 + 966 762 1195 407 408 590 622 342 265 282 264 1003 321 688 739 276 668 918 + 506 590 561 401 548 174 641 905 853 1027 558 1110 588 415 379 155 346 480 + 300 724 788 377 325 777 173 966 761 772 453 1010 90 617 692 585 1006 1031 +1035 162 383 1041 96 187 669 717 583 975 492 370 613 1041 482 112 890 409 + 868 1054 845 311 386 440 1103 796 801 0 175 565 472 325 624 440 311 309 + 495 597 583 833 504 128 76 146 283 271 343 260 641 211 541 263 382 300 + 556 32 76 47 272 30 537 290 536 484 658 318 741 222 256 320 376 193 + 56 224 355 419 318 231 636 527 604 369 403 210 641 469 103 216 109 637 + 662 673 374 243 672 432 349 278 423 225 606 104 164 99 679 57 439 528 + 112 506 685 476 246 114 134 741 427 409 522 0 585 67 146 292 135 385 + 371 405 175 458 147 249 499 698 628 501 675 803 856 716 57 781 221 498 + 895 334 131 590 558 571 842 575 993 332 481 392 303 326 215 404 571 645 + 832 662 626 689 365 261 715 657 200 983 74 435 356 530 245 925 655 452 + 515 318 176 62 830 813 287 888 805 367 387 433 232 530 734 580 120 652 + 895 159 731 104 289 421 816 709 570 121 325 438 978 616 0 250 640 540 + 400 699 515 277 384 465 672 526 908 466 99 89 221 245 178 250 220 716 + 96 452 338 289 375 631 105 189 160 151 147 447 365 611 559 733 322 816 + 349 250 282 286 155 76 186 430 494 280 203 541 437 679 444 478 212 716 + 379 138 291 184 712 737 748 318 122 747 342 299 353 423 235 681 138 114 + 212 754 39 349 603 40 581 760 551 138 46 136 816 502 484 432 96 691 + 0 717 221 251 424 137 385 503 499 307 417 301 95 653 830 760 633 807 + 935 988 848 190 913 353 631 1027 459 169 722 690 703 974 707 1125 464 481 + 392 246 458 117 536 703 777 964 794 758 821 402 346 847 789 354 1115 150 + 446 356 662 169 1057 787 584 647 272 125 92 962 945 228 1020 937 487 416 + 565 181 662 866 712 69 784 1027 197 863 236 213 421 948 841 702 162 325 + 435 1110 748 154 823 0 246 454 361 213 373 183 332 130 384 340 472 585 + 745 472 402 237 528 656 709 569 530 555 430 167 748 171 372 364 332 345 + 616 349 846 202 279 227 407 303 490 257 424 498 685 515 400 542 157 221 + 568 510 525 836 429 70 144 383 390 778 429 174 289 386 411 484 683 587 + 421 741 658 153 132 286 355 383 508 354 431 426 748 346 505 395 434 219 + 590 483 423 630 176 65 831 390 505 465 500 0 788 302 322 495 208 456 + 574 570 378 488 372 23 724 901 831 704 818 1006 1059 919 203 984 424 701 +1098 530 240 793 761 774 1045 778 1196 535 552 463 317 529 188 607 774 848 +1035 865 829 892 473 417 918 860 425 1186 221 517 427 733 240 1128 858 655 + 718 343 196 173 1033 1016 299 1091 1008 558 487 636 252 733 937 783 154 855 +1098 268 934 307 284 492 1019 912 773 138 396 506 1181 819 235 894 81 571 + 0 426 596 503 356 662 478 182 380 370 635 431 864 253 183 365 397 27 + 181 234 82 672 237 357 514 273 337 587 281 365 336 317 323 371 310 574 + 522 696 227 779 257 84 19 210 83 255 67 393 457 65 35 446 361 635 + 430 441 122 679 303 392 467 360 675 700 704 208 299 710 266 183 338 386 + 252 644 267 145 388 710 257 273 559 299 537 723 514 227 213 225 772 465 + 470 355 297 647 259 779 500 850 0 596 575 330 377 237 179 497 375 552 + 100 589 407 941 709 639 512 693 821 874 734 421 792 460 467 913 335 236 + 601 569 582 853 586 1011 367 91 117 72 468 259 422 589 663 850 680 637 + 707 278 221 733 675 642 1001 308 316 212 548 153 943 666 463 526 47 212 + 334 848 824 95 906 823 363 292 451 156 548 745 591 268 663 913 241 742 + 506 172 133 827 720 588 452 185 305 996 627 364 702 322 370 393 665 0 + 634 910 817 670 976 792 496 694 684 949 745 1178 414 391 573 605 325 248 + 185 247 986 304 671 722 162 651 901 489 573 544 384 531 32 624 888 836 +1010 541 1093 571 398 362 129 329 463 283 707 771 360 308 760 33 949 744 + 755 436 983 52 600 675 568 989 1014 1018 169 366 1024 122 194 652 700 566 + 958 475 353 596 1024 465 66 873 392 851 1037 828 294 369 423 1086 779 784 + 142 505 961 415 1003 814 1164 339 979 0 507 209 111 201 139 172 408 286 + 213 329 223 351 575 620 550 423 604 732 785 645 275 703 259 384 824 202 + 87 512 480 493 764 497 922 278 268 141 173 252 256 333 500 574 761 591 + 548 618 138 74 644 586 276 912 144 233 143 459 156 854 577 374 437 208 + 177 219 759 735 187 817 734 274 159 362 121 459 656 502 197 574 824 59 + 653 147 200 208 738 631 499 328 112 222 907 538 218 613 266 287 337 576 + 208 890 0 463 186 79 155 157 161 251 216 167 318 206 369 558 576 506 + 379 553 681 734 594 262 659 213 376 773 176 115 468 436 449 720 453 871 + 210 257 168 219 206 274 282 449 523 710 540 504 567 112 48 593 535 259 + 861 172 195 120 408 202 803 533 330 393 254 195 247 708 691 233 766 683 + 204 133 311 167 408 612 458 215 530 773 87 609 121 246 197 694 587 448 + 350 101 199 856 494 225 569 284 269 355 525 251 839 46 0 408 169 105 + 116 242 298 131 229 57 455 118 437 468 315 451 325 341 469 522 382 245 + 525 72 322 561 158 200 413 382 394 605 398 659 155 394 305 344 86 359 + 228 237 311 498 328 362 355 188 160 381 323 169 649 208 259 269 196 327 + 591 478 276 339 391 280 277 496 587 358 554 471 191 211 177 292 260 369 + 403 283 362 561 172 448 110 371 334 515 362 272 345 238 299 644 439 220 + 408 352 329 423 313 388 627 183 137 0 529 389 278 310 236 127 430 308 + 366 125 403 447 755 642 572 445 626 754 807 667 420 725 408 400 846 268 + 235 534 502 515 786 519 944 300 80 68 112 401 299 355 522 596 783 613 + 570 640 211 169 666 608 456 934 307 249 225 481 193 876 599 396 459 89 + 231 353 781 757 135 839 756 296 225 384 175 481 678 524 287 596 846 240 + 675 320 212 84 760 653 521 471 133 238 929 560 363 635 362 303 433 598 + 52 912 156 199 336 0 192 412 319 172 477 293 160 154 342 450 430 680 + 573 228 235 108 383 371 443 360 488 311 388 167 482 153 403 119 165 178 + 372 154 637 126 389 337 511 162 594 71 207 420 476 232 136 324 209 273 + 418 331 482 627 451 246 256 161 494 569 262 120 110 490 515 590 474 343 + 525 532 449 127 202 74 459 96 264 187 526 182 539 375 261 353 538 329 + 346 239 165 588 280 286 622 151 463 221 595 294 666 397 480 605 391 341 + 287 413 0 529 286 231 310 177 165 430 308 319 182 328 379 680 642 572 + 445 626 754 807 667 344 725 365 406 846 268 159 534 502 515 786 519 944 + 300 137 106 75 370 231 355 522 596 783 613 570 640 211 155 666 608 381 + 934 231 255 165 481 125 876 599 396 459 77 155 247 781 757 89 839 756 + 296 225 384 99 481 678 524 211 596 846 164 675 252 148 168 760 653 521 + 365 137 244 929 560 287 635 294 309 365 598 80 912 131 177 314 87 413 + 0 434 710 617 470 776 592 296 494 484 749 545 978 346 191 373 405 125 + 82 142 47 786 145 471 522 145 451 701 289 373 344 225 331 238 424 688 + 636 810 341 893 371 198 162 77 129 263 83 507 571 160 108 560 228 749 + 544 555 236 793 170 400 475 368 789 814 818 76 207 824 133 51 452 500 + 366 758 275 153 396 824 265 140 673 233 651 837 628 135 210 223 886 579 + 584 223 305 761 241 893 614 964 139 779 206 690 639 427 712 405 712 0 + 535 811 718 571 877 693 397 595 585 850 646 1079 336 292 474 506 226 94 + 76 129 887 154 572 623 75 552 802 390 474 445 202 432 175 525 789 737 + 911 442 994 472 299 263 58 230 364 184 608 672 261 209 661 160 850 645 + 656 337 894 140 501 576 469 890 915 919 91 184 925 113 88 553 601 467 + 859 376 176 497 925 276 110 774 242 752 938 729 123 219 324 987 680 685 + 205 406 862 265 994 715 1065 240 880 143 791 740 528 813 506 813 82 0 + 630 108 191 337 165 424 416 450 220 483 188 190 540 743 673 546 720 848 + 901 761 43 826 266 543 940 379 161 635 603 616 887 620 1038 877 520 431 + 315 371 216 449 616 690 877 707 671 734 410 306 760 702 241 1028 104 480 + 395 575 246 970 700 497 560 348 177 55 875 858 299 933 850 412 432 478 + 233 575 779 625 121 697 940 189 776 149 290 460 861 754 615 80 364 474 +1023 661 41 736 147 550 160 692 394 1006 248 270 265 393 508 317 806 907 + 0 446 252 145 227 162 111 347 225 233 268 272 374 624 559 489 362 543 + 671 724 584 346 642 279 323 763 185 161 451 419 432 703 436 861 217 207 + 141 162 272 279 272 439 513 700 530 487 557 128 50 583 525 325 851 233 + 172 82 398 179 793 516 313 376 175 200 273 698 674 176 756 673 213 142 + 301 144 398 595 441 220 513 763 108 592 187 223 147 677 570 438 391 51 + 161 846 477 289 552 289 226 360 515 167 829 49 66 203 115 330 98 629 + 730 319 0 166 518 425 277 437 247 336 114 448 404 536 649 749 435 365 + 150 590 578 650 567 594 518 494 90 689 235 436 402 295 383 579 387 844 + 189 343 291 471 295 554 247 428 627 683 500 363 531 221 285 625 538 589 + 834 493 134 208 372 454 776 392 137 252 450 475 548 681 550 485 739 656 + 150 196 276 419 353 471 317 495 389 746 410 468 459 498 283 553 446 432 + 694 240 129 829 353 569 428 564 80 635 604 434 812 351 333 393 367 257 + 373 612 713 614 290 0 471 313 202 252 166 99 372 250 290 210 358 378 + 679 584 514 387 568 696 749 609 350 667 332 348 788 210 165 476 444 457 + 728 461 886 242 156 61 135 311 276 297 464 538 725 555 512 582 153 93 + 608 550 380 876 237 197 107 423 170 818 541 338 401 147 191 277 723 699 + 149 781 698 238 167 326 135 423 620 466 224 538 788 139 617 244 214 118 + 702 595 462 395 67 186 871 502 293 577 293 251 364 540 128 854 80 123 + 260 76 355 70 654 755 323 39 315 0 442 718 625 478 784 600 304 502 + 492 757 553 986 300 199 381 413 81 137 184 53 794 209 479 530 194 459 + 709 297 381 352 285 339 261 432 696 644 818 349 901 379 206 126 90 137 + 271 91 515 579 111 116 568 259 757 552 563 244 801 185 408 483 376 797 + 822 826 60 267 832 126 35 460 508 374 766 283 161 404 832 273 155 681 + 293 659 845 636 195 270 231 894 587 592 222 313 769 301 901 622 972 108 + 787 229 698 647 435 720 413 720 55 123 814 637 620 662 0 523 230 147 + 304 81 188 424 302 235 255 174 293 596 636 566 439 620 748 801 661 265 + 719 281 400 840 262 75 528 496 509 780 513 938 294 284 195 104 321 193 + 349 516 590 777 607 564 634 205 149 660 602 297 928 147 249 159 475 87 + 870 593 390 453 119 108 192 775 751 118 833 750 290 219 378 52 475 672 + 518 139 590 840 80 669 168 131 224 754 647 515 310 128 238 923 554 208 + 629 208 303 279 592 161 906 69 115 240 160 407 84 706 807 238 92 367 + 87 714 0 566 45 139 273 228 383 352 386 121 540 60 314 411 679 609 + 482 656 784 837 697 81 762 132 479 876 315 189 571 539 552 823 556 974 + 313 479 390 366 307 308 385 552 626 813 643 607 670 346 266 696 638 112 + 964 158 416 342 511 335 906 636 433 496 381 266 155 811 794 380 869 786 + 348 368 414 314 511 715 561 213 633 876 182 712 97 379 419 797 690 551 + 189 323 456 959 597 93 672 247 486 284 628 607 942 244 218 178 421 444 + 346 742 843 124 284 550 345 750 262 0 235 313 220 73 371 187 168 43 + 243 344 331 583 581 348 278 151 364 492 545 405 389 431 289 137 584 48 + 304 240 208 221 492 225 682 32 283 231 405 144 488 93 260 334 521 351 + 276 378 103 167 404 346 384 672 352 95 150 219 388 614 305 94 165 384 + 409 421 519 463 419 577 494 12 92 122 353 219 384 230 429 302 584 276 + 381 254 432 223 466 359 259 489 174 135 667 266 364 341 498 165 569 336 + 374 650 285 215 188 307 115 307 450 551 409 224 154 249 458 301 345 0 + 432 822 722 582 881 697 441 566 629 854 690 1090 491 217 302 403 270 105 + 69 215 898 99 616 520 108 557 813 287 371 342 77 329 383 547 793 741 + 915 486 998 531 343 307 222 226 258 228 612 676 305 253 705 373 861 626 + 660 381 898 315 351 473 366 894 919 930 254 66 929 278 235 535 605 511 + 863 320 185 394 936 221 285 785 177 763 942 733 57 164 254 998 684 666 + 368 303 873 195 1005 647 1076 284 884 351 795 751 572 817 403 817 192 145 + 819 734 610 759 252 811 854 523 0 435 653 560 413 719 535 239 437 427 + 692 488 921 220 192 374 406 29 190 243 64 729 246 414 523 282 394 644 + 290 374 345 326 332 380 367 631 579 753 284 836 314 141 78 219 123 264 + 84 450 514 34 75 503 370 692 487 498 179 736 312 401 476 369 732 757 + 761 137 308 767 275 112 395 443 309 701 276 154 397 767 266 282 616 308 + 594 780 571 236 222 234 829 522 527 365 306 704 268 836 557 907 56 722 + 348 633 582 370 655 406 655 148 249 749 572 613 597 77 649 685 393 293 + 0 369 167 79 77 205 259 153 190 97 416 185 435 537 482 412 286 459 + 587 640 500 243 555 111 283 679 119 163 375 343 356 626 360 777 116 355 + 266 305 108 322 189 356 429 616 446 411 473 149 121 499 441 238 767 206 + 220 230 315 288 709 439 237 300 352 243 275 614 587 319 672 589 152 172 + 218 253 315 518 364 281 436 679 135 515 108 332 295 600 493 355 343 199 + 260 762 401 218 475 350 290 421 431 349 745 144 98 39 297 248 275 545 + 646 263 164 354 221 553 201 199 149 657 488 0 121 511 418 271 570 386 + 309 255 441 543 529 779 518 142 99 84 297 285 357 274 587 225 487 209 + 396 246 502 35 29 42 286 36 551 236 482 430 604 316 687 220 268 334 + 390 207 70 238 301 365 332 245 581 541 550 315 349 222 587 483 126 162 + 55 583 608 619 388 257 618 446 363 224 294 249 552 104 178 60 625 96 + 453 474 175 452 631 422 260 153 146 687 373 355 536 47 562 135 694 336 + 765 311 573 519 484 440 386 506 169 506 319 520 607 423 299 448 327 500 + 543 212 317 320 347 0 +DISPLAY_DATA_SECTION + 1 8.0 124.0 + 2 125.0 80.0 + 3 97.0 74.0 + 4 69.0 96.0 + 5 106.0 46.0 + 6 49.0 57.0 + 7 80.0 125.0 + 8 42.0 93.0 + 9 104.0 94.0 + 10 35.0 17.0 + 11 118.0 96.0 + 12 151.0 22.0 + 13 154.0 182.0 + 14 57.0 165.0 + 15 18.0 159.0 + 16 27.0 123.0 + 17 96.0 170.0 + 18 63.0 198.0 + 19 59.0 211.0 + 20 88.0 182.0 + 21 142.0 72.0 + 22 48.0 190.0 + 23 106.0 106.0 + 24 28.0 102.0 + 25 63.0 224.0 + 26 58.0 93.0 + 27 103.0 56.0 + 28 38.0 149.0 + 29 23.0 138.0 + 30 22.0 146.0 + 31 32.0 208.0 + 32 27.0 144.0 + 33 75.0 258.0 + 34 59.0 101.0 + 35 41.0 32.0 + 36 53.0 46.0 + 37 76.0 19.0 + 38 79.0 115.0 + 39 109.0 13.0 + 40 59.0 118.0 + 41 84.0 147.0 + 42 95.0 160.0 + 43 87.0 213.0 + 44 73.0 166.0 + 45 43.0 153.0 + 46 81.0 175.0 + 47 59.0 77.0 + 48 70.0 68.0 + 49 106.0 169.0 + 50 86.0 168.0 + 51 127.0 109.0 + 52 68.0 243.0 + 53 116.0 57.0 + 54 39.0 78.0 + 55 54.0 65.0 + 56 77.0 141.0 + 57 95.0 24.0 + 58 89.0 238.0 + 59 9.0 158.0 + 60 39.0 109.0 + 61 25.0 129.0 + 62 69.0 20.0 + 63 104.0 34.0 + 64 132.0 51.0 + 65 98.0 207.0 + 66 37.0 203.0 + 67 80.0 16.0 + 68 103.0 224.0 + 69 94.0 202.0 + 70 49.0 96.0 + 71 55.0 80.0 + 72 62.0 123.0 + 73 91.0 31.0 + 74 51.0 142.0 + 75 64.0 172.0 + 76 14.0 138.0 + 77 120.0 37.0 + 78 38.0 160.0 + 79 86.0 230.0 + 80 96.0 59.0 + 81 33.0 177.0 + 82 108.0 78.0 + 83 93.0 12.0 + 84 43.0 47.0 + 85 52.0 200.0 + 86 48.0 171.0 + 87 62.0 153.0 + 88 159.0 53.0 + 89 60.0 60.0 + 90 36.0 73.0 + 91 111.0 243.0 + 92 31.0 150.0 + 93 130.0 67.0 + 94 36.0 172.0 + 95 132.0 28.0 + 96 29.0 73.0 + 97 150.0 28.0 + 98 89.0 166.0 + 99 58.0 21.0 + 100 78.0 244.0 + 101 82.0 58.0 + 102 81.0 68.0 + 103 92.0 98.0 + 104 56.0 33.0 + 105 47.0 126.0 + 106 70.0 34.0 + 107 78.0 195.0 + 108 77.0 215.0 + 109 140.0 62.0 + 110 70.0 57.0 + 111 16.0 89.0 + 112 66.0 50.0 + 113 98.0 194.0 + 114 87.0 45.0 + 115 132.0 87.0 + 116 52.0 99.0 + 117 50.0 212.0 + 118 103.0 176.0 + 119 84.0 91.0 + 120 31.0 140.0 +EOF diff --git a/glpk-5.0/examples/tsp/main.c b/glpk-5.0/examples/tsp/main.c new file mode 100644 index 0000000..0685742 --- /dev/null +++ b/glpk-5.0/examples/tsp/main.c @@ -0,0 +1,535 @@ +/* main.c */ + +/* Written by Andrew Makhorin <mao@gnu.org>, October 2015. */ + +/*********************************************************************** +* This program is a stand-alone solver intended for solving Symmetric +* Traveling Salesman Problem (TSP) with the branch-and-bound method. +* +* Please note that this program is only an illustrative example. It is +* *not* a state-of-the-art code, so only small TSP instances (perhaps, +* having up to 150-200 nodes) can be solved with this code. +* +* To run this program use the following command: +* +* tspsol tsp-file +* +* where tsp-file specifies an input text file containing TSP data in +* TSPLIB 95 format. +* +* Detailed description of the input format recognized by this program +* is given in the report: Gerhard Reinelt, "TSPLIB 95". This report as +* well as TSPLIB, a library of sample TSP instances (and other related +* problems), are freely available for research purposes at the webpage +* <http://www.iwr.uni-heidelberg.de/groups/comopt/software/TSPLIB95/>. +* +* Symmetric Traveling Salesman Problem +* ------------------------------------ +* Let a complete undirected graph be given: +* +* K = (V, E), (1) +* +* where V = {1, ..., n} is a set of nodes, E = V cross V is a set of +* edges. Let also each edge e = (i,j) be assigned a positive number +* c[i,j], which is the length of e. The Symmetric Traveling Salesman +* Problem (TSP) is to find a tour in K of minimal length. +* +* Integer programming formulation of TSP +* -------------------------------------- +* For a set of nodes W within V introduce the following notation: +* +* d(W) = {(i,j):i in W and j not in W or i not in W and j in W}, (2) +* +* i.e. d(W) is the set of edges which have exactly one endnode in W. +* If W = {v}, i.e. W consists of the only node, we write simply d(v). +* +* The integer programming formulation of TSP is the following: +* +* minimize sum c[i,j] * x[i,j] (3) +* i,j +* +* subject to sum x[i,j] = 2 for all v in V (4) +* (i,j) in d(v) +* +* sum x[i,j] >= 2 for all W within V, (5) +* (i,j) in d(W) W != empty, W != V +* +* x[i,j] in {0, 1} for all i, j (6) +* +* The binary variables x[i,j] have conventional meaning: if x[i,j] = 1, +* the edge (i,j) is included in the tour, otherwise, if x[i,j] = 0, the +* edge is not included in the tour. +* +* The constraints (4) are called degree constraints. They require that +* for each node v in V there must be exactly two edges included in the +* tour which are incident to v. +* +* The constraints (5) are called subtour elimination constraints. They +* are used to forbid subtours. Note that the number of the subtour +* elimination constraints grows exponentially on the size of the TSP +* instance, so these constraints are not included explicitly in the +* IP, but generated dynamically during the B&B search. +***********************************************************************/ + +#include <errno.h> +#include <math.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> + +#include <glpk.h> +#include "maxflow.h" +#include "mincut.h" +#include "misc.h" +#include "tsplib.h" + +int n; +/* number of nodes in the problem, n >= 2 */ + +int *c; /* int c[1+n*(n-1)/2]; */ +/* upper triangle (without diagonal entries) of the (symmetric) matrix + * C = (c[i,j]) in row-wise format, where c[i,j] specifies a length of + * edge e = (i,j), 1 <= i < j <= n */ + +int *tour; /* int tour[1+n]; */ +/* solution to TSP, which is a tour specified by the list of node + * numbers tour[1] -> ... -> tour[nn] -> tour[1] in the order the nodes + * are visited; note that any tour is a permutation of node numbers */ + +glp_prob *P; +/* integer programming problem object */ + +/*********************************************************************** +* loc - determine reduced index of element of symmetric matrix +* +* Given indices i and j of an element of a symmetric nxn-matrix, +* 1 <= i, j <= n, i != j, this routine returns the index of that +* element in an array, which is the upper triangle (without diagonal +* entries) of the matrix in row-wise format. */ + +int loc(int i, int j) +{ xassert(1 <= i && i <= n); + xassert(1 <= j && j <= n); + xassert(i != j); + if (i < j) + return ((n - 1) + (n - i + 1)) * (i - 1) / 2 + (j - i); + else + return loc(j, i); +} + +/*********************************************************************** +* read_data - read TSP data +* +* This routine reads TSP data from a specified text file in TSPLIB 95 +* format. */ + +void read_data(const char *fname) +{ TSP *tsp; + int i, j; + tsp = tsp_read_data(fname); + if (tsp == NULL) + { xprintf("TSP data file processing error\n"); + exit(EXIT_FAILURE); + } + if (tsp->type != TSP_TSP) + { xprintf("Invalid TSP data type\n"); + exit(EXIT_FAILURE); + } + n = tsp->dimension; + xassert(n >= 2); + if (n > 32768) + { xprintf("TSP instance too large\n"); + exit(EXIT_FAILURE); + } + c = xalloc(1+loc(n-1, n), sizeof(int)); + for (i = 1; i <= n; i++) + { for (j = i+1; j <= n; j++) + c[loc(i, j)] = tsp_distance(tsp, i, j); + } + tsp_free_data(tsp); + return; +} + +/*********************************************************************** +* build_prob - build initial integer programming problem +* +* This routine builds the initial integer programming problem, which +* includes all variables (6), objective (3) and all degree constraints +* (4). Subtour elimination constraints (5) are considered "lazy" and +* not included in the initial problem. */ + +void build_prob(void) +{ int i, j, k, *ind; + double *val; + char name[50]; + /* create problem object */ + P = glp_create_prob(); + /* add all binary variables (6) */ + for (i = 1; i <= n; i++) + { for (j = i+1; j <= n; j++) + { k = glp_add_cols(P, 1); + xassert(k == loc(i,j)); + sprintf(name, "x[%d,%d]", i, j); + glp_set_col_name(P, k, name); + glp_set_col_kind(P, k, GLP_BV); + /* set objective coefficient (3) */ + glp_set_obj_coef(P, k, c[k]); + } + } + /* add all degree constraints (4) */ + ind = xalloc(1+n, sizeof(int)); + val = xalloc(1+n, sizeof(double)); + for (i = 1; i <= n; i++) + { k = glp_add_rows(P, 1); + xassert(k == i); + sprintf(name, "v[%d]", i); + glp_set_row_name(P, i, name); + glp_set_row_bnds(P, i, GLP_FX, 2, 2); + k = 0; + for (j = 1; j <= n; j++) + { if (i != j) + k++, ind[k] = loc(i,j), val[k] = 1; + } + xassert(k == n-1); + glp_set_mat_row(P, i, n-1, ind, val); + } + xfree(ind); + xfree(val); + return; +} + +/*********************************************************************** +* build_tour - build tour for corresponding solution to IP +* +* Given a feasible solution to IP (3)-(6) this routine builds the +* corresponding solution to TSP, which is a tour specified by the list +* of node numbers tour[1] -> ... -> tour[nn] -> tour[1] in the order +* the nodes are to be visited */ + +void build_tour(void) +{ int i, j, k, kk, *beg, *end; + /* solution to MIP should be feasible */ + switch (glp_mip_status(P)) + { case GLP_FEAS: + case GLP_OPT: + break; + default: + xassert(P != P); + } + /* build the list of edges included in the tour */ + beg = xalloc(1+n, sizeof(int)); + end = xalloc(1+n, sizeof(int)); + k = 0; + for (i = 1; i <= n; i++) + { for (j = i+1; j <= n; j++) + { double x; + x = glp_mip_col_val(P, loc(i,j)); + xassert(x == 0 || x == 1); + if (x) + { k++; + xassert(k <= n); + beg[k] = i, end[k] = j; + } + } + } + xassert(k == n); + /* reorder edges in the list as they follow in the tour */ + for (k = 1; k <= n; k++) + { /* find k-th edge of the tour */ + j = (k == 1 ? 1 : end[k-1]); + for (kk = k; kk <= n; kk++) + { if (beg[kk] == j) + break; + if (end[kk] == j) + { end[kk] = beg[kk], beg[kk] = j; + break; + } + } + xassert(kk <= n); + /* put the edge to k-th position in the list */ + i = beg[k], beg[k] = beg[kk], beg[kk] = i; + j = end[k], end[k] = end[kk], end[kk] = j; + } + /* build the tour starting from node 1 */ + xassert(beg[1] == 1); + for (k = 1; k <= n; k++) + { if (k > 1) + xassert(end[k-1] == beg[k]); + tour[k] = beg[k]; + } + xassert(end[n] == 1); + xfree(beg); + xfree(end); + return; +} + +/*********************************************************************** +* tour_length - calculate tour length +* +* This routine calculates the length of the specified tour, which is +* the sum of corresponding edge lengths. */ + +int tour_length(const int tour[/*1+n*/]) +{ int i, j, sum; + sum = 0; + for (i = 1; i <= n; i++) + { j = (i < n ? i+1 : 1); + sum += c[loc(tour[i], tour[j])]; + } + return sum; +} + +/*********************************************************************** +* write_tour - write tour to text file in TSPLIB format +* +* This routine writes the specified tour to a text file in TSPLIB +* format. */ + +void write_tour(const char *fname, const int tour[/*1+n*/]) +{ FILE *fp; + int i; + xprintf("Writing TSP solution to '%s'...\n", fname); + fp = fopen(fname, "w"); + if (fp == NULL) + { xprintf("Unable to create '%s' - %s\n", fname, + strerror(errno)); + return; + } + fprintf(fp, "NAME : %s\n", fname); + fprintf(fp, "COMMENT : Tour length is %d\n", tour_length(tour)); + fprintf(fp, "TYPE : TOUR\n"); + fprintf(fp, "DIMENSION : %d\n", n); + fprintf(fp, "TOUR_SECTION\n"); + for (i = 1; i <= n; i++) + fprintf(fp, "%d\n", tour[i]); + fprintf(fp, "-1\n"); + fprintf(fp, "EOF\n"); + fclose(fp); + return; +} + +/*********************************************************************** +* gen_subt_row - generate violated subtour elimination constraint +* +* This routine is called from the MIP solver to generate a violated +* subtour elimination constraint (5). +* +* Constraints of this class has the form: +* +* sum x[i,j] >= 2, i in W, j in V \ W, +* +* for all W, where W is a proper nonempty subset of V, V is the set of +* nodes of the given graph. +* +* In order to find a violated constraint of this class this routine +* finds a min cut in a capacitated network, which has the same sets of +* nodes and edges as the original graph, and where capacities of edges +* are values of variables x[i,j] in a basic solution to LP relaxation +* of the current subproblem. */ + +void gen_subt(glp_tree *T) +{ int i, j, ne, nz, *beg, *end, *cap, *cut, *ind; + double sum, *val; + /* MIP preprocessor should not be used */ + xassert(glp_ios_get_prob(T) == P); + /* if some variable x[i,j] is zero in basic solution, then the + * capacity of corresponding edge in the associated network is + * zero, so we may not include such edge in the network */ + /* count number of edges having non-zero capacity */ + ne = 0; + for (i = 1; i <= n; i++) + { for (j = i+1; j <= n; j++) + { if (glp_get_col_prim(P, loc(i,j)) >= .001) + ne++; + } + } + /* build the capacitated network */ + beg = xalloc(1+ne, sizeof(int)); + end = xalloc(1+ne, sizeof(int)); + cap = xalloc(1+ne, sizeof(int)); + nz = 0; + for (i = 1; i <= n; i++) + { for (j = i+1; j <= n; j++) + { if (glp_get_col_prim(P, loc(i,j)) >= .001) + { nz++; + xassert(nz <= ne); + beg[nz] = i, end[nz] = j; + /* scale all edge capacities to make them integral */ + cap[nz] = ceil(1000 * glp_get_col_prim(P, loc(i,j))); + } + } + } + xassert(nz == ne); + /* find minimal cut in the capacitated network */ + cut = xalloc(1+n, sizeof(int)); + min_cut(n, ne, beg, end, cap, cut); + /* determine the number of non-zero coefficients in the subtour + * elimination constraint and calculate its left-hand side which + * is the (unscaled) capacity of corresponding min cut */ + ne = 0, sum = 0; + for (i = 1; i <= n; i++) + { for (j = i+1; j <= n; j++) + { if (cut[i] && !cut[j] || !cut[i] && cut[j]) + { ne++; + sum += glp_get_col_prim(P, loc(i,j)); + } + } + } + /* if the (unscaled) capacity of min cut is less than 2, the + * corresponding subtour elimination constraint is violated */ + if (sum <= 1.999) + { /* build the list of non-zero coefficients */ + ind = xalloc(1+ne, sizeof(int)); + val = xalloc(1+ne, sizeof(double)); + nz = 0; + for (i = 1; i <= n; i++) + { for (j = i+1; j <= n; j++) + { if (cut[i] && !cut[j] || !cut[i] && cut[j]) + { nz++; + xassert(nz <= ne); + ind[nz] = loc(i,j); + val[nz] = 1; + } + } + } + xassert(nz == ne); + /* add violated tour elimination constraint to the current + * subproblem */ + i = glp_add_rows(P, 1); + glp_set_row_bnds(P, i, GLP_LO, 2, 0); + glp_set_mat_row(P, i, nz, ind, val); + xfree(ind); + xfree(val); + } + /* free working arrays */ + xfree(beg); + xfree(end); + xfree(cap); + xfree(cut); + return; +} + +/*********************************************************************** +* cb_func - application callback routine +* +* This routine is called from the MIP solver at various points of +* the branch-and-cut algorithm. */ + +void cb_func(glp_tree *T, void *info) +{ xassert(info == info); + switch (glp_ios_reason(T)) + { case GLP_IROWGEN: + /* generate one violated subtour elimination constraint */ + gen_subt(T); + break; + } + return; +} + +/*********************************************************************** +* main - TSP solver main program +* +* This main program parses command-line arguments, reads specified TSP +* instance from a text file, and calls the MIP solver to solve it. */ + +int main(int argc, char *argv[]) +{ int j; + char *in_file = NULL, *out_file = NULL; + time_t start; + glp_iocp iocp; + /* parse command-line arguments */ +# define p(str) (strcmp(argv[j], str) == 0) + for (j = 1; j < argc; j++) + { if (p("--output") || p("-o")) + { j++; + if (j == argc || argv[j][0] == '\0' || argv[j][0] == '-') + { xprintf("No solution output file specified\n"); + exit(EXIT_FAILURE); + } + if (out_file != NULL) + { xprintf("Only one solution output file allowed\n"); + exit(EXIT_FAILURE); + } + out_file = argv[j]; + } + else if (p("--help") || p("-h")) + { xprintf("Usage: %s [options...] tsp-file\n", argv[0]); + xprintf("\n"); + xprintf("Options:\n"); + xprintf(" -o filename, --output filename\n"); + xprintf(" write solution to filename\n") + ; + xprintf(" -h, --help display this help information" + " and exit\n"); + exit(EXIT_SUCCESS); + } + else if (argv[j][0] == '-' || + (argv[j][0] == '-' && argv[j][1] == '-')) + { xprintf("Invalid option '%s'; try %s --help\n", argv[j], + argv[0]); + exit(EXIT_FAILURE); + } + else + { if (in_file != NULL) + { xprintf("Only one input file allowed\n"); + exit(EXIT_FAILURE); + } + in_file = argv[j]; + } + } + if (in_file == NULL) + { xprintf("No input file specified; try %s --help\n", argv[0]); + exit(EXIT_FAILURE); + } +# undef p + /* display program banner */ + xprintf("TSP Solver for GLPK %s\n", glp_version()); + /* remove output solution file specified in command-line */ + if (out_file != NULL) + remove(out_file); + /* read TSP instance from input data file */ + read_data(in_file); + /* build initial IP problem */ + start = time(NULL); + build_prob(); + tour = xalloc(1+n, sizeof(int)); + /* solve LP relaxation of initial IP problem */ + xprintf("Solving initial LP relaxation...\n"); + xassert(glp_simplex(P, NULL) == 0); + xassert(glp_get_status(P) == GLP_OPT); + /* solve IP problem with "lazy" constraints */ + glp_init_iocp(&iocp); + iocp.br_tech = GLP_BR_MFV; /* most fractional variable */ + iocp.bt_tech = GLP_BT_BLB; /* best local bound */ + iocp.sr_heur = GLP_OFF; /* disable simple rounding heuristic */ + iocp.gmi_cuts = GLP_ON; /* enable Gomory cuts */ + iocp.cb_func = cb_func; + glp_intopt(P, &iocp); + build_tour(); + /* display some statistics */ + xprintf("Time used: %.1f secs\n", difftime(time(NULL), start)); + { size_t tpeak; + glp_mem_usage(NULL, NULL, NULL, &tpeak); + xprintf("Memory used: %.1f Mb (%.0f bytes)\n", + (double)tpeak / 1048576.0, (double)tpeak); + } + /* write solution to output file, if required */ + if (out_file != NULL) + write_tour(out_file, tour); + /* deallocate working objects */ + xfree(c); + xfree(tour); + glp_delete_prob(P); + /* check that no memory blocks are still allocated */ + { int count; + size_t total; + glp_mem_usage(&count, NULL, &total, NULL); + if (count != 0) + xerror("Error: %d memory block(s) were lost\n", count); + xassert(total == 0); + } + return 0; +} + +/* eof */ diff --git a/glpk-5.0/examples/tsp/maxflow.c b/glpk-5.0/examples/tsp/maxflow.c new file mode 100644 index 0000000..c28f527 --- /dev/null +++ b/glpk-5.0/examples/tsp/maxflow.c @@ -0,0 +1,170 @@ +/* maxflow.c */ + +/* Written by Andrew Makhorin <mao@gnu.org>, October 2015. */ + +#include <math.h> + +#include <glpk.h> +#include "maxflow.h" +#include "misc.h" + +/*********************************************************************** +* NAME +* +* max_flow - find max flow in undirected capacitated network +* +* SYNOPSIS +* +* #include "maxflow.h" +* int max_flow(int nn, int ne, const int beg[], const int end[], +* const int cap[], int s, int t, int x[]); +* +* DESCRIPTION +* +* This routine finds max flow in a given undirected network. +* +* The undirected capacitated network is specified by the parameters +* nn, ne, beg, end, and cap. The parameter nn specifies the number of +* vertices (nodes), nn >= 2, and the parameter ne specifies the number +* of edges, ne >= 0. The network edges are specified by triplets +* (beg[k], end[k], cap[k]) for k = 1, ..., ne, where beg[k] < end[k] +* are numbers of the first and second nodes of k-th edge, and +* cap[k] > 0 is a capacity of k-th edge. Loops and multiple edges are +* not allowed. +* +* The parameter s is the number of a source node, and the parameter t +* is the number of a sink node, s != t. +* +* On exit the routine computes elementary flows thru edges and stores +* their values to locations x[1], ..., x[ne]. Positive value of x[k] +* means that the elementary flow goes from node beg[k] to node end[k], +* and negative value means that the flow goes in opposite direction. +* +* RETURNS +* +* The routine returns the total maximum flow through the network. */ + +int max_flow(int nn, int ne, const int beg[/*1+ne*/], + const int end[/*1+ne*/], const int cap[/*1+ne*/], int s, int t, + int x[/*1+ne*/]) +{ int k; + /* sanity checks */ + xassert(nn >= 2); + xassert(ne >= 0); + xassert(1 <= s && s <= nn); + xassert(1 <= t && t <= nn); + xassert(s != t); + for (k = 1; k <= ne; k++) + { xassert(1 <= beg[k] && beg[k] < end[k] && end[k] <= nn); + xassert(cap[k] > 0); + } + /* find max flow */ + return max_flow_lp(nn, ne, beg, end, cap, s, t, x); +} + +/*********************************************************************** +* NAME +* +* max_flow_lp - find max flow with simplex method +* +* SYNOPSIS +* +* #include "maxflow.h" +* int max_flow_lp(int nn, int ne, const int beg[], const int end[], +* const int cap[], int s, int t, int x[]); +* +* DESCRIPTION +* +* This routine finds max flow in a given undirected network with the +* simplex method. +* +* Parameters of this routine have the same meaning as for the routine +* max_flow (see above). +* +* RETURNS +* +* The routine returns the total maximum flow through the network. */ + +int max_flow_lp(int nn, int ne, const int beg[/*1+ne*/], + const int end[/*1+ne*/], const int cap[/*1+ne*/], int s, int t, + int x[/*1+ne*/]) +{ glp_prob *lp; + glp_smcp smcp; + int i, k, nz, flow, *rn, *cn; + double temp, *aa; + /* create LP problem instance */ + lp = glp_create_prob(); + /* create LP rows; i-th row is the conservation condition of the + * flow at i-th node, i = 1, ..., nn */ + glp_add_rows(lp, nn); + for (i = 1; i <= nn; i++) + glp_set_row_bnds(lp, i, GLP_FX, 0.0, 0.0); + /* create LP columns; k-th column is the elementary flow thru + * k-th edge, k = 1, ..., ne; the last column with the number + * ne+1 is the total flow through the network, which goes along + * a dummy feedback edge from the sink to the source */ + glp_add_cols(lp, ne+1); + for (k = 1; k <= ne; k++) + { xassert(cap[k] > 0); + glp_set_col_bnds(lp, k, GLP_DB, -cap[k], +cap[k]); + } + glp_set_col_bnds(lp, ne+1, GLP_FR, 0.0, 0.0); + /* build the constraint matrix; structurally this matrix is the + * incidence matrix of the network, so each its column (including + * the last column for the dummy edge) has exactly two non-zero + * entries */ + rn = xalloc(1+2*(ne+1), sizeof(int)); + cn = xalloc(1+2*(ne+1), sizeof(int)); + aa = xalloc(1+2*(ne+1), sizeof(double)); + nz = 0; + for (k = 1; k <= ne; k++) + { /* x[k] > 0 means the elementary flow thru k-th edge goes from + * node beg[k] to node end[k] */ + nz++, rn[nz] = beg[k], cn[nz] = k, aa[nz] = -1.0; + nz++, rn[nz] = end[k], cn[nz] = k, aa[nz] = +1.0; + } + /* total flow thru the network goes from the sink to the source + * along the dummy feedback edge */ + nz++, rn[nz] = t, cn[nz] = ne+1, aa[nz] = -1.0; + nz++, rn[nz] = s, cn[nz] = ne+1, aa[nz] = +1.0; + /* check the number of non-zero entries */ + xassert(nz == 2*(ne+1)); + /* load the constraint matrix into the LP problem object */ + glp_load_matrix(lp, nz, rn, cn, aa); + xfree(rn); + xfree(cn); + xfree(aa); + /* objective function is the total flow through the network to + * be maximized */ + glp_set_obj_dir(lp, GLP_MAX); + glp_set_obj_coef(lp, ne + 1, 1.0); + /* solve LP instance with the (primal) simplex method */ + glp_term_out(0); + glp_adv_basis(lp, 0); + glp_term_out(1); + glp_init_smcp(&smcp); + smcp.msg_lev = GLP_MSG_ON; + smcp.out_dly = 5000; + xassert(glp_simplex(lp, &smcp) == 0); + xassert(glp_get_status(lp) == GLP_OPT); + /* obtain optimal elementary flows thru edges of the network */ + /* (note that the constraint matrix is unimodular and the data + * are integral, so all elementary flows in basic solution should + * also be integral) */ + for (k = 1; k <= ne; k++) + { temp = glp_get_col_prim(lp, k); + x[k] = (int)floor(temp + .5); + xassert(fabs(x[k] - temp) <= 1e-6); + } + /* obtain the maximum flow thru the original network which is the + * flow thru the dummy feedback edge */ + temp = glp_get_col_prim(lp, ne+1); + flow = (int)floor(temp + .5); + xassert(fabs(flow - temp) <= 1e-6); + /* delete LP problem instance */ + glp_delete_prob(lp); + /* return to the calling program */ + return flow; +} + +/* eof */ diff --git a/glpk-5.0/examples/tsp/maxflow.h b/glpk-5.0/examples/tsp/maxflow.h new file mode 100644 index 0000000..245c5ec --- /dev/null +++ b/glpk-5.0/examples/tsp/maxflow.h @@ -0,0 +1,20 @@ +/* maxflow.h */ + +/* Written by Andrew Makhorin <mao@gnu.org>, October 2015. */ + +#ifndef MAXFLOW_H +#define MAXFLOW_H + +int max_flow(int nn, int ne, const int beg[/*1+ne*/], + const int end[/*1+ne*/], const int cap[/*1+ne*/], int s, int t, + int x[/*1+ne*/]); +/* find max flow in undirected capacitated network */ + +int max_flow_lp(int nn, int ne, const int beg[/*1+ne*/], + const int end[/*1+ne*/], const int cap[/*1+ne*/], int s, int t, + int x[/*1+ne*/]); +/* find max flow with simplex method */ + +#endif + +/* eof */ diff --git a/glpk-5.0/examples/tsp/mincut.c b/glpk-5.0/examples/tsp/mincut.c new file mode 100644 index 0000000..225fb7f --- /dev/null +++ b/glpk-5.0/examples/tsp/mincut.c @@ -0,0 +1,392 @@ +/* mincut.c */ + +/* Written by Andrew Makhorin <mao@gnu.org>, October 2015. */ + +#include <limits.h> + +#include "maxflow.h" +#include "mincut.h" +#include "misc.h" + +/*********************************************************************** +* NAME +* +* min_cut - find min cut in undirected capacitated network +* +* SYNOPSIS +* +* #include "mincut.h" +* int min_cut(int nn, int ne, const int beg[], const int end[], +* const cap[], int cut[]); +* +* DESCRIPTION +* +* This routine finds min cut in a given undirected network. +* +* The undirected capacitated network is specified by the parameters +* nn, ne, beg, end, and cap. The parameter nn specifies the number of +* vertices (nodes), nn >= 2, and the parameter ne specifies the number +* of edges, ne >= 0. The network edges are specified by triplets +* (beg[k], end[k], cap[k]) for k = 1, ..., ne, where beg[k] < end[k] +* are numbers of the first and second nodes of k-th edge, and +* cap[k] > 0 is a capacity of k-th edge. Loops and multiple edges are +* not allowed. +* +* Let V be the set of nodes of the network and let W be an arbitrary +* non-empty proper subset of V. A cut associated with the subset W is +* a subset of all the edges, one node of which belongs to W and other +* node belongs to V \ W. The capacity of a cut (W, V \ W) is the sum +* of the capacities of all the edges, which belong to the cut. Minimal +* cut is a cut, whose capacity is minimal. +* +* On exit the routine stores flags of nodes v[i], i = 1, ..., nn, to +* locations cut[i], where cut[i] = 1 means that v[i] belongs to W and +* cut[i] = 0 means that v[i] belongs to V \ W, where W corresponds to +* the minimal cut found. +* +* RETURNS +* +* The routine returns the capacity of the min cut found. */ + +int min_cut(int nn, int ne, const int beg[/*1+ne*/], + const int end[/*1+ne*/], const cap[/*1+ne*/], int cut[/*1+nn*/]) +{ int k; + /* sanity checks */ + xassert(nn >= 2); + xassert(ne >= 0); + for (k = 1; k <= ne; k++) + { xassert(1 <= beg[k] && beg[k] < end[k] && end[k] <= nn); + xassert(cap[k] > 0); + } + /* find min cut */ + return min_cut_sw(nn, ne, beg, end, cap, cut); +} + +/*********************************************************************** +* NAME +* +* min_st_cut - find min (s,t)-cut for known max flow +* +* SYNOPSIS +* +* #include "mincut.h" +* +* DESCRIPTION +* +* This routine finds min (s,t)-cut in a given undirected network that +* corresponds to a known max flow from s to t in the network. +* +* Parameters nn, ne, beg, end, and cap specify the network in the same +* way as for the routine min_cut (see above). +* +* Parameters s and t specify, resp., the number of the source node +* and the number of the sink node, s != t, for which the min (s,t)-cut +* has to be found. +* +* Parameter x specifies the known max flow from s to t in the network, +* where locations x[1], ..., x[ne] contains elementary flow thru edges +* of the network (positive value of x[k] means that the elementary +* flow goes from node beg[k] to node end[k], and negative value means +* that the flow goes in opposite direction). +* +* This routine splits the set of nodes V of the network into two +* non-empty subsets V(s) and V(t) = V \ V(s), where the source node s +* belongs to V(s), the sink node t belongs to V(t), and all edges, one +* node of which belongs to V(s) and other one belongs to V(t), are +* saturated (that is, x[k] = +cap[k] or x[k] = -cap[k]). +* +* On exit the routine stores flags of the nodes v[i], i = 1, ..., nn, +* to locations cut[i], where cut[i] = 1 means that v[i] belongs to V(s) +* and cut[i] = 0 means that v[i] belongs to V(t) = V \ V(s). +* +* RETURNS +* +* The routine returns the capacity of min (s,t)-cut, which is the sum +* of the capacities of all the edges, which belong to the cut. (Note +* that due to theorem by Ford and Fulkerson this value is always equal +* to corresponding max flow.) +* +* ALGORITHM +* +* To determine the set V(s) the routine simply finds all nodes, which +* can be reached from the source node s via non-saturated edges. The +* set V(t) is determined as the complement V \ V(s). */ + +int min_st_cut(int nn, int ne, const int beg[/*1+ne*/], + const int end[/*1+ne*/], const int cap[/*1+ne*/], int s, int t, + const int x[/*1+ne*/], int cut[/*1+nn*/]) +{ int i, j, k, p, q, temp, *head1, *next1, *head2, *next2, *list; + /* head1[i] points to the first edge with beg[k] = i + * next1[k] points to the next edge with the same beg[k] + * head2[i] points to the first edge with end[k] = i + * next2[k] points to the next edge with the same end[k] */ + head1 = xalloc(1+nn, sizeof(int)); + head2 = xalloc(1+nn, sizeof(int)); + next1 = xalloc(1+ne, sizeof(int)); + next2 = xalloc(1+ne, sizeof(int)); + for (i = 1; i <= nn; i++) + head1[i] = head2[i] = 0; + for (k = 1; k <= ne; k++) + { i = beg[k], next1[k] = head1[i], head1[i] = k; + j = end[k], next2[k] = head2[j], head2[j] = k; + } + /* on constructing the set V(s) list[1], ..., list[p-1] contain + * nodes, which can be reached from source node and have been + * visited, and list[p], ..., list[q] contain nodes, which can be + * reached from source node but havn't been visited yet */ + list = xalloc(1+nn, sizeof(int)); + for (i = 1; i <= nn; i++) + cut[i] = 0; + p = q = 1, list[1] = s, cut[s] = 1; + while (p <= q) + { /* pick next node, which is reachable from the source node and + * has not visited yet, and visit it */ + i = list[p++]; + /* walk through edges with beg[k] = i */ + for (k = head1[i]; k != 0; k = next1[k]) + { j = end[k]; + xassert(beg[k] == i); + /* from v[i] we can reach v[j], if the elementary flow from + * v[i] to v[j] is non-saturated */ + if (cut[j] == 0 && x[k] < +cap[k]) + list[++q] = j, cut[j] = 1; + } + /* walk through edges with end[k] = i */ + for (k = head2[i]; k != 0; k = next2[k]) + { j = beg[k]; + xassert(end[k] == i); + /* from v[i] we can reach v[j], if the elementary flow from + * v[i] to v[j] is non-saturated */ + if (cut[j] == 0 && x[k] > -cap[k]) + list[++q] = j, cut[j] = 1; + } + } + /* sink cannot belong to V(s) */ + xassert(!cut[t]); + /* free working arrays */ + xfree(head1); + xfree(head2); + xfree(next1); + xfree(next2); + xfree(list); + /* compute capacity of the minimal (s,t)-cut found */ + temp = 0; + for (k = 1; k <= ne; k++) + { i = beg[k], j = end[k]; + if (cut[i] && !cut[j] || !cut[i] && cut[j]) + temp += cap[k]; + } + /* return to the calling program */ + return temp; +} + +/*********************************************************************** +* NAME +* +* min_cut_sw - find min cut with Stoer and Wagner algorithm +* +* SYNOPSIS +* +* #include "mincut.h" +* int min_cut_sw(int nn, int ne, const int beg[], const int end[], +* const cap[], int cut[]); +* +* DESCRIPTION +* +* This routine find min cut in a given undirected network with the +* algorithm proposed by Stoer and Wagner (see references below). +* +* Parameters of this routine have the same meaning as for the routine +* min_cut (see above). +* +* RETURNS +* +* The routine returns the capacity of the min cut found. +* +* ALGORITHM +* +* The basic idea of Stoer&Wagner algorithm is the following. Let G be +* a capacitated network, and G(s,t) be a network, in which the nodes s +* and t are merged into one new node, loops are deleted, but multiple +* edges are retained. It is obvious that a minimum cut in G is the +* minimum of two quantities: the minimum cut in G(s,t) and a minimum +* cut that separates s and t. This allows to find a minimum cut in the +* original network solving at most nn max flow problems. +* +* REFERENCES +* +* M. Stoer, F. Wagner. A Simple Min Cut Algorithm. Algorithms, ESA'94 +* LNCS 855 (1994), pp. 141-47. +* +* J. Cheriyan, R. Ravi. Approximation Algorithms for Network Problems. +* Univ. of Waterloo (1998), p. 147. */ + +int min_cut_sw(int nn, int ne, const int beg[/*1+ne*/], + const int end[/*1+ne*/], const cap[/*1+ne*/], int cut[/*1+nn*/]) +{ int i, j, k, min_cut, flow, temp, *head1, *next1, *head2, *next2; + int I, J, K, S, T, DEG, NV, NE, *HEAD, *NEXT, *NUMB, *BEG, *END, + *CAP, *X, *ADJ, *SUM, *CUT; + /* head1[i] points to the first edge with beg[k] = i + * next1[k] points to the next edge with the same beg[k] + * head2[i] points to the first edge with end[k] = i + * next2[k] points to the next edge with the same end[k] */ + head1 = xalloc(1+nn, sizeof(int)); + head2 = xalloc(1+nn, sizeof(int)); + next1 = xalloc(1+ne, sizeof(int)); + next2 = xalloc(1+ne, sizeof(int)); + for (i = 1; i <= nn; i++) + head1[i] = head2[i] = 0; + for (k = 1; k <= ne; k++) + { i = beg[k], next1[k] = head1[i], head1[i] = k; + j = end[k], next2[k] = head2[j], head2[j] = k; + } + /* an auxiliary network used in the algorithm is resulted from + * the original network by merging some nodes into one supernode; + * all variables and arrays related to this auxiliary network are + * denoted in CAPS */ + /* HEAD[I] points to the first node of the original network that + * belongs to the I-th supernode + * NEXT[i] points to the next node of the original network that + * belongs to the same supernode as the i-th node + * NUMB[i] is a supernode, which the i-th node belongs to */ + /* initially the auxiliary network is equivalent to the original + * network, i.e. each supernode consists of one node */ + NV = nn; + HEAD = xalloc(1+nn, sizeof(int)); + NEXT = xalloc(1+nn, sizeof(int)); + NUMB = xalloc(1+nn, sizeof(int)); + for (i = 1; i <= nn; i++) + HEAD[i] = i, NEXT[i] = 0, NUMB[i] = i; + /* number of edges in the auxiliary network is never greater than + * in the original one */ + BEG = xalloc(1+ne, sizeof(int)); + END = xalloc(1+ne, sizeof(int)); + CAP = xalloc(1+ne, sizeof(int)); + X = xalloc(1+ne, sizeof(int)); + /* allocate some auxiliary arrays */ + ADJ = xalloc(1+nn, sizeof(int)); + SUM = xalloc(1+nn, sizeof(int)); + CUT = xalloc(1+nn, sizeof(int)); + /* currently no min cut is found so far */ + min_cut = INT_MAX; + /* main loop starts here */ + while (NV > 1) + { /* build the set of edges of the auxiliary network */ + NE = 0; + /* multiple edges are not allowed in the max flow algorithm, + * so we can replace each multiple edge, which is the result + * of merging nodes into supernodes, by a single edge, whose + * capacity is the sum of capacities of particular edges; + * these summary capacities will be stored in the array SUM */ + for (I = 1; I <= NV; I++) + SUM[I] = 0.0; + for (I = 1; I <= NV; I++) + { /* DEG is number of single edges, which connects I-th + * supernode and some J-th supernode, where I < J */ + DEG = 0; + /* walk thru nodes that belong to I-th supernode */ + for (i = HEAD[I]; i != 0; i = NEXT[i]) + { /* i-th node belongs to I-th supernode */ + /* walk through edges with beg[k] = i */ + for (k = head1[i]; k != 0; k = next1[k]) + { j = end[k]; + /* j-th node belongs to J-th supernode */ + J = NUMB[j]; + /* ignore loops and edges with I > J */ + if (I >= J) + continue; + /* add an edge that connects I-th and J-th supernodes + * (if not added yet) */ + if (SUM[J] == 0.0) + ADJ[++DEG] = J; + /* sum up the capacity of the original edge */ + xassert(cap[k] > 0.0); + SUM[J] += cap[k]; + } + /* walk through edges with end[k] = i */ + for (k = head2[i]; k != 0; k = next2[k]) + { j = beg[k]; + /* j-th node belongs to J-th supernode */ + J = NUMB[j]; + /* ignore loops and edges with I > J */ + if (I >= J) + continue; + /* add an edge that connects I-th and J-th supernodes + * (if not added yet) */ + if (SUM[J] == 0.0) + ADJ[++DEG] = J; + /* sum up the capacity of the original edge */ + xassert(cap[k] > 0.0); + SUM[J] += cap[k]; + } + } + /* add single edges connecting I-th supernode with other + * supernodes to the auxiliary network; restore the array + * SUM for subsequent use */ + for (K = 1; K <= DEG; K++) + { NE++; + xassert(NE <= ne); + J = ADJ[K]; + BEG[NE] = I, END[NE] = J, CAP[NE] = SUM[J]; + SUM[J] = 0.0; + } + } + /* choose two arbitrary supernodes of the auxiliary network, + * one of which is the source and other is the sink */ + S = 1, T = NV; + /* determine max flow from S to T */ + flow = max_flow(NV, NE, BEG, END, CAP, S, T, X); + /* if the min cut that separates supernodes S and T is less + * than the currently known, remember it */ + if (min_cut > flow) + { min_cut = flow; + /* find min (s,t)-cut in the auxiliary network */ + temp = min_st_cut(NV, NE, BEG, END, CAP, S, T, X, CUT); + /* (Ford and Fulkerson insist on this) */ + xassert(flow == temp); + /* build corresponding min cut in the original network */ + for (i = 1; i <= nn; i++) cut[i] = CUT[NUMB[i]]; + /* if the min cut capacity is zero (i.e. the network has + * unconnected components), the search can be prematurely + * terminated */ + if (min_cut == 0) + break; + } + /* now merge all nodes of the original network, which belong + * to the supernodes S and T, into one new supernode; this is + * attained by carrying all nodes from T to S (for the sake of + * convenience T should be the last supernode) */ + xassert(T == NV); + /* assign new references to nodes from T */ + for (i = HEAD[T]; i != 0; i = NEXT[i]) + NUMB[i] = S; + /* find last entry in the node list of S */ + i = HEAD[S]; + xassert(i != 0); + while (NEXT[i] != 0) + i = NEXT[i]; + /* and attach to it the node list of T */ + NEXT[i] = HEAD[T]; + /* decrease number of nodes in the auxiliary network */ + NV--; + } + /* free working arrays */ + xfree(HEAD); + xfree(NEXT); + xfree(NUMB); + xfree(BEG); + xfree(END); + xfree(CAP); + xfree(X); + xfree(ADJ); + xfree(SUM); + xfree(CUT); + xfree(head1); + xfree(head2); + xfree(next1); + xfree(next2); + /* return to the calling program */ + return min_cut; +} + +/* eof */ diff --git a/glpk-5.0/examples/tsp/mincut.h b/glpk-5.0/examples/tsp/mincut.h new file mode 100644 index 0000000..aefdbb7 --- /dev/null +++ b/glpk-5.0/examples/tsp/mincut.h @@ -0,0 +1,23 @@ +/* mincut.c */ + +/* Written by Andrew Makhorin <mao@gnu.org>, October 2015. */ + +#ifndef MINCUT_H +#define MINCUT_H + +int min_cut(int nn, int ne, const int beg[/*1+ne*/], + const int end[/*1+ne*/], const cap[/*1+ne*/], int cut[/*1+nn*/]); +/* find min cut in undirected capacitated network */ + +int min_st_cut(int nn, int ne, const int beg[/*1+ne*/], + const int end[/*1+ne*/], const int cap[/*1+ne*/], int s, int t, + const int x[/*1+ne*/], int cut[/*1+nn*/]); +/* find min (s,t)-cut for known max flow */ + +int min_cut_sw(int nn, int ne, const int beg[/*1+ne*/], + const int end[/*1+ne*/], const cap[/*1+ne*/], int cut[/*1+nn*/]); +/* find min cut with Stoer and Wagner algorithm */ + +#endif + +/* eof */ diff --git a/glpk-5.0/examples/tsp/misc.c b/glpk-5.0/examples/tsp/misc.c new file mode 100644 index 0000000..e0b08fb --- /dev/null +++ b/glpk-5.0/examples/tsp/misc.c @@ -0,0 +1,159 @@ +/* misc.c */ + +/* Written by Andrew Makhorin <mao@gnu.org>, October 2015. */ + +#include <ctype.h> +#include <float.h> +#include <limits.h> +#include <stdlib.h> +#include "misc.h" + +/*********************************************************************** +* NAME +* +* str2int - convert character string to value of int type +* +* SYNOPSIS +* +* #include "misc.h" +* int str2int(const 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(const 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 /* s < 0 */ + { 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 has been done */ + *val_ = val; + return 0; +} + +/*********************************************************************** +* NAME +* +* str2num - convert character string to value of double type +* +* SYNOPSIS +* +* #include "misc.h" +* int str2num(const char *str, double *val); +* +* DESCRIPTION +* +* The routine str2num 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 str2num(const 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 has been done */ + *val_ = val; + return 0; +} + +/* eof */ diff --git a/glpk-5.0/examples/tsp/misc.h b/glpk-5.0/examples/tsp/misc.h new file mode 100644 index 0000000..0973831 --- /dev/null +++ b/glpk-5.0/examples/tsp/misc.h @@ -0,0 +1,24 @@ +/* misc.h */ + +/* Written by Andrew Makhorin <mao@gnu.org>, October 2015. */ + +#ifndef MISC_H +#define MISC_H + +#include <glpk.h> + +#define xprintf glp_printf +#define xerror glp_error +#define xassert glp_assert +#define xalloc glp_alloc +#define xfree glp_free + +int str2int(const char *str, int *val); +/* convert character string to value of int type */ + +int str2num(const char *str, double *val); +/* convert character string to value of double type */ + +#endif + +/* eof */ diff --git a/glpk-5.0/examples/tsp/moscow.tsp b/glpk-5.0/examples/tsp/moscow.tsp new file mode 100644 index 0000000..a2d4ea2 --- /dev/null +++ b/glpk-5.0/examples/tsp/moscow.tsp @@ -0,0 +1,200 @@ +NAME: MOSCOW +TYPE: TSP +COMMENT: 68 cities in Moscow region (Andrew Makhorin <mao@gnu.org>) +DIMENSION: 68 +EDGE_WEIGHT_TYPE: EXPLICIT +EDGE_WEIGHT_FORMAT: LOWER_DIAG_ROW +EDGE_WEIGHT_SECTION +0 +80 0 +99 66 0 +73 153 156 0 +118 156 205 116 0 +136 103 37 190 242 0 +134 128 180 141 90 217 0 +72 75 127 126 81 164 86 0 +131 94 146 184 133 183 67 91 0 +75 38 90 136 126 127 94 45 56 0 +67 52 46 124 169 83 165 88 132 76 0 +134 66 69 207 219 68 189 138 136 101 106 0 +179 142 194 204 153 231 87 139 52 104 180 188 0 +145 98 63 216 240 26 212 159 178 122 109 53 226 0 +83 7 69 156 159 106 131 78 97 41 55 60 145 95 0 +85 38 68 158 180 105 152 99 118 62 57 74 166 100 41 0 +188 163 97 222 294 77 277 223 243 187 135 145 291 93 166 165 0 +38 101 125 92 80 162 96 34 101 71 93 164 149 176 104 116 214 0 +88 66 118 142 97 155 62 40 67 36 103 129 115 150 69 90 215 50 0 +113 50 102 174 164 139 136 83 92 46 88 94 140 134 53 74 199 109 74 0 +67 94 146 113 62 183 81 19 86 64 107 157 134 178 97 118 242 29 35 102 0 +133 132 96 167 239 91 245 168 212 156 80 159 260 117 135 137 55 159 183 + 168 187 0 +51 64 54 108 157 91 159 82 139 83 25 118 187 117 67 69 143 77 97 100 101 + 88 0 +122 116 168 129 78 205 12 74 55 82 153 177 75 200 119 140 265 84 50 124 + 69 233 147 0 +148 115 49 202 254 29 229 176 195 139 95 97 243 45 118 117 48 174 167 + 151 195 83 103 217 0 +95 32 84 156 146 121 118 65 84 28 70 95 132 116 35 56 181 91 56 18 84 + 150 82 106 133 0 +133 70 122 194 184 159 156 103 112 66 108 99 160 148 73 94 219 129 94 25 + 122 188 120 144 171 38 0 +57 58 110 118 98 147 103 17 84 28 71 121 132 142 61 82 206 43 42 66 36 + 151 65 91 159 48 86 0 +164 101 142 225 188 167 122 134 55 97 139 109 107 152 104 125 239 150 + 116 67 135 219 151 110 191 69 87 117 0 +145 93 78 218 240 41 212 159 153 122 117 27 205 26 87 100 118 176 150 + 121 178 132 129 200 70 116 126 142 126 0 +142 74 77 215 227 60 197 146 134 109 114 8 186 45 68 82 137 172 137 102 + 165 151 126 185 89 103 107 129 107 19 0 +85 48 100 146 119 137 84 55 63 10 86 111 111 132 51 72 197 72 38 56 57 + 166 93 72 149 38 76 38 107 132 119 0 +106 26 73 179 182 110 154 101 120 64 78 48 168 97 30 62 170 127 92 76 + 120 158 90 142 122 58 84 84 102 75 56 74 0 +171 138 72 225 277 52 252 199 218 162 118 120 266 68 141 140 25 197 190 + 174 218 80 126 240 23 156 194 182 214 93 112 172 145 0 +65 18 48 138 160 85 132 79 98 42 37 69 146 80 21 20 145 96 70 54 98 117 + 49 120 97 36 74 62 105 80 77 52 44 120 0 +90 163 173 17 99 207 124 111 167 138 141 217 187 228 166 168 239 77 127 + 176 96 184 125 112 219 158 196 120 222 228 225 148 189 242 148 0 +47 22 67 116 121 104 106 40 80 24 44 85 128 99 25 39 164 66 44 46 59 124 + 46 94 116 28 66 23 97 99 93 34 48 139 19 118 0 +89 26 78 150 140 115 112 59 78 22 64 89 126 110 29 50 175 85 50 24 78 + 144 76 100 127 6 44 42 75 110 97 32 52 150 30 152 22 0 +31 111 118 42 134 155 153 91 157 101 86 165 205 176 114 116 207 57 107 + 139 86 152 70 141 167 121 159 83 190 176 173 111 137 190 96 59 78 115 0 +115 35 56 188 191 93 158 110 111 73 87 31 159 80 42 45 153 136 101 63 + 129 152 99 146 105 65 68 93 86 58 39 83 17 128 53 198 57 61 146 0 +37 70 103 91 121 140 121 44 101 45 62 124 149 135 73 75 197 41 59 83 63 + 142 56 109 152 65 103 27 134 135 132 55 96 175 55 93 25 59 56 105 0 +143 142 106 177 249 101 255 178 222 166 90 169 270 127 145 147 65 169 + 193 178 197 10 98 243 93 160 198 161 229 142 161 176 168 90 127 194 134 + 154 162 162 152 0 +152 151 115 186 258 110 264 187 231 175 99 178 279 136 154 156 100 178 + 202 187 206 45 107 252 98 169 207 170 238 151 170 185 177 121 136 203 + 143 163 171 171 161 55 0 +146 74 81 219 230 70 191 149 124 112 118 12 176 55 72 84 147 175 140 102 + 168 161 130 179 99 104 107 132 97 29 10 122 56 122 81 229 96 100 177 39 + 136 171 180 0 +118 50 53 191 203 84 173 122 126 85 90 16 174 69 44 58 150 148 113 78 + 141 149 102 161 102 79 83 105 101 43 24 95 32 125 53 201 69 73 149 15 + 108 159 168 28 0 +50 56 62 107 155 99 151 74 131 75 17 110 179 121 59 61 151 76 89 92 93 + 96 8 139 111 74 112 57 143 121 118 85 82 134 41 124 38 68 69 91 48 106 + 115 122 94 0 +107 126 110 113 209 117 221 144 201 145 87 179 249 143 129 131 149 133 + 159 162 162 94 62 209 129 144 182 127 213 158 177 155 152 152 111 130 + 108 138 98 161 118 104 113 187 163 70 0 +105 42 94 166 156 131 128 75 84 38 80 86 132 126 45 66 191 101 66 8 94 + 160 92 116 143 10 28 58 59 113 94 48 68 166 46 168 38 16 131 55 75 170 + 179 94 70 84 154 0 +114 133 117 120 216 124 228 151 208 152 94 186 256 150 136 138 156 140 + 166 169 169 101 69 216 136 151 189 134 220 165 184 162 159 159 118 137 + 115 145 105 168 125 111 120 194 170 77 35 161 0 +89 42 72 162 184 109 156 103 122 66 61 70 170 104 45 4 169 120 94 78 122 + 141 73 144 121 60 98 86 127 97 78 76 58 144 24 172 43 54 120 41 79 151 + 160 80 54 65 135 70 142 0 +218 166 151 291 313 114 285 232 226 195 190 100 278 99 160 173 191 249 + 223 194 251 205 202 273 143 189 199 215 199 73 92 205 148 166 153 301 + 172 183 249 131 208 215 224 102 116 194 231 186 238 170 0 +81 147 168 48 68 205 93 80 136 117 136 208 156 219 150 159 250 46 96 155 + 65 195 120 81 217 137 175 89 191 219 216 118 173 240 139 31 109 131 66 + 182 84 205 214 220 192 119 141 147 148 163 292 0 +147 84 125 208 180 160 115 117 48 80 122 100 100 145 87 108 222 133 99 + 50 118 202 134 103 174 52 70 100 17 119 100 90 85 197 88 210 80 58 173 + 69 117 212 221 90 84 126 196 42 203 110 192 179 0 +93 112 96 99 195 103 207 130 187 131 73 165 235 129 115 117 135 119 145 + 148 148 80 48 195 115 130 168 113 199 144 163 141 138 138 97 116 94 124 + 84 147 104 90 99 173 149 56 14 140 21 121 217 127 182 0 +97 91 143 151 103 180 37 49 76 57 128 152 100 175 94 115 240 59 25 99 44 + 208 122 25 192 81 119 66 125 175 160 47 117 215 95 136 69 75 116 121 84 + 218 227 160 136 114 184 91 191 119 248 105 108 170 0 +122 121 85 156 228 80 234 157 201 145 69 148 249 106 124 126 70 148 172 + 157 176 15 77 222 68 139 177 140 208 121 140 155 147 91 106 173 113 133 + 141 141 131 25 30 150 138 85 83 149 90 130 194 184 191 69 197 0 +179 142 194 232 181 222 115 139 48 104 180 164 38 207 145 166 291 149 + 115 126 134 260 187 103 243 128 146 132 83 181 162 111 161 266 146 215 + 128 126 205 145 149 270 279 152 160 179 249 118 256 170 254 184 76 235 + 124 249 0 +38 67 82 99 144 119 146 69 126 70 50 121 174 132 70 72 171 64 84 103 88 + 116 34 134 131 85 123 52 154 132 129 80 93 154 52 116 40 79 57 102 43 + 126 135 133 105 33 90 95 97 76 205 107 137 76 109 105 174 0 +100 34 86 173 168 123 140 87 100 50 72 70 148 118 37 58 183 113 78 52 + 106 152 84 128 135 44 57 70 75 97 78 60 27 158 38 180 39 38 131 39 87 + 162 171 78 54 76 146 44 153 62 170 159 58 132 103 141 134 87 0 +69 46 98 130 117 135 82 39 72 16 83 109 120 130 49 70 195 65 20 54 55 + 163 77 70 147 36 74 22 105 130 117 26 72 170 50 132 24 30 95 81 39 173 + 182 120 93 69 139 46 146 74 203 111 88 125 45 152 120 64 58 0 +160 97 138 219 168 173 102 126 35 91 135 113 87 158 100 121 235 136 102 + 63 121 215 147 90 187 65 83 113 30 132 113 98 98 210 101 202 93 71 186 + 82 130 225 234 103 97 139 209 55 216 123 205 171 13 195 111 204 83 150 + 71 101 0 +70 89 73 110 176 104 184 107 164 108 50 142 212 130 92 94 136 96 122 125 + 125 81 25 172 116 107 145 90 176 145 150 118 115 139 74 127 71 101 89 + 124 81 91 100 154 126 33 37 117 44 98 218 138 159 23 147 70 212 53 109 + 102 172 0 +188 136 121 261 283 84 255 202 196 165 160 70 248 69 130 143 161 219 193 + 164 221 175 172 243 113 159 169 185 169 43 62 175 118 136 123 271 142 + 153 219 101 178 185 194 72 86 164 201 156 208 140 30 262 162 187 218 + 164 224 175 140 173 175 188 0 +94 28 80 167 162 117 134 81 100 44 66 69 148 112 31 52 177 107 72 56 100 + 146 78 122 129 38 63 64 81 96 77 54 21 152 32 174 33 32 125 38 81 156 + 165 77 53 70 140 48 147 56 169 153 64 126 97 135 140 81 6 52 77 103 139 + 0 +45 43 75 118 142 112 138 61 118 62 30 97 166 108 46 48 164 76 76 79 80 + 109 21 126 124 61 99 44 130 108 105 72 69 147 28 128 25 55 76 78 35 119 + 128 109 81 13 83 71 90 52 181 119 113 69 101 98 166 32 63 56 126 46 151 + 57 0 +113 35 48 186 191 85 163 110 119 73 85 37 167 72 39 37 145 136 101 71 + 129 144 97 151 97 67 76 93 94 64 45 83 25 120 48 196 57 61 144 8 103 + 154 163 47 21 89 158 63 165 33 137 182 77 144 126 133 153 100 47 81 90 + 121 107 46 76 0 +97 21 57 170 173 94 145 92 111 55 69 46 159 81 14 55 154 118 83 67 111 + 149 81 133 106 49 87 75 118 73 54 65 18 129 35 180 39 43 128 33 87 159 + 168 58 30 73 143 59 150 58 146 164 101 129 108 138 159 84 45 63 114 106 + 116 39 60 25 0 +116 79 131 177 133 168 98 76 51 41 117 127 63 163 82 103 228 86 52 77 71 + 197 124 86 180 69 97 69 100 154 135 48 105 203 83 163 65 63 142 96 86 + 207 216 135 111 116 186 69 193 107 227 132 83 172 61 186 63 111 85 57 + 86 149 197 85 103 104 96 0 +EOF + +Vertices of the graph: + 1 Aprelevka 35 Lyubertsy + 2 Balashikha 36 Mozhaysk + 3 Bronnitsy 37 Moskva + 4 Vereya 38 Mytischi + 5 Volokolamsk 39 Naro-Fominsk + 6 Voskresensk 40 Noginsk + 7 Vysokovsk 41 Odintsovo + 8 Dedovsk 42 Ozherel'ye + 9 Dmitrov 43 Ozyory +10 Dolgoprudny 44 Orekhovo-Zuevo +11 Domodedovo 45 Pavlovsky Posad +12 Drezna 46 Podol'sk +13 Dubna 47 Protvino +14 Egor'yevsk 48 Pushkino +15 Zheleznodorozhny 49 Puschino +16 Zhukovsky 50 Ramenskoye +17 Zaraysk 51 Roshal +18 Zvenigorod 52 Ruza +19 Zelenograd 53 Sergiyev Posad +20 Ivanteyevka 54 Serpukhov +21 Istra 55 Solnechnogorsk +22 Kashira 56 Stupino +23 Klimovsk 57 Taldom +24 Klin 58 Troitsk +25 Kolomna 59 Fryazino +26 Korolyov (Podlipki) 60 Khimki +27 Krasnoarmeysk 61 Khot'kovo +28 Krasnogorsk 62 Chekhov +29 Krasnozavodsk 63 Shatura +30 Kurovskoye 64 Schyolkovo +31 Likino-Dulyovo 65 Scherbinka +32 Lobnya 66 Elektrostal +33 Losino-Petrovsky 67 Elektrougli +34 Lukhovitsy 68 Yakhroma + +Optimal tour length is 1994 kilometers (obtained by glpk tspsol): +1 39 4 36 52 5 7 24 55 19 60 10 32 68 13 57 9 61 53 29 27 20 48 26 38 +59 64 33 67 15 2 35 16 50 66 40 45 12 44 31 63 51 30 14 6 3 25 34 17 22 +42 56 43 47 49 54 62 23 46 11 65 58 41 37 28 8 21 18 1 diff --git a/glpk-5.0/examples/tsp/sample.tsp b/glpk-5.0/examples/tsp/sample.tsp new file mode 100644 index 0000000..9e1367a --- /dev/null +++ b/glpk-5.0/examples/tsp/sample.tsp @@ -0,0 +1,16 @@ +NAME: SAMPLE +TYPE: TSP +COMMENT: Example from D.Phillips, A.Garcia-Diaz, p.124 +DIMENSION: 8 +EDGE_WEIGHT_TYPE: EXPLICIT +EDGE_WEIGHT_FORMAT: LOWER_DIAG_ROW +EDGE_WEIGHT_SECTION +0 +190 0 +210 380 0 +680 760 890 0 +690 790 900 480 0 +460 610 340 760 890 0 +780 670 410 510 490 720 0 +750 450 600 250 560 600 500 0 +EOF diff --git a/glpk-5.0/examples/tsp/tsplib.c b/glpk-5.0/examples/tsp/tsplib.c new file mode 100644 index 0000000..189ff8a --- /dev/null +++ b/glpk-5.0/examples/tsp/tsplib.c @@ -0,0 +1,730 @@ +/* tsplib.c */ + +/* Written by Andrew Makhorin <mao@gnu.org>, October 2015. */ + +#include <ctype.h> +#include <errno.h> +#include <float.h> +#include <math.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "misc.h" +#include "tsplib.h" + +/*********************************************************************** +* NAME +* +* tsp_read_data - read TSP instance data +* +* SYNOPSIS +* +* #include "tsplib.h" +* TSP *tsp_read_data(const char *fname); +* +* DESCRIPTION +* +* The routine tsp_read_data reads a TSP (or related problem) instance +* data from a text file, whose name is the character string fname. +* +* For detailed description of the format recognized by the routine see +* the report: G.Reinelt, TSPLIB 95. +* +* RETURNS +* +* If no error occurred, the routine tsp_read_data returns a pointer to +* the TSP instance data block, which contains loaded data. In the case +* of error the routine prints an error message and returns NULL. */ + +struct csa +{ /* common storage area used by the routine tsp_read_data */ + const char *fname; + /* name of the input text file */ + FILE *fp; + /* stream assigned to the input text file */ + int seqn; + /* line sequential number */ + int c; + /* current character */ + char token[255+1]; + /* current token */ +}; + +static int get_char(struct csa *csa) +{ csa->c = fgetc(csa->fp); + if (ferror(csa->fp)) + { xprintf("%s:%d: read error - %s\n", csa->fname, csa->seqn, + strerror(errno)); + return 1; + } + if (feof(csa->fp)) + csa->c = EOF; + else if (csa->c == '\n') + csa->seqn++; + else if (isspace(csa->c)) + csa->c = ' '; + else if (iscntrl(csa->c)) + { xprintf("%s:%d: invalid control character 0x%02X\n", + csa->fname, csa->seqn, csa->c); + return 1; + } + return 0; +} + +static int skip_spaces(struct csa *csa, int across) +{ while (csa->c == ' ' || (across && csa->c == '\n')) + if (get_char(csa)) return 1; + return 0; +} + +static int scan_keyword(struct csa *csa) +{ int len = 0; + if (skip_spaces(csa, 0)) + return 1; + if (csa->c == EOF) + { xprintf("%s:%d: warning: missing EOF inserted\n", csa->fname, + csa->seqn); + strcpy(csa->token, "EOF"); + return 0; + } + csa->token[0] = '\0'; + while (isalnum(csa->c) || csa->c == '_') + { if (len == 31) + { xprintf("%s:%d: keyword '%s...' too long\n", csa->fname, + csa->seqn, csa->token); + return 1; + } + csa->token[len++] = (char)csa->c, csa->token[len] = '\0'; + if (get_char(csa)) + return 1; + } + if (len == 0) + { xprintf("%s:%d: missing keyword\n", csa->fname, csa->seqn); + return 1; + } + return 0; +} + +static int check_colon(struct csa *csa) +{ if (skip_spaces(csa, 0)) + return 1; + if (csa->c != ':') + { xprintf("%s:%d: missing colon after '%s'\n", csa->fname, + csa->seqn, csa->token); + return 1; + } + if (get_char(csa)) + return 1; + return 0; +} + +static int scan_token(struct csa *csa, int across) +{ int len = 0; + if (skip_spaces(csa, across)) + return 1; + csa->token[0] = '\0'; + while (!(csa->c == EOF || csa->c == '\n' || csa->c == ' ')) + { if (len == 255) + { csa->token[31] = '\0'; + xprintf("%s:%d: token '%s...' too long\n", csa->fname, + csa->seqn, csa->token); + return 1; + } + csa->token[len++] = (char)csa->c, csa->token[len] = '\0'; + if (get_char(csa)) + return 1; + } + return 0; +} + +static int check_newline(struct csa *csa) +{ if (skip_spaces(csa, 0)) + return 1; + if (!(csa->c == EOF || csa->c == '\n')) + { xprintf("%s:%d: extra symbols detected\n", csa->fname, + csa->seqn); + return 1; + } + if (get_char(csa)) + return 1; + return 0; +} + +static int scan_comment(struct csa *csa) +{ int len = 0; + if (skip_spaces(csa, 0)) + return 1; + csa->token[0] = '\0'; + while (!(csa->c == EOF || csa->c == '\n')) + { if (len == 255) + { xprintf("%s:%d: comment too long\n", csa->fname, csa->seqn); + return 1; + } + csa->token[len++] = (char)csa->c, csa->token[len] = '\0'; + if (get_char(csa)) + return 1; + } + return 0; +} + +static int scan_integer(struct csa *csa, int across, int *val) +{ if (scan_token(csa, across)) + return 1; + if (strlen(csa->token) == 0) + { xprintf("%s:%d: missing integer\n", csa->fname, csa->seqn); + return 1; + } + if (str2int(csa->token, val)) + { xprintf("%s:%d: integer '%s' invalid\n", csa->fname, csa->seqn, + csa->token); + return 1; + } + return 0; +} + +static int scan_number(struct csa *csa, int across, double *val) +{ if (scan_token(csa, across)) + return 1; + if (strlen(csa->token) == 0) + { xprintf("%s:%d: missing number\n", csa->fname, csa->seqn); + return 1; + } + if (str2num(csa->token, val)) + { xprintf("%s:%d: number '%s' invalid\n", csa->fname, csa->seqn, + csa->token); + return 1; + } + return 0; +} + +TSP *tsp_read_data(const char *fname) +{ struct csa _dsa, *csa = &_dsa; + TSP *tsp = NULL; + csa->fname = fname; + xprintf("Reading TSP data from '%s'...\n", csa->fname); + csa->fp = fopen(csa->fname, "r"); + if (csa->fp == NULL) + { xprintf("Unable to open '%s' - %s\n", csa->fname, + strerror(errno)); + goto fail; + } + tsp = xalloc(1, sizeof(TSP)); + tsp->name = NULL; + tsp->type = TSP_UNDEF; + tsp->comment = NULL; + tsp->dimension = 0; + tsp->edge_weight_type = TSP_UNDEF; + tsp->edge_weight_format = TSP_UNDEF; + tsp->display_data_type = TSP_UNDEF; + tsp->node_x_coord = NULL; + tsp->node_y_coord = NULL; + tsp->dply_x_coord = NULL; + tsp->dply_y_coord = NULL; + tsp->tour = NULL; + tsp->edge_weight = NULL; + csa->seqn = 1; + if (get_char(csa)) + goto fail; +loop: if (scan_keyword(csa)) + goto fail; + if (strcmp(csa->token, "NAME") == 0) + { if (tsp->name != NULL) + { xprintf("%s:%d: NAME entry multiply defined\n", csa->fname, + csa->seqn); + goto fail; + } + if (check_colon(csa)) + goto fail; + if (scan_token(csa, 0)) + goto fail; + if (strlen(csa->token) == 0) + { xprintf("%s:%d: NAME entry incomplete\n", csa->fname, + csa->seqn); + goto fail; + } + tsp->name = xalloc(strlen(csa->token)+1, sizeof(char)); + strcpy(tsp->name, csa->token); + xprintf("NAME: %s\n", tsp->name); + if (check_newline(csa)) + goto fail; + } + else if (strcmp(csa->token, "TYPE") == 0) + { if (tsp->type != TSP_UNDEF) + { xprintf("%s:%d: TYPE entry multiply defined\n", csa->fname, + csa->seqn); + goto fail; + } + if (check_colon(csa)) + goto fail; + if (scan_keyword(csa)) + goto fail; + if (strcmp(csa->token, "TSP") == 0) + tsp->type = TSP_TSP; + else if (strcmp(csa->token, "ATSP") == 0) + tsp->type = TSP_ATSP; + else if (strcmp(csa->token, "TOUR") == 0) + tsp->type = TSP_TOUR; + else + { xprintf("%s:%d: data type '%s' not recognized\n", + csa->fname, csa->seqn, csa->token); + goto fail; + } + xprintf("TYPE: %s\n", csa->token); + if (check_newline(csa)) + goto fail; + } + else if (strcmp(csa->token, "COMMENT") == 0) + { if (check_colon(csa)) + goto fail; + if (scan_comment(csa)) + goto fail; + xprintf("COMMENT: %s\n", csa->token); + if (tsp->comment == NULL) + { tsp->comment = xalloc(strlen(csa->token)+1, sizeof(char)); + strcpy(tsp->comment, csa->token); + } + else + { xprintf("%s:%d: warning: extra COMMENT entry ignored\n", + csa->fname, csa->seqn); + } + if (check_newline(csa)) + goto fail; + } + else if (strcmp(csa->token, "DIMENSION") == 0) + { if (tsp->dimension != 0) + { xprintf("%s:%d: DIMENSION entry multiply defined\n", + csa->fname, csa->seqn); + goto fail; + } + if (check_colon(csa)) + goto fail; + if (scan_integer(csa, 0, &tsp->dimension)) + goto fail; + if (tsp->dimension < 1) + { xprintf("%s:%d: invalid dimension\n", csa->fname, + csa->seqn); + goto fail; + } + xprintf("DIMENSION: %d\n", tsp->dimension); + if (check_newline(csa)) + goto fail; + } + else if (strcmp(csa->token, "EDGE_WEIGHT_TYPE") == 0) + { if (tsp->edge_weight_type != TSP_UNDEF) + { xprintf("%s:%d: EDGE_WEIGHT_TYPE entry multiply defined\n", + csa->fname, csa->seqn); + goto fail; + } + if (check_colon(csa)) + goto fail; + if (scan_keyword(csa)) + goto fail; + if (strcmp(csa->token, "GEO") == 0) + tsp->edge_weight_type = TSP_GEO; + else if (strcmp(csa->token, "EUC_2D") == 0) + tsp->edge_weight_type = TSP_EUC_2D; + else if (strcmp(csa->token, "ATT") == 0) + tsp->edge_weight_type = TSP_ATT; + else if (strcmp(csa->token, "EXPLICIT") == 0) + tsp->edge_weight_type = TSP_EXPLICIT; + else if (strcmp(csa->token, "CEIL_2D") == 0) + tsp->edge_weight_type = TSP_CEIL_2D; + else + { xprintf("%s:%d: edge weight type '%s' not recognized\n", + csa->fname, csa->seqn, csa->token); + goto fail; + } + xprintf("EDGE_WEIGHT_TYPE: %s\n", csa->token); + if (check_newline(csa)) + goto fail; + } + else if (strcmp(csa->token, "EDGE_WEIGHT_FORMAT") == 0) + { if (tsp->edge_weight_format != TSP_UNDEF) + { xprintf("%s:%d: EDGE_WEIGHT_FORMAT entry multiply defined\n" + , csa->fname, csa->seqn); + goto fail; + } + if (check_colon(csa)) + goto fail; + if (scan_keyword(csa)) + goto fail; + if (strcmp(csa->token, "UPPER_ROW") == 0) + tsp->edge_weight_format = TSP_UPPER_ROW; + else if (strcmp(csa->token, "FULL_MATRIX") == 0) + tsp->edge_weight_format = TSP_FULL_MATRIX; + else if (strcmp(csa->token, "FUNCTION") == 0) + tsp->edge_weight_format = TSP_FUNCTION; + else if (strcmp(csa->token, "LOWER_DIAG_ROW") == 0) + tsp->edge_weight_format = TSP_LOWER_DIAG_ROW; + else + { xprintf("%s:%d: edge weight format '%s' not recognized\n", + csa->fname, csa->seqn, csa->token); + goto fail; + } + xprintf("EDGE_WEIGHT_FORMAT: %s\n", csa->token); + if (check_newline(csa)) + goto fail; + } + else if (strcmp(csa->token, "DISPLAY_DATA_TYPE") == 0) + { if (tsp->display_data_type != TSP_UNDEF) + { xprintf("%s:%d: DISPLAY_DATA_TYPE entry multiply defined\n", + csa->fname, csa->seqn); + goto fail; + } + if (check_colon(csa)) + goto fail; + if (scan_keyword(csa)) + goto fail; + if (strcmp(csa->token, "COORD_DISPLAY") == 0) + tsp->display_data_type = TSP_COORD_DISPLAY; + else if (strcmp(csa->token, "TWOD_DISPLAY") == 0) + tsp->display_data_type = TSP_TWOD_DISPLAY; + else + { xprintf("%s:%d: display data type '%s' not recognized\n", + csa->fname, csa->seqn, csa->token); + goto fail; + } + xprintf("DISPLAY_DATA_TYPE: %s\n", csa->token); + if (check_newline(csa)) + goto fail; + } + else if (strcmp(csa->token, "NODE_COORD_SECTION") == 0) + { int n = tsp->dimension, k, node; + if (n == 0) + { xprintf("%s:%d: DIMENSION entry not specified\n", + csa->fname, csa->seqn); + goto fail; + } + if (tsp->node_x_coord != NULL) + { xprintf("%s:%d: NODE_COORD_SECTION multiply specified\n", + csa->fname, csa->seqn); + goto fail; + } + if (check_newline(csa)) + goto fail; + tsp->node_x_coord = xalloc(1+n, sizeof(double)); + tsp->node_y_coord = xalloc(1+n, sizeof(double)); + for (node = 1; node <= n; node++) + tsp->node_x_coord[node] = tsp->node_y_coord[node] = DBL_MAX; + for (k = 1; k <= n; k++) + { if (scan_integer(csa, 0, &node)) + goto fail; + if (!(1 <= node && node <= n)) + { xprintf("%s:%d: invalid node number %d\n", csa->fname, + csa->seqn, node); + goto fail; + } + if (tsp->node_x_coord[node] != DBL_MAX) + { xprintf("%s:%d: node number %d multiply specified\n", + csa->fname, csa->seqn, node); + goto fail; + } + if (scan_number(csa, 0, &tsp->node_x_coord[node])) + goto fail; + if (scan_number(csa, 0, &tsp->node_y_coord[node])) + goto fail; + if (check_newline(csa)) + goto fail; + } + } + else if (strcmp(csa->token, "DISPLAY_DATA_SECTION") == 0) + { int n = tsp->dimension, k, node; + if (n == 0) + { xprintf("%s:%d: DIMENSION entry not specified\n", + csa->fname, csa->seqn); + goto fail; + } + if (tsp->dply_x_coord != NULL) + { xprintf("%s:%d: DISPLAY_DATA_SECTION multiply specified\n", + csa->fname, csa->seqn); + goto fail; + } + if (check_newline(csa)) + goto fail; + tsp->dply_x_coord = xalloc(1+n, sizeof(double)); + tsp->dply_y_coord = xalloc(1+n, sizeof(double)); + for (node = 1; node <= n; node++) + tsp->dply_x_coord[node] = tsp->dply_y_coord[node] = DBL_MAX; + for (k = 1; k <= n; k++) + { if (scan_integer(csa, 0, &node)) + goto fail; + if (!(1 <= node && node <= n)) + { xprintf("%s:%d: invalid node number %d\n", csa->fname, + csa->seqn, node); + goto fail; + } + if (tsp->dply_x_coord[node] != DBL_MAX) + { xprintf("%s:%d: node number %d multiply specified\n", + csa->fname, csa->seqn, node); + goto fail; + } + if (scan_number(csa, 0, &tsp->dply_x_coord[node])) + goto fail; + if (scan_number(csa, 0, &tsp->dply_y_coord[node])) + goto fail; + if (check_newline(csa)) + goto fail; + } + } + else if (strcmp(csa->token, "TOUR_SECTION") == 0) + { int n = tsp->dimension, k, node; + if (n == 0) + { xprintf("%s:%d: DIMENSION entry not specified\n", + csa->fname, csa->seqn); + goto fail; + } + if (tsp->tour != NULL) + { xprintf("%s:%d: TOUR_SECTION multiply specified\n", + csa->fname, csa->seqn); + goto fail; + } + if (check_newline(csa)) + goto fail; + tsp->tour = xalloc(1+n, sizeof(int)); + for (k = 1; k <= n; k++) + { if (scan_integer(csa, 1, &node)) + goto fail; + if (!(1 <= node && node <= n)) + { xprintf("%s:%d: invalid node number %d\n", csa->fname, + csa->seqn, node); + goto fail; + } + tsp->tour[k] = node; + } + if (scan_integer(csa, 1, &node)) + goto fail; + if (node != -1) + { xprintf("%s:%d: extra node(s) detected\n", csa->fname, + csa->seqn); + goto fail; + } + if (check_newline(csa)) + goto fail; + } + else if (strcmp(csa->token, "EDGE_WEIGHT_SECTION") == 0) + { int n = tsp->dimension, i, j, temp; + if (n == 0) + { xprintf("%s:%d: DIMENSION entry not specified\n", + csa->fname, csa->seqn); + goto fail; + } + if (tsp->edge_weight_format == TSP_UNDEF) + { xprintf("%s:%d: EDGE_WEIGHT_FORMAT entry not specified\n", + csa->fname, csa->seqn); + goto fail; + } + if (tsp->edge_weight != NULL) + { xprintf("%s:%d: EDGE_WEIGHT_SECTION multiply specified\n", + csa->fname, csa->seqn); + goto fail; + } + if (check_newline(csa)) + goto fail; + tsp->edge_weight = xalloc(1+n*n, sizeof(int)); + switch (tsp->edge_weight_format) + { case TSP_FULL_MATRIX: + for (i = 1; i <= n; i++) + { for (j = 1; j <= n; j++) + { if (scan_integer(csa, 1, &temp)) + goto fail; + tsp->edge_weight[(i - 1) * n + j] = temp; + } + } + break; + case TSP_UPPER_ROW: + for (i = 1; i <= n; i++) + { tsp->edge_weight[(i - 1) * n + i] = 0; + for (j = i + 1; j <= n; j++) + { if (scan_integer(csa, 1, &temp)) + goto fail; + tsp->edge_weight[(i - 1) * n + j] = temp; + tsp->edge_weight[(j - 1) * n + i] = temp; + } + } + break; + case TSP_LOWER_DIAG_ROW: + for (i = 1; i <= n; i++) + { for (j = 1; j <= i; j++) + { if (scan_integer(csa, 1, &temp)) + goto fail; + tsp->edge_weight[(i - 1) * n + j] = temp; + tsp->edge_weight[(j - 1) * n + i] = temp; + } + } + break; + default: + goto fail; + } + if (check_newline(csa)) + goto fail; + } + else if (strcmp(csa->token, "EOF") == 0) + { if (check_newline(csa)) + goto fail; + goto done; + } + else + { xprintf("%s:%d: keyword '%s' not recognized\n", csa->fname, + csa->seqn, csa->token); + goto fail; + } + goto loop; +done: xprintf("%d lines were read\n", csa->seqn-1); + fclose(csa->fp); + return tsp; +fail: if (tsp != NULL) + { if (tsp->name != NULL) + xfree(tsp->name); + if (tsp->comment != NULL) + xfree(tsp->comment); + if (tsp->node_x_coord != NULL) + xfree(tsp->node_x_coord); + if (tsp->node_y_coord != NULL) + xfree(tsp->node_y_coord); + if (tsp->dply_x_coord != NULL) + xfree(tsp->dply_x_coord); + if (tsp->dply_y_coord != NULL) + xfree(tsp->dply_y_coord); + if (tsp->tour != NULL) + xfree(tsp->tour); + if (tsp->edge_weight != NULL) + xfree(tsp->edge_weight); + xfree(tsp); + } + if (csa->fp != NULL) + fclose(csa->fp); + return NULL; +} + +/*********************************************************************** +* NAME +* +* tsp_distance - compute distance between two nodes +* +* SYNOPSIS +* +* #include "tsplib.h" +* int tsp_distance(TSP *tsp, int i, int j); +* +* DESCRIPTION +* +* The routine tsp_distance computes the distance between i-th and j-th +* nodes for the TSP instance, which tsp points to. +* +* RETURNS +* +* The routine tsp_distance returns the computed distance. */ + +#define nint(x) ((int)((x) + 0.5)) + +static double rad(double x) +{ /* convert input coordinate to longitude/latitude, in radians */ + double pi = 3.141592, deg, min; + deg = (int)x; + min = x - deg; + return pi * (deg + 5.0 * min / 3.0) / 180.0; +} + +int tsp_distance(const TSP *tsp, int i, int j) +{ int n = tsp->dimension, dij; + if (!(tsp->type == TSP_TSP || tsp->type == TSP_ATSP)) + xerror("tsp_distance: invalid TSP instance\n"); + if (!(1 <= i && i <= n && 1 <= j && j <= n)) + xerror("tsp_distance: node number out of range\n"); + switch (tsp->edge_weight_type) + { case TSP_UNDEF: + xerror("tsp_distance: edge weight type not specified\n"); + case TSP_EXPLICIT: + if (tsp->edge_weight == NULL) + xerror("tsp_distance: edge weights not specified\n"); + dij = tsp->edge_weight[(i - 1) * n + j]; + break; + case TSP_EUC_2D: + if (tsp->node_x_coord == NULL || tsp->node_y_coord == NULL) + xerror("tsp_distance: node coordinates not specified\n"); + { double xd, yd; + xd = tsp->node_x_coord[i] - tsp->node_x_coord[j]; + yd = tsp->node_y_coord[i] - tsp->node_y_coord[j]; + dij = nint(sqrt(xd * xd + yd * yd)); + } + break; + case TSP_CEIL_2D: + if (tsp->node_x_coord == NULL || tsp->node_y_coord == NULL) + xerror("tsp_distance: node coordinates not specified\n"); + { double xd, yd; + xd = tsp->node_x_coord[i] - tsp->node_x_coord[j]; + yd = tsp->node_y_coord[i] - tsp->node_y_coord[j]; + dij = (int)ceil(sqrt(xd * xd + yd * yd)); + } + break; + case TSP_GEO: + if (tsp->node_x_coord == NULL || tsp->node_y_coord == NULL) + xerror("tsp_distance: node coordinates not specified\n"); + { double rrr = 6378.388; + double latitude_i = rad(tsp->node_x_coord[i]); + double latitude_j = rad(tsp->node_x_coord[j]); + double longitude_i = rad(tsp->node_y_coord[i]); + double longitude_j = rad(tsp->node_y_coord[j]); + double q1 = cos(longitude_i - longitude_j); + double q2 = cos(latitude_i - latitude_j); + double q3 = cos(latitude_i + latitude_j); + dij = (int)(rrr * acos(0.5 * ((1.0 + q1) * q2 - + (1.0 - q1) *q3)) + 1.0); + } + break; + case TSP_ATT: + if (tsp->node_x_coord == NULL || tsp->node_y_coord == NULL) + xerror("tsp_distance: node coordinates not specified\n"); + { int tij; + double xd, yd, rij; + xd = tsp->node_x_coord[i] - tsp->node_x_coord[j]; + yd = tsp->node_y_coord[i] - tsp->node_y_coord[j]; + rij = sqrt((xd * xd + yd * yd) / 10.0); + tij = nint(rij); + if (tij < rij) dij = tij + 1; else dij = tij; + } + break; + default: + xassert(tsp->edge_weight_type != tsp->edge_weight_type); + } + return dij; +} + +/*********************************************************************** +* NAME +* +* tsp_free_data - free TSP instance data +* +* SYNOPSIS +* +* #include "tsplib.h" +* void tsp_free_data(TSP *tsp); +* +* DESCRIPTION +* +* The routine tsp_free_data frees all the memory allocated to the TSP +* instance data block, which the parameter tsp points to. */ + +void tsp_free_data(TSP *tsp) +{ if (tsp->name != NULL) + xfree(tsp->name); + if (tsp->comment != NULL) + xfree(tsp->comment); + if (tsp->node_x_coord != NULL) + xfree(tsp->node_x_coord); + if (tsp->node_y_coord != NULL) + xfree(tsp->node_y_coord); + if (tsp->dply_x_coord != NULL) + xfree(tsp->dply_x_coord); + if (tsp->dply_y_coord != NULL) + xfree(tsp->dply_y_coord); + if (tsp->tour != NULL) + xfree(tsp->tour); + if (tsp->edge_weight != NULL) + xfree(tsp->edge_weight); + xfree(tsp); + return; +} + +/* eof */ diff --git a/glpk-5.0/examples/tsp/tsplib.h b/glpk-5.0/examples/tsp/tsplib.h new file mode 100644 index 0000000..19936ad --- /dev/null +++ b/glpk-5.0/examples/tsp/tsplib.h @@ -0,0 +1,80 @@ +/* tsplib.h */ + +/* Written by Andrew Makhorin <mao@gnu.org>, October 2015. */ + +#ifndef TSPLIB_H +#define TSPLIB_H + +typedef struct TSP TSP; + +struct TSP +{ /* TSP (or related problem) instance in the format described in + * [G.Reinelt, TSPLIB 95] */ + /*--------------------------------------------------------------*/ + /* 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 triangular 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(const char *fname); +/* read TSP instance data */ + +int tsp_distance(const TSP *tsp, int i, int j); +/* compute distance between two nodes */ + +void tsp_free_data(TSP *tsp); +/* free TSP instance data */ + +#endif + +/* eof */ diff --git a/glpk-5.0/examples/tsp/ulysses16.tsp b/glpk-5.0/examples/tsp/ulysses16.tsp new file mode 100644 index 0000000..4ce24a6 --- /dev/null +++ b/glpk-5.0/examples/tsp/ulysses16.tsp @@ -0,0 +1,24 @@ +NAME: ulysses16.tsp +TYPE: TSP +COMMENT: Odyssey of Ulysses (Groetschel/Padberg) +DIMENSION: 16 +EDGE_WEIGHT_TYPE: GEO +DISPLAY_DATA_TYPE: COORD_DISPLAY +NODE_COORD_SECTION + 1 38.24 20.42 + 2 39.57 26.15 + 3 40.56 25.32 + 4 36.26 23.12 + 5 33.48 10.54 + 6 37.56 12.19 + 7 38.42 13.11 + 8 37.52 20.44 + 9 41.23 9.10 + 10 41.17 13.05 + 11 36.08 -5.21 + 12 38.47 15.13 + 13 38.15 15.35 + 14 37.51 15.17 + 15 35.49 14.32 + 16 39.36 19.56 + EOF diff --git a/glpk-5.0/examples/tsp/ulysses22.tsp b/glpk-5.0/examples/tsp/ulysses22.tsp new file mode 100644 index 0000000..9e95fb8 --- /dev/null +++ b/glpk-5.0/examples/tsp/ulysses22.tsp @@ -0,0 +1,30 @@ +NAME: ulysses22.tsp +TYPE: TSP +COMMENT: Odyssey of Ulysses (Groetschel/Padberg) +DIMENSION: 22 +EDGE_WEIGHT_TYPE: GEO +DISPLAY_DATA_TYPE: COORD_DISPLAY +NODE_COORD_SECTION + 1 38.24 20.42 + 2 39.57 26.15 + 3 40.56 25.32 + 4 36.26 23.12 + 5 33.48 10.54 + 6 37.56 12.19 + 7 38.42 13.11 + 8 37.52 20.44 + 9 41.23 9.10 + 10 41.17 13.05 + 11 36.08 -5.21 + 12 38.47 15.13 + 13 38.15 15.35 + 14 37.51 15.17 + 15 35.49 14.32 + 16 39.36 19.56 + 17 38.09 24.36 + 18 36.09 23.00 + 19 40.44 13.57 + 20 40.33 14.15 + 21 40.37 14.23 + 22 37.57 22.56 +EOF diff --git a/glpk-5.0/examples/wolfra6d.lp b/glpk-5.0/examples/wolfra6d.lp new file mode 100644 index 0000000..a3437d8 --- /dev/null +++ b/glpk-5.0/examples/wolfra6d.lp @@ -0,0 +1,596 @@ +\* Any Wolfram elementary CA in 6D eucl. Neumann CA grid emulator generator *\ + +\* Written and converted to *LP format by NASZVADI, Peter, 2016,2017 *\ +\* <vuk@cs.elte.hu> *\ + +\* Standalone version; GMPL version is in wolfra6d.mod *\ + +\* This model looks up for a subset of vertices in 6D euclyd. grid, *\ +\* which has the following properties: *\ +\* 1. each vertex' coordinate pairs' difference is at most 1 *\ +\* 2. contains the vertices in the main diagonal of the 6d space *\ +\* 3. connecting with directed graph edges from all selected vertices *\ +\* to all selected ones with greater coordinate sums with *\ +\* Hamming-distance 1, the following in-out edge numbers are *\ +\* allowed: (3,6), (1,2), (2,3), (1,2), (4,1), (3,1); according to *\ +\* the mod 6 sum of the coordinate values *\ +\* 4. Only vertices of the unit cube's with {0,1} coordinates are *\ +\* calculated, but the other cells could be obtained via shifting. *\ +\* Assume that the grid is a 6dim. cellular automaton grid with Neumann- *\ +\* -neighbourhood, now construct an outer-totalistic rule that emulates *\ +\* W110 cellular automaton on the selected vertices: *\ +\* Suppose that the 1D W110 cellspace cells are denoted with signed *\ +\* integers. Every 1D cell is assigned to (at most "6 over 2") selected *\ +\* vertices where each coordinate sums are the same with the integer *\ +\* assigned to the origin cell in the domain, they must have the same *\ +\* value. Rule-110 means that cell's value is being changed only when its *\ +\* neighbours are: (1,1,1), (1,0,1), (0,0,1), other cells remain unchanged. *\ +\* Let's denote the default cellstate with "2" in the 6D automaton, and *\ +\* the remaining 2 states with "0" and "1" respectively, which correspond *\ +\* with the states in W110. The selected vertices must be 0 or 1 of course, *\ +\* and the others are "2". *\ +\* Now, the transition rule for emulating W110 is the following: *\ +\* (x),{1,1,1,1,1,1,1,1,1,2,2,2}->(1-x), x!=2, *\ +\* (x),{1,1,1,2,2,2,2,2,2,2,2,2}->(1-x), x!=2, *\ +\* (x),{1,1,1,1,2,2,2,2,2,2,2,2}->(1-x), x!=2, *\ +\* (x),{1,1,1,1,1,2,2,2,2,2,2,2}->(1-x), x!=2, *\ +\* (1),{0,0,0,1,1,1,1,1,1,2,2,2}->(0), *\ +\* (1),{0,1,1,2,2,2,2,2,2,2,2,2}->(0), *\ +\* (1),{0,0,1,1,1,2,2,2,2,2,2,2}->(0), *\ +\* (1),{0,0,0,0,1,2,2,2,2,2,2,2}->(0), *\ +\* (1),{0,0,0,1,2,2,2,2,2,2,2,2}->(0); *\ +\* notation: (old state),{old neighbours - all permutations}->(new state) *\ +\* Other states won't change between two generations. And is known that W110 *\ +\* is Turing-complete. So there is a universal CA rule in 6+D eucl. gridS *\ +\* Result is in x****** binary variables (total 44 among the 64) *\ + +Minimize + obj: x000000 +x000001 +x000010 +x000011 +x000100 +x000101 +x000110 +x000111 + +x001000 +x001001 +x001010 +x001011 +x001100 +x001101 +x001110 +x001111 + +x010000 +x010001 +x010010 +x010011 +x010100 +x010101 +x010110 +x010111 + +x011000 +x011001 +x011010 +x011011 +x011100 +x011101 +x011110 +x011111 + +x100000 +x100001 +x100010 +x100011 +x100100 +x100101 +x100110 +x100111 + +x101000 +x101001 +x101010 +x101011 +x101100 +x101101 +x101110 +x101111 + +x110000 +x110001 +x110010 +x110011 +x110100 +x110101 +x110110 +x110111 + +x111000 +x111001 +x111010 +x111011 +x111100 +x111101 +x111110 +x111111 +Subject To + x000000 = 1 + x111111 = 1 + x111110 -x111101 >= 0 + x111101 -x111011 >= 0 + x111011 -x110111 >= 0 + x110111 -x101111 >= 0 + x101111 -x011111 >= 0 + dn000000 -dn111111 = 0 + up000000 -up111111 = 0 + cup000000: + x000001 +x000010 +x000100 +x001000 +x010000 +x100000 -up000000 = 0 + cup000001: + x000011 +x000101 +x001001 +x010001 +x100001 -up000001 = 0 + cup000010: + x000011 +x000110 +x001010 +x010010 +x100010 -up000010 = 0 + cup000011: + x000111 +x001011 +x010011 +x100011 -up000011 = 0 + cup000100: + x000101 +x000110 +x001100 +x010100 +x100100 -up000100 = 0 + cup000101: + x000111 +x001101 +x010101 +x100101 -up000101 = 0 + cup000110: + x000111 +x001110 +x010110 +x100110 -up000110 = 0 + cup000111: + x001111 +x010111 +x100111 -up000111 = 0 + cup001000: + x001001 +x001010 +x001100 +x011000 +x101000 -up001000 = 0 + cup001001: + x001011 +x001101 +x011001 +x101001 -up001001 = 0 + cup001010: + x001011 +x001110 +x011010 +x101010 -up001010 = 0 + cup001011: + x001111 +x011011 +x101011 -up001011 = 0 + cup001100: + x001101 +x001110 +x011100 +x101100 -up001100 = 0 + cup001101: + x001111 +x011101 +x101101 -up001101 = 0 + cup001110: + x001111 +x011110 +x101110 -up001110 = 0 + cup001111: + x011111 +x101111 -up001111 = 0 + cup010000: + x010001 +x010010 +x010100 +x011000 +x110000 -up010000 = 0 + cup010001: + x010011 +x010101 +x011001 +x110001 -up010001 = 0 + cup010010: + x010011 +x010110 +x011010 +x110010 -up010010 = 0 + cup010011: + x010111 +x011011 +x110011 -up010011 = 0 + cup010100: + x010101 +x010110 +x011100 +x110100 -up010100 = 0 + cup010101: + x010111 +x011101 +x110101 -up010101 = 0 + cup010110: + x010111 +x011110 +x110110 -up010110 = 0 + cup010111: + x011111 +x110111 -up010111 = 0 + cup011000: + x011001 +x011010 +x011100 +x111000 -up011000 = 0 + cup011001: + x011011 +x011101 +x111001 -up011001 = 0 + cup011010: + x011011 +x011110 +x111010 -up011010 = 0 + cup011011: + x011111 +x111011 -up011011 = 0 + cup011100: + x011101 +x011110 +x111100 -up011100 = 0 + cup011101: + x011111 +x111101 -up011101 = 0 + cup011110: + x011111 +x111110 -up011110 = 0 + cup011111: + x111111 -up011111 = 0 + cup100000: + x100001 +x100010 +x100100 +x101000 +x110000 -up100000 = 0 + cup100001: + x100011 +x100101 +x101001 +x110001 -up100001 = 0 + cup100010: + x100011 +x100110 +x101010 +x110010 -up100010 = 0 + cup100011: + x100111 +x101011 +x110011 -up100011 = 0 + cup100100: + x100101 +x100110 +x101100 +x110100 -up100100 = 0 + cup100101: + x100111 +x101101 +x110101 -up100101 = 0 + cup100110: + x100111 +x101110 +x110110 -up100110 = 0 + cup100111: + x101111 +x110111 -up100111 = 0 + cup101000: + x101001 +x101010 +x101100 +x111000 -up101000 = 0 + cup101001: + x101011 +x101101 +x111001 -up101001 = 0 + cup101010: + x101011 +x101110 +x111010 -up101010 = 0 + cup101011: + x101111 +x111011 -up101011 = 0 + cup101100: + x101101 +x101110 +x111100 -up101100 = 0 + cup101101: + x101111 +x111101 -up101101 = 0 + cup101110: + x101111 +x111110 -up101110 = 0 + cup101111: + x111111 -up101111 = 0 + cup110000: + x110001 +x110010 +x110100 +x111000 -up110000 = 0 + cup110001: + x110011 +x110101 +x111001 -up110001 = 0 + cup110010: + x110011 +x110110 +x111010 -up110010 = 0 + cup110011: + x110111 +x111011 -up110011 = 0 + cup110100: + x110101 +x110110 +x111100 -up110100 = 0 + cup110101: + x110111 +x111101 -up110101 = 0 + cup110110: + x110111 +x111110 -up110110 = 0 + cup110111: + x111111 -up110111 = 0 + cup111000: + x111001 +x111010 +x111100 -up111000 = 0 + cup111001: + x111011 +x111101 -up111001 = 0 + cup111010: + x111011 +x111110 -up111010 = 0 + cup111011: + x111111 -up111011 = 0 + cup111100: + x111101 +x111110 -up111100 = 0 + cup111101: + x111111 -up111101 = 0 + cup111110: + x111111 -up111110 = 0 + cdn000001: + x000000 -dn000001 = 0 + cdn000010: + x000000 -dn000010 = 0 + cdn000011: + x000001 +x000010 -dn000011 = 0 + cdn000100: + x000000 -dn000100 = 0 + cdn000101: + x000001 +x000100 -dn000101 = 0 + cdn000110: + x000010 +x000100 -dn000110 = 0 + cdn000111: + x000011 +x000101 +x000110 -dn000111 = 0 + cdn001000: + x000000 -dn001000 = 0 + cdn001001: + x000001 +x001000 -dn001001 = 0 + cdn001010: + x000010 +x001000 -dn001010 = 0 + cdn001011: + x000011 +x001001 +x001010 -dn001011 = 0 + cdn001100: + x000100 +x001000 -dn001100 = 0 + cdn001101: + x000101 +x001001 +x001100 -dn001101 = 0 + cdn001110: + x000110 +x001010 +x001100 -dn001110 = 0 + cdn001111: + x000111 +x001011 +x001101 +x001110 -dn001111 = 0 + cdn010000: + x000000 -dn010000 = 0 + cdn010001: + x000001 +x010000 -dn010001 = 0 + cdn010010: + x000010 +x010000 -dn010010 = 0 + cdn010011: + x000011 +x010001 +x010010 -dn010011 = 0 + cdn010100: + x000100 +x010000 -dn010100 = 0 + cdn010101: + x000101 +x010001 +x010100 -dn010101 = 0 + cdn010110: + x000110 +x010010 +x010100 -dn010110 = 0 + cdn010111: + x000111 +x010011 +x010101 +x010110 -dn010111 = 0 + cdn011000: + x001000 +x010000 -dn011000 = 0 + cdn011001: + x001001 +x010001 +x011000 -dn011001 = 0 + cdn011010: + x001010 +x010010 +x011000 -dn011010 = 0 + cdn011011: + x001011 +x010011 +x011001 +x011010 -dn011011 = 0 + cdn011100: + x001100 +x010100 +x011000 -dn011100 = 0 + cdn011101: + x001101 +x010101 +x011001 +x011100 -dn011101 = 0 + cdn011110: + x001110 +x010110 +x011010 +x011100 -dn011110 = 0 + cdn011111: + x001111 +x010111 +x011011 +x011101 +x011110 -dn011111 = 0 + cdn100000: + x000000 -dn100000 = 0 + cdn100001: + x000001 +x100000 -dn100001 = 0 + cdn100010: + x000010 +x100000 -dn100010 = 0 + cdn100011: + x000011 +x100001 +x100010 -dn100011 = 0 + cdn100100: + x000100 +x100000 -dn100100 = 0 + cdn100101: + x000101 +x100001 +x100100 -dn100101 = 0 + cdn100110: + x000110 +x100010 +x100100 -dn100110 = 0 + cdn100111: + x000111 +x100011 +x100101 +x100110 -dn100111 = 0 + cdn101000: + x001000 +x100000 -dn101000 = 0 + cdn101001: + x001001 +x100001 +x101000 -dn101001 = 0 + cdn101010: + x001010 +x100010 +x101000 -dn101010 = 0 + cdn101011: + x001011 +x100011 +x101001 +x101010 -dn101011 = 0 + cdn101100: + x001100 +x100100 +x101000 -dn101100 = 0 + cdn101101: + x001101 +x100101 +x101001 +x101100 -dn101101 = 0 + cdn101110: + x001110 +x100110 +x101010 +x101100 -dn101110 = 0 + cdn101111: + x001111 +x100111 +x101011 +x101101 +x101110 -dn101111 = 0 + cdn110000: + x010000 +x100000 -dn110000 = 0 + cdn110001: + x010001 +x100001 +x110000 -dn110001 = 0 + cdn110010: + x010010 +x100010 +x110000 -dn110010 = 0 + cdn110011: + x010011 +x100011 +x110001 +x110010 -dn110011 = 0 + cdn110100: + x010100 +x100100 +x110000 -dn110100 = 0 + cdn110101: + x010101 +x100101 +x110001 +x110100 -dn110101 = 0 + cdn110110: + x010110 +x100110 +x110010 +x110100 -dn110110 = 0 + cdn110111: + x010111 +x100111 +x110011 +x110101 +x110110 -dn110111 = 0 + cdn111000: + x011000 +x101000 +x110000 -dn111000 = 0 + cdn111001: + x011001 +x101001 +x110001 +x111000 -dn111001 = 0 + cdn111010: + x011010 +x101010 +x110010 +x111000 -dn111010 = 0 + cdn111011: + x011011 +x101011 +x110011 +x111001 +x111010 -dn111011 = 0 + cdn111100: + x011100 +x101100 +x110100 +x111000 -dn111100 = 0 + cdn111101: + x011101 +x101101 +x110101 +x111001 +x111100 -dn111101 = 0 + cdn111110: + x011110 +x101110 +x110110 +x111010 +x111100 -dn111110 = 0 + cdn111111: + x011111 +x101111 +x110111 +x111011 +x111101 +x111110 -dn111111 = 0 + up000000 -6 x000000 >= 0 + up000000 +64 x000000 <= 70 + up000001 -2 x000001 >= 0 + up000001 +64 x000001 <= 66 + up000010 -2 x000010 >= 0 + up000010 +64 x000010 <= 66 + up000011 -3 x000011 >= 0 + up000011 +64 x000011 <= 67 + up000100 -2 x000100 >= 0 + up000100 +64 x000100 <= 66 + up000101 -3 x000101 >= 0 + up000101 +64 x000101 <= 67 + up000110 -3 x000110 >= 0 + up000110 +64 x000110 <= 67 + up000111 -2 x000111 >= 0 + up000111 +64 x000111 <= 66 + up001000 -2 x001000 >= 0 + up001000 +64 x001000 <= 66 + up001001 -3 x001001 >= 0 + up001001 +64 x001001 <= 67 + up001010 -3 x001010 >= 0 + up001010 +64 x001010 <= 67 + up001011 -2 x001011 >= 0 + up001011 +64 x001011 <= 66 + up001100 -3 x001100 >= 0 + up001100 +64 x001100 <= 67 + up001101 -2 x001101 >= 0 + up001101 +64 x001101 <= 66 + up001110 -2 x001110 >= 0 + up001110 +64 x001110 <= 66 + up001111 -1 x001111 >= 0 + up001111 +64 x001111 <= 65 + up010000 -2 x010000 >= 0 + up010000 +64 x010000 <= 66 + up010001 -3 x010001 >= 0 + up010001 +64 x010001 <= 67 + up010010 -3 x010010 >= 0 + up010010 +64 x010010 <= 67 + up010011 -2 x010011 >= 0 + up010011 +64 x010011 <= 66 + up010100 -3 x010100 >= 0 + up010100 +64 x010100 <= 67 + up010101 -2 x010101 >= 0 + up010101 +64 x010101 <= 66 + up010110 -2 x010110 >= 0 + up010110 +64 x010110 <= 66 + up010111 -1 x010111 >= 0 + up010111 +64 x010111 <= 65 + up011000 -3 x011000 >= 0 + up011000 +64 x011000 <= 67 + up011001 -2 x011001 >= 0 + up011001 +64 x011001 <= 66 + up011010 -2 x011010 >= 0 + up011010 +64 x011010 <= 66 + up011011 -1 x011011 >= 0 + up011011 +64 x011011 <= 65 + up011100 -2 x011100 >= 0 + up011100 +64 x011100 <= 66 + up011101 -1 x011101 >= 0 + up011101 +64 x011101 <= 65 + up011110 -1 x011110 >= 0 + up011110 +64 x011110 <= 65 + up011111 -1 x011111 >= 0 + up011111 +64 x011111 <= 65 + up100000 -2 x100000 >= 0 + up100000 +64 x100000 <= 66 + up100001 -3 x100001 >= 0 + up100001 +64 x100001 <= 67 + up100010 -3 x100010 >= 0 + up100010 +64 x100010 <= 67 + up100011 -2 x100011 >= 0 + up100011 +64 x100011 <= 66 + up100100 -3 x100100 >= 0 + up100100 +64 x100100 <= 67 + up100101 -2 x100101 >= 0 + up100101 +64 x100101 <= 66 + up100110 -2 x100110 >= 0 + up100110 +64 x100110 <= 66 + up100111 -1 x100111 >= 0 + up100111 +64 x100111 <= 65 + up101000 -3 x101000 >= 0 + up101000 +64 x101000 <= 67 + up101001 -2 x101001 >= 0 + up101001 +64 x101001 <= 66 + up101010 -2 x101010 >= 0 + up101010 +64 x101010 <= 66 + up101011 -1 x101011 >= 0 + up101011 +64 x101011 <= 65 + up101100 -2 x101100 >= 0 + up101100 +64 x101100 <= 66 + up101101 -1 x101101 >= 0 + up101101 +64 x101101 <= 65 + up101110 -1 x101110 >= 0 + up101110 +64 x101110 <= 65 + up101111 -1 x101111 >= 0 + up101111 +64 x101111 <= 65 + up110000 -3 x110000 >= 0 + up110000 +64 x110000 <= 67 + up110001 -2 x110001 >= 0 + up110001 +64 x110001 <= 66 + up110010 -2 x110010 >= 0 + up110010 +64 x110010 <= 66 + up110011 -1 x110011 >= 0 + up110011 +64 x110011 <= 65 + up110100 -2 x110100 >= 0 + up110100 +64 x110100 <= 66 + up110101 -1 x110101 >= 0 + up110101 +64 x110101 <= 65 + up110110 -1 x110110 >= 0 + up110110 +64 x110110 <= 65 + up110111 -1 x110111 >= 0 + up110111 +64 x110111 <= 65 + up111000 -2 x111000 >= 0 + up111000 +64 x111000 <= 66 + up111001 -1 x111001 >= 0 + up111001 +64 x111001 <= 65 + up111010 -1 x111010 >= 0 + up111010 +64 x111010 <= 65 + up111011 -1 x111011 >= 0 + up111011 +64 x111011 <= 65 + up111100 -1 x111100 >= 0 + up111100 +64 x111100 <= 65 + up111101 -1 x111101 >= 0 + up111101 +64 x111101 <= 65 + up111110 -1 x111110 >= 0 + up111110 +64 x111110 <= 65 + dn000001 -1 x000001 >= 0 + dn000001 +64 x000001 <= 65 + dn000010 -1 x000010 >= 0 + dn000010 +64 x000010 <= 65 + dn000011 -2 x000011 >= 0 + dn000011 +64 x000011 <= 66 + dn000100 -1 x000100 >= 0 + dn000100 +64 x000100 <= 65 + dn000101 -2 x000101 >= 0 + dn000101 +64 x000101 <= 66 + dn000110 -2 x000110 >= 0 + dn000110 +64 x000110 <= 66 + dn000111 -1 x000111 >= 0 + dn000111 +64 x000111 <= 65 + dn001000 -1 x001000 >= 0 + dn001000 +64 x001000 <= 65 + dn001001 -2 x001001 >= 0 + dn001001 +64 x001001 <= 66 + dn001010 -2 x001010 >= 0 + dn001010 +64 x001010 <= 66 + dn001011 -1 x001011 >= 0 + dn001011 +64 x001011 <= 65 + dn001100 -2 x001100 >= 0 + dn001100 +64 x001100 <= 66 + dn001101 -1 x001101 >= 0 + dn001101 +64 x001101 <= 65 + dn001110 -1 x001110 >= 0 + dn001110 +64 x001110 <= 65 + dn001111 -4 x001111 >= 0 + dn001111 +64 x001111 <= 68 + dn010000 -1 x010000 >= 0 + dn010000 +64 x010000 <= 65 + dn010001 -2 x010001 >= 0 + dn010001 +64 x010001 <= 66 + dn010010 -2 x010010 >= 0 + dn010010 +64 x010010 <= 66 + dn010011 -1 x010011 >= 0 + dn010011 +64 x010011 <= 65 + dn010100 -2 x010100 >= 0 + dn010100 +64 x010100 <= 66 + dn010101 -1 x010101 >= 0 + dn010101 +64 x010101 <= 65 + dn010110 -1 x010110 >= 0 + dn010110 +64 x010110 <= 65 + dn010111 -4 x010111 >= 0 + dn010111 +64 x010111 <= 68 + dn011000 -2 x011000 >= 0 + dn011000 +64 x011000 <= 66 + dn011001 -1 x011001 >= 0 + dn011001 +64 x011001 <= 65 + dn011010 -1 x011010 >= 0 + dn011010 +64 x011010 <= 65 + dn011011 -4 x011011 >= 0 + dn011011 +64 x011011 <= 68 + dn011100 -1 x011100 >= 0 + dn011100 +64 x011100 <= 65 + dn011101 -4 x011101 >= 0 + dn011101 +64 x011101 <= 68 + dn011110 -4 x011110 >= 0 + dn011110 +64 x011110 <= 68 + dn011111 -3 x011111 >= 0 + dn011111 +64 x011111 <= 67 + dn100000 -1 x100000 >= 0 + dn100000 +64 x100000 <= 65 + dn100001 -2 x100001 >= 0 + dn100001 +64 x100001 <= 66 + dn100010 -2 x100010 >= 0 + dn100010 +64 x100010 <= 66 + dn100011 -1 x100011 >= 0 + dn100011 +64 x100011 <= 65 + dn100100 -2 x100100 >= 0 + dn100100 +64 x100100 <= 66 + dn100101 -1 x100101 >= 0 + dn100101 +64 x100101 <= 65 + dn100110 -1 x100110 >= 0 + dn100110 +64 x100110 <= 65 + dn100111 -4 x100111 >= 0 + dn100111 +64 x100111 <= 68 + dn101000 -2 x101000 >= 0 + dn101000 +64 x101000 <= 66 + dn101001 -1 x101001 >= 0 + dn101001 +64 x101001 <= 65 + dn101010 -1 x101010 >= 0 + dn101010 +64 x101010 <= 65 + dn101011 -4 x101011 >= 0 + dn101011 +64 x101011 <= 68 + dn101100 -1 x101100 >= 0 + dn101100 +64 x101100 <= 65 + dn101101 -4 x101101 >= 0 + dn101101 +64 x101101 <= 68 + dn101110 -4 x101110 >= 0 + dn101110 +64 x101110 <= 68 + dn101111 -3 x101111 >= 0 + dn101111 +64 x101111 <= 67 + dn110000 -2 x110000 >= 0 + dn110000 +64 x110000 <= 66 + dn110001 -1 x110001 >= 0 + dn110001 +64 x110001 <= 65 + dn110010 -1 x110010 >= 0 + dn110010 +64 x110010 <= 65 + dn110011 -4 x110011 >= 0 + dn110011 +64 x110011 <= 68 + dn110100 -1 x110100 >= 0 + dn110100 +64 x110100 <= 65 + dn110101 -4 x110101 >= 0 + dn110101 +64 x110101 <= 68 + dn110110 -4 x110110 >= 0 + dn110110 +64 x110110 <= 68 + dn110111 -3 x110111 >= 0 + dn110111 +64 x110111 <= 67 + dn111000 -1 x111000 >= 0 + dn111000 +64 x111000 <= 65 + dn111001 -4 x111001 >= 0 + dn111001 +64 x111001 <= 68 + dn111010 -4 x111010 >= 0 + dn111010 +64 x111010 <= 68 + dn111011 -3 x111011 >= 0 + dn111011 +64 x111011 <= 67 + dn111100 -4 x111100 >= 0 + dn111100 +64 x111100 <= 68 + dn111101 -3 x111101 >= 0 + dn111101 +64 x111101 <= 67 + dn111110 -3 x111110 >= 0 + dn111110 +64 x111110 <= 67 + dn111111 -3 x111111 >= 0 + dn111111 +64 x111111 <= 67 +binary + x000000 x000001 x000010 x000011 x000100 x000101 x000110 x000111 + x001000 x001001 x001010 x001011 x001100 x001101 x001110 x001111 + x010000 x010001 x010010 x010011 x010100 x010101 x010110 x010111 + x011000 x011001 x011010 x011011 x011100 x011101 x011110 x011111 + x100000 x100001 x100010 x100011 x100100 x100101 x100110 x100111 + x101000 x101001 x101010 x101011 x101100 x101101 x101110 x101111 + x110000 x110001 x110010 x110011 x110100 x110101 x110110 x110111 + x111000 x111001 x111010 x111011 x111100 x111101 x111110 x111111 +integer + dn000000 up000000 dn000001 up000001 dn000010 up000010 dn000011 up000011 + dn000100 up000100 dn000101 up000101 dn000110 up000110 dn000111 up000111 + dn001000 up001000 dn001001 up001001 dn001010 up001010 dn001011 up001011 + dn001100 up001100 dn001101 up001101 dn001110 up001110 dn001111 up001111 + dn010000 up010000 dn010001 up010001 dn010010 up010010 dn010011 up010011 + dn010100 up010100 dn010101 up010101 dn010110 up010110 dn010111 up010111 + dn011000 up011000 dn011001 up011001 dn011010 up011010 dn011011 up011011 + dn011100 up011100 dn011101 up011101 dn011110 up011110 dn011111 up011111 + dn100000 up100000 dn100001 up100001 dn100010 up100010 dn100011 up100011 + dn100100 up100100 dn100101 up100101 dn100110 up100110 dn100111 up100111 + dn101000 up101000 dn101001 up101001 dn101010 up101010 dn101011 up101011 + dn101100 up101100 dn101101 up101101 dn101110 up101110 dn101111 up101111 + dn110000 up110000 dn110001 up110001 dn110010 up110010 dn110011 up110011 + dn110100 up110100 dn110101 up110101 dn110110 up110110 dn110111 up110111 + dn111000 up111000 dn111001 up111001 dn111010 up111010 dn111011 up111011 + dn111100 up111100 dn111101 up111101 dn111110 up111110 dn111111 up111111 +End diff --git a/glpk-5.0/examples/wolfra6d.mod b/glpk-5.0/examples/wolfra6d.mod new file mode 100644 index 0000000..c478487 --- /dev/null +++ b/glpk-5.0/examples/wolfra6d.mod @@ -0,0 +1,94 @@ +/* Any Wolfram elementary CA in 6D eucl. Neumann CA grid emulator generator */ + +/* Implemented, inspected, written and converted to GNU MathProg + by NASZVADI, Peter, 2016-2017 <vuk@cs.elte.hu> */ + +/* see background info and more details in wolfra6d.lp */ + +/* each axis has this two endpoints */ +set V := 0..1; + +/* this model processes a hypercube in 6d, so 6+1 parallel planes intersect */ +set H := 0..6; + +/* denoting all vertices in the 6d unit hypercube */ +set Cells := V cross V cross V cross V cross V cross V; + + +/* input parameters, bup/bdn = number of upper/lower neighbour 6d cells of a (cyclic) segment */ +param bup{i in H}, default 1; +param bdn{i in H}, default 2; + +/* boolean meaning if a vertex is chosen */ +var x{Cells}, binary; + +/* temporary calculations to enforce bup/bdn */ +var up{Cells}, >=0; +var dn{Cells}, >=0; + +/* the total weight of selected cells near the main diagonal */ +var obj; + +/* up/dn vars denote the number of selected upper/lower neighbours */ +s.t. cup{(v1,v2,v3,v4,v5,v6) in Cells: v1+v2+v3+v4+v5+v6<6}: + sum{(w1,w2,w3,w4,w5,w6) in Cells: max(v1-w1,v2-w2,v3-w3,v4-w4,v5-w5,v6-w6)<=0} + if (w1+w2+w3+w4+w5+w6) = (1+v1+v2+v3+v4+v5+v6) then x[w1,w2,w3,w4,w5,w6] else 0 = + up[v1,v2,v3,v4,v5,v6]; + +s.t. cdn{(v1,v2,v3,v4,v5,v6) in Cells: v1+v2+v3+v4+v5+v6>0}: + sum{(w1,w2,w3,w4,w5,w6) in Cells: min(v1-w1,v2-w2,v3-w3,v4-w4,v5-w5,v6-w6)>=0} + if (w1+w2+w3+w4+w5+w6) = (-1+v1+v2+v3+v4+v5+v6) then x[w1,w2,w3,w4,w5,w6] else 0 = + dn[v1,v2,v3,v4,v5,v6]; + +/* 4 helper constraints, hences the leading "c" */ +s.t. cbup1{(v1,v2,v3,v4,v5,v6) in Cells: v1+v2+v3+v4+v5+v6<6}: + up[v1,v2,v3,v4,v5,v6] >= bup[v1+v2+v3+v4+v5+v6] * x[v1,v2,v3,v4,v5,v6]; + +s.t. cbup2{(v1,v2,v3,v4,v5,v6) in Cells: v1+v2+v3+v4+v5+v6<6}: + up[v1,v2,v3,v4,v5,v6] + (2**6) * x[v1,v2,v3,v4,v5,v6] <= (2**6) + bup[v1+v2+v3+v4+v5+v6]; + +s.t. cbdn1{(v1,v2,v3,v4,v5,v6) in Cells: v1+v2+v3+v4+v5+v6>0}: + dn[v1,v2,v3,v4,v5,v6] >= bdn[v1+v2+v3+v4+v5+v6] * x[v1,v2,v3,v4,v5,v6]; + +s.t. cbdn2{(v1,v2,v3,v4,v5,v6) in Cells: v1+v2+v3+v4+v5+v6>0}: + dn[v1,v2,v3,v4,v5,v6] + (2**6) * x[v1,v2,v3,v4,v5,v6] <= (2**6) + bdn[v1+v2+v3+v4+v5+v6]; + +/* these two promoted points should be selected */ +s.t. initdiag: x[0,0,0,0,0,0] + x[1,1,1,1,1,1] = 2; + +/* obvious */ +s.t. sumx: sum{(v1,v2,v3,v4,v5,v6) in Cells} x[v1,v2,v3,v4,v5,v6] = obj; + +minimize cobj: obj; + +solve; + +/* pretty-printing hopefully nontrivial solution */ +printf "\nChosen vertex subset:\n"; +for{i in H}: { + printf "Weight=%s\n", i; + printf{(v1,v2,v3,v4,v5,v6) in Cells: v1+v2+v3+v4+v5+v6 = i+(8-8*x[v1,v2,v3,v4,v5,v6])} + " %s%s%s%s%s%s\n",v1,v2,v3,v4,v5,v6; +} +printf "\nTotal number of selected cells in the hypercube: %g\n\n", obj; + +data; + +/* these parameters were chosen in the first run that yielded a solution */ +param bup := 0 6 + 1 2 + 2 3 + 3 2 + 4 1 + 5 1 + 6 6; + +param bdn := 0 3 + 1 1 + 2 2 + 3 1 + 4 4 + 5 3 + 6 3; + +end; diff --git a/glpk-5.0/examples/xyacfs.mod b/glpk-5.0/examples/xyacfs.mod new file mode 100644 index 0000000..5a0b22e --- /dev/null +++ b/glpk-5.0/examples/xyacfs.mod @@ -0,0 +1,56 @@ +/*Extended Yet Another Curve Fitting Solution (The poor man's RMA) + + An extension of yacfs.mod adding a Weight parameter: + When set to 1 the model produces best fit by least squares with all error in y and none in x (YonX); + When set to zero the model produces best fit by least squares with all error in x and none in y (XonY); + When set to 0.5 the model assumes equal error in x and y producing results similar to fitting by Reduced Major Axis Analysis. + + Nigel_Galloway@operamail.com + November 5th., 2009 +*/ +set Sample; +param Sx {z in Sample}; +param Sy {z in Sample}; +param Weight := 0.5; + +var a; +var b; +var p; +var q; + +XonY1 :sum{z in Sample} q*Sy[z]*Sy[z] + sum{z in Sample} p*Sy[z] = sum{z in Sample} Sy[z]*Sx[z]; +XonY2 :sum{z in Sample} q*Sy[z] + sum{z in Sample} p = sum{z in Sample} Sx[z]; +YonX1 :sum{z in Sample} a*Sx[z]*Sx[z] + sum{z in Sample} b*Sx[z] = sum{z in Sample} Sy[z]*Sx[z]; +YonX2 :sum{z in Sample} a*Sx[z] + sum{z in Sample} b = sum{z in Sample} Sy[z]; + +solve; + +param W := Weight*a + (1-Weight)*(1/q); +printf "\nbest linear fit is:\n\ty = %f %s %fx\n\n", b*Weight - (1-Weight)*(p/q), if W < 0 then "-" else "+", abs(W); + +data; + +param: +Sample: Sx Sy := + 1 0 1 + 2 0.5 0.9 + 3 1 0.7 + 4 1.5 1.5 + 5 1.9 2 + 6 2.5 2.4 + 7 3 3.2 + 8 3.5 2 + 9 4 2.7 + 10 4.5 3.5 + 11 5 1 + 12 5.5 4 + 13 6 3.6 + 14 6.6 2.7 + 15 7 5.7 + 16 7.6 4.6 + 17 8.5 6 + 18 9 6.8 + 19 10 7.3 +; + +end; diff --git a/glpk-5.0/examples/yacfs.mod b/glpk-5.0/examples/yacfs.mod new file mode 100644 index 0000000..270f2a0 --- /dev/null +++ b/glpk-5.0/examples/yacfs.mod @@ -0,0 +1,48 @@ +/*Yet Another Curve Fitting Solution + + Obviously this solution produces the same answer + as examples/cflsq.mod + + Nigel_Galloway@operamail.com + February 1st., 2009 +*/ +set Sample; +param Sx {z in Sample}; +param Sy {z in Sample}; + +var a; +var b; + +equalz1 :sum{z in Sample} a*Sx[z]*Sx[z] + sum{z in Sample} b*Sx[z] = sum{z in Sample} Sy[z]*Sx[z]; +equalz2 :sum{z in Sample} a*Sx[z] + sum{z in Sample} b = sum{z in Sample} Sy[z]; + +solve; + +printf "\nbest linear fit is:\n\ty = %f %s %fx\n\n", b, if a < 0 then "-" else "+", abs(a); + +data; + +param: +Sample: Sx Sy := + 1 0 1 + 2 0.5 0.9 + 3 1 0.7 + 4 1.5 1.5 + 5 1.9 2 + 6 2.5 2.4 + 7 3 3.2 + 8 3.5 2 + 9 4 2.7 + 10 4.5 3.5 + 11 5 1 + 12 5.5 4 + 13 6 3.6 + 14 6.6 2.7 + 15 7 5.7 + 16 7.6 4.6 + 17 8.5 6 + 18 9 6.8 + 19 10 7.3 +; + +end; diff --git a/glpk-5.0/examples/zebra.mod b/glpk-5.0/examples/zebra.mod new file mode 100644 index 0000000..66f8c1a --- /dev/null +++ b/glpk-5.0/examples/zebra.mod @@ -0,0 +1,151 @@ +/* ZEBRA, Who Owns the Zebra? */ + +/* Written in GNU MathProg by Andrew Makhorin <mao@gnu.org> */ + +######################################################################## +# The Zebra Puzzle is a well-known logic puzzle. +# +# It is often called "Einstein's Puzzle" or "Einstein's Riddle" +# because it is said to have been invented by Albert Einstein as a boy, +# with the common claim that Einstein said "only 2 percent of the +# world's population can solve". It is also sometimes attributed to +# Lewis Carroll. However, there is no known evidence for Einstein's or +# Carroll's authorship. +# +# There are several versions of this puzzle. The version below is +# quoted from the first known publication in Life International +# magazine on December 17, 1962. +# +# 1. There are five houses. +# 2. The Englishman lives in the red house. +# 3. The Spaniard owns the dog. +# 4. Coffee is drunk in the green house. +# 5. The Ukrainian drinks tea. +# 6. The green house is immediately to the right of the ivory house. +# 7. The Old Gold smoker owns snails. +# 8. Kools are smoked in the yellow house. +# 9. Milk is drunk in the middle house. +# 10. The Norwegian lives in the first house. +# 11. The man who smokes Chesterfields lives in the house next to the +# man with the fox. +# 12. Kools are smoked in the house next to the house where the horse +# is kept. +# 13. The Lucky Strike smoker drinks orange juice. +# 14. The Japanese smokes Parliaments. +# 15. The Norwegian lives next to the blue house. +# +# Now, who drinks water? Who owns the zebra? +# +# In the interest of clarity, it must be added that each of the five +# houses is painted a different color, and their inhabitants are of +# different national extractions, own different pets, drink different +# beverages and smoke different brands of American cigarettes. One +# other thing: In statement 6, right means your right. +# +# (From Wikipedia, the free encyclopedia.) +######################################################################## + +set HOUSE := { 1..5 }; + +set COLOR := { "blue", "green", "ivory", "red", "yellow" }; + +set NATIONALITY := { "Englishman", "Japanese", "Norwegian", "Spaniard", + "Ukranian" }; + +set DRINK := { "coffee", "milk", "orange_juice", "tea", "water" }; + +set SMOKE := { "Chesterfield", "Kools", "Lucky_Strike", "Old_Gold", + "Parliament" }; + +set PET := { "dog", "fox", "horse", "snails", "zebra" }; + +var color{HOUSE, COLOR}, binary; +c1{h in HOUSE}: sum{c in COLOR} color[h,c] = 1; +c2{c in COLOR}: sum{h in HOUSE} color[h,c] = 1; + +var nationality{HOUSE, NATIONALITY}, binary; +n1{h in HOUSE}: sum{n in NATIONALITY} nationality[h,n] = 1; +n2{n in NATIONALITY}: sum{h in HOUSE} nationality[h,n] = 1; + +var drink{HOUSE, DRINK}, binary; +d1{h in HOUSE}: sum{d in DRINK} drink[h,d] = 1; +d2{d in DRINK}: sum{h in HOUSE} drink[h,d] = 1; + +var smoke{HOUSE, SMOKE}, binary; +s1{h in HOUSE}: sum{s in SMOKE} smoke[h,s] = 1; +s2{s in SMOKE}: sum{h in HOUSE} smoke[h,s] = 1; + +var pet{HOUSE, PET}, binary; +p1{h in HOUSE}: sum{p in PET} pet[h,p] = 1; +p2{p in PET}: sum{h in HOUSE} pet[h,p] = 1; + +/* the Englishman lives in the red house */ +f2{h in HOUSE}: nationality[h,"Englishman"] = color[h,"red"]; + +/* the Spaniard owns the dog */ +f3{h in HOUSE}: nationality[h,"Spaniard"] = pet[h,"dog"]; + +/* coffee is drunk in the green house */ +f4{h in HOUSE}: drink[h,"coffee"] = color[h,"green"]; + +/* the Ukrainian drinks tea */ +f5{h in HOUSE}: nationality[h,"Ukranian"] = drink[h,"tea"]; + +/* the green house is immediately to the right of the ivory house */ +f6{h in HOUSE}: + color[h,"green"] = if h = 1 then 0 else color[h-1,"ivory"]; + +/* the Old Gold smoker owns snails */ +f7{h in HOUSE}: smoke[h,"Old_Gold"] = pet[h,"snails"]; + +/* Kools are smoked in the yellow house */ +f8{h in HOUSE}: smoke[h,"Kools"] = color[h,"yellow"]; + +/* milk is drunk in the middle house */ +f9: drink[3,"milk"] = 1; + +/* the Norwegian lives in the first house */ +f10: nationality[1,"Norwegian"] = 1; + +/* the man who smokes Chesterfields lives in the house next to the man + with the fox */ +f11{h in HOUSE}: + (1 - smoke[h,"Chesterfield"]) + + (if h = 1 then 0 else pet[h-1,"fox"]) + + (if h = 5 then 0 else pet[h+1,"fox"]) >= 1; + +/* Kools are smoked in the house next to the house where the horse is + kept */ +f12{h in HOUSE}: + (1 - smoke[h,"Kools"]) + + (if h = 1 then 0 else pet[h-1,"horse"]) + + (if h = 5 then 0 else pet[h+1,"horse"]) >= 1; + +/* the Lucky Strike smoker drinks orange juice */ +f13{h in HOUSE}: smoke[h,"Lucky_Strike"] = drink[h,"orange_juice"]; + +/* the Japanese smokes Parliaments */ +f14{h in HOUSE}: nationality[h,"Japanese"] = smoke[h,"Parliament"]; + +/* the Norwegian lives next to the blue house */ +f15{h in HOUSE}: + (1 - nationality[h,"Norwegian"]) + + (if h = 1 then 0 else color[h-1,"blue"]) + + (if h = 5 then 0 else color[h+1,"blue"]) >= 1; + +solve; + +printf "\n"; +printf "HOUSE COLOR NATIONALITY DRINK SMOKE PET\n"; +for {h in HOUSE} +{ printf "%5d", h; + printf{c in COLOR: color[h,c]} " %-6s", c; + printf{n in NATIONALITY: nationality[h,n]} " %-11s", n; + printf{d in DRINK: drink[h,d]} " %-12s", d; + printf{s in SMOKE: smoke[h,s]} " %-12s", s; + printf{p in PET: pet[h,p]} " %-6s", p; + printf "\n"; +} +printf "\n"; + +end; |