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); } }
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; }
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); } }
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; }
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; }
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; }
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); } }
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>(); }
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) })); }
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))); }
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); } } }
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 })); } } }
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); }
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; }
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 {}; }
//--------------------------------------------------------------------------- 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); }
// 排序的主函数 //--第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; }
//--序列评估函数,对一个序列,若到达有序状态所需的翻转次数越少,得分越少 //--若到达有序状态所需的翻转次数越多,得分越多 //--搜索时可以优先搜索得分少的序列,这样能尽快达到最优解 int Evaluate(int* pCakeArray, int nCakeCnt) { return LowerBound(pCakeArray, nCakeCnt); }
//========================================================================== 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; }