Scippy

    SCIP

    Solving Constraint Integer Programs

    hypergraph.c
    Go to the documentation of this file.
    1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    2/* */
    3/* This file is part of the program and library */
    4/* SCIP --- Solving Constraint Integer Programs */
    5/* */
    6/* Copyright (c) 2002-2025 Zuse Institute Berlin (ZIB) */
    7/* */
    8/* Licensed under the Apache License, Version 2.0 (the "License"); */
    9/* you may not use this file except in compliance with the License. */
    10/* You may obtain a copy of the License at */
    11/* */
    12/* http://www.apache.org/licenses/LICENSE-2.0 */
    13/* */
    14/* Unless required by applicable law or agreed to in writing, software */
    15/* distributed under the License is distributed on an "AS IS" BASIS, */
    16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
    17/* See the License for the specific language governing permissions and */
    18/* limitations under the License. */
    19/* */
    20/* You should have received a copy of the Apache-2.0 license */
    21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
    22/* */
    23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    24
    25/**@file hypergraph.c
    26 * @ingroup OTHER_CFILES
    27 * @brief internal methods for dealing with hypergraphs
    28 * @author Matthias Walter
    29 */
    30
    31/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    32
    33#include <assert.h>
    34
    35#include "scip/hypergraph.h"
    36#include "scip/misc.h"
    37#include "scip/pub_message.h" /* For SCIPdebugMessage */
    38
    39#ifndef NDEBUG
    41#endif
    42
    43/** @brief enlarges vertex arrays to have capacity for at least \p required vertices */
    44static
    46 SCIP_HYPERGRAPH* hypergraph, /**< The hypergraph. */
    47 int required /**< Required vertex capacity. */
    48 )
    49{
    50 assert(hypergraph);
    51 assert(required >= 0);
    52
    53 if( hypergraph->memvertices < required )
    54 {
    55 int newcapacity;
    56 newcapacity = MAX(256, hypergraph->memvertices);
    57 while( newcapacity < required )
    58 newcapacity *= 2;
    59
    60 assert( hypergraph->memvertices >= 0 );
    62 hypergraph->memvertices * hypergraph->sizevertexdata / sizeof(*(hypergraph->verticesdata)),
    63 newcapacity * hypergraph->sizevertexdata / sizeof(*(hypergraph->verticesdata))) ); /*lint --e{737}*/
    64 hypergraph->memvertices = newcapacity;
    65 SCIPdebugMessage("ensuring memory for %d vertices.\n", newcapacity);
    66 }
    67
    68 return SCIP_OKAY;
    69}
    70
    71/** @brief enlarges edge arrays to have capacity for at least \p required edges */
    72static
    74 SCIP_HYPERGRAPH* hypergraph, /**< The hypergraph. */
    75 int required /**< Required edge capacity. */
    76 )
    77{
    78 assert(hypergraph);
    79 assert(required >= 0);
    80
    81 if( hypergraph->memedges < required )
    82 {
    83 int newcapacity;
    84 newcapacity = MAX(256, hypergraph->memedges);
    85 while( newcapacity < required )
    86 newcapacity *= 2;
    87
    88 assert( hypergraph->memedges >= 0 );
    89 SCIP_ALLOC( BMSreallocBlockMemoryArray(hypergraph->blkmem, &hypergraph->edgesdata,
    90 hypergraph->memedges * hypergraph->sizeedgedata / sizeof(*(hypergraph->edgesdata)),
    91 newcapacity * hypergraph->sizeedgedata / sizeof(*(hypergraph->edgesdata))) ); /*lint --e{737}*/
    92
    93 if( hypergraph->edgesverticesbeg )
    94 {
    96 hypergraph->memedges + 1, newcapacity + 1) );
    97 }
    98 else
    99 {
    100 assert(hypergraph->memedges == 0);
    101 SCIP_ALLOC( BMSallocBlockMemoryArray(hypergraph->blkmem, &hypergraph->edgesverticesbeg, newcapacity + 1) );
    102 hypergraph->edgesverticesbeg[0] = 0;
    103 }
    104 hypergraph->memedges = newcapacity;
    105 SCIPdebugMessage("ensuring memory for %d edges.\n", newcapacity);
    106 }
    107
    108 return SCIP_OKAY;
    109}
    110
    111/** @brief enlarges arrays for incident vertex/edge pairs to have capacity for at least \p required */
    112static
    114 SCIP_HYPERGRAPH* hypergraph, /**< The hypergraph. */
    115 int required /**< Required incident vertex/edge capacity. */
    116 )
    117{
    118 assert(hypergraph);
    119 assert(required >= 0);
    120
    121 if( hypergraph->memedgesvertices < required )
    122 {
    123 int newcapacity;
    124 newcapacity = MAX(256, hypergraph->memedgesvertices);
    125 while( newcapacity < required )
    126 newcapacity *= 2;
    127
    129 hypergraph->memedgesvertices, newcapacity) );
    130 hypergraph->memedgesvertices = newcapacity;
    131 SCIPdebugMessage("ensuring memory for %d vertex/edge pairs.\n", newcapacity);
    132 }
    133
    134 return SCIP_OKAY;
    135}
    136
    137/** @brief enlarges overlap arrays to have capacity for at least \p required overlaps */
    138static
    140 SCIP_HYPERGRAPH* hypergraph, /**< The hypergraph. */
    141 int required /**< Required overlap capacity. */
    142 )
    143{
    144 assert(hypergraph);
    145 assert(required >= 0);
    146
    147 if( hypergraph->memoverlaps < required )
    148 {
    149 int newcapacity;
    150 newcapacity = MAX(256, hypergraph->memoverlaps);
    151 while( newcapacity < required )
    152 newcapacity *= 2;
    153
    154 if( hypergraph->overlapsverticesbeg )
    155 {
    157 hypergraph->memoverlaps + 1, newcapacity + 1) );
    158 }
    159 else
    160 {
    161 assert(hypergraph->memoverlaps == 0);
    162 SCIP_ALLOC( BMSallocBlockMemoryArray(hypergraph->blkmem, &hypergraph->overlapsverticesbeg, newcapacity + 1) );
    163 }
    164 if( hypergraph->overlapsdata )
    165 {
    166 assert( hypergraph->memoverlaps >= 0 );
    167 SCIP_ALLOC( BMSreallocBlockMemoryArray(hypergraph->blkmem, &hypergraph->overlapsdata,
    168 hypergraph->memoverlaps * hypergraph->sizeoverlapdata / sizeof(*(hypergraph->overlapsdata)),
    169 newcapacity * hypergraph->sizeoverlapdata / sizeof(*(hypergraph->overlapsdata))) ); /*lint --e{737}*/
    170 }
    171 else
    172 {
    173 SCIP_ALLOC( BMSallocBlockMemoryArray(hypergraph->blkmem, &hypergraph->overlapsdata,
    174 newcapacity * hypergraph->sizeoverlapdata / sizeof(*(hypergraph->overlapsdata))) ); /*lint --e{737}*/
    175 }
    176 hypergraph->memoverlaps = newcapacity;
    177 SCIPdebugMessage("ensuring memory for %d overlaps.\n", newcapacity);
    178 }
    179
    180 return SCIP_OKAY;
    181}
    182
    183/** @brief enlarges overlapVertices array to have capacity for at least \p required overlaps' vertices */
    184static
    186 SCIP_HYPERGRAPH* hypergraph, /**< The hypergraph. */
    187 int required /**< Required overlapVertices capacity. */
    188 )
    189{
    190 assert(hypergraph);
    191 assert(required >= 0);
    192
    193 if( hypergraph->memoverlapsvertices < required )
    194 {
    195 int newcapacity;
    196 newcapacity = MAX(256, hypergraph->memoverlapsvertices);
    197 while( newcapacity < required )
    198 newcapacity *= 2;
    199
    201 hypergraph->memoverlapsvertices, newcapacity) );
    202 hypergraph->memoverlapsvertices = newcapacity;
    203 SCIPdebugMessage("ensuring memory for %d overlaps' vertices.\n", newcapacity);
    204 }
    205
    206 return SCIP_OKAY;
    207}
    208
    209/** @brief creates a hypergraph */
    211 SCIP_HYPERGRAPH** phypergraph, /**< Pointer for storing the hypergraph. */
    212 BMS_BLKMEM* blkmem, /**< Block memory for storage. */
    213 int memvertices, /**< Upper bound on expected number of vertices. */
    214 int memedges, /**< Upper bound on expected number of edges. */
    215 int memoverlaps, /**< Upper bound on expected number of overlaps. */
    216 int memedgesvertices, /**< Upper bound on expected average size of edges. */
    217 size_t sizevertexdata, /**< Size (in bytes) of additional vertex data. */
    218 size_t sizeedgedata, /**< Size (in bytes) of additional edge data. */
    219 size_t sizeoverlapdata /**< Size (in bytes) of additional overlap data. */
    220 )
    221{
    222 SCIP_HYPERGRAPH* hypergraph;
    223
    224 assert(phypergraph);
    225 assert(blkmem);
    226
    227 assert(memvertices >= 0);
    228 assert(memedges >= 0);
    229 assert(memoverlaps >= 0);
    230 assert(memedgesvertices > 0);
    231
    232 SCIP_ALLOC( BMSallocBlockMemory(blkmem, phypergraph) );
    233 hypergraph = *phypergraph;
    234 hypergraph->blkmem = blkmem;
    235 hypergraph->memvertices = 0;
    236 hypergraph->memedges = 0;
    237 hypergraph->memoverlaps = 0;
    238 hypergraph->memedgesvertices = 0;
    239 hypergraph->memverticesedges = 0;
    240 hypergraph->memverticesedgesbeg = 0;
    241 hypergraph->memoverlapsvertices = 0;
    242 hypergraph->memedgesoverlaps = 0;
    243 hypergraph->memedgesoverlapsbeg = 0;
    244 hypergraph->sizevertexdata = sizevertexdata;
    245 hypergraph->sizeedgedata = sizeedgedata;
    246 hypergraph->sizeoverlapdata = sizeoverlapdata;
    247
    248 hypergraph->verticesdata = NULL;
    249 hypergraph->verticesedgesbeg = NULL;
    250 SCIP_CALL( ensureNumVertices(hypergraph, memvertices) );
    251 hypergraph->edgesdata = NULL;
    252 hypergraph->edgesverticesbeg = NULL;
    253 SCIP_CALL( ensureNumEdges(hypergraph, memedges) );
    254 hypergraph->overlapsdata = NULL;
    255 hypergraph->overlapsverticesbeg = NULL;
    256 hypergraph->overlapsvertices = NULL;
    257 SCIP_CALL( ensureNumOverlaps(hypergraph, memoverlaps) );
    258 hypergraph->edgesvertices = NULL;
    259 hypergraph->verticesedges = NULL;
    260 hypergraph->edgesoverlaps = NULL;
    261 hypergraph->edgesoverlapsbeg = NULL;
    262 SCIP_CALL( ensureNumEdgesVertices(hypergraph, memedgesvertices * memedges) );
    263 hypergraph->overlaphashtable = NULL;
    264
    265 hypergraph->memoverlapsedgesbeg = 0;
    266 hypergraph->overlapsedgesbeg = NULL;
    267 hypergraph->memoverlapsedges = 0;
    268 hypergraph->overlapsedges = NULL;
    269
    270 hypergraph->memverticesoverlapsbeg = 0;
    271 hypergraph->verticesoverlapsbeg = NULL;
    272 hypergraph->memverticesoverlaps = 0;
    273 hypergraph->verticesoverlaps = NULL;
    274
    275 SCIP_CALL( SCIPhypergraphClear(hypergraph) );
    276
    277 return SCIP_OKAY;
    278}
    279
    280/** @brief frees a hypergraph */
    282 SCIP_HYPERGRAPH** phypergraph /**< Pointer to the hypergraph. */
    283 )
    284{
    285 SCIP_HYPERGRAPH* hypergraph;
    286
    287 assert(phypergraph);
    288
    289 hypergraph = *phypergraph;
    290 if( hypergraph == NULL )
    291 return SCIP_OKAY;
    292
    293 BMSfreeBlockMemoryArray(hypergraph->blkmem, &hypergraph->verticesdata,
    294 hypergraph->memvertices * hypergraph->sizevertexdata / sizeof(*hypergraph->verticesdata) );
    295 BMSfreeBlockMemoryArray(hypergraph->blkmem, &hypergraph->edgesdata,
    296 hypergraph->memedges * hypergraph->sizeedgedata / sizeof(*hypergraph->edgesdata));
    297 if( hypergraph->edgesverticesbeg )
    298 BMSfreeBlockMemoryArray(hypergraph->blkmem, &hypergraph->edgesverticesbeg, hypergraph->memedges + 1);
    299 if( hypergraph->edgesvertices )
    300 BMSfreeBlockMemoryArray(hypergraph->blkmem, &hypergraph->edgesvertices, hypergraph->memedgesvertices);
    301
    302 if( hypergraph->hasvertexedges )
    303 {
    304 if( hypergraph->verticesedges )
    305 BMSfreeBlockMemoryArray(hypergraph->blkmem, &hypergraph->verticesedges, hypergraph->memverticesedges);
    306 if( hypergraph->verticesedgesbeg )
    307 BMSfreeBlockMemoryArray(hypergraph->blkmem, &hypergraph->verticesedgesbeg, hypergraph->memvertices + 1);
    308 }
    309
    310 if( hypergraph->overlapsdata )
    311 {
    312 BMSfreeBlockMemoryArray(hypergraph->blkmem, &hypergraph->overlapsdata,
    313 hypergraph->memoverlaps * hypergraph->sizeoverlapdata / sizeof(*hypergraph->overlapsdata));
    314 }
    315
    316 if( hypergraph->overlapsverticesbeg )
    317 BMSfreeBlockMemoryArray(hypergraph->blkmem, &hypergraph->overlapsverticesbeg, hypergraph->memoverlaps + 1);
    318
    319 if( hypergraph->hasoverlaps )
    320 {
    321 if( hypergraph->overlapsvertices )
    322 BMSfreeBlockMemoryArray(hypergraph->blkmem, &hypergraph->overlapsvertices, hypergraph->memoverlapsvertices);
    323 if( hypergraph->overlaphashtable )
    325 if( hypergraph->edgesoverlapsbeg )
    326 {
    327 BMSfreeBlockMemoryArray(hypergraph->blkmem, &hypergraph->edgesoverlapsbeg,
    328 hypergraph->memedgesoverlapsbeg + 1);
    329 }
    330 if( hypergraph->edgesoverlaps )
    331 BMSfreeBlockMemoryArray(hypergraph->blkmem, &hypergraph->edgesoverlaps, hypergraph->memedgesoverlaps);
    332 }
    333
    334 if( hypergraph->hasoverlapsedges )
    335 {
    336 if( hypergraph->overlapsedges )
    337 BMSfreeBlockMemoryArray(hypergraph->blkmem, &hypergraph->overlapsedges, hypergraph->memoverlapsedges);
    338 if( hypergraph->overlapsedgesbeg )
    339 {
    340 BMSfreeBlockMemoryArray(hypergraph->blkmem, &hypergraph->overlapsedgesbeg,
    341 hypergraph->memoverlapsedgesbeg + 1);
    342 }
    343 }
    344
    345 if( hypergraph->hasverticesoverlaps )
    346 {
    347 BMSfreeBlockMemoryArray(hypergraph->blkmem, &hypergraph->verticesoverlaps, hypergraph->memverticesoverlaps);
    348 if( hypergraph->verticesoverlapsbeg )
    349 {
    350 BMSfreeBlockMemoryArray(hypergraph->blkmem, &hypergraph->verticesoverlapsbeg,
    351 hypergraph->memverticesoverlapsbeg + 1);
    352 }
    353 }
    354
    355 BMSfreeBlockMemory(hypergraph->blkmem, phypergraph);
    356
    357 return SCIP_OKAY;
    358}
    359
    360/** @brief clears a hypergraph, deleting all vertices and edges */
    362 SCIP_HYPERGRAPH* hypergraph /**< The hypergraph. */
    363 )
    364{
    365 assert(hypergraph);
    366
    367 hypergraph->nvertices = 0;
    368 hypergraph->nedges = 0;
    369 hypergraph->noverlaps = 0;
    370 if( hypergraph->edgesverticesbeg )
    371 hypergraph->edgesverticesbeg[0] = 0;
    372 hypergraph->hasvertexedges = FALSE;
    373 hypergraph->hasoverlaps = FALSE;
    374
    375 if( hypergraph->overlaphashtable )
    377
    378 hypergraph->hasoverlapsedges = FALSE;
    379 hypergraph->hasverticesoverlaps = FALSE;
    380
    381 return SCIP_OKAY;
    382}
    383
    384
    385/** @brief adds a new vertex to the hypergraph */
    387 SCIP_HYPERGRAPH* hypergraph, /**< The hypergraph. */
    388 SCIP_HYPERGRAPH_VERTEX* pvertex, /**< Pointer for storing the new vertex. */
    389 SCIP_HYPERGRAPH_VERTEXDATA** pvertexdata /**< Pointer for returning the vertex's data (may be \c NULL). */
    390 )
    391{
    392 assert(hypergraph);
    393 assert(pvertex);
    394
    395 SCIP_CALL( ensureNumVertices(hypergraph, hypergraph->nvertices + 1) );
    396
    397 *pvertex = hypergraph->nvertices;
    398 if( pvertexdata != NULL )
    399 {
    400 assert( hypergraph->nvertices >= 0 );
    401 *pvertexdata = (SCIP_HYPERGRAPH_VERTEXDATA*)(hypergraph->verticesdata
    402 + hypergraph->nvertices * hypergraph->sizevertexdata / sizeof(*(hypergraph->verticesdata)) ); /*lint --e{737}*/
    403 }
    404
    405 hypergraph->nvertices++;
    406 hypergraph->hasvertexedges = FALSE;
    407
    408 return SCIP_OKAY;
    409}
    410
    411/**
    412 * @brief adds a new edge to the hypergraph
    413 *
    414 * Does not update the vertices' or overlaps' lists of incident edges.
    415 */
    417 SCIP_HYPERGRAPH* hypergraph, /**< The hypergraph. */
    418 int nvertices, /**< Number of vertices of this edge. */
    419 SCIP_HYPERGRAPH_VERTEX* vertices, /**< Array with vertices. */
    420 SCIP_HYPERGRAPH_EDGE* pedge, /**< Pointer for storing the new edge. */
    421 SCIP_HYPERGRAPH_EDGEDATA** pedgedata /**< Pointer for returning the edge's data (may be \c NULL). */
    422 )
    423{
    424 int first;
    425 int beyond;
    426
    427 assert(hypergraph);
    428 assert(nvertices > 0);
    429 assert(vertices);
    430 assert(pedge);
    431
    432 SCIP_CALL( ensureNumEdges(hypergraph, hypergraph->nedges + 1) );
    433 first = hypergraph->edgesverticesbeg[hypergraph->nedges];
    434 beyond = first + nvertices;
    435 SCIP_CALL( ensureNumEdgesVertices(hypergraph, beyond) );
    436 hypergraph->edgesverticesbeg[hypergraph->nedges + 1] = beyond;
    437 for( int i = 0; i < nvertices; ++i )
    438 hypergraph->edgesvertices[first + i] = vertices[i];
    439 SCIPsortInt(&hypergraph->edgesvertices[first], nvertices);
    440
    441 *pedge = hypergraph->nedges;
    442 if( pedgedata != NULL )
    443 {
    444 assert( hypergraph->nedges >= 0 );
    445 *pedgedata = (SCIP_HYPERGRAPH_EDGEDATA*)(hypergraph->edgesdata +
    446 hypergraph->nedges * hypergraph->sizeedgedata / sizeof(*(hypergraph->edgesdata))); /*lint --e{737}*/
    447 }
    448 hypergraph->nedges++;
    449 hypergraph->hasvertexedges = FALSE;
    450
    451 return SCIP_OKAY;
    452}
    453
    454/** @brief get-key function for overlap hashtable */
    455static
    456SCIP_DECL_HASHGETKEY(overlapHashGetKey)
    457{ /*lint --e{715}*/
    458 return elem;
    459}
    460
    461/** @brief equality function for overlap hashtable */
    462static
    463SCIP_DECL_HASHKEYEQ(overlapHashKeyEqPtr)
    464{
    465 size_t o1;
    466 size_t o2;
    467 SCIP_HYPERGRAPH* hypergraph;
    468 int begin1;
    469 int beyond1;
    470 int begin2;
    471 int beyond2;
    472 int i2;
    473
    474 o1 = (size_t)key1 - 1;
    475 o2 = (size_t)key2 - 1;
    476 hypergraph = (SCIP_HYPERGRAPH*) userptr;
    477 begin1 = hypergraph->overlapsverticesbeg[o1];
    478 beyond1 = hypergraph->overlapsverticesbeg[o1 + 1];
    479 begin2 = hypergraph->overlapsverticesbeg[o2];
    480 beyond2 = hypergraph->overlapsverticesbeg[o2 + 1];
    481
    482 if( beyond1 - begin1 != beyond2 - begin2 )
    483 return FALSE;
    484
    485 i2 = begin2;
    486 for( int i1 = begin1; i1 < beyond1; ++i1 )
    487 {
    488 if( hypergraph->overlapsvertices[i1] != hypergraph->overlapsvertices[i2] )
    489 return FALSE;
    490 ++i2;
    491 }
    492
    493 return TRUE;
    494}
    495
    496/** @brief hash function for overlap hashtable */
    497static
    498SCIP_DECL_HASHKEYVAL(overlapHashKeyValPtr)
    499{
    500 size_t o;
    501 SCIP_HYPERGRAPH* hypergraph;
    502 int begin;
    503 int beyond;
    504 int i;
    505 uint32_t hash;
    506
    507 o = (size_t)key - 1;
    508 hypergraph = (SCIP_HYPERGRAPH*) userptr;
    509 begin = hypergraph->overlapsverticesbeg[o];
    510 beyond = hypergraph->overlapsverticesbeg[o + 1];
    511
    512 assert(beyond > begin);
    513
    514 hash = (uint32_t) (beyond - begin);
    515 for( i = begin + 2; i < beyond; i += 3 )
    516 {
    517 hash = SCIPhashFour(hash, hypergraph->overlapsvertices[i - 2], hypergraph->overlapsvertices[i - 1],
    518 hypergraph->overlapsvertices[i]);
    519 }
    520 if( i - 1 < beyond )
    521 hash = SCIPhashThree(hash, hypergraph->overlapsvertices[i - 2], hypergraph->overlapsvertices[i - 1]);
    522 else if( i - 2 < beyond )
    523 hash = SCIPhashTwo(hash, hypergraph->overlapsvertices[i - 2]);
    524
    525 return hash;
    526}
    527
    528/** @brief finds an overlap specified by a sorted vertex set, potentially adding it */
    529static
    531 SCIP_HYPERGRAPH* hypergraph, /**< Hypergraph. */
    532 int nvertices, /**< Number of vertices. */
    533 int* vertices, /**< Sorted array of vertices. */
    534 int* poverlap, /**< Pointer for storing the overlap. */
    535 SCIP_Bool add, /**< Whether a missing overlap set should be added. */
    536 SCIP_Bool* padded /**< Whether a missing overlap set was added. */
    537 )
    538{
    539 int first;
    540 int beyond;
    541 void* element;
    542 size_t nextoverlap;
    543
    544 assert(hypergraph);
    545 assert(nvertices > 0);
    546 assert(vertices);
    547 assert(poverlap);
    548
    549 /* In order to find a set of vertices we need to add it to the overlaps' vertex storage. */
    550
    551 SCIP_CALL( ensureNumOverlaps(hypergraph, hypergraph->noverlaps + 1) );
    552 first = hypergraph->overlapsverticesbeg[hypergraph->noverlaps];
    553 beyond = first + nvertices;
    554 SCIP_CALL( ensureNumOverlapsVertices(hypergraph, beyond) );
    555 for( int i = 0; i < nvertices; ++i )
    556 hypergraph->overlapsvertices[first + i] = vertices[i];
    557 hypergraph->overlapsverticesbeg[hypergraph->noverlaps + 1] = beyond;
    558
    559 nextoverlap = (size_t) hypergraph->noverlaps + 1UL; /*lint !e571 */
    560 element = SCIPhashtableRetrieve(hypergraph->overlaphashtable, (void*) nextoverlap);
    561 if( element != NULL )
    562 {
    563 *poverlap = (size_t)element - 1; /*lint !e712*/
    564 if( padded )
    565 *padded = FALSE;
    566 }
    567 else if( add )
    568 {
    569 SCIP_CALL_ABORT( SCIPhashtableInsert(hypergraph->overlaphashtable, (void*) nextoverlap) );
    570
    571 *poverlap = hypergraph->noverlaps;
    572 hypergraph->noverlaps++;
    573 if( padded )
    574 *padded = TRUE;
    575 }
    576 else
    577 *poverlap = -1;
    578
    579 return SCIP_OKAY;
    580}
    581
    582/**
    583 * @brief computes all overlaps and stores overlaps' vertices and all edges' overlaps
    584 *
    585 * Requires \ref SCIPhypergraphHasVertexEdges to be \c TRUE which results from \ref SCIPhypergraphComputeVerticesEdges.
    586 */
    588 SCIP_HYPERGRAPH* hypergraph, /**< The hypergraph. */
    589 SCIP_DECL_HYPERGRAPH_OVERLAP((*handler)), /**< Function to be called once the overlap is found. */
    590 void* userdata /**< Pointer passed to \p handler. */
    591 )
    592{
    593 int memCommonVertices = 32;
    594 int* commonVertices = NULL;
    595 int numCommonVertices;
    596 int memEdgeOverlapPairs;
    597 int numEdgeOverlapPairs = 0;
    598 SCIP_Longint* edgeOverlapPairs = NULL;
    599 int o;
    600 int lastEdge;
    601
    602 assert(hypergraph);
    603
    604 if( !hypergraph->hasvertexedges )
    605 return SCIP_ERROR;
    606
    607 if( hypergraph->hasoverlaps )
    608 return SCIP_OKAY;
    609
    610 hypergraph->noverlaps = 0;
    611 hypergraph->overlapsverticesbeg[0] = 0;
    612
    613 hypergraph->hasoverlaps = TRUE;
    614 assert(hypergraph->overlaphashtable == NULL);
    615 SCIP_CALL( SCIPhashtableCreate(&hypergraph->overlaphashtable, hypergraph->blkmem, 4 * hypergraph->nedges + 4,
    616 overlapHashGetKey, overlapHashKeyEqPtr, overlapHashKeyValPtr, hypergraph) );
    617
    618 /* Allocate memory for the vertices in common to two edges. */
    619 SCIP_ALLOC( BMSallocBlockMemoryArray(hypergraph->blkmem, &commonVertices, memCommonVertices) );
    620
    621 /* Allocate memory for an array consisting of pairs (e,o) where o is an overlap incident to edge e. */
    622 memEdgeOverlapPairs = 2 * (hypergraph->nedges + hypergraph->noverlaps) + 2;
    623 SCIP_ALLOC( BMSallocBlockMemoryArray(hypergraph->blkmem, &edgeOverlapPairs, memEdgeOverlapPairs) );
    624
    625 /* We iterate over all edges e. */
    626 for( SCIP_HYPERGRAPH_EDGE e = 0; e < hypergraph->nedges; ++e )
    627 {
    628 int eBeyond;
    629 int eSize;
    630
    631 eBeyond = hypergraph->edgesverticesbeg[e + 1];
    632 eSize = eBeyond - hypergraph->edgesverticesbeg[e];
    633 if( eSize > memCommonVertices )
    634 {
    635 int newcapacity;
    636 newcapacity = memCommonVertices;
    637 while( memCommonVertices < eSize )
    638 memCommonVertices *= 2;
    639 SCIP_ALLOC( BMSreallocBlockMemoryArray(hypergraph->blkmem, &commonVertices, newcapacity, memCommonVertices) );
    640 }
    641
    642 /* We iterate over all vertices v of e and then over all edges f incident to v to avoid scanning all pairs
    643 * of edges because most of them will be disjoint. */
    644 for( int i = 0; i < eSize; ++i )
    645 {
    647 int vFirst, vBeyond;
    648
    649 v = hypergraph->edgesvertices[hypergraph->edgesverticesbeg[e] + i];
    650 vFirst = hypergraph->verticesedgesbeg[v];
    651 vBeyond = hypergraph->verticesedgesbeg[v + 1];
    652 for( int j = vFirst; j < vBeyond; ++j )
    653 {
    655 int fBeyond;
    656 int ie;
    657 int je;
    658 int u;
    659 int w;
    660
    661 f = hypergraph->verticesedges[j];
    662
    663 /* Avoid considering (e,f) and (f,e). */
    664 if( f <= e )
    665 continue;
    666
    667 /* We now traverse the sorted lists of vertices of e and f simultaneously to find common vertices. */
    668 fBeyond = hypergraph->edgesverticesbeg[f + 1];
    669 numCommonVertices = 0;
    670 ie = hypergraph->edgesverticesbeg[e];
    671 je = hypergraph->edgesverticesbeg[f];
    672 while( ie < eBeyond && je < fBeyond )
    673 {
    674 u = hypergraph->edgesvertices[ie];
    675 w = hypergraph->edgesvertices[je];
    676 if( u < w )
    677 ++ie;
    678 else if( u > w )
    679 ++je;
    680 else
    681 {
    682 /* Vertex u = w is part of e and of f. */
    683 if( numCommonVertices == 0 && u != v )
    684 {
    685 /* v is not the minimum vertex in e \cap f, so we skip f since we have considered it already
    686 * for a smaller v. */
    687 break;
    688 }
    689 commonVertices[numCommonVertices++] = u;
    690 ++ie;
    691 ++je;
    692 }
    693 }
    694
    695 /* We only consider overlap sets that are not just vertices. */
    696 if( numCommonVertices >= 2 )
    697 {
    698 int overlap;
    699 SCIP_Bool added;
    700 uint64_t ebits;
    701 uint64_t fbits;
    702 uint64_t obits;
    703 uint64_t ocardinalitybits;
    704
    705 /* Find out if that overlap (as a set) already exists. */
    706 SCIP_CALL( findOverlap(hypergraph, numCommonVertices, commonVertices, &overlap, TRUE, &added) );
    707 if( handler != NULL )
    708 {
    709 SCIP_CALL( handler(hypergraph, overlap, SCIPhypergraphOverlapData(hypergraph, overlap), e, f, added,
    710 userdata) );
    711 }
    712
    713 if( numEdgeOverlapPairs >= memEdgeOverlapPairs - 1 )
    714 {
    715 SCIP_ALLOC( BMSreallocBlockMemoryArray(hypergraph->blkmem, &edgeOverlapPairs, memEdgeOverlapPairs,
    716 2 * memEdgeOverlapPairs) ); /*lint !e647 */
    717 memEdgeOverlapPairs *= 2;
    718 }
    719
    720 /* For the pair (overlap,e) we store (e << 40) | (|overlap| << 24) | overlap and sort by it to find
    721 * duplicates and the get overlaps incident to e in order of increasing cardinality. */
    722 assert(overlap >= 0);
    723 assert(numCommonVertices >= 0);
    724 assert(e >= 0);
    725 assert(f >= 0);
    726 obits = (uint64_t) overlap; /*lint !e571*/
    727 ocardinalitybits = ((uint64_t) numCommonVertices) << 24; /*lint !e571*/
    728 ebits = ((uint64_t) e) << 40; /*lint !e571*/
    729 ebits |= ocardinalitybits | obits;
    730 fbits = ((uint64_t) f) << 40; /*lint !e571*/
    731 fbits |= ocardinalitybits | obits;
    732 edgeOverlapPairs[numEdgeOverlapPairs] = (long long) ebits;
    733 edgeOverlapPairs[numEdgeOverlapPairs + 1] = (long long) fbits;
    734 numEdgeOverlapPairs += 2;
    735 }
    736 }
    737 }
    738 }
    739
    740 SCIPdebugMessage("found %d edge-overlap incidences, including possible duplicates.\n", numEdgeOverlapPairs);
    741 SCIPsortLong(edgeOverlapPairs, numEdgeOverlapPairs);
    742
    743 o = -1; /* Last pair written. */
    744 for( int i = 0; i < numEdgeOverlapPairs; ++i)
    745 {
    746 if( o < 0 || edgeOverlapPairs[i] != edgeOverlapPairs[o] )
    747 edgeOverlapPairs[++o] = edgeOverlapPairs[i];
    748 }
    749
    750 numEdgeOverlapPairs = o + 1;
    751 SCIPdebugMessage("found %d unique edge-overlap incidences.\n", numEdgeOverlapPairs);
    752
    753 /* Compute edges' incident overlaps. */
    754 if( hypergraph->memedgesoverlapsbeg == 0 || hypergraph->memedgesoverlapsbeg < hypergraph->nedges )
    755 {
    756 int newcapacity;
    757
    758 newcapacity = MAX(256, hypergraph->memedgesoverlapsbeg);
    759 while( newcapacity < hypergraph->nedges )
    760 newcapacity *= 2;
    761 if( hypergraph->edgesoverlapsbeg )
    762 {
    764 hypergraph->memedgesoverlapsbeg + 1, newcapacity + 1) );
    765 }
    766 else
    767 {
    768 assert(hypergraph->memedgesoverlapsbeg == 0);
    769 SCIP_ALLOC( BMSallocBlockMemoryArray(hypergraph->blkmem, &hypergraph->edgesoverlapsbeg, newcapacity + 1) );
    770 }
    771 hypergraph->memedgesoverlapsbeg = newcapacity;
    772 }
    773
    774 if( hypergraph->memedgesoverlaps < numEdgeOverlapPairs )
    775 {
    776 int newcapacity;
    777
    778 newcapacity = MAX(256, hypergraph->memedgesoverlaps);
    779 while( newcapacity < numEdgeOverlapPairs )
    780 newcapacity *= 2;
    782 hypergraph->memedgesoverlaps, newcapacity) );
    783 hypergraph->memedgesoverlaps = newcapacity;
    784 }
    785
    786 lastEdge = -1;
    787 for( int i = 0; i < numEdgeOverlapPairs; ++i )
    788 {
    789 uint64_t bits;
    790 int edge;
    791 int overlap;
    792
    793 bits = (uint64_t) edgeOverlapPairs[i];
    794 edge = (int) (bits >> 40); /*lint !e704 */
    795 overlap = bits & ((1L << 24) - 1L); /*lint !e712 */
    796
    797 while( lastEdge < edge )
    798 hypergraph->edgesoverlapsbeg[++lastEdge] = i;
    799 hypergraph->edgesoverlaps[i] = overlap;
    800 }
    801 while( lastEdge < hypergraph->nedges )
    802 hypergraph->edgesoverlapsbeg[++lastEdge] = numEdgeOverlapPairs;
    803
    804 BMSfreeBlockMemoryArray(hypergraph->blkmem, &edgeOverlapPairs, memEdgeOverlapPairs);
    805 BMSfreeBlockMemoryArray(hypergraph->blkmem, &commonVertices, memCommonVertices);
    806
    807 return SCIP_OKAY;
    808}
    809
    810/** @brief computes each vertex' list of incident edges */
    812 SCIP_HYPERGRAPH* hypergraph /**< The hypergraph. */
    813 )
    814{
    815 int nincidences;
    816
    817 assert(hypergraph);
    818
    819 if( hypergraph->hasvertexedges )
    820 return SCIP_OKAY;
    821
    822 if( hypergraph->memverticesedgesbeg == 0 || hypergraph->memverticesedgesbeg < hypergraph->nvertices )
    823 {
    824 int newcapacity = MAX(256, hypergraph->memvertices);
    825 while( newcapacity < hypergraph->nvertices )
    826 newcapacity *= 2;
    827
    828 if( hypergraph->verticesedgesbeg )
    829 {
    831 hypergraph->memverticesedgesbeg + 1, newcapacity + 1) );
    832 }
    833 else
    834 {
    835 assert(hypergraph->memverticesedgesbeg == 0);
    836 SCIP_ALLOC( BMSallocBlockMemoryArray(hypergraph->blkmem, &hypergraph->verticesedgesbeg, newcapacity + 1) );
    837 }
    838 hypergraph->memverticesedgesbeg = newcapacity;
    839 SCIPdebugMessage("ensuring memory for %d vertices' edges slice.\n", newcapacity);
    840 }
    841
    842 /* We know the total number of vertex-edge incidences from the edges. */
    843 nincidences = hypergraph->edgesverticesbeg[hypergraph->nedges];
    844 if( hypergraph->memverticesedges < nincidences )
    845 {
    846 int newcapacity;
    847
    848 newcapacity = MAX(256, hypergraph->memverticesedges);
    849 while( newcapacity < nincidences )
    850 newcapacity *= 2;
    851
    853 hypergraph->memverticesedges, newcapacity) );
    854 hypergraph->memverticesedges = newcapacity;
    855 SCIPdebugMessage("ensuring memory for %d vertices' edges.\n", newcapacity);
    856 }
    857
    858 /* We initialize beg[v] = 0. */
    859 for( SCIP_HYPERGRAPH_VERTEX v = 0; v < hypergraph->nvertices; ++v)
    860 hypergraph->verticesedgesbeg[v] = 0;
    861
    862 /* We traverse through all incidences (using the edges' vertex arrays) and count the degree deg(v) in beg[v]. */
    863 for( int i = 0; i < nincidences; ++i)
    864 hypergraph->verticesedgesbeg[hypergraph->edgesvertices[i]]++;
    865
    866 /* This loop sets beg[0] = 0, beg[1] = deg(0), beg[2] = deg(0) + deg(1), beg[v] = deg(0) + ... + deg(v-1). */
    867 int current = 0;
    868 for( SCIP_HYPERGRAPH_VERTEX v = 0; v < hypergraph->nvertices; ++v )
    869 {
    870 int temp;
    871
    872 temp = current;
    873 current += hypergraph->verticesedgesbeg[v];
    874 hypergraph->verticesedgesbeg[v] = temp;
    875 }
    876
    877 /* We now traverse through all edges e and their incident vertices v, storing e at beg[v], which is incremented. */
    878 for( SCIP_HYPERGRAPH_EDGE e = 0; e < hypergraph->nedges; ++e )
    879 {
    880 int first;
    881 int beyond;
    882
    883 first = hypergraph->edgesverticesbeg[e];
    884 beyond = hypergraph->edgesverticesbeg[e + 1];
    885 for( int i = first; i < beyond; ++i )
    886 {
    887 SCIP_HYPERGRAPH_VERTEX v = hypergraph->edgesvertices[i];
    888 hypergraph->verticesedges[hypergraph->verticesedgesbeg[v]++] = e;
    889 }
    890 }
    891
    892 /* We now revert the incrementation of the beg[v]-values again. */
    893 for( SCIP_HYPERGRAPH_VERTEX v = hypergraph->nvertices; v > 0; --v )
    894 hypergraph->verticesedgesbeg[v] = hypergraph->verticesedgesbeg[v-1];
    895 hypergraph->verticesedgesbeg[0] = 0;
    896 hypergraph->hasvertexedges = TRUE;
    897
    898 return SCIP_OKAY;
    899}
    900
    901/**
    902 * @brief finds the overlap corresponding to vertex set \p vertices; returns -1 if it is not found
    903 *
    904 * Requires \ref SCIPhypergraphHasOverlaps to be \c TRUE which results from \ref SCIPhypergraphComputeOverlaps.
    905 */
    907 SCIP_HYPERGRAPH* hypergraph, /**< The hypergraph. */
    908 int nvertices, /**< Number of vertices. */
    909 SCIP_HYPERGRAPH_VERTEX* vertices, /**< Sorted array of vertices. */
    910 SCIP_HYPERGRAPH_OVERLAP* poverlap /**< Pointer for storing the overlap. */
    911 )
    912{
    913 assert(hypergraph);
    914 assert(nvertices > 0);
    915 assert(vertices);
    916 assert(poverlap);
    917 assert(hypergraph->hasoverlaps);
    918
    919 SCIP_CALL( findOverlap(hypergraph, nvertices, vertices, poverlap, FALSE, NULL) );
    920
    921 return SCIP_OKAY;
    922}
    923
    924/**
    925 * @brief finds the overlap or singleton vertex corresponding to the intersection of edges \p first and \p second
    926 *
    927 * Requires \ref SCIPhypergraphHasOverlaps to be \c TRUE which results from \ref SCIPhypergraphComputeOverlaps.
    928 */
    930 SCIP_HYPERGRAPH* hypergraph, /**< The hypergraph. */
    931 SCIP_HYPERGRAPH_EDGE first, /**< First edge to intersect. */
    932 SCIP_HYPERGRAPH_EDGE second, /**< Second edge to intersect. */
    933 SCIP_HYPERGRAPH_OVERLAP* poverlap, /**< Pointer for storing the overlap. */
    934 SCIP_HYPERGRAPH_VERTEX* pvertex /**< Pointer for storing the vertex. */
    935 )
    936{
    937 int* commonVertices = NULL;
    938 int memCommonVertices;
    939 int firstBeyond;
    940 int secondBeyond;
    941 int numCommonVertices = 0;
    942 int i;
    943 int j;
    944
    945 assert(hypergraph);
    946 assert(first >= 0 && first < hypergraph->nedges);
    947 assert(second >= 0 && second < hypergraph->nedges);
    948 assert(poverlap);
    949 assert(hypergraph->hasoverlaps);
    950
    951 memCommonVertices = SCIPhypergraphEdgeSize(hypergraph, first);
    952 SCIP_ALLOC( BMSallocBlockMemoryArray(hypergraph->blkmem, &commonVertices, memCommonVertices) );
    953 firstBeyond = hypergraph->edgesverticesbeg[first + 1];
    954 secondBeyond = hypergraph->edgesverticesbeg[second + 1];
    955 i = hypergraph->edgesverticesbeg[first];
    956 j = hypergraph->edgesverticesbeg[second];
    957 while( i < firstBeyond && j < secondBeyond )
    958 {
    959 int u;
    960 int w;
    961
    962 u = hypergraph->edgesvertices[i];
    963 w = hypergraph->edgesvertices[j];
    964 if( u < w )
    965 ++i;
    966 else if( u > w )
    967 ++j;
    968 else
    969 {
    970 commonVertices[numCommonVertices++] = u;
    971 ++i;
    972 ++j;
    973 }
    974 }
    975
    976 SCIP_CALL( findOverlap(hypergraph, numCommonVertices, commonVertices, poverlap, FALSE, NULL) );
    977 if( (*poverlap) < 0 && pvertex != NULL )
    978 *pvertex = numCommonVertices > 0 ? commonVertices[0] : -1;
    979
    980 BMSfreeBlockMemoryArray(hypergraph->blkmem, &commonVertices, memCommonVertices);
    981
    982 return SCIP_OKAY;
    983}
    984
    985/**
    986 * @brief computes all overlaps' lists of incident edges
    987 *
    988 * Requires \ref SCIPhypergraphHasOverlaps to be \c TRUE which results from \ref SCIPhypergraphComputeOverlaps.
    989 */
    991 SCIP_HYPERGRAPH* hypergraph /**< The hypergraph. */
    992 )
    993{
    994 int nincidences;
    995 int current;
    996
    997 assert(hypergraph);
    998 assert(hypergraph->hasoverlaps);
    999
    1000 if( hypergraph->hasoverlapsedges )
    1001 return SCIP_OKAY;
    1002
    1003 if( hypergraph->memoverlapsedgesbeg < hypergraph->noverlaps + 1 )
    1004 {
    1005 int newcapacity;
    1006
    1007 newcapacity = MAX(256, hypergraph->memoverlapsedgesbeg);
    1008 while( newcapacity < hypergraph->noverlaps )
    1009 newcapacity *= 2;
    1010
    1011 if( hypergraph->overlapsedgesbeg )
    1012 {
    1014 hypergraph->memoverlapsedgesbeg + 1, newcapacity + 1) );
    1015 }
    1016 else
    1017 {
    1018 assert(hypergraph->memoverlapsedgesbeg == 0);
    1019 SCIP_ALLOC( BMSallocBlockMemoryArray(hypergraph->blkmem, &hypergraph->overlapsedgesbeg, newcapacity + 1) );
    1020 }
    1021 hypergraph->memoverlapsedgesbeg = newcapacity;
    1022 SCIPdebugMessage("ensuring memory for %d overlaps' edges slice.\n", newcapacity);
    1023 }
    1024
    1025 /* We know the total number of overlap-edge incidences from the edges. */
    1026 nincidences = hypergraph->edgesoverlapsbeg[hypergraph->nedges];
    1027 if( hypergraph->memoverlapsedges < nincidences )
    1028 {
    1029 int newcapacity;
    1030
    1031 newcapacity = MAX(256, hypergraph->memoverlaps);
    1032 while( newcapacity < nincidences )
    1033 newcapacity *= 2;
    1034
    1035 SCIP_ALLOC( BMSreallocBlockMemoryArray(hypergraph->blkmem, &hypergraph->overlapsedges,
    1036 hypergraph->memoverlapsedges, newcapacity) );
    1037 hypergraph->memoverlapsedges = newcapacity;
    1038 SCIPdebugMessage("ensuring memory for %d overlaps' edges.\n", newcapacity);
    1039 }
    1040
    1041 /* We initialize beg[v] = 0. */
    1042 for( SCIP_HYPERGRAPH_OVERLAP o = 0; o < hypergraph->noverlaps; ++o )
    1043 hypergraph->overlapsedgesbeg[o] = 0;
    1044
    1045 /* We traverse through all incidences (using the edges' overlap arrays) and count the degree deg(o) in beg[o],
    1046 * where deg(o) shall denote the number of edges incident to overlap o. */
    1047 for( int i = 0; i < nincidences; ++i )
    1048 hypergraph->overlapsedgesbeg[hypergraph->edgesoverlaps[i]]++;
    1049
    1050 /* This loop sets beg[0] = 0, beg[1] = deg(0), beg[2] = deg(0) + deg(1), beg[o] = deg(0) + ... + deg(o-1) */
    1051 current = 0;
    1052 for( SCIP_HYPERGRAPH_OVERLAP o = 0; o < hypergraph->noverlaps; ++o )
    1053 {
    1054 int temp;
    1055
    1056 temp = current;
    1057 current += hypergraph->overlapsedgesbeg[o];
    1058 hypergraph->overlapsedgesbeg[o] = temp;
    1059 }
    1060
    1061 /* We now traverse through all edges e and their incident overlaps o, storing e at beg[o], which is incremented. */
    1062 for( SCIP_HYPERGRAPH_EDGE e = 0; e < hypergraph->nedges; ++e )
    1063 {
    1064 int first;
    1065 int beyond;
    1066
    1067 first = hypergraph->edgesoverlapsbeg[e];
    1068 beyond = hypergraph->edgesoverlapsbeg[e + 1];
    1069 for( int i = first; i < beyond; ++i )
    1070 {
    1071 SCIP_HYPERGRAPH_OVERLAP o = hypergraph->edgesoverlaps[i];
    1072 hypergraph->overlapsedges[hypergraph->overlapsedgesbeg[o]++] = e;
    1073 }
    1074 }
    1075
    1076 /* We now revert the incrementation of the beg[o]-values again. */
    1077 for( SCIP_HYPERGRAPH_OVERLAP o = hypergraph->noverlaps; o > 0; --o )
    1078 hypergraph->overlapsedgesbeg[o] = hypergraph->overlapsedgesbeg[o-1];
    1079 hypergraph->overlapsedgesbeg[0] = 0;
    1080 hypergraph->hasoverlapsedges = TRUE;
    1081
    1082 return SCIP_OKAY;
    1083}
    1084
    1085
    1086/**
    1087 * @brief computes all vertices' lists of incident overlaps
    1088 *
    1089 * Requires \ref SCIPhypergraphHasOverlaps.
    1090 */
    1092 SCIP_HYPERGRAPH* hypergraph /**< The hypergraph. */
    1093 )
    1094{
    1095 int nincidences;
    1096 int current;
    1097
    1098 assert(hypergraph);
    1099 assert(hypergraph->hasoverlaps);
    1100
    1101 if( hypergraph->hasverticesoverlaps )
    1102 return SCIP_OKAY;
    1103
    1104 if( hypergraph->memverticesoverlapsbeg < hypergraph->nvertices )
    1105 {
    1106 int newcapacity;
    1107
    1108 newcapacity = MAX(256, hypergraph->memverticesoverlapsbeg);
    1109 while( newcapacity < hypergraph->nvertices )
    1110 newcapacity *= 2;
    1111
    1112 if( hypergraph->verticesoverlapsbeg )
    1113 {
    1115 hypergraph->memverticesoverlapsbeg, newcapacity) );
    1116 }
    1117 else
    1118 {
    1119 assert(hypergraph->memverticesoverlapsbeg == 0);
    1120 SCIP_ALLOC( BMSallocBlockMemoryArray(hypergraph->blkmem, &hypergraph->verticesoverlapsbeg, newcapacity) );
    1121 }
    1122 hypergraph->memverticesoverlapsbeg = newcapacity;
    1123 SCIPdebugMessage("ensuring memory for %d vertices' overlaps slice.\n", newcapacity);
    1124 }
    1125
    1126 /* We know the total number of vertex-overlap incidences from the over. */
    1127 nincidences = hypergraph->overlapsverticesbeg[hypergraph->noverlaps];
    1128 if( hypergraph->memverticesoverlaps < nincidences )
    1129 {
    1130 int newcapacity;
    1131
    1132 newcapacity = MAX(256, hypergraph->memverticesoverlaps);
    1133 while( newcapacity < nincidences )
    1134 newcapacity *= 2;
    1135
    1137 hypergraph->memverticesoverlaps, newcapacity) );
    1138 hypergraph->memverticesoverlaps = newcapacity;
    1139 SCIPdebugMessage("ensuring memory for %d vertices' overlaps.\n", newcapacity);
    1140 }
    1141
    1142 /* We initialize beg[v] = 0. */
    1143 for( SCIP_HYPERGRAPH_VERTEX v = 0; v < hypergraph->nvertices; ++v )
    1144 hypergraph->verticesoverlapsbeg[v] = 0;
    1145
    1146 /* We traverse through all incidences (using the overlaps' vertex arrays) and count the degree deg(v) in beg[v],
    1147 * where deg(v) shall denote the number of overlaps incident to vertex v. */
    1148 for( int i = 0; i < nincidences; ++i )
    1149 hypergraph->verticesoverlapsbeg[hypergraph->overlapsvertices[i]]++;
    1150
    1151 /* This loop sets beg[0] = 0, beg[1] = deg(0), beg[2] = deg(0) + deg(1), beg[v] = deg(0) + ... + deg(v-1) */
    1152 current = 0;
    1153 for( SCIP_HYPERGRAPH_VERTEX v = 0; v < hypergraph->nvertices; ++v )
    1154 {
    1155 int temp;
    1156
    1157 temp = current;
    1158 current += hypergraph->verticesoverlapsbeg[v];
    1159 hypergraph->verticesoverlapsbeg[v] = temp;
    1160 }
    1161
    1162 /* We traverse through all overlaps o and their incident vertices v, storing o at beg[v], which is incremented. */
    1163 for( SCIP_HYPERGRAPH_OVERLAP o = 0; o < hypergraph->noverlaps; ++o )
    1164 {
    1165 int first;
    1166 int beyond;
    1167
    1168 first = hypergraph->overlapsverticesbeg[o];
    1169 beyond = hypergraph->overlapsverticesbeg[o + 1];
    1170 for( int i = first; i < beyond; ++i )
    1171 {
    1172 SCIP_HYPERGRAPH_VERTEX v = hypergraph->overlapsvertices[i];
    1173 hypergraph->verticesoverlaps[hypergraph->verticesoverlapsbeg[v]++] = o;
    1174 }
    1175 }
    1176
    1177 /* We now revert the incrementation of the beg[o]-values again. */
    1178 for( SCIP_HYPERGRAPH_VERTEX v = hypergraph->nvertices; v > 0; --v )
    1179 hypergraph->verticesoverlapsbeg[v] = hypergraph->verticesoverlapsbeg[v-1];
    1180 hypergraph->verticesoverlapsbeg[0] = 0;
    1181 hypergraph->hasverticesoverlaps = TRUE;
    1182
    1183 return SCIP_OKAY;
    1184}
    1185
    1186/** @brief returns whether overlaps \p overlap1 and \p overlap2 are disjoint */
    1188 SCIP_HYPERGRAPH* hypergraph, /**< The hypergraph. */
    1189 SCIP_HYPERGRAPH_OVERLAP overlap1, /**< First overlap. */
    1190 SCIP_HYPERGRAPH_OVERLAP overlap2 /**< Second overlap. */
    1191 )
    1192{
    1193 int size1;
    1194 SCIP_HYPERGRAPH_VERTEX* vertices1;
    1195 int size2;
    1196 SCIP_HYPERGRAPH_VERTEX* vertices2;
    1197 int i = 0;
    1198 int j = 0;
    1199
    1200 assert(hypergraph);
    1201
    1202 /* We loop over the vertices in parallel because they are sorted. */
    1203 size1 = SCIPhypergraphOverlapSize(hypergraph, overlap1);
    1204 vertices1 = SCIPhypergraphOverlapVertices(hypergraph, overlap1);
    1205 size2 = SCIPhypergraphOverlapSize(hypergraph, overlap2);
    1206 vertices2 = SCIPhypergraphOverlapVertices(hypergraph, overlap2);
    1207 while( i < size1 && j < size2 )
    1208 {
    1209 if( vertices1[i] < vertices2[j] )
    1210 ++i;
    1211 else if( vertices1[i] > vertices2[j] )
    1212 ++j;
    1213 else
    1214 return FALSE;
    1215 }
    1216
    1217 return TRUE;
    1218}
    1219
    1220/** @brief asserts that the hypergraph data structures are valid */
    1222 SCIP_HYPERGRAPH* hypergraph, /**< The hypergraph. */
    1223 FILE* file /**< A file stream to print problems to (can be \c NULL). */
    1224 )
    1225{
    1226 SCIP_Bool valid = TRUE;
    1227
    1228 assert(hypergraph);
    1229
    1230 if( SCIPhypergraphHasVertexEdges(hypergraph) )
    1231 {
    1232 int nincidences;
    1233 long long* incidences1 = NULL;
    1234 long long* incidences2 = NULL;
    1235 int i1 = 0;
    1236 int i2 = 0;
    1237
    1238 nincidences = SCIPhypergraphGetNIncidences(hypergraph);
    1239 SCIP_ALLOC_ABORT( BMSallocBlockMemoryArray(hypergraph->blkmem, &incidences1, nincidences) );
    1240 SCIP_ALLOC_ABORT( BMSallocBlockMemoryArray(hypergraph->blkmem, &incidences2, nincidences) );
    1241 for( SCIP_HYPERGRAPH_EDGE e = 0; e < SCIPhypergraphGetNEdges(hypergraph); ++e )
    1242 {
    1243 int esize = SCIPhypergraphEdgeSize(hypergraph, e);
    1244 for( int i = 0; i < esize; ++i )
    1245 {
    1247 long long pair = v + (long long) SCIPhypergraphGetNVertices(hypergraph) * (long long) e;
    1248 incidences1[i1++] = pair;
    1249 }
    1250 }
    1251
    1252 if ( i1 != nincidences )
    1253 {
    1254 valid = FALSE;
    1255 if( file )
    1256 {
    1257 fprintf(file, "SCIPhypergraphIsValid detected inconsistency: "
    1258 "number of incidences is claimed to be %d but counting via edges yields %d!\n", nincidences, i1);
    1259 fflush(file);
    1260 }
    1261 }
    1262
    1263 for( SCIP_HYPERGRAPH_VERTEX v = 0; v < SCIPhypergraphGetNVertices(hypergraph); ++v )
    1264 {
    1265 int first = SCIPhypergraphVertexEdgesFirst(hypergraph, v);
    1266 int beyond = SCIPhypergraphVertexEdgesBeyond(hypergraph, v);
    1267 for( int j = first; j < beyond; ++j )
    1268 {
    1270 long long pair = v + (long long) SCIPhypergraphGetNVertices(hypergraph) * (long long) e;
    1271 incidences2[i2++] = pair;
    1272 }
    1273 }
    1274
    1275 if ( i2 != nincidences )
    1276 {
    1277 valid = FALSE;
    1278 if( file )
    1279 {
    1280 fprintf(file, "SCIPhypergraphIsValid detected inconsistency: "
    1281 "number of incidences is claimed to be %d but counting via vertices yields %d!\n", nincidences, i2);
    1282 fflush(file);
    1283 }
    1284 }
    1285
    1286 if( valid )
    1287 {
    1288 SCIPsortLong(incidences1, nincidences);
    1289 SCIPsortLong(incidences2, nincidences);
    1290
    1291 for( int i = 0; i < nincidences; ++i )
    1292 {
    1293 if( incidences1[i] != incidences2[i] )
    1294 {
    1295 valid = FALSE;
    1296 if( file )
    1297 {
    1298 fprintf(file, "SCIPhypergraphIsValid detected inconsistency: "
    1299 "incidence #%d is %lld (via edges) and %lld (via vertices)!\n", i, incidences1[i], incidences2[i]);
    1300 fflush(file);
    1301 }
    1302 }
    1303 }
    1304 }
    1305
    1306 BMSfreeBlockMemoryArray(hypergraph->blkmem, &incidences2, nincidences);
    1307 BMSfreeBlockMemoryArray(hypergraph->blkmem, &incidences1, nincidences);
    1308 }
    1309
    1310 if( SCIPhypergraphHasVertexEdges(hypergraph) )
    1311 {
    1312 int nincidences;
    1313 long long* incidences1 = NULL;
    1314 long long* incidences2 = NULL;
    1315 int i1 = 0;
    1316 int i2 = 0;
    1317
    1318 nincidences = SCIPhypergraphGetNIncidences(hypergraph);
    1319 SCIP_ALLOC_ABORT( BMSallocBlockMemoryArray(hypergraph->blkmem, &incidences1, nincidences) );
    1320 SCIP_ALLOC_ABORT( BMSallocBlockMemoryArray(hypergraph->blkmem, &incidences2, nincidences) );
    1321 for( SCIP_HYPERGRAPH_EDGE e = 0; e < SCIPhypergraphGetNEdges(hypergraph); ++e )
    1322 {
    1323 int esize = SCIPhypergraphEdgeSize(hypergraph, e);
    1324 for( int i = 0; i < esize; ++i )
    1325 {
    1327 long long pair = v + (long long) SCIPhypergraphGetNVertices(hypergraph) * (long long) e;
    1328 incidences1[i1++] = pair;
    1329 }
    1330 }
    1331
    1332 if ( i1 != nincidences )
    1333 {
    1334 valid = FALSE;
    1335 if( file )
    1336 {
    1337 fprintf(file, "SCIPhypergraphIsValid detected inconsistency: "
    1338 "number of incidences is claimed to be %d but counting via edges yields %d!\n", nincidences, i1);
    1339 fflush(file);
    1340 }
    1341 }
    1342
    1343 for( SCIP_HYPERGRAPH_VERTEX v = 0; v < SCIPhypergraphGetNVertices(hypergraph); ++v )
    1344 {
    1345 int first = SCIPhypergraphVertexEdgesFirst(hypergraph, v);
    1346 int beyond = SCIPhypergraphVertexEdgesBeyond(hypergraph, v);
    1347 for( int j = first; j < beyond; ++j )
    1348 {
    1350 long long pair = v + (long long) SCIPhypergraphGetNVertices(hypergraph) * (long long) e;
    1351 incidences2[i2++] = pair;
    1352 }
    1353 }
    1354
    1355 if ( i2 != nincidences )
    1356 {
    1357 valid = FALSE;
    1358 if( file )
    1359 {
    1360 fprintf(file, "SCIPhypergraphIsValid detected inconsistency: "
    1361 "number of incidences is claimed to be %d but counting via vertices yields %d!\n", nincidences, i2);
    1362 fflush(file);
    1363 }
    1364 }
    1365
    1366 if( valid )
    1367 {
    1368 SCIPsortLong(incidences1, nincidences);
    1369 SCIPsortLong(incidences2, nincidences);
    1370
    1371 for( int i = 0; i < nincidences; ++i )
    1372 {
    1373 if( incidences1[i] != incidences2[i] )
    1374 {
    1375 valid = FALSE;
    1376 if( file )
    1377 {
    1378 fprintf(file, "SCIPhypergraphIsValid detected inconsistency: "
    1379 "incidence #%d is %lld (via edges) and %lld (via vertices)!\n", i, incidences1[i], incidences2[i]);
    1380 fflush(file);
    1381 }
    1382 }
    1383 }
    1384 }
    1385
    1386 BMSfreeBlockMemoryArray(hypergraph->blkmem, &incidences2, nincidences);
    1387 BMSfreeBlockMemoryArray(hypergraph->blkmem, &incidences1, nincidences);
    1388 }
    1389
    1390 if( SCIPhypergraphHasOverlaps(hypergraph) )
    1391 {
    1392 int n;
    1393 SCIP_Bool* marked = NULL;
    1394
    1395 /* Verify edge-overlap incidences. */
    1396 n = SCIPhypergraphGetNVertices(hypergraph);
    1397 SCIP_ALLOC_ABORT( BMSallocBlockMemoryArray(hypergraph->blkmem, &marked, n) );
    1398 for( SCIP_HYPERGRAPH_VERTEX v = 0; v < n; ++v )
    1399 marked[v] = FALSE;
    1400 for( SCIP_HYPERGRAPH_EDGE e = 0; e < hypergraph->nedges && valid; ++e )
    1401 {
    1402 int first;
    1403 int beyond;
    1404 int esize;
    1405 int lastcardinality = 0;
    1406
    1407 esize = SCIPhypergraphEdgeSize(hypergraph, e);
    1408 SCIP_HYPERGRAPH_VERTEX* evertices = SCIPhypergraphEdgeVertices(hypergraph, e);
    1409 for( int i = 0; i < esize; ++i )
    1410 marked[evertices[i]] = TRUE;
    1411 first = SCIPhypergraphEdgesOverlapsFirst(hypergraph, e);
    1412 beyond = SCIPhypergraphEdgesOverlapsBeyond(hypergraph, e);
    1413 for( int i = first; i < beyond && valid; ++i )
    1414 {
    1416 int cardinality;
    1417
    1418 o = SCIPhypergraphEdgesOverlapsGetAtIndex(hypergraph, i);
    1419 cardinality = SCIPhypergraphOverlapSize(hypergraph, o);
    1420
    1421 /* Check if the cardinalities are nontrivial and form a non-decreasing sequences for each edge. */
    1422 if (cardinality < 1 || cardinality < lastcardinality)
    1423 {
    1424 valid = FALSE;
    1425 if( file )
    1426 {
    1427 fprintf(file, "SCIPhypergraphIsValid detected inconsistency: edge e%d = {", e);
    1428 for( int k = 0; k < esize; ++k )
    1429 fprintf(file, "%sv%d", k ? "," : "", SCIPhypergraphEdgeVertices(hypergraph, e)[k]);
    1430 fprintf(file, "} has incidence #%d of [%d,%d) to overlap o%d = {", i, first, beyond, o);
    1431 for( int k = 0; k < SCIPhypergraphOverlapSize(hypergraph, o); ++k )
    1432 fprintf(file, "%sv%d", k ? "," : "", SCIPhypergraphOverlapVertices(hypergraph, o)[k]);
    1433 fprintf(file, "} of cardinality |o%d| = %d, but previous cardinality is %d.\n", o, cardinality,
    1434 lastcardinality);
    1435 fflush(file);
    1436 }
    1437 }
    1438 lastcardinality = cardinality;
    1439
    1440 for( int j = 0; j < SCIPhypergraphOverlapSize(hypergraph, o) && valid; ++j )
    1441 {
    1442 if( !marked[SCIPhypergraphOverlapVertices(hypergraph, o)[j]])
    1443 {
    1444 valid = FALSE;
    1445 if( file )
    1446 {
    1447 fprintf(file, "SCIPhypergraphIsValid detected inconsistency: edge e%d = {", e);
    1448 for( int k = 0; k < esize; ++k )
    1449 fprintf(file, "%sv%d", k ? "," : "", SCIPhypergraphEdgeVertices(hypergraph, e)[k]);
    1450 fprintf(file, "} has incidence #%d of [%d,%d) to overlap o%d = {", i, first, beyond, o);
    1451 for( int k = 0; k < SCIPhypergraphOverlapSize(hypergraph, o); ++k )
    1452 fprintf(file, "%sv%d", k ? "," : "", SCIPhypergraphOverlapVertices(hypergraph, o)[k]);
    1453 fprintf(file, "} which is not a subset!\n");
    1454 fflush(file);
    1455 }
    1456 }
    1457 }
    1458 }
    1459 for( int i = 0; i < esize; ++i )
    1460 marked[evertices[i]] = FALSE;
    1461 }
    1462 BMSfreeBlockMemoryArray(hypergraph->blkmem, &marked, n);
    1463 }
    1464
    1465 return valid;
    1466}
    1467
    1468/** @brief initializes a hypergraph iterator's internal memory */
    1470 SCIP_HYPERGRAPH* hypergraph, /**< The hypergraph of this iterator. */
    1471 SCIP_HYPERGRAPH_ITER* iterator /**< Iterator to be initialized. */
    1472 )
    1473{
    1474 assert(hypergraph);
    1475 assert(iterator);
    1476
    1477 iterator->base = -1;
    1478 iterator->vertexidx = -1;
    1479 iterator->minvertex = -1;
    1480 iterator->edgeidx = -1;
    1481 iterator->adjacent = -1;
    1482 iterator->sizecommonvertices = 32;
    1483 iterator->commonvertices = NULL;
    1484 iterator->minoverlapsize = 2;
    1485 iterator->onlylater = FALSE;
    1486 iterator->findoverlaps = FALSE;
    1487
    1488 SCIP_ALLOC( BMSallocBlockMemoryArray(hypergraph->blkmem, &iterator->commonvertices, 32) );
    1489
    1490 return SCIP_OKAY;
    1491}
    1492
    1493/** @brief frees a hypergraph iterator's internal memory */
    1495 SCIP_HYPERGRAPH* hypergraph, /**< The hypergraph of this iterator. */
    1496 SCIP_HYPERGRAPH_ITER* iterator /**< Iterator to be cleared. */
    1497 )
    1498{
    1499 assert(hypergraph);
    1500 assert(iterator);
    1501
    1502 BMSfreeBlockMemoryArray(hypergraph->blkmem, &iterator->commonvertices, iterator->sizecommonvertices);
    1503}
    1504
    1505/** @brief initializes the iterator to the first adjacent edge of \p base */
    1507 SCIP_HYPERGRAPH* hypergraph, /**< The hypergraph of this iterator. */
    1508 SCIP_HYPERGRAPH_ITER* iterator, /**< Iterator to be initialized. */
    1509 SCIP_HYPERGRAPH_EDGE base, /**< Base edge. */
    1510 unsigned int minoverlapsize, /**< Minimum size of the overlap. */
    1511 SCIP_Bool onlylater, /**< Whether to only consider edges greater than \p base. */
    1512 SCIP_Bool findoverlaps /**< Whether to compute the overlap sets. */
    1513 )
    1514{
    1515 assert(hypergraph);
    1516 assert(iterator);
    1517 assert(base >= 0);
    1518 assert(base < hypergraph->nedges);
    1519 assert(hypergraph->hasvertexedges);
    1520 assert(hypergraph->hasoverlaps || !findoverlaps);
    1521
    1522 iterator->base = base;
    1523 iterator->vertexidx = -1;
    1524 iterator->edgeidx = -1;
    1525 iterator->minvertex = -1;
    1526 iterator->adjacent = -1;
    1527 iterator->ncommonvertices = 0;
    1528 iterator->overlap = -1;
    1529 iterator->minoverlapsize = minoverlapsize;
    1530 iterator->onlylater = onlylater;
    1531 iterator->findoverlaps = findoverlaps;
    1532
    1533 SCIPhypergraphIterNext(hypergraph, iterator);
    1534}
    1535
    1536/** @brief returns whether the iterator is valid */
    1538 SCIP_HYPERGRAPH_ITER* iterator /**< Iterator. */
    1539 )
    1540{
    1541 assert(iterator);
    1542
    1543 return iterator->vertexidx != -2;
    1544}
    1545
    1546/** @brief initializes the iterator to the first adjacent edge of \p base */
    1548 SCIP_HYPERGRAPH* hypergraph, /**< The hypergraph of this iterator. */
    1549 SCIP_HYPERGRAPH_ITER* iterator /**< Iterator. */
    1550 )
    1551{
    1552 assert(hypergraph);
    1553 assert(iterator);
    1554 assert(iterator->base >= 0);
    1555 assert(iterator->base < hypergraph->nedges);
    1556 assert(iterator->vertexidx == -1 || iterator->vertexidx >= hypergraph->edgesverticesbeg[iterator->base]);
    1557 assert(iterator->vertexidx < hypergraph->edgesverticesbeg[iterator->base + 1]);
    1558
    1559 if( iterator->vertexidx < 0 )
    1560 {
    1561 /* Freshly initialized iterator. */
    1562 iterator->vertexidx = hypergraph->edgesverticesbeg[iterator->base];
    1563 if( iterator->vertexidx == hypergraph->edgesverticesbeg[iterator->base + 1] )
    1564 {
    1565 /* No vertices in this edge. */
    1566 iterator->vertexidx = -2;
    1567 return;
    1568 }
    1569
    1570 /* Edge index is set to one before the first edge and incremented in next loop. */
    1571 iterator->minvertex = hypergraph->edgesvertices[iterator->vertexidx];
    1572 iterator->edgeidx = hypergraph->verticesedgesbeg[iterator->minvertex] - 1;
    1573 }
    1574
    1575 while( iterator->vertexidx >= 0 )
    1576 {
    1577 int i, iend;
    1578 int j, jend;
    1579
    1580 assert(iterator->minvertex >= 0);
    1581 assert(iterator->minvertex < hypergraph->nvertices);
    1582 assert(iterator->edgeidx >= hypergraph->verticesedgesbeg[iterator->minvertex] - 1);
    1583 assert(iterator->edgeidx < hypergraph->verticesedgesbeg[iterator->minvertex + 1]);
    1584
    1585 /* Go to next edge of vertex. */
    1586
    1587 iterator->edgeidx++;
    1588 if( iterator->edgeidx < hypergraph->verticesedgesbeg[iterator->minvertex + 1] )
    1589 {
    1590 /* There is a next edge. */
    1591 iterator->adjacent = hypergraph->verticesedges[iterator->edgeidx];
    1592 }
    1593 else
    1594 {
    1595 /* There is no next edge, so we consider the next vertex. */
    1596 iterator->vertexidx++;
    1597 if( iterator->vertexidx == hypergraph->edgesverticesbeg[iterator->base + 1] )
    1598 {
    1599 /* There is no next vertex either. */
    1600 iterator->vertexidx = -2;
    1601 return;
    1602 }
    1603
    1604 /* Edge index is set to one before the first edge of the next vertex and incremented in the next iteration. */
    1605 iterator->minvertex = hypergraph->edgesvertices[iterator->vertexidx];
    1606 iterator->edgeidx = hypergraph->verticesedgesbeg[iterator->minvertex] - 1;
    1607 continue;
    1608 }
    1609
    1610 /* Skip if we consider the base edge. */
    1611 if( iterator->adjacent == iterator->base )
    1612 continue;
    1613
    1614 /* Check for adjacent < base and discard if not desired. */
    1615 if( iterator->onlylater && (iterator->adjacent < iterator->base) )
    1616 continue;
    1617
    1618 /* We traverse the common vertices. */
    1619 iterator->ncommonvertices = 0;
    1620 i = hypergraph->edgesverticesbeg[iterator->base];
    1621 iend = hypergraph->edgesverticesbeg[iterator->base + 1];
    1622 j = hypergraph->edgesverticesbeg[iterator->adjacent];
    1623 jend = hypergraph->edgesverticesbeg[iterator->adjacent + 1];
    1624 while( i < iend && j < jend )
    1625 {
    1626 SCIP_HYPERGRAPH_VERTEX ivertex, jvertex;
    1627
    1628 ivertex = hypergraph->edgesvertices[i];
    1629 jvertex = hypergraph->edgesvertices[j];
    1630
    1631 if( ivertex < jvertex )
    1632 ++i;
    1633 else if( ivertex > jvertex )
    1634 ++j;
    1635 else
    1636 {
    1637 if( iterator->ncommonvertices == 0 )
    1638 {
    1639 /* First common vertex must be the iterator vertex. Otherwise we abort. */
    1640 if( ivertex != iterator->minvertex )
    1641 {
    1642 iterator->ncommonvertices = -1;
    1643 break;
    1644 }
    1645 }
    1646 if( iterator->ncommonvertices == iterator->sizecommonvertices )
    1647 {
    1648 int newsize = 2 * iterator->sizecommonvertices;
    1650 iterator->sizecommonvertices, newsize) );
    1651 iterator->sizecommonvertices = newsize;
    1652 }
    1653 iterator->commonvertices[iterator->ncommonvertices] = ivertex;
    1654 iterator->ncommonvertices++;
    1655 ++i;
    1656 ++j;
    1657 }
    1658 }
    1659 assert(iterator->ncommonvertices != 0);
    1660
    1661 if( iterator->ncommonvertices < iterator->minoverlapsize )
    1662 {
    1663 /* Abort since either ncommonvertices = -1 (minvertex not minimum vertex in intersection)
    1664 * or if it was smaller than requested. */
    1665 continue;
    1666 }
    1667
    1668 if( iterator->findoverlaps )
    1669 {
    1670 /* If requested, find corresponding overlap set. */
    1671 if( iterator->ncommonvertices >= 2 )
    1672 {
    1673 SCIP_CALL_ABORT( findOverlap(hypergraph, iterator->ncommonvertices, iterator->commonvertices,
    1674 &iterator->overlap, FALSE, NULL) );
    1675 }
    1676 else
    1677 iterator->overlap = -1;
    1678 }
    1679
    1680 break;
    1681 }
    1682}
    1683
    1684/** @brief returns the base edge */
    1686 SCIP_HYPERGRAPH_ITER* iterator /**< Iterator. */
    1687 )
    1688{
    1689 return iterator->base;
    1690}
    1691
    1692/** @brief returns the current adjacent edge */
    1694 SCIP_HYPERGRAPH_ITER* iterator /**< Iterator. */
    1695 )
    1696{
    1697 return iterator->adjacent;
    1698}
    1699
    1700/** @brief returns the minimum vertex in the intersection of the base and the current adjacent edge */
    1702 SCIP_HYPERGRAPH_ITER* iterator /**< Iterator. */
    1703 )
    1704{
    1705 return iterator->minvertex;
    1706}
    1707
    1708/**
    1709 * @brief returns the overlap for the intersection of the base and the current adjacent edge
    1710 *
    1711 * If the intersection of the two edges has only one element, then -1 is returned, and if overlap information was not
    1712 * requested in \ref SCIPhypergraphIterStart, then -2 is returned.
    1713 */
    1715 SCIP_HYPERGRAPH_ITER* iterator /**< Iterator. */
    1716 )
    1717{
    1718 return iterator->overlap;
    1719}
    1720
    1721
    1722/*
    1723 * simple functions implemented as defines
    1724 */
    1725
    1726#ifndef NDEBUG
    1727
    1728/*
    1729 * In debug mode, the following methods are implemented as function calls to ensure type validity.
    1730 * In optimized mode, the methods are implemented as defines to improve performance.
    1731 * However, we want to have them in the library anyways, so we have to undef the defines.
    1732 */
    1733
    1734#undef SCIPhypergraphNumVertices
    1735#undef SCIPhypergraphNumEdges
    1736#undef SCIPhypergraphBlkmem
    1737#undef SCIPhypergraphNumOverlaps
    1738#undef SCIPhypergraphVertexData
    1739#undef SCIPhypergraphEdgeData
    1740#undef SCIPhypergraphOverlapData
    1741#undef SCIPhypergraphEdgeSize
    1742#undef SCIPhypergraphEdgeVertices
    1743#undef SCIPhypergraphHasVertexEdges
    1744#undef SCIPhypergraphVerticesEdgesFirst
    1745#undef SCIPhypergraphVerticesEdgesBeyond
    1746#undef SCIPhypergraphVerticesEdgesGet
    1747#undef SCIPhypergraphHasOverlaps
    1748#undef SCIPhypergraphOverlapSize
    1749#undef SCIPhypergraphOverlapVertices
    1750#undef SCIPhypergraphEdgesOverlapsFirst
    1751#undef SCIPhypergraphEdgesOverlapsBeyond
    1752#undef SCIPhypergraphEdgesOverlapsGet
    1753#undef SCIPhypergraphHasOverlapsEdges
    1754#undef SCIPhypergraphOverlapsEdgesFirst
    1755#undef SCIPhypergraphOverlapsEdgesBeyond
    1756#undef SCIPhypergraphOverlapsEdgesGet
    1757#undef SCIPhypergraphHasVerticesOverlaps
    1758#undef SCIPhypergraphVerticesOverlapsFirst
    1759#undef SCIPhypergraphVerticesOverlapsBeyond
    1760#undef SCIPhypergraphVerticesOverlapsGet
    1761
    1762
    1763/** @brief returns the number of vertices */
    1765 SCIP_HYPERGRAPH* hypergraph /**< The hypergraph. */
    1766 )
    1767{
    1768 assert(hypergraph);
    1769
    1770 return hypergraph->nvertices;
    1771}
    1772
    1773/** @brief returns the number of edges */
    1775 SCIP_HYPERGRAPH* hypergraph /**< The hypergraph. */
    1776 )
    1777{
    1778 assert(hypergraph);
    1779
    1780 return hypergraph->nedges;
    1781}
    1782
    1783/** @brief returns the hypergraph's block memory structure */
    1785 SCIP_HYPERGRAPH* hypergraph /**< The hypergraph. */
    1786 )
    1787{
    1788 assert(hypergraph != NULL);
    1789
    1790 return hypergraph->blkmem;
    1791}
    1792
    1793/** @brief returns the number of overlaps */
    1795 SCIP_HYPERGRAPH* hypergraph /**< The hypergraph. */
    1796 )
    1797{
    1798 assert(hypergraph);
    1799
    1800 return hypergraph->noverlaps;
    1801}
    1802
    1803/** @brief returns the number of edge-vertex incidences */
    1805 SCIP_HYPERGRAPH* hypergraph /**< The hypergraph. */
    1806 )
    1807{
    1808 assert(hypergraph);
    1809
    1810 return hypergraph->edgesverticesbeg[hypergraph->nedges];
    1811}
    1812
    1813/** @brief returns additional data of \p vertex */
    1815 SCIP_HYPERGRAPH* hypergraph, /**< The hypergraph. */
    1816 SCIP_HYPERGRAPH_VERTEX vertex /**< A vertex. */
    1817 )
    1818{
    1819 assert(hypergraph != NULL);
    1820
    1821 return (SCIP_HYPERGRAPH_VERTEXDATA*)(hypergraph->verticesdata
    1822 + vertex * hypergraph->sizevertexdata / sizeof(*(hypergraph->verticesdata))); /*lint --e{737}*/
    1823}
    1824
    1825/** @brief returns additional data of \p edge */
    1827 SCIP_HYPERGRAPH* hypergraph, /**< The hypergraph. */
    1828 SCIP_HYPERGRAPH_EDGE edge /**< An edge. */
    1829 )
    1830{
    1831 assert(hypergraph != NULL);
    1832
    1833 return (SCIP_HYPERGRAPH_EDGEDATA*)(hypergraph->edgesdata
    1834 + edge * hypergraph->sizeedgedata / sizeof(*(hypergraph->edgesdata))); /*lint --e{737}*/
    1835}
    1836
    1837/** @brief returns additional data of \p overlap */
    1839 SCIP_HYPERGRAPH* hypergraph, /**< The hypergraph. */
    1840 SCIP_HYPERGRAPH_OVERLAP overlap /**< An overlap. */
    1841 )
    1842{
    1843 assert(hypergraph != NULL);
    1844
    1845 return (SCIP_HYPERGRAPH_OVERLAPDATA*)(hypergraph->overlapsdata
    1846 + overlap * hypergraph->sizeoverlapdata / sizeof(*(hypergraph->overlapsdata))); /*lint --e{737}*/
    1847}
    1848
    1849/** @brief returns the number of vertices of \p edge */
    1851 SCIP_HYPERGRAPH* hypergraph, /**< The hypergraph. */
    1852 SCIP_HYPERGRAPH_EDGE edge /**< An edge. */
    1853 )
    1854{
    1855 assert(hypergraph);
    1856 assert(edge >= 0 && edge < hypergraph->nedges);
    1857
    1858 return hypergraph->edgesverticesbeg[edge + 1] - hypergraph->edgesverticesbeg[edge];
    1859}
    1860
    1861/**
    1862 * @brief returns the array of vertices of \p edge
    1863 *
    1864 * The length of the array is \ref SCIPhypergraphEdgeSize.
    1865 */
    1866
    1868 SCIP_HYPERGRAPH* hypergraph, /**< The hypergraph. */
    1869 SCIP_HYPERGRAPH_EDGE edge /**< An edge. */
    1870 )
    1871{
    1872 assert(hypergraph);
    1873 assert(edge >= 0 && edge < hypergraph->nedges);
    1874
    1875 return &hypergraph->edgesvertices[hypergraph->edgesverticesbeg[edge]];
    1876}
    1877
    1878/**
    1879 * @brief returns whether vertices' incident edges are known.
    1880 *
    1881 * Use \ref SCIPhypergraphComputeVerticesEdges to compute them.
    1882 */
    1884 SCIP_HYPERGRAPH* hypergraph /**< The hypergraph. */
    1885 )
    1886{
    1887 assert(hypergraph);
    1888
    1889 return hypergraph->hasvertexedges;
    1890}
    1891
    1892/** @brief returns an index for the first edge incident to \p vertex */
    1894 SCIP_HYPERGRAPH* hypergraph, /**< The hypergraph. */
    1895 SCIP_HYPERGRAPH_VERTEX vertex /**< A vertex. */
    1896 )
    1897{
    1898 assert(hypergraph);
    1899 assert(hypergraph->hasvertexedges);
    1900
    1901 return hypergraph->verticesedgesbeg[vertex];
    1902}
    1903
    1904/** @brief returns an index beyond the last edge incident to \p vertex */
    1906 SCIP_HYPERGRAPH* hypergraph, /**< The hypergraph. */
    1907 SCIP_HYPERGRAPH_VERTEX vertex /**< A vertex. */
    1908 )
    1909{
    1910 assert(hypergraph);
    1911 assert(hypergraph->hasvertexedges);
    1912
    1913 return hypergraph->verticesedgesbeg[vertex + 1];
    1914}
    1915
    1916/**
    1917 * @brief returns the edge corresponding to \p index that is incident to a vertex
    1918 *
    1919 * See \ref SCIPhypergraphVertexEdgesFirst and \ref SCIPhypergraphVertexEdgesBeyond to obtain such indices for a vertex.
    1920 */
    1922 SCIP_HYPERGRAPH* hypergraph, /**< The hypergraph. */
    1923 int idx /**< Index. */
    1924 )
    1925{
    1926 assert(hypergraph);
    1927 assert(hypergraph->hasvertexedges);
    1928
    1929 return hypergraph->verticesedges[idx];
    1930}
    1931
    1932/**
    1933 * @brief returns whether edges' overlaps and overlaps' vertices are known.
    1934 *
    1935 * Use \ref SCIPhypergraphComputeOverlaps to compute them.
    1936 */
    1938 SCIP_HYPERGRAPH* hypergraph /**< The hypergraph. */
    1939 )
    1940{
    1941 assert(hypergraph);
    1942
    1943 return hypergraph->hasoverlaps;
    1944}
    1945
    1946/**
    1947 * @brief returns the number of vertices of \p overlap
    1948 *
    1949 * Requires \ref SCIPhypergraphHasOverlaps to be \c TRUE which results from \ref SCIPhypergraphComputeOverlaps.
    1950 */
    1952 SCIP_HYPERGRAPH* hypergraph, /**< The hypergraph. */
    1953 SCIP_HYPERGRAPH_OVERLAP overlap /**< Overlap. */
    1954 )
    1955{
    1956 assert(hypergraph);
    1957 assert(overlap >= 0 && overlap < hypergraph->noverlaps);
    1958 assert(hypergraph->hasoverlaps);
    1959
    1960 return hypergraph->overlapsverticesbeg[overlap + 1] - hypergraph->overlapsverticesbeg[overlap];
    1961}
    1962
    1963/**
    1964 * @brief returns the array of sorted vertices of \p overlap
    1965 *
    1966 * The length of the array is \ref SCIPhypergraphOverlapSize.
    1967 * Requires \ref SCIPhypergraphHasOverlaps to be \c TRUE which results from \ref SCIPhypergraphComputeOverlaps.
    1968 */
    1970 SCIP_HYPERGRAPH* hypergraph, /**< The hypergraph. */
    1971 SCIP_HYPERGRAPH_OVERLAP overlap /**< Overlap. */
    1972 )
    1973{
    1974 assert(hypergraph);
    1975 assert(overlap >= 0 && overlap < hypergraph->noverlaps);
    1976 assert(hypergraph->hasoverlaps);
    1977
    1978 return &hypergraph->overlapsvertices[hypergraph->overlapsverticesbeg[overlap]];
    1979}
    1980
    1981/** @brief returns an index for the first overlap incident to \p edge */
    1983 SCIP_HYPERGRAPH* hypergraph, /**< The hypergraph. */
    1984 SCIP_HYPERGRAPH_EDGE edge /**< Edge. */
    1985 )
    1986{
    1987 assert(hypergraph);
    1988 assert(edge >= 0 && edge < hypergraph->nedges);
    1989 assert(hypergraph->hasoverlaps);
    1990
    1991 return hypergraph->edgesoverlapsbeg[edge];
    1992}
    1993
    1994/** @brief returns an index beyond the last overlap incident to \p edge */
    1996 SCIP_HYPERGRAPH* hypergraph, /**< The hypergraph. */
    1997 SCIP_HYPERGRAPH_EDGE edge /**< Edge. */
    1998 )
    1999{
    2000 assert(hypergraph);
    2001 assert(edge >= 0 && edge < hypergraph->nedges);
    2002 assert(hypergraph->hasoverlaps);
    2003
    2004 return hypergraph->edgesoverlapsbeg[edge + 1];
    2005}
    2006
    2007/**
    2008 * @brief returns the overlap corresponding to \p idx that is incident to an edge
    2009 *
    2010 * See \ref SCIPhypergraphEdgesOverlapsFirst and \ref SCIPhypergraphEdgesOverlapsBeyond to obtain such indices for an
    2011 * edge.
    2012 */
    2014 SCIP_HYPERGRAPH* hypergraph, /**< The hypergraph. */
    2015 int idx /**< Index. */
    2016 )
    2017{
    2018 assert(hypergraph);
    2019 assert(hypergraph->hasoverlaps);
    2020
    2021 return hypergraph->edgesoverlaps[idx];
    2022}
    2023
    2024/**
    2025 * @brief returns whether overlaps' incident edges are known.
    2026 *
    2027 * Use \ref SCIPhypergraphComputeOverlapsEdges to compute them.
    2028 */
    2030 SCIP_HYPERGRAPH* hypergraph /**< The hypergraph. */
    2031 )
    2032{
    2033 assert(hypergraph);
    2034
    2035 return hypergraph->hasoverlapsedges;
    2036}
    2037
    2038/** @brief returns an index for the first edge incident to \p overlap */
    2040 SCIP_HYPERGRAPH* hypergraph, /**< The hypergraph. */
    2041 SCIP_HYPERGRAPH_OVERLAP overlap /**< Overlap. */
    2042 )
    2043{
    2044 assert(hypergraph);
    2045 assert(hypergraph->hasoverlapsedges);
    2046
    2047 return hypergraph->overlapsedgesbeg[overlap];
    2048}
    2049
    2050/** @brief returns an index beyond the last edge incident to \p overlap */
    2052 SCIP_HYPERGRAPH* hypergraph, /**< The hypergraph. */
    2053 SCIP_HYPERGRAPH_OVERLAP overlap /**< Overlap. */
    2054 )
    2055{
    2056 assert(hypergraph);
    2057 assert(hypergraph->hasoverlapsedges);
    2058
    2059 return hypergraph->overlapsedgesbeg[overlap + 1];
    2060}
    2061
    2062/**
    2063 * @brief returns the edge corresponding to \p idx that is incident to an overlap
    2064 *
    2065 * See \ref SCIPhypergraphOverlapsEdgesFirst and \ref SCIPhypergraphOverlapsEdgesBeyond to obtain such indices for an
    2066 * overlap.
    2067 */
    2069 SCIP_HYPERGRAPH* hypergraph, /**< The hypergraph. */
    2070 int idx /**< Index. */
    2071 )
    2072{
    2073 assert(hypergraph);
    2074 assert(hypergraph->hasoverlapsedges);
    2075
    2076 return hypergraph->overlapsedges[idx];
    2077}
    2078
    2079
    2080/**
    2081 * @brief returns whether vertices' incident overlaps are known
    2082 *
    2083 * Use \ref SCIPhypergraphComputeOverlaps to compute them.
    2084 */
    2086 SCIP_HYPERGRAPH* hypergraph /**< The hypergraph. */
    2087 )
    2088{
    2089 assert(hypergraph);
    2090
    2091 return hypergraph->hasverticesoverlaps;
    2092}
    2093
    2094/** @brief returns an index for the first overlap containing \p vertex */
    2096 SCIP_HYPERGRAPH* hypergraph, /**< The hypergraph. */
    2097 SCIP_HYPERGRAPH_VERTEX vertex /**< A vertex. */
    2098 )
    2099{
    2100 assert(hypergraph);
    2101 assert(hypergraph->hasverticesoverlaps);
    2102
    2103 return hypergraph->verticesoverlapsbeg[vertex];
    2104}
    2105
    2106/** @brief returns an index beyond the last overlap incident to \p vertex */
    2108 SCIP_HYPERGRAPH* hypergraph, /**< The hypergraph. */
    2109 SCIP_HYPERGRAPH_VERTEX vertex /**< A vertex. */
    2110 )
    2111{
    2112 assert(hypergraph);
    2113 assert(hypergraph->hasverticesoverlaps);
    2114
    2115 return hypergraph->verticesoverlapsbeg[vertex + 1];
    2116}
    2117
    2118/**
    2119 * @brief returns the overlap corresponding to \p idx that is incident to a vertex
    2120 *
    2121 * See \ref SCIPhypergraphVertexOverlapsFirst and \ref SCIPhypergraphVertexOverlapsBeyond to obtain such indices for a
    2122 * vertex.
    2123 */
    2125 SCIP_HYPERGRAPH* hypergraph, /**< The hypergraph. */
    2126 int idx /**< Index. */
    2127 )
    2128{
    2129 assert(hypergraph);
    2130 assert(hypergraph->hasverticesoverlaps);
    2131
    2132 return hypergraph->verticesoverlaps[idx];
    2133}
    2134
    2135#endif /* NDEBUG */
    SCIP_VAR * w
    Definition: circlepacking.c:67
    #define NULL
    Definition: def.h:248
    #define SCIP_Longint
    Definition: def.h:141
    #define SCIP_ALLOC_ABORT(x)
    Definition: def.h:345
    #define SCIP_Bool
    Definition: def.h:91
    #define SCIP_ALLOC(x)
    Definition: def.h:366
    #define TRUE
    Definition: def.h:93
    #define FALSE
    Definition: def.h:94
    #define MAX(x, y)
    Definition: def.h:220
    #define SCIP_CALL_ABORT(x)
    Definition: def.h:334
    #define SCIP_CALL(x)
    Definition: def.h:355
    void SCIPhashtableFree(SCIP_HASHTABLE **hashtable)
    Definition: misc.c:2348
    #define SCIPhashTwo(a, b)
    Definition: pub_misc.h:568
    #define SCIPhashFour(a, b, c, d)
    Definition: pub_misc.h:573
    #define SCIPhashThree(a, b, c)
    Definition: pub_misc.h:570
    SCIP_RETCODE SCIPhashtableCreate(SCIP_HASHTABLE **hashtable, BMS_BLKMEM *blkmem, int tablesize, SCIP_DECL_HASHGETKEY((*hashgetkey)), SCIP_DECL_HASHKEYEQ((*hashkeyeq)), SCIP_DECL_HASHKEYVAL((*hashkeyval)), void *userptr)
    Definition: misc.c:2298
    void * SCIPhashtableRetrieve(SCIP_HASHTABLE *hashtable, void *key)
    Definition: misc.c:2596
    SCIP_RETCODE SCIPhashtableInsert(SCIP_HASHTABLE *hashtable, void *element)
    Definition: misc.c:2535
    void SCIPsortLong(SCIP_Longint *longarray, int len)
    void SCIPsortInt(int *intarray, int len)
    void SCIPhypergraphIterStart(SCIP_HYPERGRAPH *hypergraph, SCIP_HYPERGRAPH_ITER *iterator, SCIP_HYPERGRAPH_EDGE base, unsigned int minoverlapsize, SCIP_Bool onlylater, SCIP_Bool findoverlaps)
    initializes the iterator to the first adjacent edge of base
    Definition: hypergraph.c:1506
    int SCIPhypergraphEdgesOverlapsBeyond(SCIP_HYPERGRAPH *hypergraph, SCIP_HYPERGRAPH_EDGE edge)
    returns an index beyond the last overlap incident to edge
    Definition: hypergraph.c:1995
    void SCIPhypergraphIterNext(SCIP_HYPERGRAPH *hypergraph, SCIP_HYPERGRAPH_ITER *iterator)
    initializes the iterator to the first adjacent edge of base
    Definition: hypergraph.c:1547
    static SCIP_RETCODE ensureNumEdgesVertices(SCIP_HYPERGRAPH *hypergraph, int required)
    enlarges arrays for incident vertex/edge pairs to have capacity for at least required
    Definition: hypergraph.c:113
    SCIP_RETCODE SCIPhypergraphFree(SCIP_HYPERGRAPH **phypergraph)
    frees a hypergraph
    Definition: hypergraph.c:281
    SCIP_HYPERGRAPH_EDGE SCIPhypergraphIterAdjacent(SCIP_HYPERGRAPH_ITER *iterator)
    returns the current adjacent edge
    Definition: hypergraph.c:1693
    SCIP_HYPERGRAPH_EDGE SCIPhypergraphIterBase(SCIP_HYPERGRAPH_ITER *iterator)
    returns the base edge
    Definition: hypergraph.c:1685
    SCIP_RETCODE SCIPhypergraphAddEdge(SCIP_HYPERGRAPH *hypergraph, int nvertices, SCIP_HYPERGRAPH_VERTEX *vertices, SCIP_HYPERGRAPH_EDGE *pedge, SCIP_HYPERGRAPH_EDGEDATA **pedgedata)
    adds a new edge to the hypergraph
    Definition: hypergraph.c:416
    static SCIP_DECL_HASHGETKEY(overlapHashGetKey)
    get-key function for overlap hashtable
    Definition: hypergraph.c:456
    SCIP_HYPERGRAPH_OVERLAP SCIPhypergraphIterOverlap(SCIP_HYPERGRAPH_ITER *iterator)
    returns the overlap for the intersection of the base and the current adjacent edge
    Definition: hypergraph.c:1714
    int SCIPhypergraphOverlapsEdgesBeyond(SCIP_HYPERGRAPH *hypergraph, SCIP_HYPERGRAPH_OVERLAP overlap)
    returns an index beyond the last edge incident to overlap
    Definition: hypergraph.c:2051
    void SCIPhypergraphIterClear(SCIP_HYPERGRAPH *hypergraph, SCIP_HYPERGRAPH_ITER *iterator)
    frees a hypergraph iterator's internal memory
    Definition: hypergraph.c:1494
    SCIP_HYPERGRAPH_EDGE SCIPhypergraphVertexEdgesGetAtIndex(SCIP_HYPERGRAPH *hypergraph, int idx)
    returns the edge corresponding to index that is incident to a vertex
    Definition: hypergraph.c:1921
    int SCIPhypergraphVertexEdgesBeyond(SCIP_HYPERGRAPH *hypergraph, SCIP_HYPERGRAPH_VERTEX vertex)
    returns an index beyond the last edge incident to vertex
    Definition: hypergraph.c:1905
    static SCIP_DECL_HASHKEYEQ(overlapHashKeyEqPtr)
    equality function for overlap hashtable
    Definition: hypergraph.c:463
    SCIP_RETCODE SCIPhypergraphIntersectEdges(SCIP_HYPERGRAPH *hypergraph, SCIP_HYPERGRAPH_EDGE first, SCIP_HYPERGRAPH_EDGE second, SCIP_HYPERGRAPH_OVERLAP *poverlap, SCIP_HYPERGRAPH_VERTEX *pvertex)
    finds the overlap or singleton vertex corresponding to the intersection of edges first and second
    Definition: hypergraph.c:929
    static SCIP_RETCODE ensureNumVertices(SCIP_HYPERGRAPH *hypergraph, int required)
    enlarges vertex arrays to have capacity for at least required vertices
    Definition: hypergraph.c:45
    SCIP_Bool SCIPhypergraphIterValid(SCIP_HYPERGRAPH_ITER *iterator)
    returns whether the iterator is valid
    Definition: hypergraph.c:1537
    int SCIPhypergraphGetNEdges(SCIP_HYPERGRAPH *hypergraph)
    returns the number of edges
    Definition: hypergraph.c:1774
    int SCIPhypergraphVertexOverlapsBeyond(SCIP_HYPERGRAPH *hypergraph, SCIP_HYPERGRAPH_VERTEX vertex)
    returns an index beyond the last overlap incident to vertex
    Definition: hypergraph.c:2107
    SCIP_RETCODE SCIPhypergraphComputeVerticesEdges(SCIP_HYPERGRAPH *hypergraph)
    computes each vertex' list of incident edges
    Definition: hypergraph.c:811
    SCIP_HYPERGRAPH_OVERLAPDATA * SCIPhypergraphOverlapData(SCIP_HYPERGRAPH *hypergraph, SCIP_HYPERGRAPH_OVERLAP overlap)
    returns additional data of overlap
    Definition: hypergraph.c:1838
    SCIP_RETCODE SCIPhypergraphAddVertex(SCIP_HYPERGRAPH *hypergraph, SCIP_HYPERGRAPH_VERTEX *pvertex, SCIP_HYPERGRAPH_VERTEXDATA **pvertexdata)
    adds a new vertex to the hypergraph
    Definition: hypergraph.c:386
    int SCIPhypergraphEdgeSize(SCIP_HYPERGRAPH *hypergraph, SCIP_HYPERGRAPH_EDGE edge)
    returns the number of vertices of edge
    Definition: hypergraph.c:1850
    static SCIP_RETCODE ensureNumOverlaps(SCIP_HYPERGRAPH *hypergraph, int required)
    enlarges overlap arrays to have capacity for at least required overlaps
    Definition: hypergraph.c:139
    SCIP_Bool SCIPhypergraphHasOverlapsEdges(SCIP_HYPERGRAPH *hypergraph)
    returns whether overlaps' incident edges are known.
    Definition: hypergraph.c:2029
    SCIP_Bool SCIPhypergraphOverlapsDisjoint(SCIP_HYPERGRAPH *hypergraph, SCIP_HYPERGRAPH_OVERLAP overlap1, SCIP_HYPERGRAPH_OVERLAP overlap2)
    returns whether overlaps overlap1 and overlap2 are disjoint
    Definition: hypergraph.c:1187
    SCIP_Bool SCIPhypergraphIsValid(SCIP_HYPERGRAPH *hypergraph, FILE *file)
    asserts that the hypergraph data structures are valid
    Definition: hypergraph.c:1221
    SCIP_RETCODE SCIPhypergraphOverlapFind(SCIP_HYPERGRAPH *hypergraph, int nvertices, SCIP_HYPERGRAPH_VERTEX *vertices, SCIP_HYPERGRAPH_OVERLAP *poverlap)
    finds the overlap corresponding to vertex set vertices; returns -1 if it is not found
    Definition: hypergraph.c:906
    static SCIP_RETCODE ensureNumEdges(SCIP_HYPERGRAPH *hypergraph, int required)
    enlarges edge arrays to have capacity for at least required edges
    Definition: hypergraph.c:73
    SCIP_RETCODE SCIPhypergraphClear(SCIP_HYPERGRAPH *hypergraph)
    clears a hypergraph, deleting all vertices and edges
    Definition: hypergraph.c:361
    SCIP_Bool SCIPhypergraphHasOverlaps(SCIP_HYPERGRAPH *hypergraph)
    returns whether edges' overlaps and overlaps' vertices are known.
    Definition: hypergraph.c:1937
    SCIP_Bool SCIPhypergraphHasVertexOverlaps(SCIP_HYPERGRAPH *hypergraph)
    returns whether vertices' incident overlaps are known
    Definition: hypergraph.c:2085
    SCIP_HYPERGRAPH_VERTEX * SCIPhypergraphEdgeVertices(SCIP_HYPERGRAPH *hypergraph, SCIP_HYPERGRAPH_EDGE edge)
    returns the array of vertices of edge
    Definition: hypergraph.c:1867
    int SCIPhypergraphEdgesOverlapsFirst(SCIP_HYPERGRAPH *hypergraph, SCIP_HYPERGRAPH_EDGE edge)
    returns an index for the first overlap incident to edge
    Definition: hypergraph.c:1982
    int SCIPhypergraphOverlapsEdgesFirst(SCIP_HYPERGRAPH *hypergraph, SCIP_HYPERGRAPH_OVERLAP overlap)
    returns an index for the first edge incident to overlap
    Definition: hypergraph.c:2039
    static SCIP_DECL_HASHKEYVAL(overlapHashKeyValPtr)
    hash function for overlap hashtable
    Definition: hypergraph.c:498
    SCIP_HYPERGRAPH_VERTEX SCIPhypergraphIterMinVertex(SCIP_HYPERGRAPH_ITER *iterator)
    returns the minimum vertex in the intersection of the base and the current adjacent edge
    Definition: hypergraph.c:1701
    SCIP_HYPERGRAPH_VERTEXDATA * SCIPhypergraphVertexData(SCIP_HYPERGRAPH *hypergraph, SCIP_HYPERGRAPH_VERTEX vertex)
    returns additional data of vertex
    Definition: hypergraph.c:1814
    SCIP_HYPERGRAPH_OVERLAP SCIPhypergraphVertexOverlapsGetAtIndex(SCIP_HYPERGRAPH *hypergraph, int idx)
    returns the overlap corresponding to idx that is incident to a vertex
    Definition: hypergraph.c:2124
    int SCIPhypergraphVertexOverlapsFirst(SCIP_HYPERGRAPH *hypergraph, SCIP_HYPERGRAPH_VERTEX vertex)
    returns an index for the first overlap containing vertex
    Definition: hypergraph.c:2095
    SCIP_RETCODE SCIPhypergraphComputeOverlapsEdges(SCIP_HYPERGRAPH *hypergraph)
    computes all overlaps' lists of incident edges
    Definition: hypergraph.c:990
    SCIP_HYPERGRAPH_OVERLAP SCIPhypergraphOverlapsEdgesGetAtIndex(SCIP_HYPERGRAPH *hypergraph, int idx)
    returns the edge corresponding to idx that is incident to an overlap
    Definition: hypergraph.c:2068
    SCIP_RETCODE SCIPhypergraphComputeOverlaps(SCIP_HYPERGRAPH *hypergraph, SCIP_DECL_HYPERGRAPH_OVERLAP((*handler)), void *userdata)
    computes all overlaps and stores overlaps' vertices and all edges' overlaps
    Definition: hypergraph.c:587
    SCIP_RETCODE SCIPhypergraphComputeVerticesOverlaps(SCIP_HYPERGRAPH *hypergraph)
    computes all vertices' lists of incident overlaps
    Definition: hypergraph.c:1091
    int SCIPhypergraphGetNIncidences(SCIP_HYPERGRAPH *hypergraph)
    returns the number of edge-vertex incidences
    Definition: hypergraph.c:1804
    SCIP_Bool SCIPhypergraphHasVertexEdges(SCIP_HYPERGRAPH *hypergraph)
    returns whether vertices' incident edges are known.
    Definition: hypergraph.c:1883
    int SCIPhypergraphGetNVertices(SCIP_HYPERGRAPH *hypergraph)
    returns the number of vertices
    Definition: hypergraph.c:1764
    SCIP_HYPERGRAPH_OVERLAP SCIPhypergraphEdgesOverlapsGetAtIndex(SCIP_HYPERGRAPH *hypergraph, int idx)
    returns the overlap corresponding to idx that is incident to an edge
    Definition: hypergraph.c:2013
    SCIP_RETCODE SCIPhypergraphIterInit(SCIP_HYPERGRAPH *hypergraph, SCIP_HYPERGRAPH_ITER *iterator)
    initializes a hypergraph iterator's internal memory
    Definition: hypergraph.c:1469
    static SCIP_RETCODE findOverlap(SCIP_HYPERGRAPH *hypergraph, int nvertices, int *vertices, int *poverlap, SCIP_Bool add, SCIP_Bool *padded)
    finds an overlap specified by a sorted vertex set, potentially adding it
    Definition: hypergraph.c:530
    int SCIPhypergraphVertexEdgesFirst(SCIP_HYPERGRAPH *hypergraph, SCIP_HYPERGRAPH_VERTEX vertex)
    returns an index for the first edge incident to vertex
    Definition: hypergraph.c:1893
    SCIP_HYPERGRAPH_VERTEX * SCIPhypergraphOverlapVertices(SCIP_HYPERGRAPH *hypergraph, SCIP_HYPERGRAPH_OVERLAP overlap)
    returns the array of sorted vertices of overlap
    Definition: hypergraph.c:1969
    int SCIPhypergraphOverlapSize(SCIP_HYPERGRAPH *hypergraph, SCIP_HYPERGRAPH_OVERLAP overlap)
    returns the number of vertices of overlap
    Definition: hypergraph.c:1951
    static SCIP_RETCODE ensureNumOverlapsVertices(SCIP_HYPERGRAPH *hypergraph, int required)
    enlarges overlapVertices array to have capacity for at least required overlaps' vertices
    Definition: hypergraph.c:185
    int SCIPhypergraphGetNOverlaps(SCIP_HYPERGRAPH *hypergraph)
    returns the number of overlaps
    Definition: hypergraph.c:1794
    SCIP_HYPERGRAPH_EDGEDATA * SCIPhypergraphEdgeData(SCIP_HYPERGRAPH *hypergraph, SCIP_HYPERGRAPH_EDGE edge)
    returns additional data of edge
    Definition: hypergraph.c:1826
    BMS_BLKMEM * SCIPhypergraphBlkmem(SCIP_HYPERGRAPH *hypergraph)
    returns the hypergraph's block memory structure
    Definition: hypergraph.c:1784
    SCIP_RETCODE SCIPhypergraphCreate(SCIP_HYPERGRAPH **phypergraph, BMS_BLKMEM *blkmem, int memvertices, int memedges, int memoverlaps, int memedgesvertices, size_t sizevertexdata, size_t sizeedgedata, size_t sizeoverlapdata)
    creates a hypergraph
    Definition: hypergraph.c:210
    Internal methods for dealing with hypergraphs.
    #define BMSfreeBlockMemory(mem, ptr)
    Definition: memory.h:465
    #define BMSallocBlockMemory(mem, ptr)
    Definition: memory.h:451
    #define BMSallocBlockMemoryArray(mem, ptr, num)
    Definition: memory.h:454
    #define BMSfreeBlockMemoryArray(mem, ptr, num)
    Definition: memory.h:467
    #define BMSreallocBlockMemoryArray(mem, ptr, oldnum, newnum)
    Definition: memory.h:458
    struct BMS_BlkMem BMS_BLKMEM
    Definition: memory.h:437
    internal miscellaneous methods
    public methods for message output
    #define SCIPdebugMessage
    Definition: pub_message.h:96
    unsigned int minoverlapsize
    SCIP_HYPERGRAPH_EDGE base
    SCIP_HYPERGRAPH_OVERLAP overlap
    SCIP_HYPERGRAPH_EDGE adjacent
    SCIP_HYPERGRAPH_VERTEX * commonvertices
    unsigned int onlylater
    unsigned int findoverlaps
    SCIP_HYPERGRAPH_VERTEX minvertex
    SCIP_Bool hasverticesoverlaps
    SCIP_HYPERGRAPH_EDGE * edgesvertices
    SCIP_HYPERGRAPH_OVERLAP * verticesoverlaps
    SCIP_HYPERGRAPH_VERTEX * verticesedges
    SCIP_Bool hasoverlapsedges
    SCIP_HYPERGRAPH_OVERLAP * edgesoverlaps
    BMS_BLKMEM * blkmem
    SCIP_HYPERGRAPH_VERTEX * overlapsvertices
    SCIP_Bool hasvertexedges
    SCIP_HYPERGRAPH_EDGE * overlapsedges
    SCIP_HASHTABLE * overlaphashtable
    datastructures hypergraphs
    int SCIP_HYPERGRAPH_EDGE
    int SCIP_HYPERGRAPH_OVERLAP
    struct SCIP_Hypergraph_OverlapData SCIP_HYPERGRAPH_OVERLAPDATA
    struct SCIP_Hypergraph_NodeData SCIP_HYPERGRAPH_VERTEXDATA
    #define SCIP_DECL_HYPERGRAPH_OVERLAP(x)
    int SCIP_HYPERGRAPH_VERTEX
    struct SCIP_Hypergraph_EdgeData SCIP_HYPERGRAPH_EDGEDATA
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    @ SCIP_ERROR
    Definition: type_retcode.h:43
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63