コード例 #1
1
ファイル: IntermediateAssets.cpp プロジェクト: Clever-Boy/XLE
    static std::shared_ptr<RetainedFileRecord> GetRetainedFileRecord(StringSection<ResChar> filename)
    {
            //  We should normalize to avoid problems related to
            //  case insensitivity and slash differences
        ResolvedAssetFile assetName;
        MakeAssetName(assetName, filename);
        auto hash = Hash64(assetName._fn);

        {
            ScopedLock(RetainedRecordsLock);
            auto i = LowerBound(RetainedRecords, hash);
            if (i!=RetainedRecords.end() && i->first == hash) {
                return i->second;
            }

                //  we should call "AttachFileSystemMonitor" before we query for the
                //  file's current modification time
            auto newRecord = std::make_shared<RetainedFileRecord>(assetName._fn);
            RegisterFileDependency(newRecord, assetName._fn);
            newRecord->_state._timeMarker = GetFileModificationTime(assetName._fn);

            RetainedRecords.insert(i, std::make_pair(hash, newRecord));
            return std::move(newRecord);
        }
    }
コード例 #2
0
int main(int argc, char *argv[]) {
  IMP::base::setup_from_argv(argc, argv, "Test of base caches in C++");
  IMP_NEW(IMP::kernel::Model, m, ());
  IMP::kernel::ParticleIndexes pis;
  IMP::algebra::BoundingBox3D bb = IMP::algebra::get_unit_bounding_box_d<3>();
  for (unsigned int i = 0; i < num_particles; ++i) {
    pis.push_back(m->add_particle("P%1%"));
    IMP::core::XYZR::setup_particle(
        m, pis.back(),
        IMP::algebra::Sphere3D(IMP::algebra::get_random_vector_in(bb), radius));
  }
  IMP_NEW(IMP::core::GridClosePairsFinder, gcpf, ());
  gcpf->set_distance(.1);
  IMP::base::PointerMember<IMP::core::ClosePairsFinder> mcpf =
      IMP::misc::create_metric_close_pairs_finder(LowerBound(), UpperBound());
  mcpf->set_distance(.1);

  IMP::kernel::ParticleIndexPairs gcp = gcpf->get_close_pairs(m, pis);
  canonicalize(gcp);
  IMP::kernel::ParticleIndexPairs mcp = mcpf->get_close_pairs(m, pis);
  canonicalize(mcp);
  std::sort(gcp.begin(), gcp.end());
  std::sort(mcp.begin(), mcp.end());
  std::cout << "Lists are " << gcp << " and " << mcp << std::endl;
  IMP::kernel::ParticleIndexPairs out;
  std::set_intersection(gcp.begin(), gcp.end(), mcp.begin(), mcp.end(),
                        std::back_inserter(out));
  IMP_TEST_EQUAL(out.size(), mcp.size());
  IMP_TEST_EQUAL(out.size(), gcp.size());
  return 0;
}
コード例 #3
0
ファイル: 1_3.c プロジェクト: lvniqi/BOP
void Search(int step){
    int i,nEstimate;
    m_nSearch++;
    //估计这次搜索所需要的最小交换次数
    nEstimate = LowerBound(m_ReverseArray,m_nCakeCnt);
    //超过最大交换次数 退出
    if(step+nEstimate > m_nMaxSwap){
        return;
    }
    //如果已经排完序 直接输出结果
    if(isSorted(m_ReverseArray,m_nCakeCnt)){
        if(step < m_nMaxSwap){
            m_nMaxSwap = step;
            int i;
            for(i=0;i<m_nMaxSwap;i++){
                m_SwapArray[i] = m_ReverseSwapArray[i];
            }
        }
        return;
    }
    //递归进行翻转
    for(i=1;i<m_nCakeCnt;i++){
        Reverse(0,i);
        m_ReverseSwapArray[step] = i;
        Search(step+1);
        Reverse(0,i);
    }
}
コード例 #4
0
TDBTSettingHandle CSettingsTree::_FindSetting(const uint32_t Hash, const char * Name, const uint32_t Length)
{
	TSettingKey key = {0,0};
	key.Hash = Hash;
	iterator i = LowerBound(key);
	uint16_t l;

	TDBTSettingHandle res = 0;

	char * str = NULL;

	while ((res == 0) && (i) && (i->Hash == Hash))
	{
		l = Length;
		if (m_Owner._ReadSettingName(m_BlockManager, i->Setting, l, str) &&
			(strncmp(str, Name, Length) == 0))
		{
			res = i->Setting;
		} else {
			++i;
		}
	}

	if (str)
		free(str);

	return res;
}
コード例 #5
0
ファイル: AssetSetManager.cpp プロジェクト: ldh9451/XLE
 IAssetSet* AssetSetManager::GetSetForTypeCode(size_t typeCode)
 {
     auto i = LowerBound(_pimpl->_sets, typeCode);
     if (i != _pimpl->_sets.end() && i->first == typeCode)
         return i->second.get();
     return nullptr;
 }
コード例 #6
0
ファイル: SharedStateSet.cpp プロジェクト: ldh9451/XLE
    void SharedStateSet::BeginRenderState(
        const ModelRendererContext& context,
        SharedRenderStateSet renderStateSetIndex) const
    {
        assert(_pimpl->_capturedContext == context._context);

        if (_currentRenderState == renderStateSetIndex) { return; }

        const Techniques::CompiledRenderStateSet* compiled = nullptr;
        auto statesHash = _pimpl->_renderStateHashes[renderStateSetIndex.Value()];

        auto hash = HashCombine(statesHash, _pimpl->_currentGlobalRenderState);
        auto i = LowerBound(_pimpl->_compiledStates, hash);
        if (i != _pimpl->_compiledStates.end() && i->first == hash) {
            compiled = &i->second;
        } else {
            const auto& states = _pimpl->_renderStateSets[renderStateSetIndex.Value()];
            auto newlyCompiled = _pimpl->_currentStateResolver->Resolve(
                states, *_pimpl->_environment, context._techniqueIndex);
            compiled = &_pimpl->_compiledStates.insert(
                i, std::make_pair(hash, std::move(newlyCompiled)))->second;
        }
        
        assert(compiled);
        if (compiled->_blendState.GetUnderlying())
            context._context->Bind(compiled->_blendState);
        context._context->Bind(compiled->_rasterizerState);
        
        _currentRenderState = renderStateSetIndex;
    }
コード例 #7
0
	void TerrainCellRenderer::ShortCircuit(
		RenderCore::Metal::DeviceContext& metalContext,
		ShortCircuitBridge& bridge,
		uint64 cellHash, TerrainCoverageId layerId,
		uint32 nodeIndex)
	{
		auto i = LowerBound(_renderInfos, cellHash);
		if (i == _renderInfos.end() || i->first != cellHash) return;

		TileSetPtrs p(*this, *i->second, layerId);
		auto& sourceCell = *i->second->_sourceCell;
		auto nodeInCell = GetNodeInCell(sourceCell, nodeIndex);

		if (!p._tileSet || !p._tiles || nodeIndex >= p._tiles->size()) return;
		const auto& tile = (*p._tiles)[nodeIndex]._tile;
		if (!p._tileSet->IsValid(tile)) return;
		
		auto upd = bridge.GetShortCircuit(cellHash, nodeInCell.first, nodeInCell.second);
		if (upd._srv && upd._cellMinsInResource[0] < upd._cellMaxsInResource[0] && upd._cellMinsInResource[1] < upd._cellMaxsInResource[1]) {
			// LogInfo 
			// 	<< "ShortCircuit " << nodeIndex << " field:" << GetFieldIndex(sourceCell, nodeIndex) 
			// 	<< " (" << nodeInCell.first[0] << "," << nodeInCell.first[1] << ") ("
			// 	<< nodeInCell.second[0] << "," << nodeInCell.second[1] << ") -- update";
			ShortCircuitTileUpdate(
				metalContext, tile,
				(*p._tiles)[nodeIndex], layerId, GetFieldIndex(sourceCell, nodeIndex),
				Float2(0.f, 0.f), Float2(1.f, 1.f), upd);
		}
	}
コード例 #8
0
ファイル: RetainedEntities.cpp プロジェクト: coreafive/XLE
 std::basic_string<utf8> RetainedEntities::GetTypeName(ObjectTypeId id) const
 {
     auto i = LowerBound(_registeredObjectTypes, id);
     if (i != _registeredObjectTypes.end() && i->first == id) {
         return i->second._name;
     }
     return std::basic_string<utf8>();
 }
コード例 #9
0
    void ShortCircuitBridge::RegisterCell(uint64 cellHash, UInt2 uberMins, UInt2 uberMaxs, WriteCellsFn&& writeCells)
    {
        auto i = LowerBound(_cells, cellHash);
        if (i != _cells.end() && i->first == cellHash)
            Throw(std::logic_error("Duplicate cell registered to ShortCircuitBridge. Check for hash conflicts or overlapping cells."));

        _cells.insert(i, std::make_pair(cellHash, RegisteredCell { uberMins, uberMaxs, std::move(writeCells) }));
    }
コード例 #10
0
ファイル: AssetSetManager.cpp プロジェクト: ldh9451/XLE
 void AssetSetManager::Add(size_t typeCode, std::unique_ptr<IAssetSet>&& set)
 {
     auto i = LowerBound(_pimpl->_sets, typeCode);
     assert(i == _pimpl->_sets.end() || i->first != typeCode);
     _pimpl->_sets.insert(
         i,
         std::make_pair(
             typeCode,
             std::forward<std::unique_ptr<IAssetSet>>(set)));
 }
コード例 #11
0
ファイル: InvalidAssetManager.cpp プロジェクト: ldh9451/XLE
 void InvalidAssetManager::MarkValid(const ResChar name[])
 {
     if (_pimpl->_active) {
         ScopedLock(_pimpl->_assetsLock);
         auto hashName = Hash64(name);
         auto i = LowerBound(_pimpl->_assets, hashName);
         if (i != _pimpl->_assets.end() && i->first == hashName) {
             _pimpl->_assets.erase(i);
         }
     }
 }
コード例 #12
0
ファイル: InvalidAssetManager.cpp プロジェクト: ldh9451/XLE
 void InvalidAssetManager::MarkInvalid(const rstring& name, const rstring& errorString)
 {
     if (_pimpl->_active) {
         ScopedLock(_pimpl->_assetsLock);
         auto hashName = Hash64(name);
         auto i = LowerBound(_pimpl->_assets, hashName);
         if (i != _pimpl->_assets.end() && i->first == hashName) {
             assert(i->second._name == name);
             i->second._errorString = errorString;
         } else {
             _pimpl->_assets.insert(
                 i, std::make_pair(hashName, AssetRef { name, errorString }));
         }
     }
 }
コード例 #13
0
ファイル: AssetUtils.cpp プロジェクト: ldh9451/XLE
    void    DependencyValidation::RegisterDependency(const std::shared_ptr<Utility::OnChangeCallback>& dependency)
    {
        ResourceDependenciesLock.lock();
        auto i = LowerBound(ResourceDependencies, (const OnChangeCallback*)dependency.get());
        ResourceDependencies.insert(i, std::make_pair(dependency.get(), shared_from_this()));
        ResourceDependenciesLock.unlock();

            // We must hold a reference to the dependency -- otherwise it can be destroyed,
            // and links to downstream assets/files might be lost
            // It's a little awkward to hold it here, but it's the only way
            // to make sure that it gets destroyed when "this" gets destroyed

        for (unsigned c=0; c<dimof(_dependencies); ++c)
            if (!_dependencies[c]) { _dependencies[c] = dependency; return; }
        
        _dependenciesOverflow.push_back(dependency);
    }
コード例 #14
0
bool CSettingsTree::_DeleteSetting(const uint32_t Hash, const TDBTSettingHandle hSetting)
{
	TSettingKey key = {0,0};
	key.Hash = Hash;
	iterator i = LowerBound(key);

	while ((i) && (i->Hash == Hash) && (i->Setting != hSetting))
		++i;

	if ((i) && (i->Hash == Hash))
	{
		Delete(*i);
		return true;
	}

	return false;
}
コード例 #15
0
    ShortCircuitUpdate ShortCircuitBridge::GetShortCircuit(uint64 cellHash, Float2 cellMins, Float2 cellMaxs)
    {
        auto l = _source.lock();
        if (!l) return ShortCircuitUpdate {};

        auto i = LowerBound(_cells, cellHash);
        if (i != _cells.end() && i->first == cellHash) {
            UInt2 uberMins(
                i->second._uberMins[0] + unsigned((i->second._uberMaxs[0] - i->second._uberMins[0]) * cellMins[0]),
                i->second._uberMins[1] + unsigned((i->second._uberMaxs[1] - i->second._uberMins[1]) * cellMins[1]));
            UInt2 uberMaxs(
                i->second._uberMins[0] + unsigned((i->second._uberMaxs[0] - i->second._uberMins[0]) * cellMaxs[0]),
                i->second._uberMins[1] + unsigned((i->second._uberMaxs[1] - i->second._uberMins[1]) * cellMaxs[1]));

            return l->GetShortCircuit(uberMins, uberMaxs);
        }
        return ShortCircuitUpdate {};
    }
コード例 #16
0
ファイル: Knapsack.cpp プロジェクト: YI-YING/Algorithm
//---------------------------------------------------------------------------
void __fastcall TfKnapsack::btBranchAndBoundClick(TObject *Sender)
{
    //如果已存在 ndHeapArray 先清除
    if (ndHeapArray) {
        delete[] ndHeapArray;
        ndHeapArray = NULL;
    }

    //讀入背包限制
    iBagCapacity = StrToInt(edBagCapacity->Text);

    //產生 Heap 陣列
    iHeapCount = 0;
    ndHeapArray = new Node[iTotalNum +1];

    //產生 Heap 的第一個節點
    Node u, v;
    u.iLevel = -1;
    u.iNowProfit = 0;
    u.iNowWeight = 0;
    u.iUpperBound = UpperBound(u);
    u.iLowerBound = LowerBound(u);

    InsertHeap(u);

    Item *itm;
    int iNowUpper = INT_MAX;

    while (iHeapCount > 0) {
        u = DeleteHeap();

        if (u.iLevel == iTotalNum-1)
            continue;

        v.iLevel = u.iLevel +1;
        itm = wrItems[v.iLevel].itm;

        //現在的重量加下一個 Item 的重量沒超過限重
        //才去計算 UpperBound 與 LowerBound
        if (u.iNowWeight + itm->iWeight <= iBagCapacity) {

            //拿這個東西
            v.iNowProfit = u.iNowProfit + itm->iProfit;
            v.iNowWeight = u.iNowWeight + itm->iWeight;
            v.iUpperBound = UpperBound(v);
            v.iLowerBound = LowerBound(v);


            if (v.iUpperBound > v.iLowerBound && v.iLowerBound < iNowUpper)
                InsertHeap(v);

            if (v.iUpperBound < iNowUpper)
                iNowUpper = v.iUpperBound;

        }

        //不拿這個東西
        v.iNowProfit = u.iNowProfit;
        v.iNowWeight = u.iNowWeight;
        v.iUpperBound = UpperBound(v);
        v.iLowerBound = LowerBound(v);

        if (v.iUpperBound > v.iLowerBound && v.iLowerBound < iNowUpper)
            InsertHeap(v);

        if (v.iUpperBound < iNowUpper)
            iNowUpper = v.iUpperBound;

    }

    memSolution->Lines->Add("----------------------------------------------");
    memSolution->Lines->Add("Maximum possible profit:");
    memSolution->Lines->Add(-iNowUpper);

}
コード例 #17
0
    // 排序的主函数
    //--第endBound+1 个烧饼后均以排好序,没有必要对排好序的进行交换
    //--因为交换已经排好序的烧饼只能使交换次数增大
    //--如果当前搜索的序列排好序则返回true,否则返回false
    bool Search(int step, int endBound)
    {
        int i, nEstimate;

        m_nSearch++;

        // 估算这次搜索所需要的最小交换次数
        nEstimate = LowerBound(m_ReverseCakeArray, m_nCakeCnt);

        //--遇到相等情形,若对于翻转次数为m_nMaxSwap的结果已经保存,流程继续。
        //--后面再遇到就可以跳过了,因为针对该翻转次数的结果已经保存,
        //无需再计算
        if(step + nEstimate == m_nMaxSwap && flag1 == false);
        else if(step + nEstimate >= m_nMaxSwap)
            return false;

        //重新计算排好序的位置
        int k = endBound;
        while(k > 0 && k == m_ReverseCakeArray[k])
            --k;

        // 如果k=0,说明已经排好序,即翻转完成,输出结果
        //if(IsSorted(m_ReverseCakeArray, m_nCakeCnt))
        if(k == 0)
        {
            if(step < m_nMaxSwap)
            {
                //--当前找到的一个解
                m_nMaxSwap = step;
                for(i = 0; i < m_nMaxSwap; i++)
                    m_SwapArray[i] = m_ReverseCakeArraySwap[i];
            }
            else if(step == m_nMaxSwap && flag1 == false)
            {
                //--只有第一次碰到step == m_nMaxSwap时才做如下操作
                //--因为m_nMaxSwap可能是最小翻转次数,因此要记录此次结果
                //--后面再碰到相等时,可以忽略,因为不用重复保存结果
                for(i = 0; i < m_nMaxSwap; i++)
                    m_SwapArray[i] = m_ReverseCakeArraySwap[i];
                flag1 = true;
            }
            return true;
        }

        // 递归进行翻转,k之后已经排好序的位置就不用翻转了
        std::vector<node> swapIndexScore;
        //对翻转后的序列进行评估,评估它到排序好的序列之间的距离,优先搜索距离小的序列
        for(i = 1; i <=k; i++)
        {
            struct node tnode;
            tnode.index = i;
            tnode.score = nEstimate;//原始序列的分数
            //求翻转后的分数,翻转后只有翻转位置影响分数的大小
            if(i != m_nCakeCnt - 1)
            {
                if(abs(m_ReverseCakeArray[i] - m_ReverseCakeArray[i+1]) == 1)
                    tnode.score++;
                if(abs(m_ReverseCakeArray[0] - m_ReverseCakeArray[i+1]) == 1)
                    tnode.score--;
            }
            else
            {
                if(m_ReverseCakeArray[i] == i)tnode.score++;
                if(m_ReverseCakeArray[0] == i)tnode.score--;
            }
            swapIndexScore.push_back(tnode);
        }
        //按照得分小到大排序,得分小的优先搜索
        sort(swapIndexScore.begin(), swapIndexScore.end(),comp);

        for(i = 0; i < swapIndexScore.size() ; i++)
        {
            Revert(m_ReverseCakeArray, 0, swapIndexScore[i].index);
            m_ReverseCakeArraySwap[step] = swapIndexScore[i].index;
            bool isDone = Search(step + 1, k);
            Revert(m_ReverseCakeArray, 0, swapIndexScore[i].index);
            //如果该搜索序列有序,那么其他翻转方案肯定会导致无序,因此不需要搜索
            if(isDone == true)break;
        }

//        for(i = 1; i <=k ; i++)
//        {
//            Revert(m_ReverseCakeArray, 0, i);
//            m_ReverseCakeArraySwap[step] = i;
//            Search(step + 1, k);
//            Revert(m_ReverseCakeArray, 0, i);
//        }
        return false;
    }
コード例 #18
0
 //--序列评估函数,对一个序列,若到达有序状态所需的翻转次数越少,得分越少
 //--若到达有序状态所需的翻转次数越多,得分越多
 //--搜索时可以优先搜索得分少的序列,这样能尽快达到最优解
 int Evaluate(int* pCakeArray, int nCakeCnt)
 {
     return LowerBound(pCakeArray, nCakeCnt);
 }
コード例 #19
0
ファイル: DDSIPmain.c プロジェクト: RalfGollmer/ddsip
//==========================================================================
int
main (int argc, char * argv[])
{
    // Temporary variables
    struct stat filestat;

    char astring[DDSIP_ln_fname];

    int status = 0, cont, boundstat, comb, i;

    // guarantee minimal stacksize limit
    const rlim_t kStackSize = 128 * 1024 * 1024;   // min stack size = 128 MB
    struct rlimit rl;
    int result;
    unsigned long cur_limit;

    result = getrlimit(RLIMIT_STACK, &rl);
    if (result == 0)
    {
        cur_limit = rl.rlim_cur;
        printf ("original stacksize limit %lu\n", cur_limit);
        if (rl.rlim_cur < kStackSize)
        {
            rl.rlim_cur = kStackSize;
            result = setrlimit(RLIMIT_STACK, &rl);
            if (result != 0)
            {
                fprintf(stderr, "setrlimit returned result = %d\n", result);
            }
            result = getrlimit(RLIMIT_STACK, &rl);
            if (result == 0)
            {
                cur_limit = rl.rlim_cur;
                printf ("changed  stacksize limit %lu\n", cur_limit);
            }
        }
    }

    i = argc;
    //

    // Welcome
    printf ("#######################################################################################\n");
    printf ("#########  D D S I P -- Dual Decomposition In Stochastic Integer Programming  #########\n");
    printf ("#########  %-66s #########\n", DDSIP_version);
    printf ("For copyright, license agreements, help, comments, requests, ... ");
    printf ("see\n\thttp://www.uni-duisburg-essen.de/~hn215go/ddsip.shtml\n");
    printf ("\thttp://www.www.github.com/RalfGollmer/ddsip\n");
    /*    printf ("  Copyright (C) to University of Duisburg-Essen \n\n"); */
    /*    printf("  This program is free software; you can redistribute it and/or\n"); */
    /*    printf ("  modify it under the terms of the GNU General Public License\n"); */
    /*    printf("  as published by the Free Software Foundation; either version 2\n"); */
    /*    printf ("  of the License, or (at your option) any later version.\n\n"); */
    /*    printf ("  This program is distributed in the hope that it will be useful,\n"); */
    /*    printf("  but WITHOUT ANY WARRANTY; without even the implied warranty of\n"); */
    /*    printf ("  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"); */
    /*    printf ("  GNU General Public License for more details.\n\n"); */
    /*    printf ("  You should have received a copy of the GNU General Public License\n"); */
    /*    printf("  along with this program; if not, write to the Free Software\n"); */
    /*    printf ("  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\n"); */
    /*    printf ("==============================================================================\n\n"); */

    // These four structures shall carry the whole problem data
    DDSIP_param = NULL;
    DDSIP_bb = NULL;
    DDSIP_data = NULL;
    DDSIP_node = NULL;

    // In DDSIP some signals are handled seperatly
    DDSIP_RegisterSignalHandlers ();

    // Create output directory if it doesn't already exist
    if (stat (DDSIP_outdir, &filestat) == -1)
    {
        sprintf (astring, "mkdir %s\n", DDSIP_outdir);
        i = system (astring);
        printf ("Creating subdirectory %s ...\n", DDSIP_outdir);
    }
    // remove possibly existing output file
    sprintf (astring, "rm -f %s\n", DDSIP_outfname);
    i = system (astring);
    // Open output file
    if ((DDSIP_outfile = fopen (DDSIP_outfname, "a")) == NULL)
    {
        fprintf (stderr, "ERROR: Cannot open '%s'. \n", DDSIP_outfname);
        status = 107;
        goto TERMINATE;
    }

    setbuf (DDSIP_outfile, 0);
    fprintf (DDSIP_outfile, "%s\n", argv[0]);
    fprintf (DDSIP_outfile, "-----------------------------------------------------------\n");
    fprintf (DDSIP_outfile, "current system time: ");
    fflush (DDSIP_outfile);
#ifndef _WIN32
    i = system ("date");
    // Print time to output file
    sprintf (astring, "date >> %s\n", DDSIP_outfname);
    i = system (astring);
    fprintf (DDSIP_outfile, "host            : ");
    sprintf (astring, "hostname >> %s; cat /proc/cpuinfo | sed '/processor.*: 0/,/^$/!d' |grep -E 'vendor|cpu |model|stepping|MHz|cache |cores' >> %s\n", DDSIP_outfname, DDSIP_outfname);
    for (i = 0; i < 100; i++)
        exp(1.11*(-i-2));
    i = system (astring);
#else
    sprintf (astring, "date /T >> %s & time /T >> %s\n", DDSIP_outfname,DDSIP_outfname);
    i = system (astring);
#endif

    fprintf (DDSIP_outfile, "\nDDSIP  %s\n", DDSIP_version);
    fprintf (DDSIP_outfile, "-----------------------------------------------------------\n");

    // Open cplex environment
    DDSIP_env = CPXopenCPLEX (&status);
    if (DDSIP_env == NULL)
    {
        fprintf (stderr, "ERROR: Failed to open cplex environment, CPLEX error code %d.\n",status);
        fprintf (DDSIP_outfile, "ERROR: Failed to open cplex environment, CPLEX error code %d.\n",status);
        return status;
    }
    sprintf (astring, "%s", CPXversion (DDSIP_env));
    printf ("CPLEX version is %s\n", astring);
    fprintf (DDSIP_outfile, "CPLEX version is %s\n\n", astring);

    // Allocate the structures to hold the information on the problem
    DDSIP_param = (para_t *) DDSIP_Alloc (sizeof (para_t), 1, "param(Main)");
    DDSIP_bb    = (bb_t *)   DDSIP_Alloc (sizeof (bb_t),   1, "bb(Main)");
    DDSIP_data  = (data_t *) DDSIP_Alloc (sizeof (data_t), 1, "data(Main)");

    // Read model (lp) file
    if ((status = DDSIP_ReadModel ()))
        goto TERMINATE;

    // Read specification file
    if ((status = DDSIP_ReadSpec ()))
        goto TERMINATE;

    // Set specified CPLEX parameters
    if ((status = DDSIP_InitCpxPara ()))
        goto TERMINATE;

    // if a Benders annotation file is given, read it
    if (DDSIP_param->annotationFile)
    {
        status = CPXreadcopyannotations (DDSIP_env, DDSIP_lp, DDSIP_param->annotationFile);
        if ( status ) {
           fprintf (stderr, "ERROR: Failed to read and copy the annotation data from file %s.\n", DDSIP_param->annotationFile);
           fprintf (DDSIP_outfile, "ERROR: Failed to read and copy the annotation data from file %s.\n", DDSIP_param->annotationFile);
           goto TERMINATE;
        }
    }

    // data->cost contains: stoch. costs for all scenarios, followed by the original costs
    DDSIP_data->cost =
        (double *) DDSIP_Alloc (sizeof (double),
                                DDSIP_param->scenarios * DDSIP_param->stoccost + DDSIP_data->novar, "cost (ReadData)");
    // Store original objective coefficients
    status = CPXgetobj (DDSIP_env, DDSIP_lp, DDSIP_data->cost + DDSIP_param->scenarios * DDSIP_param->stoccost, 0, DDSIP_data->novar - 1);
    if (status)
    {
        fprintf (stderr, "ERROR: Failed to get objective coefficients\n");
        fprintf (DDSIP_outfile, "ERROR: Failed to get objective coefficients\n");
        goto TERMINATE;
    }

    DDSIP_bb->moreoutfile = NULL;
    if (DDSIP_param->outlev)
    {
        // Open debug output file
        if ((DDSIP_bb->moreoutfile = fopen (DDSIP_moreoutfname, "a")) == NULL)
        {
            fprintf (stderr, "ERROR: Cannot open '%s'. \n", DDSIP_moreoutfname);
            fprintf (DDSIP_outfile, "ERROR: Cannot open '%s'. \n", DDSIP_moreoutfname);
            status = 109;
            goto TERMINATE;
        }
        if (DDSIP_param->outlev > 10)
        {
            // Buffer size = 0
            setbuf (stdout, 0);
            if (DDSIP_param->outlev > 20)
                setbuf (DDSIP_bb->moreoutfile, 0);
        }
#ifndef _WIN32
        // Print time to output file
        sprintf (astring, "date > %s\n", DDSIP_moreoutfname);
        i = system (astring);
#else
        sprintf (astring, "date /T > %s & time /T >> %s\n", DDSIP_moreoutfname,DDSIP_moreoutfname);
        i = system (astring);
#endif
        fprintf (DDSIP_bb->moreoutfile, "--------------------------------------------------------------");
        fprintf (DDSIP_bb->moreoutfile, "---------\nThis is an additional output file of DDSIP. The ");
        fprintf (DDSIP_bb->moreoutfile, "actual amount of output\nis controlled by the parameter ");
        fprintf (DDSIP_bb->moreoutfile, "OUTLEV in the specification file.\n---------");
        fprintf (DDSIP_bb->moreoutfile, "--------------------------------------------------------------\n\n");
    }

    DDSIP_node = (node_t **) DDSIP_Alloc (sizeof (node_t *), DDSIP_param->nodelim + 3, "node(Main)");
    DDSIP_node[0] = (node_t *) DDSIP_Alloc (sizeof (node_t), 1, "node[0](Main)");
    DDSIP_node[0]->first_sol = (double **) DDSIP_Alloc (sizeof (double *), DDSIP_param->scenarios, "node[0]->first_sol(Main)");
    DDSIP_node[0]->cursubsol = (double *) DDSIP_Alloc (sizeof (double), DDSIP_param->scenarios, "node[0]->cursubsol(Main)");
    DDSIP_node[0]->subbound = (double *) DDSIP_Alloc (sizeof (double), DDSIP_param->scenarios, "node[0]->subbound(Main)");
    if (DDSIP_param->cb)
    {
        DDSIP_node[0]->scenBoundsNoLag = (double *) DDSIP_Alloc (sizeof (double), DDSIP_param->scenarios, "node[0]->scenBoundsNoLag(Main)");
        DDSIP_node[0]->BoundNoLag = -DDSIP_infty;

    }
    DDSIP_node[0]->mipstatus = (int *) DDSIP_Alloc (sizeof (int), DDSIP_param->scenarios, "node[0]->mipstatus(Main)");
    DDSIP_node[0]->ref_scenobj = (double *) DDSIP_Alloc (sizeof (double), DDSIP_param->scenarios, "node[0]->ref_scenobj(Main)");

    // Prepare first and second stage variables
    if ((status = DDSIP_InitStages ()))
    {
        fprintf (stderr, "ERROR: Failed to initialize stages\n");
        fprintf (DDSIP_outfile, "ERROR: Failed to initialize stages\n");
        goto TERMINATE;
    }

    // Read data file(s)
    if ((status = DDSIP_ReadData ()))
        goto TERMINATE;

    // Read order file if specified
    if (DDSIP_param->cpxorder)
    {
        status = CPXsetintparam (DDSIP_env, CPX_PARAM_MIPORDIND, 1);
        if (status)
        {
            fprintf (stderr, "ERROR: Failed to set cplex parameter CPX_PARAM_MIPORDIND.\n");
            return status;
        }
        if (DDSIP_ReadCPLEXOrder ())
            goto TERMINATE;
    }

    // Detect first and second stage constraints
    if ((status = DDSIP_DetectStageRows ()))
    {
        fprintf (stderr, "ERROR: Failed detection of row stages (BbInit)\n");
        fprintf (DDSIP_outfile, "ERROR: Failed detection of row stages (BbInit)\n");
        goto TERMINATE;
    }

    DDSIP_bb->DDSIP_step =  solve;

#ifdef CONIC_BUNDLE
    if (DDSIP_param->cb)
    {
        status = DDSIP_NonAnt ();
        if (status)
            goto TERMINATE;
    }
#endif

    if (DDSIP_param->outlev)
    {
        printf ("\t Total initialization time: %4.2f seconds.\n", DDSIP_GetCpuTime ());
        fprintf (DDSIP_bb->moreoutfile, " Total initialization time: %4.2f seconds.\n", DDSIP_GetCpuTime ());
    }
#ifndef _WIN32
    sprintf (astring, "grep 'MHz' /proc/cpuinfo|sort -r|head -1 >> %s\n", DDSIP_outfname);
    i = system (astring);
#endif

    // at the start there is no solution
    status = CPXsetintparam (DDSIP_env, CPX_PARAM_ADVIND, 0);
    if (status)
    {
        fprintf (stderr, "ERROR: Failed to set cplex parameter CPX_PARAM_ADVIND.\n");
        fprintf (DDSIP_outfile, "ERROR: Failed to set cplex parameter CPX_PARAM_ADVIND.\n");
        return status;
    }

#ifndef NEOS
    // Write deterministic equivalent (only expectation-based cases)
    if (DDSIP_param->write_detequ)
        DDSIP_DetEqu ();
#endif
    if (DDSIP_param->riskmod < 0)
    {
        fprintf (stderr, " pure risk models are disabled for now, exiting.\n");
        fprintf (DDSIP_outfile, " pure risk models are disabled for now, exiting.\n");
        goto TERMINATE;
    }
    if (DDSIP_param->stoccost && DDSIP_param->riskmod)
    {
        fprintf (DDSIP_outfile, "XXX Error: Risk optimization not implemented for stochastic cost coefficients.\n");
        fprintf (stderr, "XXX Error: Risk optimization not implemented for stochastic cost coefficients.\n");
        goto TERMINATE;
    }

    // Read advanced starting info
    if (DDSIP_param->advstart)
    {
        DDSIP_node[DDSIP_bb->curnode]->step = DDSIP_bb->DDSIP_step = adv;

        if ((status = DDSIP_AdvStart ()))
            goto TERMINATE;

        // Solution provided?
        if (DDSIP_param->advstart == 2)
        {
            DDSIP_bb->curnode = 0;
            DDSIP_bb->sug[DDSIP_param->nodelim + 2] = (struct sug_l *)DDSIP_Alloc (sizeof (sug_t), 1, "sug[0](Advanced start solution)");
            (DDSIP_bb->sug[DDSIP_param->nodelim + 2])->firstval =
                (double *) DDSIP_Alloc (sizeof (double), DDSIP_bb->firstvar, "sug[0]->firstval(adv start)");
            for (i = 0; i < (DDSIP_bb->firstvar); i++)
                (DDSIP_bb->sug[DDSIP_param->nodelim + 2]->firstval)[i] = DDSIP_bb->adv_sol[i];
            (DDSIP_bb->sug[DDSIP_param->nodelim + 2])->next = NULL;
            if ((status = DDSIP_UpperBound (DDSIP_param->scenarios, 0)) && status < 100000)
                goto TERMINATE;
        }
        // Only weak consistency check:
        if ((DDSIP_node[0]->bound) > DDSIP_bb->bestvalue)
        {
            status = 121;
            goto TERMINATE;
        }
        fprintf (DDSIP_outfile, "-----------------------------------------------------------\n\n");
    }
    // Solve EV and EEV if specified
    if (DDSIP_param->expected)
    {
        DDSIP_node[DDSIP_bb->curnode]->step = DDSIP_bb->DDSIP_step = eev;

        // status = 1 -> ExpValProb infeasible
        if ((status = DDSIP_ExpValProb ()) == 1)
        {
            if (DDSIP_param->outlev)
                fprintf (DDSIP_bb->moreoutfile, "    exp. val. prob: INFEASIBLE\n");
            fprintf (DDSIP_outfile, "    exp. val. prob: INFEASIBLE\n");
        }

        if (!status)
        {
            DDSIP_bb->curnode = 0;
            DDSIP_bb->sug[DDSIP_param->nodelim + 2] = (struct sug_l *)DDSIP_Alloc (sizeof (sug_t), 1, "sug[0](Advanced start solution)");
            DDSIP_bb->sug[DDSIP_param->nodelim + 2]->firstval =
                (double *) DDSIP_Alloc (sizeof (double), DDSIP_bb->firstvar, "sug[i]->firstval(Heuristic)");
            for (i = 0; i < DDSIP_bb->firstvar; i++)
                (DDSIP_bb->sug[DDSIP_param->nodelim + 2]->firstval)[i] = DDSIP_bb->adv_sol[i];
            DDSIP_bb->sug[DDSIP_param->nodelim + 2]->next = NULL;
            if ((status = DDSIP_UpperBound (DDSIP_param->scenarios, 0)) && status < 100000)
                goto TERMINATE;
        }

        if (fabs (DDSIP_bb->expbest) < DDSIP_infty)
        {
            if (DDSIP_param->outlev)
                printf ("\t\t EEV:  %13.7f\n", DDSIP_bb->expbest);
            fprintf (DDSIP_outfile, "-EEV:     %13.7f\n", DDSIP_bb->expbest);
        }
        else
        {
            if (DDSIP_param->outlev)
                printf ("\t\t EEV:  No solution found.\n");
            fprintf (DDSIP_outfile, "-EEV:     No solution found.\n");
        }
    }				// END if (EV)
    // stop here if NODELIM is zero
     if (!(DDSIP_param->nodelim))
         goto TERMINATE;
    // Print cplex log to debugfile
    if (DDSIP_param->outlev > 51)
    {
#ifdef CPLEX_12_8
       if ((status = CPXsetlogfilename (DDSIP_env, DDSIP_moreoutfname, "a")))
           goto TERMINATE;
#else
       if ((status = CPXsetlogfile (DDSIP_env, DDSIP_bb->moreoutfile)))
           goto TERMINATE;
#endif
    }

    // No of DDSIP iterations
    DDSIP_bb->noiter = 0;
    // cont = 1 if no stop criteria is fullfilled
    cont = 1;
    // comb tells in case of a combined heuristic, which one to apply (3 = RoundNear)
    comb = 3;

    if (DDSIP_param->outlev)
        printf ("Starting branch-and-bound algorithm.\n");
    fprintf (DDSIP_outfile, "----------------------------------------------------------------------------------------\n");

    while (cont)
    {
        // the cuts from the root node are contained in every following node model, there is no need to check their violation
        // for the scenario solutions. But the rounding heuristics could violate a cut, so keep them.
#ifdef CONIC_BUNDLE
#ifdef DEBUG
////////////////////////////////////////////
if (DDSIP_bb->curnode && DDSIP_param->outlev)
{ 
if((DDSIP_node[DDSIP_bb->curnode-1])->step == dual)
  fprintf(DDSIP_bb->moreoutfile, "######## last node %d step=dual, leaf= %d,  dualdescitcnt = %d, DDSIP_bb->cutoff= %d\n",DDSIP_bb->curnode-1,(DDSIP_node[DDSIP_bb->curnode-1])->leaf,DDSIP_bb->dualdescitcnt,DDSIP_bb->cutoff);
}
////////////////////////////////////////////
#endif

        if (DDSIP_param->outlev > 20 && DDSIP_bb->curnode && DDSIP_node[DDSIP_node[DDSIP_bb->curnode]->father]->cbReturn32)
            fprintf (DDSIP_bb->moreoutfile, "########## DDSIP_node[%d >father]->cbReturn32 = 1\n", DDSIP_bb->curnode);
        // Dual method
        if ((!DDSIP_bb->curnode || !DDSIP_node[DDSIP_node[DDSIP_bb->curnode]->father]->cbReturn32) &&
            ((DDSIP_param->cb > 0 && (!(DDSIP_bb->noiter % abs(DDSIP_param->cb))) && (abs(DDSIP_param->riskmod) != 4 || DDSIP_bb->noiter)) ||
             (DDSIP_param->cb < 0 && (((DDSIP_node[DDSIP_bb->curnode]->depth <= DDSIP_param->cb_depth) && abs(DDSIP_param->riskmod) != 4) ||
                                      (abs(DDSIP_param->riskmod) == 5 && DDSIP_node[DDSIP_bb->curnode]->depth == 8) ||
                                      (DDSIP_bb->noiter > DDSIP_param->cbBreakIters && 
                                        ((!(DDSIP_bb->noiter % abs(DDSIP_param->cb))) ||
                                         (!((DDSIP_bb->noiter+1) % -DDSIP_param->cb)) ||
                                         (DDSIP_bb->noiter%200 > 199 - DDSIP_param->cbContinuous) ||
                                         (DDSIP_bb->noiter < DDSIP_param->cbContinuous + DDSIP_param->cbBreakIters) ||
                                         ((DDSIP_bb->noiter  >= 2*DDSIP_param->cbBreakIters) && (DDSIP_bb->noiter < DDSIP_param->cbContinuous + 2*DDSIP_param->cbBreakIters)) ||
                                         ((DDSIP_bb->cutoff > 6) &&
                                             (((DDSIP_bb->no_reduced_front < 51) && (DDSIP_bb->noiter % -DDSIP_param->cb) < DDSIP_param->cbContinuous)
                                             || (((DDSIP_node[DDSIP_bb->curnode-1])->step == dual) && (DDSIP_node[DDSIP_bb->curnode-1])->leaf /*&& (DDSIP_bb->dualdescitcnt < 11)*/)
                                             )
                                         )
                                       )
                                     ) ||
                                     (abs(DDSIP_param->riskmod) != 5 && DDSIP_bb->noiter <= DDSIP_param->cbBreakIters && DDSIP_bb->noiter > DDSIP_param->cbBreakIters*.5 &&
                                          (CBFORALL || (DDSIP_node[DDSIP_bb->curnode]->numInheritedSols > (DDSIP_Imin(DDSIP_param->scenarios/20,2)+(DDSIP_param->scenarios+1)/2))))
                                   )
                )
            )
           )
        {
            DDSIP_bb->DDSIP_step = DDSIP_node[DDSIP_bb->curnode]->step = dual;
            if ((status = DDSIP_DualOpt ()))
            {
                if (!DDSIP_bb->curnode)
                    goto TERMINATE;
                else
                {
                    DDSIP_bb->skip = 1;
                    DDSIP_node[DDSIP_bb->curnode]->bound = DDSIP_infty;
                }
            }
        }
        else
        {
            DDSIP_node[DDSIP_bb->curnode]->step = DDSIP_bb->DDSIP_step = solve;
            // status=1 means there was no solution found to a scenario problem
            if ((status = DDSIP_LowerBound ()))
                goto TERMINATE;
        }
#else
        DDSIP_node[DDSIP_bb->curnode]->step = DDSIP_bb->DDSIP_step = solve;
        // status=1 means there was no solution found to a subproblem
        if ((status = LowerBound ()))
            goto TERMINATE;
#endif

        if (!DDSIP_bb->skip || DDSIP_bb->skip == -1)
        {
            double old_bound;
            int cntr, maxCntr;

            DDSIP_bb->cutAdded = 0;
            DDSIP_EvaluateScenarioSolutions (&comb);
            cntr = 0;
            if (DDSIP_node[DDSIP_bb->curnode]->step != dual)
                maxCntr = DDSIP_param->numberReinits;
            else
                maxCntr = 0;
            old_bound = DDSIP_node[DDSIP_bb->curnode]->bound;
            boundstat = DDSIP_Bound ();
            if (!DDSIP_bb->curnode)
            {
                int cnt, j;
                double lhs;
                cutpool_t *currentCut;
                DDSIP_PrintState (DDSIP_bb->noiter);
                if (DDSIP_bb->cutAdded && DDSIP_param->outlev)
                {
                    fprintf (DDSIP_outfile, " %6d%101d cuts\n", DDSIP_bb->curnode, DDSIP_bb->cutAdded);
                }
                while ((DDSIP_bb->cutAdded || DDSIP_node[0]->step == dual) && cntr < maxCntr)
                {
                    old_bound = DDSIP_node[0]->bound;
                    // Free the solutions from former LowerBound
                    for (i = 0; i < DDSIP_param->scenarios; i++)
                    {
                        if (((DDSIP_node[0])->first_sol)[i])
                        {
                            if (DDSIP_node[0]->step == solve)
                            {
                                currentCut = DDSIP_bb->cutpool;
                                while (currentCut)
                                {
                                    lhs = 0.;
                                    for (j = 0; j < DDSIP_bb->firstvar; j++)
                                    {
                                        lhs += (DDSIP_node[0])->first_sol[i][j] * currentCut->matval[j];
                                    }
                                    if (lhs < currentCut->rhs - 1.e-7)
                                    {
#ifdef DEBUG
                                        if (DDSIP_param->outlev > 50)
                                            fprintf (DDSIP_bb->moreoutfile, "scen %d solution violates cut %d.\n", i+1, currentCut->number);
#endif
                                        if ((cnt = (int) ((((DDSIP_node[0])->first_sol)[i])[DDSIP_bb->firstvar] - 0.9)))
                                        for (j = i + 1; cnt && j < DDSIP_param->scenarios; j++)
                                        {
                                            {
                                                if (((DDSIP_node[0])->first_sol)[j]
                                                  && ((DDSIP_node[0])->first_sol)[i] == ((DDSIP_node[0])->first_sol)[j])
                                                {
                                                    ((DDSIP_node[0])->first_sol)[j] = NULL;
                                                    cnt--;
                                                }
                                            }
                                        }
                                        DDSIP_Free ((void **) &(((DDSIP_node[0])->first_sol)[i]));
                                        break;
                                    }
                                    currentCut = currentCut->prev;
                                }
                            }
                            else
                            {
                               if ((cnt = (int) ((((DDSIP_node[0])->first_sol)[i])[DDSIP_bb->firstvar] - 0.9)))
                               for (j = i + 1; cnt && j < DDSIP_param->scenarios; j++)
                               {
                                   {
                                       if (((DDSIP_node[0])->first_sol)[j]
                                         && ((DDSIP_node[0])->first_sol)[i] == ((DDSIP_node[0])->first_sol)[j])
                                       {
                                           ((DDSIP_node[0])->first_sol)[j] = NULL;
                                           cnt--;
                                       }
                                   }
                               }
                               DDSIP_Free ((void **) &(((DDSIP_node[0])->first_sol)[i]));
                            }
                        }
                    }
                    DDSIP_node[0]->step = DDSIP_bb->DDSIP_step = solve;
                    // status=1 means there was no solution found to a scenario problem
                    if ((status = DDSIP_LowerBound ()))
                        goto TERMINATE;
                    DDSIP_bb->cutAdded = 0;
                    DDSIP_EvaluateScenarioSolutions (&comb);
                    cntr++;
                    DDSIP_bb->bestbound = DDSIP_node[0]->bound;
                    DDSIP_bb->noiter++;
                    DDSIP_PrintState (1);
                    if (DDSIP_bb->cutAdded && DDSIP_param->outlev)
                    {
                        fprintf (DDSIP_outfile, " %6d %82d. reinit: %8d cuts\n", 0, cntr, DDSIP_bb->cutAdded);
                    }
                    if ((DDSIP_node[0]->bound - old_bound)/(fabs(old_bound) + 1e-16) < 1.e-7 ||
                        (DDSIP_bb->bestvalue - DDSIP_node[0]->bound)/(fabs(DDSIP_bb->bestvalue) + 1e-16) < 0.5*DDSIP_param->relgap)
                        break;
                }
                if (DDSIP_param->deleteRedundantCuts)
                    DDSIP_CheckRedundancy(1);
            }
            else
            {
                // Print a line of output at the first, the last and each `ith' node
                if (!DDSIP_bb->noiter || (!((DDSIP_bb->noiter + 1) % DDSIP_param->logfreq)) || (DDSIP_param->outlev && (DDSIP_node[DDSIP_bb->curnode])->step == dual))
                        DDSIP_PrintState (DDSIP_bb->noiter);
                if (DDSIP_bb->cutAdded && DDSIP_param->outlev > 1)
                {
                    fprintf (DDSIP_outfile, " %6d%101d cuts\n", DDSIP_bb->curnode, DDSIP_bb->cutAdded);
                }
            }
        }
        else
        {
            boundstat = DDSIP_Bound ();
            // Print a line of output at the first, the last and each `ith' node
            if (!DDSIP_bb->noiter || (!((DDSIP_bb->noiter + 1) % DDSIP_param->logfreq)) || (DDSIP_param->outlev && (DDSIP_node[DDSIP_bb->curnode])->step == dual))
                DDSIP_PrintState (DDSIP_bb->noiter);
        }
        if (!DDSIP_bb->curnode)
             DDSIP_bb->cutCntr0 = DDSIP_bb->cutNumber;
        else if (DDSIP_param->alwaysBendersCuts)
        {
            if (DDSIP_bb->curnode == 24)
            {
                if (DDSIP_bb->cutCntr0 == DDSIP_bb->cutNumber)
                {
                    if (DDSIP_param->outlev > 20)
                        fprintf (DDSIP_bb->moreoutfile, "### setting alwaysBendersCuts to 0\n");
                    DDSIP_param->alwaysBendersCuts = 0;
                }
                else
                    DDSIP_bb->cutCntr0 = DDSIP_bb->cutNumber;
            }
            else if (DDSIP_bb->curnode == 49)
            {
                if (DDSIP_bb->cutCntr0 == DDSIP_bb->cutNumber)
                {
                    if (DDSIP_param->outlev > 20)
                        fprintf (DDSIP_bb->moreoutfile, "### setting alwaysBendersCuts to 0\n");
                    DDSIP_param->alwaysBendersCuts = 0;
                }
                else
                    DDSIP_bb->cutCntr0 = DDSIP_bb->cutNumber;
            }
            else if (DDSIP_bb->curnode == 99)
            {
                if (DDSIP_bb->cutCntr0 == DDSIP_bb->cutNumber)
                {
                    if (DDSIP_param->outlev > 20)
                        fprintf (DDSIP_bb->moreoutfile, "### setting alwaysBendersCuts to 0\n");
                    DDSIP_param->alwaysBendersCuts = 0;
                }
            }
        }

        // DDSIP_bb->skip > 0 indicates that UpperBound calls have been skipped
        // DDSIP_bb->heurval contains the objective value of the heuristic solution
        // Reset to initial values
        DDSIP_bb->heurval = DDSIP_infty;
        DDSIP_bb->skip = 0;

        cont = DDSIP_Continue (&DDSIP_bb->noiter, &boundstat);
        if (!cont)
        {
            status = boundstat;
            goto TERMINATE;
        }

        if ((status = DDSIP_Branch ()))
            goto TERMINATE;

        if (DDSIP_param->deleteRedundantCuts && !(DDSIP_bb->curnode % 10))
            DDSIP_CheckRedundancy(1);
    }

    // Termination
TERMINATE:


    DDSIP_PrintErrorMsg (status);

    printf ("\nOutput files in directory `%s'.\n", DDSIP_outdir);

    // Free up problem as allocated above
    //
    if (DDSIP_node != NULL)
    {
        DDSIP_FreeFrontNodes ();
        for (i = 0; i < DDSIP_bb->nonode; i++)
            DDSIP_Free ((void **) &(DDSIP_node[i]));
        DDSIP_Free ((void **) &(DDSIP_node));
    }

    if (DDSIP_data != NULL)
    {
        DDSIP_FreeData ();
        DDSIP_Free ((void **) &(DDSIP_data));
    }

    // Free up the problem as allocated by CPXcreateprob, if necessary
    if (DDSIP_lp != NULL)
    {
        status = CPXfreeprob (DDSIP_env, &DDSIP_lp);
        if (status)
            fprintf (stderr, "ERROR: CPXfreeprob failed, error code %d\n", status);
    }
    // Free up the CPLEX environment
    if (DDSIP_env != NULL)
    {
        status = CPXcloseCPLEX (&DDSIP_env);
        if (status)
        {
            char errmsg[1024];
            fprintf (stderr, "ERROR: Failed to close CPLEX environment.\n");
            CPXgeterrorstring (DDSIP_env, status, errmsg);
            fprintf (stderr, "%s\n", errmsg);
        }
    }

    if (DDSIP_bb != NULL)
    {
        DDSIP_FreeBb ();
        DDSIP_Free ((void **) &(DDSIP_bb));
    }

    if (DDSIP_param->outlev)
        printf ("Terminating DDSIP.\n");

    if (DDSIP_param != NULL)
    {
        DDSIP_FreeParam ();
        DDSIP_Free ((void **) &(DDSIP_param));
    }

    fprintf (DDSIP_outfile, "Current system time: ");
#ifndef _WIN32
    i = system ("date");
    // Print time to output file
    sprintf (astring, "date >> %s\n", DDSIP_outfname);
    i = system (astring);
#else
    sprintf (astring, "date /T >> %s & time /T >> %s\n", DDSIP_outfname,DDSIP_outfname);
    i = system (astring);
#endif

    if (DDSIP_outfile != NULL)
        fclose (DDSIP_outfile);

    return 0;
}