123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833 |
- #include "GCoptimization.h"
- #include "LinkedBlockList.h"
- #include <stdio.h>
- #include <time.h>
- #include <stdlib.h>
- using namespace OBJREC;
- // will leave this one just for the laughs :)
- //#define olga_assert(expr) assert(!(expr))
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // First we have functions for the base class
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // Constructor for base class
- GCoptimization::GCoptimization(SiteID nSites, LabelID nLabels)
- : m_datacostIndividual(0)
- , m_smoothcostIndividual(0)
- , m_smoothcostFn(0)
- , m_datacostFn(0)
- , m_set_up_t_links_swap(0)
- , m_set_up_t_links_expansion(0)
- , m_set_up_n_links_swap(0)
- , m_set_up_n_links_expansion(0)
- , m_giveSmoothEnergyInternal(0)
- , m_giveDataEnergyInternal(0)
- , m_datacostFnDelete(0)
- , m_smoothcostFnDelete(0)
- , m_random_label_order(false)
- {
- assert( nLabels > 1 && nSites > 0);
- m_num_labels = nLabels;
- m_num_sites = nSites;
- m_lookupSiteVar = (SiteID *) new SiteID[m_num_sites];
- m_labelTable = (LabelID *) new LabelID[m_num_labels];
- m_labeling = (LabelID *) new LabelID[m_num_sites];
- if ( !m_lookupSiteVar || !m_labelTable || !m_labeling) {
- if (m_lookupSiteVar) delete [] m_lookupSiteVar;
- if (m_labelTable) delete [] m_labelTable;
- if (m_labeling) delete [] m_labeling;
- handleError("Not enough memory");
- }
- for ( LabelID i = 0; i < m_num_labels; i++ )
- m_labelTable[i] = i;
- for ( SiteID i = 0; i < m_num_sites; i++ ) {
- m_labeling[i] = (LabelID) 0;
- m_lookupSiteVar[i] = (SiteID) - 1;
- }
- srand((unsigned int) time(NULL));
- }
- //-------------------------------------------------------------------
- GCoptimization::~GCoptimization()
- {
- delete [] m_labelTable;
- delete [] m_lookupSiteVar;
- delete [] m_labeling;
- if (m_datacostFnDelete) m_datacostFnDelete(m_datacostFn);
- if (m_smoothcostFnDelete) m_smoothcostFnDelete(m_smoothcostFn);
- if (m_datacostIndividual) delete [] m_datacostIndividual;
- if (m_smoothcostIndividual) delete [] m_smoothcostIndividual;
- }
- //------------------------------------------------------------------
- void GCoptimization::setDataCost(DataCostFn fn) {
- specializeDataCostFunctor(DataCostFnFromFunction(fn));
- }
- //------------------------------------------------------------------
- void GCoptimization::setDataCost(DataCostFnExtra fn, void *extraData) {
- specializeDataCostFunctor(DataCostFnFromFunctionExtra(fn, extraData));
- }
- //-------------------------------------------------------------------
- void GCoptimization::setDataCost(EnergyTermType *dataArray) {
- specializeDataCostFunctor(DataCostFnFromArray(dataArray, m_num_labels));
- }
- //-------------------------------------------------------------------
- void GCoptimization::setDataCost(SiteID s, LabelID l, EnergyTermType e) {
- if (!m_datacostIndividual) {
- if ( m_datacostFn ) handleError("Data Costs are already initialized");
- m_datacostIndividual = new EnergyTermType[m_num_sites*m_num_labels];
- memset(m_datacostIndividual, 0, m_num_sites*m_num_labels*sizeof(EnergyTermType));
- specializeDataCostFunctor(DataCostFnFromArray(m_datacostIndividual, m_num_labels));
- }
- m_datacostIndividual[s*m_num_labels + l] = e;
- }
- //-------------------------------------------------------------------
- void GCoptimization::setDataCostFunctor(DataCostFunctor* f) {
- if ( m_datacostFn ) handleError("Data Costs are already initialized");
- m_datacostFn = f;
- m_giveDataEnergyInternal = &GCoptimization::giveDataEnergyInternal<DataCostFunctor>;
- m_set_up_t_links_expansion = &GCoptimization::set_up_t_links_expansion<DataCostFunctor>;
- m_set_up_t_links_swap = &GCoptimization::set_up_t_links_swap<DataCostFunctor>;
- }
- //-------------------------------------------------------------------
- void GCoptimization::setSmoothCost(SmoothCostFn fn) {
- specializeSmoothCostFunctor(SmoothCostFnFromFunction(fn));
- }
- //-------------------------------------------------------------------
- void GCoptimization::setSmoothCost(SmoothCostFnExtra fn, void* extraData) {
- specializeSmoothCostFunctor(SmoothCostFnFromFunctionExtra(fn, extraData));
- }
- //-------------------------------------------------------------------
- void GCoptimization::setSmoothCost(EnergyTermType *smoothArray) {
- specializeSmoothCostFunctor(SmoothCostFnFromArray(smoothArray, m_num_labels));
- }
- //-------------------------------------------------------------------
- void GCoptimization::setSmoothCost(LabelID l1, GCoptimization::LabelID l2, EnergyTermType e) {
- if (!m_smoothcostIndividual) {
- if ( m_smoothcostFn ) handleError("Smoothness Costs are already initialized");
- m_smoothcostIndividual = new EnergyTermType[m_num_labels*m_num_labels];
- memset(m_smoothcostIndividual, 0, m_num_labels*m_num_labels*sizeof(EnergyTermType));
- specializeSmoothCostFunctor(SmoothCostFnFromArray(m_smoothcostIndividual, m_num_labels));
- }
- m_smoothcostIndividual[l1*m_num_labels + l2] = e;
- }
- //-------------------------------------------------------------------
- void GCoptimization::setSmoothCostFunctor(SmoothCostFunctor* f) {
- if ( m_smoothcostFn ) handleError("Smoothness Costs are already initialized");
- m_smoothcostFn = f;
- m_giveSmoothEnergyInternal = &GCoptimization::giveSmoothEnergyInternal<SmoothCostFunctor>;
- m_set_up_n_links_expansion = &GCoptimization::set_up_n_links_expansion<SmoothCostFunctor>;
- m_set_up_n_links_swap = &GCoptimization::set_up_n_links_swap<SmoothCostFunctor>;
- }
- //-------------------------------------------------------------------
- GCoptimization::EnergyType GCoptimization::giveSmoothEnergy()
- {
- if (readyToOptimise())
- return( (this->*m_giveSmoothEnergyInternal)() );
- else {
- handleError("Not ready to optimize yet. Set up data and smooth costs first");
- return(0);
- }
- }
- //-------------------------------------------------------------------
- GCoptimization::EnergyType GCoptimization::giveDataEnergy()
- {
- if (readyToOptimise())
- return( (this->*m_giveDataEnergyInternal)() );
- else {
- handleError("Not ready to optimize yet. Set up data and smooth costs first");
- return(0);
- }
- }
- //-------------------------------------------------------------------
- GCoptimization::EnergyType GCoptimization::compute_energy()
- {
- if (readyToOptimise())
- return( (this->*m_giveDataEnergyInternal)() + (this->*m_giveSmoothEnergyInternal)());
- else {
- handleError("Not ready to optimize yet. Set up data and smooth costs first");
- return(0);
- }
- }
- //-------------------------------------------------------------------
- void GCoptimization::scramble_label_table()
- {
- LabelID r1, r2, temp;
- LabelID num_times, cnt;
- num_times = m_num_labels;
- for ( cnt = 0; cnt < num_times; cnt++ )
- {
- r1 = rand() % m_num_labels;
- r2 = rand() % m_num_labels;
- temp = m_labelTable[r1];
- m_labelTable[r1] = m_labelTable[r2];
- m_labelTable[r2] = temp;
- }
- }
- //-------------------------------------------------------------------
- GCoptimization::EnergyType GCoptimization::expansion(int max_num_iterations )
- {
- int curr_cycle = 1;
- EnergyType new_energy, old_energy;
- new_energy = compute_energy();
- old_energy = new_energy + 1;
- while ( old_energy > new_energy && curr_cycle <= max_num_iterations)
- {
- old_energy = new_energy;
- new_energy = oneExpansionIteration();
- curr_cycle++;
- }
- return(new_energy);
- }
- //-------------------------------------------------------------------
- void GCoptimization::setLabelOrder(bool RANDOM_LABEL_ORDER)
- {
- m_random_label_order = RANDOM_LABEL_ORDER;
- }
- //-------------------------------------------------------------------
- bool GCoptimization::readyToOptimise()
- {
- if (!m_smoothcostFn)
- {
- handleError("Smoothness term is not set up yet!");
- return(false);
- }
- if (!m_datacostFn)
- {
- handleError("Data term is not set up yet!");
- return(false);
- }
- return(true);
- }
- //------------------------------------------------------------------
- void GCoptimization::handleError(const char *message)
- {
- throw GCException(message);
- }
- //-------------------------------------------------------------------//
- // METHODS for EXPANSION MOVES //
- //-------------------------------------------------------------------//
- void GCoptimization::set_up_expansion_energy(SiteID size, LabelID alpha_label, Energy *e,
- VarID *variables, SiteID *activeSites )
- {
- (this->*m_set_up_t_links_expansion)(size, alpha_label, e, variables, activeSites);
- (this->*m_set_up_n_links_expansion)(size, alpha_label, e, variables, activeSites);
- }
- //-------------------------------------------------------------------
- // Sets up the energy and optimizes it. Also updates labels of sites, if needed. ActiveSites
- // are the sites participating in expansion. They are not labeled alpha currrently
- void GCoptimization::solveExpansion(SiteID size, SiteID *activeSites, LabelID alpha_label)
- {
- SiteID i, site;
- if ( !readyToOptimise() ) handleError("Set up data and smoothness terms first. ");
- if ( size == 0 ) return;
- Energy *e = new Energy();
- Energy::Var *variables = (Energy::Var *) new Energy::Var[size];
- for ( i = 0; i < size; i++ )
- variables[i] = e ->add_variable();
- set_up_expansion_energy(size, alpha_label, e, variables, activeSites);
- Energy::TotalValue Emin = e -> minimize();
- for ( i = 0; i < size; i++ )
- {
- site = activeSites[i];
- if ( m_labeling[site] != alpha_label )
- {
- if ( e->get_var(variables[i]) == 0 )
- {
- m_labeling[site] = alpha_label;
- }
- }
- m_lookupSiteVar[site] = -1;
- }
- delete [] variables;
- delete e;
- }
- //-------------------------------------------------------------------
- // alpha expansion on all sites not currently labeled alpha
- void GCoptimization::alpha_expansion(LabelID alpha_label)
- {
- SiteID i = 0, size = 0;
- assert( alpha_label >= 0 && alpha_label < m_num_labels);
- SiteID *activeSites = new SiteID[m_num_sites];
- for ( i = 0; i < m_num_sites; i++ )
- {
- if ( m_labeling[i] != alpha_label )
- {
- activeSites[size] = i;
- m_lookupSiteVar[i] = size;
- size++;
- }
- }
- solveExpansion(size, activeSites, alpha_label);
- delete [] activeSites;
- }
- //-------------------------------------------------------------------
- // alpha expansion on subset of sites in array *sites
- void GCoptimization::alpha_expansion(LabelID alpha_label, SiteID *sites, SiteID num )
- {
- SiteID i, size = 0;
- SiteID *activeSites = new SiteID[num];
- for ( i = 0; i < num; i++ )
- {
- if ( m_labeling[sites[i]] != alpha_label )
- {
- m_lookupSiteVar[sites[i]] = size;
- activeSites[size] = sites[i];
- size++;
- }
- }
- solveExpansion(size, activeSites, alpha_label);
- delete [] activeSites;
- }
- //-------------------------------------------------------------------
- GCoptimization::EnergyType GCoptimization::oneExpansionIteration()
- {
- LabelID next;
- if (m_random_label_order) scramble_label_table();
- for (next = 0; next < m_num_labels; next++ )
- {
- alpha_expansion(m_labelTable[next]);
- }
- return(compute_energy());
- }
- //-------------------------------------------------------------------//
- // METHODS for SWAP MOVES //
- //-------------------------------------------------------------------//
- GCoptimization::EnergyType GCoptimization::swap(int max_num_iterations )
- {
- int curr_cycle = 1;
- EnergyType new_energy, old_energy;
- new_energy = compute_energy();
- old_energy = new_energy + 1;
- while ( old_energy > new_energy && curr_cycle <= max_num_iterations)
- {
- old_energy = new_energy;
- new_energy = oneSwapIteration();
- curr_cycle++;
- }
- return(new_energy);
- }
- //--------------------------------------------------------------------------------
- GCoptimization::EnergyType GCoptimization::oneSwapIteration()
- {
- LabelID next, next1;
- if (m_random_label_order) scramble_label_table();
- for (next = 0; next < m_num_labels; next++ )
- for (next1 = m_num_labels - 1; next1 >= 0; next1-- )
- if ( m_labelTable[next] < m_labelTable[next1] )
- alpha_beta_swap(m_labelTable[next], m_labelTable[next1]);
- return(compute_energy());
- }
- //---------------------------------------------------------------------------------
- void GCoptimization::alpha_beta_swap(LabelID alpha_label, LabelID beta_label)
- {
- assert( alpha_label >= 0 && alpha_label < m_num_labels && beta_label >= 0 && beta_label < m_num_labels);
- SiteID i = 0, size = 0;
- SiteID *activeSites = new SiteID[m_num_sites];
- for ( i = 0; i < m_num_sites; i++ ) {
- if ( m_labeling[i] == alpha_label || m_labeling[i] == beta_label ) {
- activeSites[size] = i;
- m_lookupSiteVar[i] = size;
- size++;
- }
- }
- solveSwap(size, activeSites, alpha_label, beta_label);
- delete [] activeSites;
- }
- //-----------------------------------------------------------------------------------
- void GCoptimization::alpha_beta_swap(LabelID alpha_label, LabelID beta_label,
- SiteID *alphaSites, SiteID alpha_size, SiteID *betaSites,
- SiteID beta_size)
- {
- assert( !(alpha_label < 0 || alpha_label >= m_num_labels || beta_label < 0 || beta_label >= m_num_labels) );
- SiteID i, site, size = 0;
- SiteID *activeSites = new SiteID[alpha_size+beta_size];
- for ( i = 0; i < alpha_size; i++ )
- {
- site = alphaSites[i];
- assert(site >= 0 && site < m_num_sites );
- assert(m_labeling[site] == alpha_label);
- activeSites[size] = site;
- m_lookupSiteVar[site] = size;
- size++;
- }
- for ( i = 0; i < beta_size; i++ )
- {
- site = betaSites[i];
- assert(site >= 0 && site < m_num_sites );
- assert(m_labeling[site] == beta_label);
- activeSites[size] = site;
- m_lookupSiteVar[site] = size;
- size++;
- }
- solveSwap(size, activeSites, alpha_label, beta_label);
- delete [] activeSites;
- }
- //-----------------------------------------------------------------------------------
- void GCoptimization::solveSwap(SiteID size, SiteID *activeSites, LabelID alpha_label,
- LabelID beta_label)
- {
- SiteID i, site;
- if ( !readyToOptimise() ) handleError("Set up data and smoothness terms first. ");
- if ( size == 0 ) return;
- Energy *e = new Energy();
- Energy::Var *variables = (Energy::Var *) new Energy::Var[size];
- for ( i = 0; i < size; i++ )
- variables[i] = e ->add_variable();
- set_up_swap_energy(size, alpha_label, beta_label, e, variables, activeSites);
- Energy::TotalValue Emin = e -> minimize();
- for ( i = 0; i < size; i++ )
- {
- site = activeSites[i];
- if ( e->get_var(variables[i]) == 0 )
- m_labeling[site] = alpha_label;
- else m_labeling[site] = beta_label;
- m_lookupSiteVar[site] = -1;
- }
- delete [] variables;
- delete e;
- }
- //-----------------------------------------------------------------------------------
- void GCoptimization::set_up_swap_energy(SiteID size, LabelID alpha_label, LabelID beta_label,
- Energy* e, Energy::Var *variables, SiteID *activeSites)
- {
- (this->*m_set_up_t_links_swap)(size, alpha_label, beta_label, e, variables, activeSites);
- (this->*m_set_up_n_links_swap)(size, alpha_label, beta_label, e, variables, activeSites);
- }
- //////////////////////////////////////////////////////////////////////////////////////////////////
- // Functions for the GCoptimizationGridGraph, derived from GCoptimization
- ////////////////////////////////////////////////////////////////////////////////////////////////////
- GCoptimizationGridGraph::GCoptimizationGridGraph(SiteID width, SiteID height, LabelID num_labels)
- : GCoptimization(width*height, num_labels)
- {
- assert( (width > 1) && (height > 1) && (num_labels > 1 ));
- m_weightedGraph = 0;
- for (int i = 0; i < 4; i ++ ) m_unityWeights[i] = 1;
- m_width = width;
- m_height = height;
- m_numNeighbors = new SiteID[m_num_sites];
- m_neighbors = new SiteID[4*m_num_sites];
- SiteID indexes[4] = { -1, 1, -m_width, m_width};
- SiteID indexesL[3] = {1, -m_width, m_width};
- SiteID indexesR[3] = { -1, -m_width, m_width};
- SiteID indexesU[3] = {1, -1, m_width};
- SiteID indexesD[3] = {1, -1, -m_width};
- SiteID indexesUL[2] = {1, m_width};
- SiteID indexesUR[2] = { -1, m_width};
- SiteID indexesDL[2] = {1, -m_width};
- SiteID indexesDR[2] = { -1, -m_width};
- setupNeighbData(1, m_height - 1, 1, m_width - 1, 4, indexes);
- setupNeighbData(1, m_height - 1, 0, 1, 3, indexesL);
- setupNeighbData(1, m_height - 1, m_width - 1, m_width, 3, indexesR);
- setupNeighbData(0, 1, 1, width - 1, 3, indexesU);
- setupNeighbData(m_height - 1, m_height, 1, m_width - 1, 3, indexesD);
- setupNeighbData(0, 1, 0, 1, 2, indexesUL);
- setupNeighbData(0, 1, m_width - 1, m_width, 2, indexesUR);
- setupNeighbData(m_height - 1, m_height, 0, 1, 2, indexesDL);
- setupNeighbData(m_height - 1, m_height, m_width - 1, m_width, 2, indexesDR);
- }
- //-------------------------------------------------------------------
- GCoptimizationGridGraph::~GCoptimizationGridGraph()
- {
- delete [] m_numNeighbors;
- delete [] m_neighbors;
- if (m_weightedGraph) delete [] m_neighborsWeights;
- }
- //-------------------------------------------------------------------
- void GCoptimizationGridGraph::setupNeighbData(SiteID startY, SiteID endY, SiteID startX,
- SiteID endX, SiteID maxInd, SiteID *indexes)
- {
- SiteID x, y, pix;
- SiteID n;
- for ( y = startY; y < endY; y++ )
- for ( x = startX; x < endX; x++ )
- {
- pix = x + y * m_width;
- m_numNeighbors[pix] = maxInd;
- for (n = 0; n < maxInd; n++ )
- m_neighbors[pix*4+n] = pix + indexes[n];
- }
- }
- //-------------------------------------------------------------------
- bool GCoptimizationGridGraph::readyToOptimise()
- {
- GCoptimization::readyToOptimise();
- return(true);
- }
- //-------------------------------------------------------------------
- void GCoptimizationGridGraph::setSmoothCostVH(EnergyTermType *smoothArray, EnergyTermType *vCosts, EnergyTermType *hCosts)
- {
- setSmoothCost(smoothArray);
- m_weightedGraph = 1;
- computeNeighborWeights(vCosts, hCosts);
- }
- //-------------------------------------------------------------------
- void GCoptimizationGridGraph::giveNeighborInfo(SiteID site, SiteID *numSites, SiteID **neighbors, EnergyTermType **weights)
- {
- *numSites = m_numNeighbors[site];
- *neighbors = &m_neighbors[site*4];
- if (m_weightedGraph) *weights = &m_neighborsWeights[site*4];
- else *weights = m_unityWeights;
- }
- //-------------------------------------------------------------------
- void GCoptimizationGridGraph::computeNeighborWeights(EnergyTermType *vCosts, EnergyTermType *hCosts)
- {
- SiteID i, n, nSite;
- GCoptimization::EnergyTermType weight;
- m_neighborsWeights = new EnergyTermType[m_num_sites*4];
- for ( i = 0; i < m_num_sites; i++ )
- {
- for ( n = 0; n < m_numNeighbors[i]; n++ )
- {
- nSite = m_neighbors[4*i+n];
- if ( i - nSite == 1 ) weight = hCosts[nSite];
- else if (i - nSite == -1 ) weight = hCosts[i];
- else if ( i - nSite == m_width ) weight = vCosts[nSite];
- else if (i - nSite == -m_width ) weight = vCosts[i];
- m_neighborsWeights[i*4+n] = weight;
- }
- }
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////
- // Functions for the GCoptimizationGeneralGraph, derived from GCoptimization
- ////////////////////////////////////////////////////////////////////////////////////////////////////
- GCoptimizationGeneralGraph::GCoptimizationGeneralGraph(SiteID num_sites, LabelID num_labels): GCoptimization(num_sites, num_labels)
- {
- assert( num_sites > 1 && num_labels > 1 );
- m_neighborsIndexes = 0;
- m_neighborsWeights = 0;
- m_numNeighbors = 0;
- m_neighbors = 0;
- m_needTodeleteNeighbors = true;
- m_needToFinishSettingNeighbors = true;
- }
- //------------------------------------------------------------------
- GCoptimizationGeneralGraph::~GCoptimizationGeneralGraph()
- {
- if ( m_neighbors ) {
- delete [] m_neighbors;
- }
- if ( m_numNeighbors && m_needTodeleteNeighbors )
- {
- for ( SiteID i = 0; i < m_num_sites; i++ )
- {
- if (m_numNeighbors[i] != 0 )
- {
- delete [] m_neighborsIndexes[i];
- delete [] m_neighborsWeights[i];
- }
- }
- delete [] m_numNeighbors;
- delete [] m_neighborsIndexes;
- delete [] m_neighborsWeights;
- }
- }
- //-------------------------------------------------------------------
- bool GCoptimizationGeneralGraph::readyToOptimise()
- {
- GCoptimization::readyToOptimise();
- if (m_needToFinishSettingNeighbors) finishSettingNeighbors();
- return(true);
- }
- //------------------------------------------------------------------
- void GCoptimizationGeneralGraph::finishSettingNeighbors()
- {
- Neighbor *tmp;
- SiteID i, site, count;
- m_needToFinishSettingNeighbors = false;
- EnergyTermType *tempWeights = new EnergyTermType[m_num_sites];
- SiteID *tempIndexes = new SiteID[m_num_sites];
- if ( !tempWeights || !tempIndexes ) handleError("Not enough memory");
- m_numNeighbors = new SiteID[m_num_sites];
- m_neighborsIndexes = new SiteID*[m_num_sites];
- m_neighborsWeights = new EnergyTermType*[m_num_sites];
- if ( !m_numNeighbors || !m_neighborsIndexes || !m_neighborsWeights ) handleError("Not enough memory");
- for ( site = 0; site < m_num_sites; site++ )
- {
- if ( !m_neighbors[site].isEmpty() )
- {
- m_neighbors[site].setCursorFront();
- count = 0;
- while ( m_neighbors[site].hasNext() )
- {
- tmp = (Neighbor *) (m_neighbors[site].next());
- tempIndexes[count] = tmp->to_node;
- tempWeights[count] = tmp->weight;
- delete tmp;
- count++;
- }
- m_numNeighbors[site] = count;
- m_neighborsIndexes[site] = new SiteID[count];
- m_neighborsWeights[site] = new EnergyTermType[count];
- if ( !m_neighborsIndexes[site] || !m_neighborsWeights[site] ) handleError("Not enough memory");
- for ( i = 0; i < count; i++ )
- {
- m_neighborsIndexes[site][i] = tempIndexes[i];
- m_neighborsWeights[site][i] = tempWeights[i];
- }
- }
- else m_numNeighbors[site] = 0;
- }
- delete [] tempIndexes;
- delete [] tempWeights;
- delete [] m_neighbors;
- m_neighbors = (LinkedBlockList *) new LinkedBlockList[1];
- // this signals that the neibhorhood system is set, in case user calls setAllNeighbors
- }
- //------------------------------------------------------------------------------
- void GCoptimizationGeneralGraph::giveNeighborInfo(SiteID site, SiteID *numSites,
- SiteID **neighbors, EnergyTermType **weights)
- {
- (*numSites) = m_numNeighbors[site];
- (*neighbors) = m_neighborsIndexes[site];
- (*weights) = m_neighborsWeights[site];
- }
- //------------------------------------------------------------------
- void GCoptimizationGeneralGraph::setNeighbors(SiteID site1, SiteID site2, EnergyTermType weight)
- {
- assert( site1 < m_num_sites && site1 >= 0 && site2 < m_num_sites && site2 >= 0);
- if ( m_needToFinishSettingNeighbors == false ) handleError("Already set up neighborhood system");
- if ( !m_neighbors )
- {
- m_neighbors = (LinkedBlockList *) new LinkedBlockList[m_num_sites];
- if ( !m_neighbors ) handleError("Not enough memory");
- }
- Neighbor *temp1 = (Neighbor *) new Neighbor;
- Neighbor *temp2 = (Neighbor *) new Neighbor;
- temp1->weight = weight;
- temp1->to_node = site2;
- temp2->weight = weight;
- temp2->to_node = site1;
- m_neighbors[site1].addFront(temp1);
- m_neighbors[site2].addFront(temp2);
- }
- //------------------------------------------------------------------
- void GCoptimizationGeneralGraph::setAllNeighbors(SiteID *numNeighbors, SiteID **neighborsIndexes,
- EnergyTermType **neighborsWeights)
- {
- m_needTodeleteNeighbors = false;
- m_needToFinishSettingNeighbors = false;
- if ( m_neighbors ) handleError("Already set up neighborhood system");
- m_numNeighbors = numNeighbors;
- m_neighborsIndexes = neighborsIndexes;
- m_neighborsWeights = neighborsWeights;
- }
|