File: Mongoose_UserGuide.tex

package info (click to toggle)
suitesparse 1%3A7.10.1%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 254,920 kB
  • sloc: ansic: 1,134,743; cpp: 46,133; makefile: 4,875; fortran: 2,087; java: 1,826; sh: 996; ruby: 725; python: 495; asm: 371; sed: 166; awk: 44
file content (890 lines) | stat: -rw-r--r-- 45,791 bytes parent folder | download | duplicates (2)
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
\documentclass[letter]{article}
\batchmode
\usepackage{fancyhdr} % Required for custom headers
\usepackage{lastpage} % Required to determine the last page for the footer
\usepackage{extramarks} % Required for headers and footers
\usepackage[usenames,dvipsnames]{color} % Required for custom colors
\usepackage[table]{xcolor}
\usepackage{graphicx} % Required to insert images
\usepackage{listings} % Required for insertion of code
\usepackage{algpseudocode} % Required for pseudocode listing
\usepackage{courier} % Required for the courier font
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{booktabs}
\usepackage{multirow}
\usepackage{tikz}
\usetikzlibrary{arrows, shapes, positioning, calc}
\usepackage{caption}
\usepackage{wasysym}
\usepackage{multirow}
\usepackage{float}
\usepackage{tcolorbox}
\usepackage{csquotes}
\usepackage{fancybox}
\usepackage{enumitem}
\usepackage[letterspace=150]{microtype}
\usepackage{cancel}
\usepackage{bm}
\usepackage{makeidx}
\usepackage{url}
\usepackage[pdfborder={0 0 0}]{hyperref}

\usepackage{sourcecodepro}

\definecolor{MyDarkGreen}{rgb}{0.0,0.4,0.0} % This is the color used for comments
\definecolor{mygreen}{rgb}{0,0.6,0}
\definecolor{mygray}{rgb}{0.5,0.5,0.5}
\definecolor{mymauve}{rgb}{0.58,0,0.82}

\lstset{ %
  backgroundcolor=\color{white},   % choose the background color; you must add \usepackage{color} or \usepackage{xcolor}
  basicstyle=\sourcecodepro\footnotesize ,        % the size of the fonts that are used for the code
  breakatwhitespace=true,         % sets if automatic breaks should only happen at whitespace
  breaklines=true,                 % sets automatic line breaking
  captionpos=b,                    % sets the caption-position to bottom
  commentstyle=\color{mygreen},    % comment style
  deletekeywords={...},            % if you want to delete keywords from the given language
  escapeinside={(*}{*)},          % if you want to add LaTeX within your code
  extendedchars=true,              % lets you use non-ASCII characters; for 8-bits encodings only, does not work with UTF-8
  frame=single,                    % adds a frame around the code
  keepspaces=true,                 % keeps spaces in text, useful for keeping indentation of code (possibly needs columns=flexible)
  keywordstyle=\color{blue},       % keyword style
  language=C,                 % the language of the code
  morekeywords={repeat,integer,function,end,*,...},            % if you want to add more keywords to the set
  numbers=left,                    % where to put the line-numbers; possible values are (none, left, right)
  numbersep=5pt,                   % how far the line-numbers are from the code
  numberstyle=\tiny\color{mygray}, % the style that is used for the line-numbers
  rulecolor=\color{black},         % if not set, the frame-color may be changed on line-breaks within not-black text (e.g. comments (green here))
  showspaces=false,                % show spaces everywhere adding particular underscores; it overrides 'showstringspaces'
  showstringspaces=false,          % underline spaces within strings only
  showtabs=false,                  % show tabs within strings adding particular underscores
  stepnumber=1,                    % the step between two line-numbers. If it's 1, each line will be numbered
  stringstyle=\color{mymauve},     % string literal style
  tabsize=2,                       % sets default tabsize to 2 spaces
  title=\lstname                   % show the filename of files included with \lstinputlisting; also try caption instead of title
}


% Margins
\topmargin=-0.45in
\evensidemargin=0in
\oddsidemargin=0in
\textwidth=6.5in
%\textheight=9.0in
\headsep=0.25in

\linespread{1.1} % Line spacing

% Set up the header and footer
%\pagestyle{fancy}
%\renewcommand\headrulewidth{0.4pt} % Size of the header rule
%\renewcommand\footrulewidth{0.4pt} % Size of the footer rule

\setlength\parindent{0pt} % Removes all indentation from paragraphs

\renewcommand{\familydefault}{\sfdefault}

\newcommand{\mb}[1]{{\bf{#1}}}
\newcommand{\tr}{^{\sf T}}

\input{title-info.tex}

\makeindex

\begin{document}

\maketitle

\tableofcontents

\newpage

\section{Overview}
% What is the problem we're solving? What does this package do?
Mongoose is a graph partitioning library that can quickly compute edge cuts in arbitrary graphs \cite{MongooseTOMS}. Given a graph with a vertex set $V$ and edge set $E$, an edge cut is a partitioning of the graph into two subgraphs that are balanced (contain the same number of vertices) and the connectivity between the subgraphs is minimized (few edges are in the cut).
\\

Finding high quality edge cuts quickly is an important part of circuit simulation, parallel and distributed computing, and sparse matrix algorithms.


 Mongoose Graph Partitioning Library, Copyright (C) 2017-2018,
 Scott P. Kolodziej, Nuri S. Yeralan, Timothy A. Davis, William W. Hager
 Mongoose is licensed under Version 3 of the GNU General Public License.
 Mongoose is also available under other licenses; contact authors for details.

SPDX-License-Identifier: GPL-3.0-only

\subsection{Coarsening and Refinement Framework}

Mongoose uses a coarsening and refinement framework (sometimes referred to as a multilevel framework \cite{HendricksonLeland1995, KarypisKumar1995}). Rather than attempt to compute an edge cut on the input graph directly, Mongoose first coarsens the graph by computing a vertex matching and contracting the graph to form a smaller, but structurally similar, graph.

\begin{figure}[!ht] 
\begin{center} 
    \includegraphics[scale=0.18]{Figures/MultilevelOverview.eps} 
    \caption{Coarsening and Refinement} 
\end{center} 
\end{figure} 

Mongoose uses a variety of methods to coarsen the input graph, including random matching and heavy-edge matching. Additionally, Mongoose offers stall-reducing vertex matching strategies called Brotherly (or two-hop) matching and Community matching. Brotherly matching allows vertices who share a neighbor to be matched, even if they have no edge directly connecting them, and community matching allows two vertices whose neighbors are matched together to be matched together. These methods are advantageous in efficiently coarsening certain classes of graphs, notably social networking graphs, where the vertex degree can vary greatly.

\begin{center}
\begin{minipage}[c]{0.47\linewidth}
    \includegraphics[scale=0.26]{Figures/BrotherlyMatching.eps} 
    \captionof{figure}{Brotherly Matching} 
\end{minipage}
\hspace{22pt}
\begin{minipage}[c]{0.47\linewidth}
    \includegraphics[scale=0.26]{Figures/CommunityMatching.eps} 
    \captionof{figure}{Community Matching} 
\end{minipage}
\end{center}

Another matching strategy used in Mongoose is known as Adoption matching. If an unmatched vertex has no unmatched neighbors, it can be grouped into a 3-way matching with a neighboring matched vertex. These strategies allow the graph to be coarsened quickly even when the graph is highly irregular, which in turn decreases memory requirements and overall computational time.

\subsection{Quadratic Programming and Optimization}

Mongoose is known as a hybrid graph partitioner, as it uses multiple methods in tandem to find higher quality cuts efficiently. The first such method Mongoose employs is quadratic programming (QP). The edge cut problem was formatted as a continuous quadratic programming problem by Hager and Krylyuk \cite{HagerKrylyuk1999}. This formulation is solved (rather, improved) using a gradient projection algorithm and a modified version of NAPHEAP, a quadratic knapsack solver \cite{DavisHagerHungerford2016}.
\\

The quadratic program used is shown below. Hager and Krylyuk have proven that the global optimum to this quadratic program yields the solution to the graph partitioning problem (but note that both are NP-hard problems to solve).
%
\begin{eqnarray}
&\displaystyle\min_{\mb{x}\in\mathbb{R}^n}\quad  (\mb{1} - \mb{x})\tr (\mb{A} + \mb{I})\mb{x}
& \quad \mbox{subject to}  \quad
\mb{0} \le \mb{x} \le \mb{1}, \quad \ell \le \mb{1}\tr \mb{x} \le u, \nonumber
\end{eqnarray}

$\ell$ and $u$ are lower and upper bounds on the desired size of one partition, and $\mb{A}$ is the adjacency matrix of the graph.

\subsection{Fiduccia-Mattheyses Algorithm}

In addition to the quadratic programming approach for refining an edge cut, a standard implementation of the Fiduccia-Mattheyses algorithm \cite{FiducciaMattheyses1982} is also provided. This involves swapping vertices from one part to the other in an effort to improve the edge cut quality. Some vertices are swapped even if no immediate improvement is found in an attempt to escape a locally optimal solution. However, if no improvement is found after a number of swaps, the change is reverted.\\
\\
The Fiduccia-Mattheyses (FM) implementation in Mongoose utilizes heaps for high efficiency. 

\section{Availability}

\subsection{Getting the Code}
Mongoose is available on GitHub at \url{https://github.com/ScottKolo/Mongoose}. The code can be downloaded using \texttt{git} using the following command:
\[\text{\texttt{git clone https://github.com/ScottKolo/Mongoose}}\]
Alternatively, Mongoose can be downloaded as a zip archive from the following URL:
\[\text{\url{https://github.com/ScottKolo/Mongoose/archive/edgesep.zip}}\] 

Mongoose also appears as a component package of SuiteSparse, \url{http://suitesparse.com}.

\subsection{Prerequisites}
Mongoose requires CMake 3.18 and any ISO/IEC 14882:1998 compliant C++ compiler. Mongoose has been tested to work with GNU GCC 4.4+ and LLVM Clang 3.5+ on Linux, and Apple Xcode 6.4+ on macOS.

\subsection{Compilation}
Once downloaded, Mongoose is built with \verb'cmake'
An optional \verb'Makefile' can be used to simpilfy the use of
\verb'cmake':

\begin{lstlisting}[language=bash,numbers=none,xleftmargin=.2\textwidth, xrightmargin=.2\textwidth]
cd Mongoose
make
sudo make install
\end{lstlisting}

% mkdir build # Create a build directory
% cd build 
% cmake ..     # Use CMake to create the Makefiles
% make         # Build Mongoose

After compilation, the Mongoose demo can be run using \texttt{./build/demo}:\\

\begin{lstlisting}[numbers=none,xleftmargin=.09\textwidth, xrightmargin=.09\textwidth,keywordstyle=\color{black}]
./build/demo

********************************************************************************
Mongoose Graph Partitioning Library, Version 2.0.2 July 5, 2018
Copyright (C) 2017-2018
Scott P. Kolodziej, Nuri S. Yeralan, Timothy A. Davis, William W. Hager
Mongoose is licensed under Version 3 of the GNU General Public License.
Mongoose is also available under other licenses; contact authors for details.
********************************************************************************
Computing an edge cut for Erdos971.mtx...
Cut Cost:       1.1e+02
Cut Imbalance:  zero (a perfect balance)
Trial Time:     1.9ms
********************************************************************************
Computing an edge cut for G51.mtx...
Cut Cost:       1.5e+03
Cut Imbalance:  zero (a perfect balance)
Trial Time:     8.4ms
********************************************************************************
Computing an edge cut for GD97_b.mtx...
Cut Cost:       2.6e+03
Cut Imbalance:  1.1%
Trial Time:     0.19ms
********************************************************************************
Computing an edge cut for Pd.mtx...
Cut Cost:       1
Cut Imbalance:  0.0062%
Trial Time:     12ms
********************************************************************************
Computing an edge cut for bcspwr01.mtx...
Cut Cost:       3
Cut Imbalance:  1.3%
Trial Time:     0.18ms
********************************************************************************
Computing an edge cut for bcspwr02.mtx...
Cut Cost:       5
Cut Imbalance:  1%
Trial Time:     0.17ms
********************************************************************************
Computing an edge cut for bcspwr03.mtx...
Cut Cost:       11
Cut Imbalance:  zero (a perfect balance)
Trial Time:     0.34ms
********************************************************************************
Computing an edge cut for bcspwr04.mtx...
Cut Cost:       25
Cut Imbalance:  zero (a perfect balance)
Trial Time:     0.75ms
********************************************************************************
Computing an edge cut for bcspwr05.mtx...
Cut Cost:       12
Cut Imbalance:  0.11%
Trial Time:     0.91ms
********************************************************************************
Computing an edge cut for bcspwr06.mtx...
Cut Cost:       7
Cut Imbalance:  zero (a perfect balance)
Trial Time:     2.4ms
********************************************************************************
Computing an edge cut for bcspwr07.mtx...
Cut Cost:       7
Cut Imbalance:  zero (a perfect balance)
Trial Time:     2.6ms
********************************************************************************
Computing an edge cut for bcspwr08.mtx...
Cut Cost:       25
Cut Imbalance:  zero (a perfect balance)
Trial Time:     2.2ms
********************************************************************************
Computing an edge cut for bcspwr09.mtx...
Cut Cost:       11
Cut Imbalance:  0.029%
Trial Time:     5.4ms
********************************************************************************
Computing an edge cut for bcspwr10.mtx...
Cut Cost:       25
Cut Imbalance:  zero (a perfect balance)
Trial Time:     8.6ms
********************************************************************************
Computing an edge cut for dwt_992.mtx...
Cut Cost:       1.9e+02
Cut Imbalance:  zero (a perfect balance)
Trial Time:     4.7ms
********************************************************************************
Computing an edge cut for jagmesh7.mtx...
Cut Cost:       27
Cut Imbalance:  zero (a perfect balance)
Trial Time:     2.8ms
********************************************************************************
Computing an edge cut for NotreDame_www.mtx...
Cut Cost:       1.9e+02
Cut Imbalance:  0.00015%
Trial Time:     6.2e+02ms
********************************************************************************
Total Demo Time:  0.67s

Demo complete; all tests passed
\end{lstlisting}

To run the complete test suite, the command \texttt{make test} can be used. Note that Python 2.7+ must be installed. Additionally, this user guide can be generated from source with the command \texttt{make userguide}. XeLaTeX (commonly included in LaTeX distributions) must be installed.

\section{Using Mongoose as an Executable}

In addition to the demo executable, the \texttt{mongoose} executable is built at \texttt{./build/mongoose}. This executable can be used to partition a graph given a Matrix Market file:

\[\text{\texttt{mongoose <MM-input-file.mtx> [output-file]}}\]

The \texttt{mongoose} executable generates a text file with two blocks: a JSON-formatted information block with timing and cut quality metrics, and the partitioning information itself. The partitioning information is listed with one vertex per line, with the vertex number followed by the part (0 for part A, 1 for part B).\\

For example, the following can be used to partition the \texttt{NotreDame\_www.mtx} matrix:

\begin{lstlisting}[numbers=none,xleftmargin=.09\textwidth, xrightmargin=.09\textwidth,keywordstyle=\color{black}]
cd build
./mongoose ../Matrix/NotreDame_www.mtx NotreDame_www_out.mtx

********************************************************************************
Mongoose Graph Partitioning Library, Version 2.0.2 July 5, 2018
Copyright (C) 2017-2018
Scott P. Kolodziej, Nuri S. Yeralan, Timothy A. Davis, William W. Hager
Mongoose is licensed under Version 3 of the GNU General Public License.
Mongoose is also available under other licenses; contact authors for details.
********************************************************************************
Total Edge Separator Time: 0.256587s
 Matching:   0.03576s
 Coarsening: 0.05597s
 Refinement: 0.01149s
 FM:         0.002221s
 QP:         0.1448s
 IO:         0.3147s
Cut Properties:
 Cut Size:       320
 Cut Cost:       165
 Imbalance:      1.535e-06
\end{lstlisting}

The output file name is optional. If omitted, the default is \texttt{mongoose\_out.txt}.
For this matrix, the output file looks like the following:

\begin{lstlisting}[numbers=none,xleftmargin=.09\textwidth, xrightmargin=.09\textwidth,keywordstyle=\color{black}]
{
  "InputFile": "../Matrix/NotreDame_www.mtx",
  "Timing": {
    "Total": 0.256587,
    "Matching": 0.035762,
    "Coarsening": 0.055973,
    "Refinement": 0.011487,
    "FM": 0.002221,
    "QP": 0.144759,
    "IO": 0.314704
  },
  "CutSize": 320,
  "CutCost": 165,
  "Imbalance": 1.53502e-06
}

0 0
1 0
2 0
3 0
...
218 1
219 0
...
325660 1
325661 1
325662 1
325664 0
325665 0
...
325727 0
325728 0

\end{lstlisting}

\subsection{License}

Mongoose is licensed under the GNU Public License version 3 (GPLv3). Full text of the license can be found int \texttt{Mongoose/Doc/License.txt}. For a commercial license, please contact Dr.~Timothy A.~Davis at davis@tamu.edu.

\section{Using Mongoose in C++}

\subsection{Sample C++ Program}
% Without weights, with edge weights, with vertex weights

\begin{lstlisting}
#include "Mongoose.hpp"
#include <iostream>
#include <iomanip>
#include <math.h>

using namespace Mongoose;
using namespace std;

int main(int argn, const char **argv)
{
    EdgeCut_Options *options = EdgeCut_Options::create();
    if (!options) return EXIT_FAILURE; // Return an error if we failed.

    options->matching_strategy = HEMSRdeg;
    options->initial_cut_type = InitialEdgeCut_QP;

    Graph *graph = read_graph(argv[1]);
    if (!graph)
    {
        options->~EdgeCut_Options();
        return EXIT_FAILURE;
    }

    // Call Mongoose to compute an edge separator
    EdgeCut *result = edge_cut(graph, options);

    cout << "Partitioning Complete!" << endl;
    cout << "Cut Cost:      " << setprecision(2) << result->cut_cost << endl;
    cout << "Cut Imbalance: " << setprecision(2) << fabs(100*result->imbalance) << "%" << endl;

    options->~EdgeCut_Options();
    graph->~Graph();
    result->~EdgeCut();

    /* Return success */
    return EXIT_SUCCESS;
}
\end{lstlisting}

\subsection{Creating a Graph}

There are several different ways to create a \texttt{Graph} class instance for use in Mongoose.

The input graph to Mongoose is undirected, and can optionally be a weighted
graph.  The graph is held in compressed-sparse column form, or equivalently
compressed-sparse row form since the adjacency matrix is symmetric.  The graph
is represented by the following components:

    \begin{itemize}
    \item \texttt{Int n}: the number of vertices in the graph.
    \item \texttt{Int nz}: the number of nonzero entries in the adjacency matrix,
        which is twice the number edges.
    \item \texttt{Int p [n+1]}: the column pointer vector of size \texttt{n+1}.
    \item \texttt{Int i [nz]}: the adjacency lists held in a single array.  The adjacency
        list of vertex \texttt{j} is held in \texttt{i [p [j] ... p [j+1]-1]}.
        Self-edges must not appear.
        The graph must be undirected, and so the adjacency matrix must be symmetric.
    \item \texttt{double x [nz]}: an optional array of edge weights, where
        \texttt{x [p [j] ... p [j+1]-1]} are the edge weights of the corresponding
        edges in the adjacency list of vertex \texttt{j}.
        If \texttt{x} is \texttt{NULL}, then the edges all have weight 1.
    \item \texttt{double w [n]}: an optional array of vertex weights,
        where vertex \texttt{j} has weight \texttt{w [j]}.
        If \texttt{w} is \texttt{NULL}, then the vertices all have weight 1.
    \end{itemize}
    
Note that the \texttt{Int} type is generally a 64-bit (long) integer type. It
is defined as \verb'typedef int64_t Int;'.

\subsubsection{Creating a Graph Manually}

To create a graph manually, the following constructor is used: \\

\textbf{\texttt{static Graph *create(const Int \_n, \\
\hspace*{4.2cm} const Int \_nz, \\
\hspace*{4.2cm} Int *\_p = NULL, \\
\hspace*{4.2cm} Int *\_i = NULL, \\
\hspace*{4.2cm} double *\_x = NULL, \\
\hspace*{4.2cm} double *\_w = NULL);}}\\
\\
Using the manual constructor, the number of vertices (or dimension of the matrix, \texttt{Int \_n}) and the number of edges (or nonzero entries in the matrix, \texttt{Int \_nz}) must both be specified. The column pointer vector \texttt{Int *\_p} and row index vector \texttt{Int *\_i} must either be specified by the user, or, if left \texttt{NULL}, they will be allocated such that \texttt{\_p = (Int *)SuiteSparse\_calloc(n + 1, sizeof(Int));} and \texttt{\_i = (Int *)SuiteSparse\_malloc(nz, sizeof(Int));}. The edge weights \texttt{double *\_x} and the vertex weights \texttt{double *\_w} can either be specified, or, if left \texttt{NULL}, will be assumed to be one for all edges and vertices, respectively.\\

Here are some examples:

\begin{itemize}
\item \texttt{Graph::create(20, 50);} creates a \texttt{Graph} with 20 vertices and 50 edges, but no data. \texttt{Graph->p} and \texttt{Graph->i} are allocated by Mongoose to store exactly 20 columns (vertices) and 50 nonzero elements (edges). This allows the user to populate \texttt{Graph->p} and \texttt{Graph->i} manually. All edge and vertex weights are assumed to be one.
\item \texttt{Graph::create(20, 50, \_p, \_i);} creates a \texttt{Graph} with 20 vertices and 50 edges with the pattern specified. \texttt{Graph->p} and \texttt{Graph->i} are shallow copies of the arguments \texttt{\_p} and \texttt{\_i} and will not be freed upon calling the destructor. All edge and vertex weights are assumed to be one.
\item \texttt{Graph::create(20, 50, \_p, \_i, \_x);} creates a \texttt{Graph} with 20 vertices and 50 edges with the pattern and edge weights specified. \texttt{Graph->p}, \texttt{Graph->i}, and \texttt{Graph->x} are shallow copies of the arguments \texttt{\_p}, \texttt{\_i}, and \texttt{\_x}, and will not be freed upon calling the destructor. Edge weights are specified by \texttt{\_x}, but vertex weights are assumed to be one.
\item \texttt{Graph::create(20, 50, \_p, \_i, \_x, \_w);} creates a \texttt{Graph} with 20 vertices and 50 edges with edge and vertex weights specified. \texttt{Graph->p}, \texttt{Graph->i}, \texttt{Graph->x}, and \texttt{Graph->w} are shallow copies of the arguments \texttt{\_p}, \texttt{\_i}, \texttt{\_x}, and \texttt{\_w}, and will not be freed upon calling the destructor. Edge weights are specified by \texttt{\_x}, and vertex weights are specified by \texttt{\_w}.
\end{itemize}


\subsubsection{Creating a Graph from a Sparse Matrix}

Another way to create a \texttt{Mongoose::Graph} is from a pre-existing \texttt{CSparse} matrix struct.\\

\textbf{\texttt{static Graph *Create(cs *matrix);}}\\

Using this constructor, a \texttt{CSparse} matrix struct can be passed directly, with shallow copies made of \texttt{cs->p}, \texttt{cs->i}, and \texttt{cs->x}. Note that  this constructor is equivalent to calling the following for a \texttt{CSparse} matrix \texttt{cs *A}:\\

\textbf{\texttt{Graph::create(const Int A->n, A->p[A->n], A->p, A->i, A->x, NULL);}}

\subsubsection{Creating a Graph from a Matrix Market File}

Perhaps the easiest way to create a \texttt{Graph} instance is from a file. Mongoose provides easy file input helpers to read, sanitize, and format a Matrix Market file. The matrix contained in the file must be sparse, real, and square. If the matrix is not symmetric, it will be made symmetric by computing $\frac{1}{2}(A+A^T)$. If a diagonal is present, it will be removed.\\

\textbf{\texttt{Graph *read\_graph(const std::string \&filename);}}\\
\textbf{\texttt{Graph *read\_graph(const char *filename);}}\\

For example, to read in the Matrix Market file \texttt{jagmesh7.mtx} located in the Mongoose sample matrix directory, the following code can be used:\\

\textbf{\texttt{Mongoose::read\_graph(``../Matrix/jagmesh7.mtx");}}

\subsection{C++ API}

The following functions are available in the C++ API. After Mongoose is compiled, a static library version of Mongoose is built at \texttt{Mongoose/build/libmongoose.a}. Include the \texttt{Mongoose.hpp} header file located in \texttt{Mongoose/Include} and link with the static library to enable the following API functions.
Both the static and dynamic libraries, and the include file can then be
installed for system-wide use with \texttt{sudo make install} in the top-level
\texttt{Mongoose} directory.

\begin{itemize}
\item \textbf{\texttt{Graph *read\_graph(const std::string \&filename);}} \vspace{-6pt}
\item \textbf{\texttt{Graph *read\_graph(const char *filename);}}

\texttt{Mongoose::read\_graph} will attempt to read a Matrix Market file with the given filename and convert it to a Mongoose Graph instance. The matrix contained in the file must be sparse, real, and square. If the matrix is not symmetric, it will be made symmetric by computing $\frac{1}{2}(A+A^T)$. If a diagonal is present, it will be removed.

\texttt{Mongoose::read\_graph(const std::string \&filename)} accepts a C++-style std::string, while \texttt{Mongoose::read\_graph(const char *filename)} accepts a C-style null-terminated string.
\vspace{6pt}
\item \textbf{\texttt{EdgeCut edge\_cut(const Graph *);}} \vspace{-6pt}
\item \textbf{\texttt{EdgeCut edge\_cut(const Graph *, const EdgeCut\_Options *);}}

\texttt{Mongoose::edge\_cut} will attempt to compute an edge cut of the provided \texttt{Mongoose::Graph} object. An \texttt{EdgeCut\_Options} struct can also be supplied to modify how the edge cut is computed -- otherwise, the default options are used (see Section \ref{sec:options}). The resulting partitioning information is returned as an \texttt{EdgeCut} struct.

The \texttt{EdgeCut} struct is shown below.

\begin{lstlisting}
struct EdgeCut
{
    bool *partition;     /** T/F denoting partition side     */
    Int n;               /** # vertices                      */

    /** Cut Cost Metrics *****************************************************/
    double cut_cost;    /** Sum of edge weights in cut set    */
    Int cut_size;       /** Number of edges in cut set        */
    double w0;          /** Sum of partition 0 vertex weights */
    double w1;          /** Sum of partition 1 vertex weights */
    double imbalance;   /** Degree to which the partitioning
                            is imbalanced, and this is
                            computed as (0.5 - w0/W).         */

    // Destructor
    ~EdgeCut();
};
\end{lstlisting}

\vspace{6pt}
\item \textbf{\texttt{static EdgeCut\_Options *create();}}

\texttt{Mongoose::EdgeCut\_Options::create} will return an \texttt{EdgeCut\_Options} struct with default state (see Section \ref{sec:options} for details about option fields and defaults). To run Mongoose with specific options, call \texttt{EdgeCut\_Options::create} and modify the struct as needed.
\vspace{6pt}
\item \textbf{\texttt{static Graph *create(const Int \_n, \\
\hspace*{4.2cm} const Int \_nz, \\
\hspace*{4.2cm} Int *\_p = NULL, \\
\hspace*{4.2cm} Int *\_i = NULL, \\
\hspace*{4.2cm} double *\_x = NULL, \\
\hspace*{4.2cm} double *\_w = NULL);}}
\item \textbf{\texttt{static Graph *create(cs *matrix);}}

\texttt{Mongoose::Graph::create} is the primary constructor for the \texttt{Graph} class. There are two versions: one to manually specify attributes of the \texttt{Graph}, and one to form a \texttt{Graph} from a \texttt{CSparse} struct.

Using the manual constructor, the number of vertices (or dimension of the matrix, \texttt{Int \_n}) and the number of edges (or nonzero entries in the matrix, \texttt{Int \_nz}) must both be specified. The column pointer vector \texttt{Int *\_p} and row index vector \texttt{Int *\_i} must either be specified by the user, or, if left \texttt{NULL}, they will be allocated such that \texttt{\_p = (Int *)SuiteSparse\_calloc(n + 1, sizeof(Int));} and \texttt{\_i = (Int *)SuiteSparse\_malloc(nz, sizeof(Int));}. The edge weights \texttt{double *\_x} and the vertex weights \texttt{double *\_w} can either be specified, or, if left \texttt{NULL}, will be assumed to be one for all edges and vertices, respectively.

Note that Mongoose will NOT free pointers passed to it, and that all pointers are shallow copies (i.e. Mongoose does not make a copy of any data passed into it).

\vspace{6pt}
\item \textbf{\texttt{$\sim$EdgeCut\_Options();}} is the destructor for the \texttt{EdgeCut\_Options} struct. If the user creates an \texttt{EdgeCut\_Options} struct using \texttt{EdgeCut\_Options::create}, the user is also responsible for destructing it.
\item \textbf{\texttt{$\sim$Graph();}} is the destructor for the \texttt{Graph} class. If the user creates a \texttt{Graph} class instance using \texttt{Graph::create}, the user is also responsible for destructing it.
\item \textbf{\texttt{$\sim$EdgeCut();}} is the destructor for the \texttt{EdgeCut} struct. After calling \texttt{edge\_cut()}, the returned struct must be destructed when the user is finished reading data from it.
\end{itemize}

\subsection{A Note on Memory Management}

Mongoose uses three primary data structures to pass information: the \texttt{Graph} class, the \texttt{EdgeCut} struct, and the \texttt{EdgeCut\_Options} struct. They are all dynamically allocated and must be destructed.

\begin{itemize}
\item For each \texttt{Graph::create}, there should be a matching \texttt{Graph::$\sim$Graph()}.
\item For each \texttt{EdgeCut\_Options::create}, there should be a matching \texttt{EdgeCut\_Options::$\sim$EdgeCut\_Options()};
\item For each call to \texttt{edge\_cut}, there should be a matching \texttt{EdgeCut::$\sim$EdgeCut()};
\end{itemize}

Lastly, Mongoose will NOT free pointers passed to it, and that all pointers are shallow copies (i.e. Mongoose does not make a copy of any data passed into it). Freeing memory referenced by Mongoose prior to Mongoose completing will result in a segmentation fault.

\section{Using Mongoose in MATLAB}

\subsection{To Install the MATLAB Interface}

To compile Mongoose for MATLAB, go to the \texttt{MATLAB} directory and type
\texttt{mongoose\_make} in the MATLAB command window.  Be sure to use a
compiler supported by MATLAB.  Type \texttt{doc mex} in MATLAB, or visit
\url{https://www.mathworks.com/support/compilers.html} for details.  For
example, GCC 5.5.0 on Linux is not supported by MATLAB R2017A, and it will not
successfully compile Mongoose for that version of MATLAB.  MATLAB R2018b
supports GCC 6.3.x on Linux.

\subsection{Sample MATLAB Program}

Below is a sample MATLAB program using the Mongoose MATLAB API. First, it loads in a matrix, sanitizes it, and then partitions it using edge and vertex weights, then only edge weights, and the no weights.

\begin{lstlisting}[language=MATLAB]
% A simple demo to demonstrate Mongoose. Reads in a matrix, sanitizes it,
% and partitions it several different ways.
function mongoose_demo

% Obtain the adjacency matrix
matfile_data = matfile('494_bus.mat');
Prob = matfile_data.Problem;
A = Prob.A;
[m ~] = size(A);

% Sanitize the adjacency matrix: remove diagonal elements, make edge weights 
% positive, and make sure it is symmetric. If the matrix is not symmetric 
% or square, a symmetric matrix (A+A')/2 is built.
A = sanitize(A);

% Create a vertex weight vector and create a heavy vertex
V = ones(1,m);
V(10) = 300;

% Create a set of default options and modify the target balance
O = edgecut_options();
O.target_split = 0.3;

% Run Mongoose to partition the graph with edge and vertex weights.
partVert = edgecut(A, O, V);

fprintf('\n\nPartitioning graph with edge and vertex weights\n\n');
fprintf('=== Cut Info ===\n');
fprintf('Cut Size:   %d\n', full(sum(partVert .* sum(sign(A)))));
fprintf('Cut Weight: %d\n\n', full(sum(partVert .* sum(A))));
fprintf('=== Balance Info ===\n');
fprintf('Target Split:     0.3\n');
fprintf('Actual Split:     %1.4f\n', sum(partVert .* V) / sum(V));
fprintf('Unweighted Split: %1.4f\n', sum(partVert) / m);

% Run Mongoose to partition the graph with no vertex weights.

partEdge = edgecut(A, O);

fprintf('\n\nPartitioning graph with only edge weights\n\n');
fprintf('=== Cut Info ===\n');
fprintf('Cut Size:   %d\n', full(sum(partEdge .* sum(sign(A)))));
fprintf('Cut Weight: %d\n\n', full(sum(partEdge .* sum(A))));
fprintf('=== Balance Info ===\n');
fprintf('Target Split: 0.5\n');
fprintf('Actual Split: %1.4f\n', sum(partEdge) / m);

% Remove edge weights
A = sanitize(A, 1);

% Run Mongoose to partition the graph with no edge weights.
% Note that only the graph is passed as an argument, so default
% options are assumed.
partPattern = edgecut(A);

fprintf('\n\nPartitioning graph with only edge weights\n\n');
fprintf('=== Cut Info ===\n');
fprintf('Cut Size:   %d\n', full(sum(partPattern .* sum(sign(A)))));
fprintf('Cut Weight: %d\n\n', full(sum(partPattern .* sum(A))));
fprintf('=== Balance Info ===\n');
fprintf('Target Split: 0.5\n');
fprintf('Actual Split: %1.4f\n', sum(partPattern) / m);

figure('Position', [100, 100, 1000, 400]);

% Plot the original matrix before permutation
subplot(1, 2, 1);
spy(A)
title('Before Partitioning')

% Plot the matrix after the permutation
subplot(1, 2, 2);
perm = [find(partEdge) find(1-partEdge)];
A_perm = A(perm, perm); % Permute the matrix
spy(A_perm)
title('After Partitioning')

% Set overall title
suptitle('HB/494\_bus')

end
\end{lstlisting}

\subsection{MATLAB API}

\begin{itemize}
\item \textbf{\texttt{function [G\_coarse, A\_coarse, map] = coarsen (G, \textit{Opts}, \textit{A})}}\\
\texttt{coarsen} is used to coarsen an adjacency matrix (\texttt{G}) one level (one round of matching). An optional edgecut\_options struct (\texttt{Opts}) can be specified, as well as vertex weights (\texttt{A}).
\\
\item \textbf{\texttt{function options = edgecut\_options()}}\\
\texttt{edgecut\_options()} returns an options struct with defaults set. If modifications to the default options are needed, call \texttt{edgecut\_options()} and modify the struct as needed. See section \ref{sec:options} for details on available option fields.
\\
\item \textbf{\texttt{function partition = edgecut (G, \textit{Opts}, \textit{A})}}\\
\texttt{edgecut} computes an edge cut of the graph \texttt{G} with edgecut\_options \texttt{Opts} and vertex weights \texttt{A}, such that \texttt{A(i)} = $\text{weight}(v_i)$. The returned array, \texttt{partition}, is a $1 \times n$ binary array such that
\[
\texttt{partition(i)} = 
  \begin{cases} 
   0 & \text{if } v_i \in \text{part A} \\
   1 & \text{if } v_i \in \text{part B}
  \end{cases}
\]
\item \textbf{\texttt{function [G\_coarse, A\_coarse, map] = safe\_coarsen (G, \textit{Opts}, \textit{A})}}\\
\texttt{safe\_coarsen} attempts to coarsen a graph \texttt{G} with edgecut\_options \texttt{Opts} and vertex weights \texttt{A}. Prior to coarsening, \texttt{safe\_coarsen} first calls \texttt{sanitize(G)} to ensure that the graph is able to be coarsened.
\\
\item \textbf{\texttt{function partition = safe\_edgecut(G, \textit{Opts}, \textit{A})}}\\
\texttt{safe\_edgecut} attempts to compute and edge cut for a graph \texttt{G} with edgecut\_options \texttt{Opts} and vertex weights \texttt{A}. Note that both \texttt{Opts} and \texttt{A} are optional arguments. \texttt{safe\_edgecut} first calls \texttt{sanitize(G)} to ensure that the graph is formatted correctly.
\\ 
\item \textbf{\texttt{function A\_safe = sanitize (A, \textit{make\_binary})}}\\
\texttt{sanitize} attempts to take an adjacency matrix \texttt{A} and convert it to one that Mongoose can read and convert to an undirected graph. Note that \texttt{make\_binary} is optional, with the default being \texttt{false}. \texttt{sanitize} does the following as needed:

\begin{itemize}
\item If the matrix is unsymmetric, it forms $\frac{1}{2}(A^T + A)$.
\item The diagonal is removed (set to zero).
\item Edge weights are forced to be positive ($w = |w|$) if \texttt{make\_binary = false}.
\item Edge weights are forced to be binary ($w = \text{sign}(w)$) if \texttt{make\_binary = true}.
\end{itemize}

\end{itemize}

\section{Options}
\label{sec:options}

When calling Mongoose, an optional EdgeCut\_Options struct can be provided to specify how Mongoose should behave.

\subsection{Coarsening Options}

\begin{tabular}{|l|l|} \hline
Name & \texttt{coarsen\_limit} \\ \hline
Type & \texttt{Int} \\ \hline
Default & \texttt{50} \\ \hline
\end{tabular}\\

Prior to computing a cut, the input graph is repeatedly coarsened until a sufficiently small number of vertices exist in the graph. This limit is specified by \texttt{coarsen\_limit}. Larger values will result in less time being spent on the coarsening process, but may yield poor initial cuts or may require more time in computing such an initial cut. Smaller values may result in more time spent coarsening, as well as a resulting coarsened graph which is a poor structural representation of the input graph.

\vskip 1\baselineskip
\begin{tabular}{|l|l|} \hline
Name & \texttt{matching\_strategy} \\ \hline
Type & \texttt{MatchingStrategy} (enum) \\ \hline
Default & \texttt{HEMSR} \\ \hline
\end{tabular}\\

During coarsening, a matching of vertices is computed using one of several strategies determined by the \texttt{matching\_strategy} option field. The possible values for this field are described below:

\begin{itemize}
\item \texttt{Random}, random matching. Randomly matches unmatched vertices with each other until no more than one unmatched vertex exists.
\item \texttt{HEM}, heavy edge matching. Matches a given vertex with an unmatched neighbor with the largest weighted edge between them.
\item \texttt{HEMSR}, heavy edge matching with stall-reducing matching. A pass of heavy edge matching is followed by a brotherly, adoption, and community (if enabled) matching where vertices that have been left unmatched by heavy edge matching are paired with vertices that share a neighbor, but may not be directly connected.
\item \texttt{HEMSRdeg}, heavy edge matching with stall-reducing matching subject to a degree threshold. Same as \texttt{HEMSR}, but the stall-reducing step is only attempted on unmatched vertices whose degree is above a threshold, described by $\texttt{EdgeCut\_Options::high\_degree\_threshold}*\text{(average degree of graph)}$. \texttt{high\_degree\_threshold} is set to $2.0$ by default, meaning only unmatched vertices with degree greater than or equal to two times the average degree of the graph are considered for stall-reducing matching.
\end{itemize}

\vskip 1\baselineskip
\begin{tabular}{|l|l|} \hline
Name & \texttt{do\_community\_matching} \\ \hline
Type & \texttt{bool} \\ \hline
Default & \texttt{false} \\ \hline
\end{tabular}\\

Community matching is a matching option to aggressively match vertices whose neighbors have already been matched. This can help in cases where coarsening easily stalls (e.g. social networking graphs), but incurs a slight performance overhead during coarsening.

\vskip 1\baselineskip
\begin{tabular}{|l|l|} \hline
Name & \texttt{high\_degree\_threshold} \\ \hline
Type & \texttt{double} \\ \hline
Default & \texttt{2.0} \\ \hline
\end{tabular}\\

When using the \texttt{HEMSRdeg} matching strategy, only vertices satisfying the following inequality are considered for brotherly, adoption, and community matching:

\[
\text{degree}(v) \geq \lfloor(\texttt{high\_degree\_threshold}) \cdot \left(\frac{nz}{n}\right)\rfloor
\]

Note that $\frac{nz}{n}$ is the average degree of the vertices in the graph.

\subsection{Initial Guess/Partitioning Options}

\begin{tabular}{|l|l|} \hline
Name & \texttt{initial\_cut\_type} \\ \hline
Type & \texttt{InitialEdgeCutType} (enum) \\ \hline
Default & \texttt{InitialEdgeCut\_QP} \\ \hline
\end{tabular}\\

After coarsening, an initial partitioning is computed. This initial guess can be computed several ways:

\begin{itemize}
\item \texttt{InitialEdgeCut\_QP}. This method uses the quadratic programming solver to compute an initial partitioning.
\item \texttt{InitialEdgeCut\_Random}. This method randomly assigns vertices to a part.
\item \texttt{InitialEdgeCut\_NaturalOrder}. This method assigns the first $\lfloor n/2 \rfloor$ vertices listed to one part, and the remainder to the other part.
\end{itemize}

\subsection{Waterdance Options}
\begin{tabular}{|l|l|} \hline
Name & \texttt{num\_dances} \\ \hline
Type & \texttt{Int} \\ \hline
Default & \texttt{1} \\ \hline
\end{tabular}\\
                      
At each level of graph refinement, both the Fiduccia-Mattheyses refinement algorithm and the quadratic programming algorithm are used to refine the graph. This combination of algorithms, run back-to-back, is informally referred to as a waterdance. \texttt{num\_dances} is used to specify the number of waterdances.\\
\\
For example, if \texttt{num\_dances = 2}, at each refinement level, the FM refinement will be done, then QP refinement, then FM and QP again.

\subsection{Fiduccia-Mattheyes Options}

\begin{tabular}{|l|l|} \hline
Name & \texttt{use\_FM} \\ \hline
Type & \texttt{bool} \\ \hline
Default & \texttt{true} \\ \hline
\end{tabular}\\

\texttt{useFM} can be used to enable or disable the use of the Fiduccia-Mattheyses refinement algorithm. If \texttt{useFM} is \texttt{false}, then the FM refinement is skipped.\\

\begin{tabular}{|l|l|} \hline
Name & \texttt{FM\_search\_depth} \\ \hline
Type & \texttt{Int} \\ \hline
Default & \texttt{50} \\ \hline
\end{tabular}\\

The Fiduccia-Mattheyses algorithm attempts to make positive gain moves whenever possible. However, to better explore the non-convex search space, the FM algorithm will make unfavorable moves in an attempt to locate another more favorable solution. The \texttt{FM\_search\_depth} limits the number of these unfavorable moves before the algorithm stops.

\vskip 1\baselineskip
\begin{tabular}{|l|l|} \hline
Name & \texttt{FM\_consider\_count} \\ \hline
Type & \texttt{Int} \\ \hline
Default & \texttt{3} \\ \hline
\end{tabular}\\

During the Fiduccia-Mattheyses algorithm, a heap is maintained of the vertices sorted by their gains. Vertices that have fewer neighbors in the same part relative to neighbors in the opposite part are prioritized higher in the heap (with higher gains), and are generally more likely to yield better quality cuts when swapped to the opposite part. \texttt{FM\_consider\_count} defines the number of vertices at the top of the heap to consider swapping to the opposite part before terminating. When a vertex swap being considered does not yield a better cut after moving \texttt{FM\_search\_depth} vertices, that iteration terminates, and the next vertex in the heap is considered.

\vskip 1\baselineskip
\begin{tabular}{|l|l|} \hline
Name & \texttt{FM\_max\_num\_refinements} \\ \hline
Type & \texttt{Int} \\ \hline
Default & \texttt{20} \\ \hline
\end{tabular}\\

\texttt{FM\_max\_num\_refinements} specifies the number of passes the Fiduccia-Mattheyses algorithm takes over the graph. During each pass, suboptimal moves may be attempted to escape local optima.

\subsection{Quadratic Programming Options}

\begin{tabular}{|l|l|} \hline
Name & \texttt{use\_QP\_gradproj} \\ \hline
Type & \texttt{bool} \\ \hline
Default & \texttt{true} \\ \hline
\end{tabular}\\

\texttt{use\_QP\_gradproj} can be used to enable or disable the use of the quadratic programming refinement algorithm. If \texttt{use\_QP\_gradproj} is \texttt{false}, then the QP refinement is skipped. This may provide faster solutions at the cost of cut quality.\\
\vskip 1\baselineskip
\begin{tabular}{|l|l|} \hline
Name & \texttt{gradproj\_tolerance} \\ \hline
Type & \texttt{double} \\ \hline
Default & \texttt{0.001} \\ \hline
\end{tabular}\\

Convergence tolerance for the projected gradient algorithm in the quadratic programming refinement approach.  Decreasing the tolerance may improve solution quality at the cost of additional computation time. It may also be advisable to increase \texttt{gradproj\_iteration\_limit}, as a decreased tolerance may require additional iterations to converge.\\
\vskip 1\baselineskip
\begin{tabular}{|l|l|} \hline
Name & \texttt{gradproj\_iteration\_limit} \\ \hline
Type & \texttt{Int} \\ \hline
Default & \texttt{50} \\ \hline
\end{tabular}\\

Maximum number of iterations for the gradient projection algorithm in the quadratic programming refinement approach. More iterations may allow the gradient projection algorithm to find a better solution at the cost of additional computation time.

\subsection{Final Partition Target Options}

\begin{tabular}{|l|l|} \hline
Name & \texttt{target\_split} \\ \hline
Type & \texttt{double} \\ \hline
Default & \texttt{0.5} \\ \hline
\end{tabular}\\

\texttt{target\_split} specifies the desired balance of the edge cut. The default is a balanced cut (0.5). Note that the target split takes into account weighted vertices.\\
\vskip 1\baselineskip
\begin{tabular}{|l|l|} \hline
Name & \texttt{soft\_split\_tolerance} \\ \hline
Type & \texttt{double} \\ \hline
Default & \texttt{0} \\ \hline
\end{tabular}\\

Cuts within \texttt{target\_split} $\pm$ \texttt{soft\_split\_tolerance} are treated equally. For example, if any cut within 0.4 and 0.6 balance is acceptable, the user may specify \texttt{target\_split} = 0.5 and \texttt{soft\_split\_tolerance} = 0.1.\\

\subsection{Other Options}

\begin{tabular}{|l|l|} \hline
Name & \texttt{random\_seed} \\ \hline
Type & \texttt{Int} \\ \hline
Default & \texttt{0} \\ \hline
\end{tabular}\\

Random number generation is used primarily in random matching strategies (\texttt{matching\_strategy = Random}) and random initial guesses (\texttt{initial\_cut\_type = InitialEdgeCut\_Random}). \texttt{random\_seed} can be used to seed the random number generator with a specific value.

\section{References}

\bibliographystyle{acm}
\bibliography{references}


\printindex

\end{document}