summaryrefslogtreecommitdiff
path: root/glpk-5.0/doc/glpk05.tex
blob: 66e3c40a77da5c1aeff96487ada44ce160f10e50 (plain)
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
%* glpk05.tex *%

\chapter{Branch-and-Cut API Routines}

\section{Introduction}

\subsection{Using the callback routine}

The GLPK MIP solver based on the branch-and-cut method allows the
application program to control the solution process. This is attained
by means of the user-defined callback routine, which is called by the
solver at various points of the branch-and-cut algorithm.

The callback routine passed to the MIP solver should be written by the
user and has the following specification:\footnote{The name
{\tt foo\_bar} used here is a placeholder for the callback routine
name.}

\begin{verbatim}
   void foo_bar(glp_tree *T, void *info);
\end{verbatim}

\noindent
where \verb|tree| is a pointer to the data structure \verb|glp_tree|,
which should be used on subsequent calls to branch-and-cut interface
routines, and \verb|info| is a transit pointer passed to the routine
\verb|glp_intopt|, which may be used by the application program to pass
some external data to the callback routine.

The callback routine is passed to the MIP solver through the control
parameter structure \verb|glp_iocp| (see Chapter ``Basic API
Routines'', Section ``Mixed integer programming routines'', Subsection
``Solve MIP problem with the branch-and-cut method'') as follows:

\begin{verbatim}
   glp_prob *mip;
   glp_iocp parm;
   . . .
   glp_init_iocp(&parm);
   . . .
   parm.cb_func = foo_bar;
   parm.cb_info = ... ;
   ret = glp_intopt(mip, &parm);
   . . .
\end{verbatim}

To determine why it is being called by the MIP solver the callback
routine should use the routine \verb|glp_ios_reason| (described in this
section below), which returns a code indicating the reason for calling.
Depending on the reason the callback routine may perform necessary
actions to control the solution process.

The reason codes, which correspond to various point of the
branch-and-cut algorithm implemented in the MIP solver, are described
in Subsection ``Reasons for calling the callback routine'' below.

To ignore calls for reasons, which are not processed by the callback
routine, it should simply return to the MIP solver doing nothing. For
example:

\begin{verbatim}
void foo_bar(glp_tree *T, void *info)
{     . . .
      switch (glp_ios_reason(T))
      {  case GLP_IBRANCH:
            . . .
            break;
         case GLP_ISELECT:
            . . .
            break;
         default:
            /* ignore call for other reasons */
            break;
      }
      return;
}
\end{verbatim}

To control the solution process as well as to obtain necessary
information the callback routine may use the branch-and-cut API
routines described in this chapter. Names of all these routines begin
with `\verb|glp_ios_|'.

\subsection{Branch-and-cut algorithm}

This section gives a schematic description of the branch-and-cut
algorithm as it is implemented in the GLPK MIP solver.

{\it 1. Initialization}

Set $L:=\{P_0\}$, where $L$ is the {\it active list} (i.e. the list of
active subproblems), $P_0$ is the original MIP problem to be solved.

Set $z^{\it best}:=+\infty$ (in case of minimization) or
$z^{\it best}:=-\infty$ (in case of maximization), where $z^{\it best}$
is {\it incumbent value}, i.e. an upper (minimization) or lower
(maximization) global bound for $z^{\it opt}$, the optimal objective
value for $P^0$.

{\it 2. Subproblem selection}

If $L=\varnothing$ then GO TO 9.

Select $P\in L$, i.e. make active subproblem $P$ current.

%\newpage

{\it 3. Solving LP relaxation}

Solve $P^{\it LP}$, which is LP relaxation of $P$.

If $P^{\it LP}$ has no primal feasible solution then GO TO 8.

Let $z^{\it LP}$ be the optimal objective value for $P^{\it LP}$.

If $z^{\it LP}\geq z^{\it best}$ (minimization) or
$z^{\it LP}\leq z^{\rm best}$ (), GO TO 8.

{\it 4. Adding ``lazy'' constraints}

Let $x^{\it LP}$ be the optimal solution to $P^{\it LP}$.

If there are ``lazy'' constraints (i.e. essential constraints not
included in the original MIP problem $P_0$), which are violated at the
optimal point $x^{\it LP}$, add them to $P$, and GO TO 3.

{\it 5. Check for integrality}

Let $x_j$ be a variable, which is required to be integer, and let
$x^{\it LP}_j\in x^{\it LP}$ be its value in the optimal solution to
$P^{\it LP}$.

If $x^{\it LP}_j$ are integral for all integer variables, then a better
integer feasible solution is found. Store its components, set
$z^{\it best}:=z^{\it LP}$, and GO TO 8.

{\it 6. Adding cutting planes}

If there are cutting planes (i.e. valid constraints for $P$),
which are violated at the optimal point $x^{\it LP}$, add them to $P$,
and GO TO 3.

{\it 7. Branching}

Select {\it branching variable} $x_j$, i.e. a variable, which is
required to be integer, and whose value $x^{\it LP}_j\in x^{\it LP}$ is
fractional in the optimal solution to $P^{\it LP}$.

Create new subproblem $P^D$ (so called {\it down branch}), which is
identical to the current subproblem $P$ with exception that the upper
bound of $x_j$ is replaced by $\lfloor x^{\it LP}_j\rfloor$. (For
example, if $x^{\it LP}_j=3.14$, the new upper bound of $x_j$ in the
down branch will be $\lfloor 3.14\rfloor=3$.)

Create new subproblem $P^U$ (so called {\it up branch}), which is
identical to the current subproblem $P$ with exception that the lower
bound of $x_j$ is replaced by $\lceil x^{\it LP}_j\rceil$. (For example,
if $x^{\it LP}_j=3.14$, the new lower bound of $x_j$ in the up branch
will be $\lceil 3.14\rceil=4$.)

Set $L:=(L\backslash\{P\})\cup\{P^D,P^U\}$, i.e. remove the current
subproblem $P$ from the active list $L$ and add two new subproblems
$P^D$ and $P^U$ to it. Then GO TO 2.

{\it 8. Pruning}

Remove from the active list $L$ all subproblems (including the current
one), whose local bound $\widetilde{z}$ is not better than the global
bound $z^{\it best}$, i.e. set $L:=L\backslash\{P\}$ for all $P$, where
$\widetilde{z}\geq z^{\it best}$ (in case of minimization) or
$\widetilde{z}\leq z^{\it best}$ (in case of maximization), and then
GO TO 2.

The local bound $\widetilde{z}$ for subproblem $P$ is an lower
(minimization) or upper (maximization) bound for integer optimal
solution to {\it this} subproblem (not to the original problem). This
bound is local in the sense that only subproblems in the subtree rooted
at node $P$ cannot have better integer feasible solutions. Note that
the local bound is not necessarily the optimal objective value to LP
relaxation $P^{\it LP}$.

{\it 9. Termination}

If $z^{\it best}=+\infty$ (in case of minimization) or
$z^{\it best}=-\infty$ (in case of maximization), the original problem
$P_0$ has no integer feasible solution. Otherwise, the last integer
feasible solution stored on step 5 is the integer optimal solution to
the original problem $P_0$ with $z^{\it opt}=z^{\it best}$. STOP.

\subsection{The search tree}

On the branching step of the branch-and-cut algorithm the current
subproblem is divided into two\footnote{In more general cases the
current subproblem may be divided into more than two subproblems.
However, currently such feature is not used in GLPK.} new subproblems,
so the set of all subproblems can be represented in the form of a rooted
tree, which is called the {\it search} or {\it branch-and-bound} tree.
An example of the search tree is shown on Fig.~1. Each node of the
search tree corresponds to a subproblem, so the terms `node' and
`subproblem' may be used synonymously.

\begin{figure}[t]
\noindent\hfil
\xymatrix @R=20pt @C=10pt
{&&&&&&*+<14pt>[o][F=]{A}\ar@{-}[dllll]\ar@{-}[dr]\ar@{-}[drrrr]&&&&\\
&&*+<14pt>[o][F=]{B}\ar@{-}[dl]\ar@{-}[dr]&&&&&*+<14pt>[o][F=]{C}
\ar@{-}[dll]\ar@{-}[dr]\ar@{-}[drrr]&&&*+<14pt>[o][F-]{\times}\\
&*+<14pt>[o][F-]{\times}\ar@{-}[dl]\ar@{-}[d]\ar@{-}[dr]&&
*+<14pt>[o][F-]{D}&&*+<14pt>[o][F=]{E}\ar@{-}[dl]\ar@{-}[dr]&&&
*+<14pt>[o][F=]{F}\ar@{-}[dl]\ar@{-}[dr]&&*+<14pt>[o][F-]{G}\\
*+<14pt>[o][F-]{\times}&*+<14pt>[o][F-]{\times}&*+<14pt>[o][F-]{\times}
&&*+<14pt>[][F-]{H}&&*+<14pt>[o][F-]{I}&*+<14pt>[o][F-]{\times}&&
*+<14pt>[o][F-]{J}&\\}

\bigskip

\noindent\hspace{.8in}
\xymatrix @R=11pt
{*+<20pt>[][F-]{}&*\txt{\makebox[1in][l]{Current}}&&
*+<20pt>[o][F-]{}&*\txt{\makebox[1in][l]{Active}}\\
*+<20pt>[o][F=]{}&*\txt{\makebox[1in][l]{Non-active}}&&
*+<14pt>[o][F-]{\times}&*\txt{\makebox[1in][l]{Fathomed}}\\
}

\bigskip

\begin{center}
Fig. 1. An example of the search tree.
\end{center}
\end{figure}

In GLPK each node may have one of the following four statuses:

%\vspace*{-8pt}

%\begin{itemize}
\Item{---}{\it current node} is the active node currently being
processed;

\Item{---}{\it active node} is a leaf node, which still has to be
processed;

\Item{---}{\it non-active node} is a node, which has been processed,
but not fathomed;

\Item{---}{\it fathomed node} is a node, which has been processed and
fathomed.
%\end{itemize}

%\vspace*{-8pt}

In the data structure representing the search tree GLPK keeps only
current, active, and non-active nodes. Once a node has been fathomed,
it is removed from the tree data structure.

Being created each node of the search tree is assigned a distinct
positive integer called the {\it subproblem reference number}, which
may be used by the application program to specify a particular node of
the tree. The root node corresponding to the original problem to be
solved is always assigned the reference number 1.

\subsection{Current subproblem}

The current subproblem is a MIP problem corresponding to the current
node of the search tree. It is represented as the GLPK problem object
(\verb|glp_prob|) that allows the application program using API
routines to access its content in the standard way. If the MIP
presolver is not used, it is the original problem object passed to the
routine \verb|glp_intopt|; otherwise, it is an internal problem object
built by the MIP presolver.

Note that the problem object is used by the MIP solver itself during
the solution process for various purposes (to solve LP relaxations, to
perfom branching, etc.), and even if the MIP presolver is not used, the
current content of the problem object may differ from its original
content. For example, it may have additional rows, bounds of some rows
and columns may be changed, etc. In particular, LP segment of the
problem object corresponds to LP relaxation of the current subproblem.
However, on exit from the MIP solver the content of the problem object
is restored to its original state.

To obtain information from the problem object the application program
may use any API routines, which do not change the object. Using API
routines, which change the problem object, is restricted to stipulated
cases.

\subsection{The cut pool}

The {\it cut pool} is a set of cutting plane constraints maintained by
the MIP solver. It is used by the GLPK cut generation routines and may
be used by the application program in the same way, i.e. rather than
to add cutting plane constraints directly to the problem object the
application program may store them to the cut pool. In the latter case
the solver looks through the cut pool, selects efficient constraints,
and adds them to the problem object.

\subsection{Reasons for calling the callback routine}

The callback routine may be called by the MIP solver for the following
reasons.

\para{Request for subproblem selection}

The callback routine is called with the reason code \verb|GLP_ISELECT|
if the current subproblem has been fathomed and therefore there is no
current subproblem.

In response the callback routine may select some subproblem from the
active list and pass its reference number to the solver using the
routine \verb|glp_ios_select_node|, in which case the solver continues
the search from the specified active subproblem. If no selection is
made by the callback routine, the solver uses a backtracking technique
specified by the control parameter \verb|bt_tech|.

To explore the active list (i.e. active nodes of the branch-and-bound
tree) the callback routine may use the routines \verb|glp_ios_next_node|
and \verb|glp_ios_prev_node|.

\para{Request for preprocessing}

The callback routine is called with the reason code \verb|GLP_IPREPRO|
if the current subproblem has just been selected from the active list
and its LP relaxation is not solved yet.

In response the callback routine may perform some preprocessing of the
current subproblem like tightening bounds of some variables or removing
bounds of some redundant constraints.

\para{Request for row generation}

The callback routine is called with the reason code \verb|GLP_IROWGEN|
if LP relaxation of the current subproblem has just been solved to
optimality and its objective value is better than the best known
integer feasible solution.

In response the callback routine may add one or more ``lazy''
constraints (rows), which are violated by the current optimal solution
of LP relaxation, using API routines \verb|glp_add_rows|,
\verb|glp_set_row_name|, \verb|glp_set_row_bnds|, and
\verb|glp_set_mat_row|, in which case the solver will perform
re-optimization of LP relaxation. If there are no violated constraints,
the callback routine should just return.

Note that components of optimal solution to LP relaxation can be
obtained with API\linebreak routines \verb|glp_get_obj_val|,
\verb|glp_get_row_prim|, \verb|glp_get_row_dual|,
\verb|glp_get_col_prim|, and\linebreak \verb|glp_get_col_dual|.

\para{Request for heuristic solution}

The callback routine is called with the reason code \verb|GLP_IHEUR|
if LP relaxation of the current subproblem being solved to optimality
is integer infeasible (i.e. values of some structural variables of
integer kind are fractional), though its objective value is better than
the best known integer feasible solution.

In response the callback routine may try applying a primal heuristic
to find an integer feasible solution,\footnote{Integer feasible to the
original MIP problem, not to the current subproblem.} which is better
than the best known one. In case of success the callback routine may
store such better solution in the problem object using the routine
\verb|glp_ios_heur_sol|.

\para{Request for cut generation}

The callback routine is called with the reason code \verb|GLP_ICUTGEN|
if LP relaxation of the current subproblem being solved to optimality
is integer infeasible (i.e. values of some structural variables of
integer kind are fractional), though its objective value is better than
the best known integer feasible solution.

In response the callback routine may reformulate the {\it current}
subproblem (before it will be splitted up due to branching) by adding
to the problem object one or more {\it cutting plane constraints},
which cut off the fractional optimal point from the MIP
polytope.\footnote{Since these constraints are added to the current
subproblem, they may be globally as well as locally valid.}

Adding cutting plane constraints may be performed in two ways.
One way is the same as for the reason code \verb|GLP_IROWGEN| (see
above), in which case the callback routine adds new rows corresponding
to cutting plane constraints directly to the current subproblem.

The other way is to add cutting plane constraints to the
{\it cut pool}, a set of cutting plane constraints maintained by the
solver, rather than directly to the current subproblem. In this case
after return from the callback routine the solver looks through the
cut pool, selects efficient cutting plane constraints, adds them to the
current subproblem, drops other constraints, and then performs
re-optimization.

\para{Request for branching}

The callback routine is called with the reason code \verb|GLP_IBRANCH|
if LP relaxation of the current subproblem being solved to optimality
is integer infeasible (i.e. values of some structural variables of
integer kind are fractional), though its objective value is better than
the best known integer feasible solution.

In response the callback routine may choose some variable suitable for
branching (i.e. integer variable, whose value in optimal solution to
LP relaxation of the current subproblem is fractional) and pass its
ordinal number to the solver using the routine
\verb|glp_ios_branch_upon|, in which case the solver splits the current
subproblem in two new subproblems and continues the search.
If no choice is made by the callback routine, the solver uses
a branching technique specified by the control parameter \verb|br_tech|.

\para{Better integer solution found}

The callback routine is called with the reason code \verb|GLP_IBINGO|
if LP relaxation of the current subproblem being solved to optimality
is integer feasible (i.e. values of all structural variables of integer
kind are integral within the working precision) and its objective value
is better than the best known integer feasible solution.

Optimal solution components for LP relaxation can be obtained in the
same way as for the reason code \verb|GLP_IROWGEN| (see above).

Components of the new MIP solution can be obtained with API routines
\verb|glp_mip_obj_val|, \verb|glp_mip_row_val|, and
\verb|glp_mip_col_val|. Note, however, that due to row/cut generation
there may be additional rows in the problem object.

The difference between optimal solution to LP relaxation and
corresponding MIP solution is that in the former case some structural
variables of integer kind (namely, basic variables) may have values,
which are close to nearest integers within the working precision, while
in the latter case all such variables have exact integral values.

The reason \verb|GLP_IBINGO| is intended only for informational
purposes, so the callback routine should not modify the problem object
in this case.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newpage

\section{Basic routines}

\subsection{glp\_ios\_reason --- determine reason for calling the
callback routine}

\synopsis

\begin{verbatim}
   int glp_ios_reason(glp_tree *T);
\end{verbatim}

\returns

The routine \verb|glp_ios_reason| returns a code, which indicates why
the user-defined callback routine is being called:

\verb|GLP_ISELECT| --- request for subproblem selection;

\verb|GLP_IPREPRO| --- request for preprocessing;

\verb|GLP_IROWGEN| --- request for row generation;

\verb|GLP_IHEUR  | --- request for heuristic solution;

\verb|GLP_ICUTGEN| --- request for cut generation;

\verb|GLP_IBRANCH| --- request for branching;

\verb|GLP_IBINGO | --- better integer solution found.

\subsection{glp\_ios\_get\_prob --- access the problem object}

\synopsis

\begin{verbatim}
   glp_prob *glp_ios_get_prob(glp_tree *T);
\end{verbatim}

\description

The routine \verb|glp_ios_get_prob| can be called from the user-defined
callback routine to access the problem object, which is used by the MIP
solver. It is the original problem object passed to the routine
\verb|glp_intopt| if the MIP presolver is not used; otherwise it is an
internal problem object built by the presolver.

\returns

The routine \verb|glp_ios_get_prob| returns a pointer to the problem
object used by the MIP solver.

\para{Comments}

To obtain various information about the problem instance the callback
routine can access the problem object (i.e. the object of type
\verb|glp_prob|) using the routine \verb|glp_ios_get_prob|. It is the
original problem object passed to the routine \verb|glp_intopt| if the
MIP presolver is not used; otherwise it is an internal problem object
built by the presolver.

\newpage

\subsection{glp\_ios\_row\_attr --- determine additional row
attributes}

\synopsis

\begin{verbatim}
   void glp_ios_row_attr(glp_tree *T, int i, glp_attr *attr);
\end{verbatim}

\description

The routine \verb|glp_ios_row_attr| retrieves additional attributes of
$i$-th row of the current subproblem and stores them in the structure
\verb|glp_attr|, which the parameter \verb|attr| points to.

The structure \verb|glp_attr| has the following fields:

\medskip

{\tt int level}

Subproblem level at which the row was created. (If \verb|level| = 0,
the row was added either to the original problem object passed to the
routine \verb|glp_intopt| or to the root subproblem on generating
``lazy'' or/and cutting plane constraints.)

\medskip

{\tt int origin}

The row origin flag:

\verb|GLP_RF_REG | --- regular constraint;

\verb|GLP_RF_LAZY| --- ``lazy'' constraint;

\verb|GLP_RF_CUT | --- cutting plane constraint.

\medskip

{\tt int klass}

The row class descriptor, which is a number passed to the routine
\verb|glp_ios_add_row| as its third parameter. If the row is a cutting
plane constraint generated by the solver, its class may be the
following:

\verb|GLP_RF_GMI | --- Gomory's mixed integer cut;

\verb|GLP_RF_MIR | --- mixed integer rounding cut;

\verb|GLP_RF_COV | --- mixed cover cut;

\verb|GLP_RF_CLQ | --- clique cut.

\subsection{glp\_ios\_mip\_gap --- compute relative MIP gap}

\synopsis

\begin{verbatim}
   double glp_ios_mip_gap(glp_tree *T);
\end{verbatim}

\description

The routine \verb|glp_ios_mip_gap| computes the relative MIP gap (also
called {\it duality gap}) with the following formula:
$${\tt gap} = \frac{|{\tt best\_mip} - {\tt best\_bnd}|}
{|{\tt best\_mip}| + {\tt DBL\_EPSILON}}$$
where \verb|best_mip| is the best integer feasible solution found so
far, \verb|best_bnd| is the best (global) bound. If no integer feasible
solution has been found yet, \verb|gap| is set to \verb|DBL_MAX|.

\newpage

\returns

The routine \verb|glp_ios_mip_gap| returns the relative MIP gap.

\para{Comments}

The relative MIP gap is used to measure the quality of the best integer
feasible solution found so far, because the optimal solution value
$z^*$ for the original MIP problem always lies in the range
$${\tt best\_bnd}\leq z^*\leq{\tt best\_mip}$$
in case of minimization, or in the range
$${\tt best\_mip}\leq z^*\leq{\tt best\_bnd}$$
in case of maximization.

To express the relative MIP gap in percents the value returned by the
routine \verb|glp_ios_mip_gap| should be multiplied by 100\%.

\subsection{glp\_ios\_node\_data --- access application-specific data}

\synopsis

\begin{verbatim}
   void *glp_ios_node_data(glp_tree *T, int p);
\end{verbatim}

\description

The routine \verb|glp_ios_node_data| allows the application accessing
a memory block allocated for the subproblem (which may be active or
inactive), whose reference number is $p$.

The size of the block is defined by the control parameter
\verb|cb_size| passed to the routine \verb|glp_intopt|. The block is
initialized by binary zeros on creating corresponding subproblem, and
its contents is kept until the subproblem will be removed from the
tree.

The application may use these memory blocks to store specific data for
each subproblem.

\returns

The routine \verb|glp_ios_node_data| returns a pointer to the memory
block for the specified subproblem. Note that if \verb|cb_size| = 0,
the routine returns a null pointer.

\subsection{glp\_ios\_select\_node --- select subproblem to continue
the search}

\synopsis

\begin{verbatim}
   void glp_ios_select_node(glp_tree *T, int p);
\end{verbatim}

\description

The routine \verb|glp_ios_select_node| can be called from the
user-defined callback routine in response to the reason
\verb|GLP_ISELECT| to select an active subproblem, whose reference
number\linebreak is $p$. The search will be continued from the
subproblem selected.

\newpage

\subsection{glp\_ios\_heur\_sol --- provide solution found by
heuristic}

\synopsis

\begin{verbatim}
   int glp_ios_heur_sol(glp_tree *T, const double x[]);
\end{verbatim}

\description

The routine \verb|glp_ios_heur_sol| can be called from the user-defined
callback routine in response to the reason \verb|GLP_IHEUR| to provide
an integer feasible solution found by a primal heuristic.

Primal values of {\it all} variables (columns) found by the heuristic
should be placed in locations $x[1]$, \dots, $x[n]$, where $n$ is the
number of columns in the original problem object. Note that the routine
\verb|glp_ios_heur_sol| does {\it not} check primal feasibility of the
solution provided.

Using the solution passed in the array $x$ the routine computes value
of the objective function. If the objective value is better than the
best known integer feasible solution, the routine computes values of
auxiliary variables (rows) and stores all solution components in the
problem object.

\returns

If the provided solution is accepted, the routine
\verb|glp_ios_heur_sol| returns zero. Otherwise, if the provided
solution is rejected, the routine returns non-zero.

\vspace*{-5pt}

\subsection{glp\_ios\_can\_branch --- check if can branch upon
specified variable}

\synopsis

\begin{verbatim}
   int glp_ios_can_branch(glp_tree *T, int j);
\end{verbatim}

\returns

If $j$-th variable (column) can be used to branch upon, the routine
returns non-zero, otherwise zero.

\vspace*{-5pt}

\subsection{glp\_ios\_branch\_upon --- choose variable to branch upon}

\synopsis

\begin{verbatim}
   void glp_ios_branch_upon(glp_tree *T, int j, int sel);
\end{verbatim}

\description

The routine \verb|glp_ios_branch_upon| can be called from the
user-defined callback routine in response to the reason
\verb|GLP_IBRANCH| to choose a branching variable, whose ordinal number
\linebreak is $j$. Should note that only variables, for which the
routine \verb|glp_ios_can_branch| returns non-zero, can be used to
branch upon.

The parameter \verb|sel| is a flag that indicates which branch
(subproblem) should be selected next to continue the search:

\verb|GLP_DN_BRNCH| --- select down-branch;

\verb|GLP_UP_BRNCH| --- select up-branch;

\verb|GLP_NO_BRNCH| --- use general selection technique.

\newpage

\para{Comments}

On branching the solver removes the current active subproblem from the
active list and creates two new subproblems ({\it down-} and {\it
up-branches}), which are added to the end of the active list. Note that
the down-branch is created before the up-branch, so the last active
subproblem will be the up-branch.

The down- and up-branches are identical to the current subproblem with
exception that in the down-branch the upper bound of $x_j$, the variable
chosen to branch upon, is replaced by $\lfloor x_j^*\rfloor$, while in
the up-branch the lower bound of $x_j$ is replaced by
$\lceil x_j^*\rceil$, where $x_j^*$ is the value of $x_j$ in optimal
solution to LP relaxation of the current subproblem. For example, if
$x_j^*=3.14$, the new upper bound of $x_j$ in the down-branch is
$\lfloor 3.14\rfloor=3$, and the new lower bound in the up-branch is
$\lceil 3.14\rceil=4$.)

Additionally the callback routine may select either down- or up-branch,
from which the solver will continue the search. If none of the branches
is selected, a general selection technique will be used.

\subsection{glp\_ios\_terminate --- terminate the solution process}

\synopsis

\begin{verbatim}
   void glp_ios_terminate(glp_tree *T);
\end{verbatim}

\description

The routine \verb|glp_ios_terminate| sets a flag indicating that the
MIP solver should prematurely terminate the search.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newpage

\section{The search tree exploring routines}

\subsection{glp\_ios\_tree\_size --- determine size of the search tree}

\synopsis

\begin{verbatim}
   void glp_ios_tree_size(glp_tree *T, int *a_cnt, int *n_cnt, int *t_cnt);
\end{verbatim}

\description

The routine \verb|glp_ios_tree_size| stores the following three counts
which characterize the current size of the search tree:

\verb|a_cnt| is the current number of active nodes, i.e. the current
size of the active list;

\verb|n_cnt| is the current number of all (active and inactive) nodes;

\verb|t_cnt| is the total number of nodes including those which have
been already removed from the tree. This count is increased whenever
a new node appears in the tree and never decreased.

If some of the parameters \verb|a_cnt|, \verb|n_cnt|, \verb|t_cnt| is
a null pointer, the corresponding count is not stored.

\subsection{glp\_ios\_curr\_node --- determine current active
subproblem}

\synopsis

\begin{verbatim}
   int glp_ios_curr_node(glp_tree *T);
\end{verbatim}

\returns

The routine \verb|glp_ios_curr_node| returns the reference number of
the current active subproblem. However, if the current subproblem does
not exist, the routine returns zero.

\subsection{glp\_ios\_next\_node --- determine next active subproblem}

\synopsis

\begin{verbatim}
   int glp_ios_next_node(glp_tree *T, int p);
\end{verbatim}

\returns

If the parameter $p$ is zero, the routine \verb|glp_ios_next_node|
returns the reference number of the first active subproblem. However,
if the tree is empty, zero is returned.

If the parameter $p$ is not zero, it must specify the reference number
of some active subproblem, in which case the routine returns the
reference number of the next active subproblem. However, if there is
no next active subproblem in the list, zero is returned.

All subproblems in the active list are ordered chronologically, i.e.
subproblem $A$ precedes subproblem $B$ if $A$ was created before $B$.

\newpage

\subsection{glp\_ios\_prev\_node --- determine previous active
subproblem}

\synopsis

\begin{verbatim}
   int glp_ios_prev_node(glp_tree *T, int p);
\end{verbatim}

\returns

If the parameter $p$ is zero, the routine \verb|glp_ios_prev_node|
returns the reference number of the last active subproblem. However, if
the tree is empty, zero is returned.

If the parameter $p$ is not zero, it must specify the reference number
of some active subproblem, in which case the routine returns the
reference number of the previous active subproblem. However, if there
is no previous active subproblem in the list, zero is returned.

All subproblems in the active list are ordered chronologically, i.e.
subproblem $A$ precedes subproblem $B$ if $A$ was created before $B$.

\subsection{glp\_ios\_up\_node --- determine parent subproblem}

\synopsis

\begin{verbatim}
   int glp_ios_up_node(glp_tree *T, int p);
\end{verbatim}

\returns

The parameter $p$ must specify the reference number of some (active or
inactive) subproblem, in which case the routine \verb|iet_get_up_node|
returns the reference number of its parent subproblem. However, if the
specified subproblem is the root of the tree and, therefore, has
no parent, the routine returns zero.

\subsection{glp\_ios\_node\_level --- determine subproblem level}

\synopsis

\begin{verbatim}
   int glp_ios_node_level(glp_tree *T, int p);
\end{verbatim}

\returns

The routine \verb|glp_ios_node_level| returns the level of the
subproblem, whose reference number is $p$, in the branch-and-bound
tree. (The root subproblem has level 0, and the level of any other
subproblem is the level of its parent plus one.)

\subsection{glp\_ios\_node\_bound --- determine subproblem local bound}

\synopsis

\begin{verbatim}
   double glp_ios_node_bound(glp_tree *T, int p);
\end{verbatim}

\returns

The routine \verb|glp_ios_node_bound| returns the local bound for
(active or inactive) subproblem, whose reference number is $p$.

\newpage

\para{Comments}

The local bound for subproblem $p$ is an lower (minimization) or upper
(maximization) bound for integer optimal solution to {\it this}
subproblem (not to the original problem). This bound is local in the
sense that only subproblems in the subtree rooted at node $p$ cannot
have better integer feasible solutions.

On creating a subproblem (due to the branching step) its local bound is
inherited from its parent and then may get only stronger (never weaker).
For the root subproblem its local bound is initially set to
\verb|-DBL_MAX| (minimization) or \verb|+DBL_MAX| (maximization) and
then improved as the root LP relaxation has been solved.

Note that the local bound is not necessarily the optimal objective
value to corresponding LP relaxation.

\subsection{glp\_ios\_best\_node --- find active subproblem with best
local bound}

\synopsis

\begin{verbatim}
   int glp_ios_best_node(glp_tree *T);
\end{verbatim}

\returns

The routine \verb|glp_ios_best_node| returns the reference number of
the active subproblem, whose local bound is best (i.e. smallest in case
of minimization or largest in case of maximization). However, if the
tree is empty, the routine returns zero.

\para{Comments}

The best local bound is an lower (minimization) or upper (maximization)
bound for integer optimal solution to the original MIP problem.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newpage

\section{The cut pool routines}

\subsection{glp\_ios\_pool\_size --- determine current size of the cut
pool}

\synopsis

\begin{verbatim}
   int glp_ios_pool_size(glp_tree *T);
\end{verbatim}

\returns

The routine \verb|glp_ios_pool_size| returns the current size of the
cut pool, that is, the number of cutting plane constraints currently
added to it.

\subsection{glp\_ios\_add\_row --- add constraint to the cut pool}

\synopsis

\begin{verbatim}
   int glp_ios_add_row(glp_tree *T, const char *name, int klass, int flags,
       int len, const int ind[], const double val[], int type, double rhs);
\end{verbatim}

\description

The routine \verb|glp_ios_add_row| adds specified row (cutting plane
constraint) to the cut pool.

The cutting plane constraint should have the following format:
$$\sum_{j\in J}a_jx_j\left\{\begin{array}{@{}c@{}}\geq\\\leq\\
\end{array}\right\}b,$$
where $J$ is a set of indices (ordinal numbers) of structural
variables, $a_j$ are constraint coefficients, $x_j$ are structural
variables, $b$ is the right-hand side.

The parameter \verb|name| specifies a symbolic name assigned to the
constraint (1 up to 255 characters). If it is \verb|NULL| or an empty
string, no name is assigned.

The parameter \verb|klass| specifies the constraint class, which must
be either zero or a number in the range from 101 to 200.
The application may use this attribute to distinguish between cutting
plane constraints of different classes.\footnote{Constraint classes
numbered from 1 to 100 are reserved for GLPK cutting plane generators.}

The parameter \verb|flags| currently is not used and must be zero.

Ordinal numbers of structural variables (i.e. column indices) $j\in J$
and numerical values of corresponding constraint coefficients $a_j$
should be placed in locations \verb|ind[1]|, \dots, \verb|ind[len]| and
\verb|val[1]|, \dots, \verb|val[len]|, respectively, where
${\tt len}=|J|$ is the number of constraint coefficients,
$0\leq{\tt len}\leq n$, and $n$ is the number of columns in the problem
object. Coefficients with identical column indices are not allowed.
Zero coefficients are allowed, however, they are ignored.

The parameter \verb|type| specifies the constraint type as follows:

\verb|GLP_LO| means inequality constraint $\Sigma a_jx_j\geq b$;

\verb|GLP_UP| means inequality constraint $\Sigma a_jx_j\leq b$;

\newpage

The parameter \verb|rhs| specifies the right-hand side $b$.

All cutting plane constraints in the cut pool are identified by their
ordinal numbers 1, 2, \dots, $size$, where $size$ is the current size
of the cut pool. New constraints are always added to the end of the cut
pool, thus, ordinal numbers of previously added constraints are not
changed.

\returns

The routine \verb|glp_ios_add_row| returns the ordinal number of the
cutting plane constraint added, which is the new size of the cut pool.

\para{Example}

\begin{verbatim}
/* generate triangle cutting plane:
   x[i] + x[j] + x[k] <= 1 */
. . .
/* add the constraint to the cut pool */
ind[1] = i, val[1] = 1.0;
ind[2] = j, val[2] = 1.0;
ind[3] = k, val[3] = 1.0;
glp_ios_add_row(tree, NULL, TRIANGLE_CUT, 0, 3, ind, val, GLP_UP, 1.0);
\end{verbatim}

\para{Comments}

Cutting plane constraints added to the cut pool are intended to be then
added only to the {\it current} subproblem, so these constraints can be
globally as well as locally valid. However, adding a constraint to the
cut pool does not mean that it will be added to the current
subproblem---it depends on the solver's decision: if the constraint
seems to be efficient, it is moved from the pool to the current
subproblem, otherwise it is simply dropped.\footnote{Globally valid
constraints could be saved and then re-used for other subproblems, but
currently such feature is not implemented.}

Normally, every time the callback routine is called for cut generation,
the cut pool is empty. On the other hand, the solver itself can
generate cutting plane constraints (like Gomory's or mixed integer
rounding cuts), in which case the cut pool may be non-empty.

\subsection{glp\_ios\_del\_row --- remove constraint from the cut pool}

\synopsis

\begin{verbatim}
   void glp_ios_del_row(glp_tree *T, int i);
\end{verbatim}

\description

The routine \verb|glp_ios_del_row| deletes $i$-th row (cutting plane
constraint) from the cut pool, where $1\leq i\leq size$ is the ordinal
number of the constraint in the pool, $size$ is the current size of the
cut pool.

Note that deleting a constraint from the cut pool leads to changing
ordinal numbers of other constraints remaining in the pool. New ordinal
numbers of the remaining constraints are assigned under assumption that
the original order of constraints is not changed. Let, for example,
there be four constraints $a$, $b$, $c$ and $d$ in the cut pool, which
have ordinal numbers 1, 2, 3 and 4, respectively, and let constraint
$b$ have been deleted. Then after deletion the remaining constraint $a$,
$c$ and $d$ are assigned new ordinal numbers 1, 2 and 3, respectively.

To find the constraint to be deleted the routine \verb|glp_ios_del_row|
uses ``smart'' linear search, so it is recommended to remove
constraints in a natural or reverse order and avoid removing them in
a random order.

\para{Example}

\begin{verbatim}
/* keep first 10 constraints in the cut pool and remove other
   constraints */
while (glp_ios_pool_size(tree) > 10)
   glp_ios_del_row(tree, glp_ios_pool_size(tree));
\end{verbatim}

\subsection{glp\_ios\_clear\_pool --- remove all constraints from the
cut pool}

\synopsis

\begin{verbatim}
   void glp_ios_clear_pool(glp_tree *T);
\end{verbatim}

\description

The routine \verb|glp_ios_clear_pool| makes the cut pool empty deleting
all existing rows (cutting plane constraints) from it.

%* eof *%