Path: blob/master/sage/graphs/planarity/graphK23Search_Extensions.c
4078 views
/*1Planarity-Related Graph Algorithms Project2Copyright (c) 1997-2010, John M. Boyer3All rights reserved. Includes a reference implementation of the following:45* John M. Boyer. "Simplified O(n) Algorithms for Planar Graph Embedding,6Kuratowski Subgraph Isolation, and Related Problems". Ph.D. Dissertation,7University of Victoria, 2001.89* John M. Boyer and Wendy J. Myrvold. "On the Cutting Edge: Simplified O(n)10Planarity by Edge Addition". Journal of Graph Algorithms and Applications,11Vol. 8, No. 3, pp. 241-273, 2004.1213* John M. Boyer. "A New Method for Efficiently Generating Planar Graph14Visibility Representations". In P. Eades and P. Healy, editors,15Proceedings of the 13th International Conference on Graph Drawing 2005,16Lecture Notes Comput. Sci., Volume 3843, pp. 508-511, Springer-Verlag, 2006.1718Redistribution and use in source and binary forms, with or without modification,19are permitted provided that the following conditions are met:2021* Redistributions of source code must retain the above copyright notice, this22list of conditions and the following disclaimer.2324* Redistributions in binary form must reproduce the above copyright notice, this25list of conditions and the following disclaimer in the documentation and/or26other materials provided with the distribution.2728* Neither the name of the Planarity-Related Graph Algorithms Project nor the names29of its contributors may be used to endorse or promote products derived from this30software without specific prior written permission.3132THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"33AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE34IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE35DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR36ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES37(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;38LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON39ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT40(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS41SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.42*/4344#include <stdlib.h>4546#include "graphK23Search.private.h"47#include "graphK23Search.h"4849extern int _SearchForK23(graphP theGraph, int I);5051extern int _TestForK23GraphObstruction(graphP theGraph, int *degrees, int *imageVerts);52extern int _getImageVertices(graphP theGraph, int *degrees, int maxDegree,53int *imageVerts, int maxNumImageVerts);54extern int _TestSubgraph(graphP theSubgraph, graphP theGraph);5556/* Forward declarations of overloading functions */5758int _K23Search_HandleBlockedEmbedIteration(graphP theGraph, int I);59int _K23Search_EmbedPostprocess(graphP theGraph, int I, int edgeEmbeddingResult);60int _K23Search_CheckEmbeddingIntegrity(graphP theGraph, graphP origGraph);61int _K23Search_CheckObstructionIntegrity(graphP theGraph, graphP origGraph);6263/* Forward declarations of functions used by the extension system */6465void *_K23Search_DupContext(void *pContext, void *theGraph);66void _K23Search_FreeContext(void *);6768/****************************************************************************69* K23SEARCH_ID - the variable used to hold the integer identifier for this70* extension, enabling this feature's extension context to be distinguished71* from other features' extension contexts that may be attached to a graph.72****************************************************************************/7374int K23SEARCH_ID = 0;7576/****************************************************************************77gp_AttachK23Search()7879This function adjusts the graph data structure to attach the K2,3 search80feature.81****************************************************************************/8283int gp_AttachK23Search(graphP theGraph)84{85K23SearchContext *context = NULL;8687// If the K2,3 search feature has already been attached to the graph88// then there is no need to attach it again89gp_FindExtension(theGraph, K23SEARCH_ID, (void *)&context);90if (context != NULL)91{92return OK;93}9495// Allocate a new extension context96context = (K23SearchContext *) malloc(sizeof(K23SearchContext));97if (context == NULL)98{99return NOTOK;100}101102// Put the overload functions into the context function table.103// gp_AddExtension will overload the graph's functions with these, and104// return the base function pointers in the context function table105memset(&context->functions, 0, sizeof(graphFunctionTable));106107context->functions.fpHandleBlockedEmbedIteration = _K23Search_HandleBlockedEmbedIteration;108context->functions.fpEmbedPostprocess = _K23Search_EmbedPostprocess;109context->functions.fpCheckEmbeddingIntegrity = _K23Search_CheckEmbeddingIntegrity;110context->functions.fpCheckObstructionIntegrity = _K23Search_CheckObstructionIntegrity;111112// Store the K23 search context, including the data structure and the113// function pointers, as an extension of the graph114if (gp_AddExtension(theGraph, &K23SEARCH_ID, (void *) context,115_K23Search_DupContext, _K23Search_FreeContext,116&context->functions) != OK)117{118_K23Search_FreeContext(context);119return NOTOK;120}121122return OK;123}124125/********************************************************************126gp_DetachK23Search()127********************************************************************/128129int gp_DetachK23Search(graphP theGraph)130{131return gp_RemoveExtension(theGraph, K23SEARCH_ID);132}133134/********************************************************************135_K23Search_DupContext()136********************************************************************/137138void *_K23Search_DupContext(void *pContext, void *theGraph)139{140K23SearchContext *context = (K23SearchContext *) pContext;141K23SearchContext *newContext = (K23SearchContext *) malloc(sizeof(K23SearchContext));142143if (newContext != NULL)144{145*newContext = *context;146}147148return newContext;149}150151/********************************************************************152_K23Search_FreeContext()153********************************************************************/154155void _K23Search_FreeContext(void *pContext)156{157free(pContext);158}159160/********************************************************************161********************************************************************/162163int _K23Search_HandleBlockedEmbedIteration(graphP theGraph, int I)164{165if (theGraph->embedFlags == EMBEDFLAGS_SEARCHFORK23)166return _SearchForK23(theGraph, I);167168else169{170K23SearchContext *context = NULL;171gp_FindExtension(theGraph, K23SEARCH_ID, (void *)&context);172173if (context != NULL)174{175return context->functions.fpHandleBlockedEmbedIteration(theGraph, I);176}177}178179return NOTOK;180}181182/********************************************************************183********************************************************************/184185int _K23Search_EmbedPostprocess(graphP theGraph, int I, int edgeEmbeddingResult)186{187// For K2,3 search, we just return the edge embedding result because the188// search result has been obtained already.189if (theGraph->embedFlags == EMBEDFLAGS_SEARCHFORK23)190{191return edgeEmbeddingResult;192}193194// When not searching for K2,3, we let the superclass do the work195else196{197K23SearchContext *context = NULL;198gp_FindExtension(theGraph, K23SEARCH_ID, (void *)&context);199200if (context != NULL)201{202return context->functions.fpEmbedPostprocess(theGraph, I, edgeEmbeddingResult);203}204}205206return NOTOK;207}208209/********************************************************************210********************************************************************/211212int _K23Search_CheckEmbeddingIntegrity(graphP theGraph, graphP origGraph)213{214if (theGraph->embedFlags == EMBEDFLAGS_SEARCHFORK23)215{216return OK;217}218219// When not searching for K2,3, we let the superclass do the work220else221{222K23SearchContext *context = NULL;223gp_FindExtension(theGraph, K23SEARCH_ID, (void *)&context);224225if (context != NULL)226{227return context->functions.fpCheckEmbeddingIntegrity(theGraph, origGraph);228}229}230231return NOTOK;232}233234/********************************************************************235********************************************************************/236237int _K23Search_CheckObstructionIntegrity(graphP theGraph, graphP origGraph)238{239// When searching for K2,3, we ensure that theGraph is a subgraph of240// the original graph and that it contains a K2,3 homeomorph241if (theGraph->embedFlags == EMBEDFLAGS_SEARCHFORK23)242{243int degrees[4], imageVerts[5];244245if (_TestSubgraph(theGraph, origGraph) != TRUE)246return NOTOK;247248if (_getImageVertices(theGraph, degrees, 3, imageVerts, 5) != OK)249return NOTOK;250251if (_TestForK23GraphObstruction(theGraph, degrees, imageVerts) == TRUE)252{253return OK;254}255256return NOTOK;257}258259// When not searching for K2,3, we let the superclass do the work260else261{262K23SearchContext *context = NULL;263gp_FindExtension(theGraph, K23SEARCH_ID, (void *)&context);264265if (context != NULL)266{267return context->functions.fpCheckObstructionIntegrity(theGraph, origGraph);268}269}270271return NOTOK;272}273274275