243 class gain_bucket_type :
public map<net_weight_type, set<FM_node_type*, compare_type2>, compare_type1>
247 typedef set<FM_node_type*, compare_type2> nested_type;
248 typedef map<net_weight_type, nested_type, compare_type1> base_type;
261 net_weight_type gain = pFMNode->
gain();
262 typename base_type::iterator found = this->find(gain);
263 if (found == this->end())
265 set<FM_node_type*, compare_type2> sTmp;
266 sTmp.insert(pFMNode);
267 this->base_type::insert(make_pair(gain, sTmp));
271 found->second.insert(pFMNode);
278 net_weight_type gain = pFMNode->
gain();
279 typename base_type::iterator found = this->find(gain);
280 if (found != this->end())
282 if (found->second.empty())
return;
283 else if (found->second.size() == 1 && found->second.count(pFMNode))
284 this->base_type::erase(found);
286 found->second.erase(pFMNode);
294 for (
typename base_type::const_iterator it1 = this->begin();
295 it1 != this->end(); ++it1)
296 for (
typename nested_type::const_iterator it2 = it1->second.begin();
297 it2 != it1->second.end(); ++it2)
304 cout <<
"------- gain_bucket -------" << endl;
305 cout <<
"total # element = " << this->
element_size() << endl;
306 for (
typename base_type::const_iterator it1 = this->begin();
307 it1 != this->end(); ++it1)
309 cout <<
"gain = " << it1->first <<
": ";
310 for (
typename nested_type::const_iterator it2 = it1->second.begin();
311 it2 != it1->second.end(); ++it2)
312 cout << FM_node_traits<node_type>::tie_id(*((*it2)->pNode)) <<
" ";
354 bool add_net(net_weight_type
const& weight, Iterator first, Iterator last)
359 for (Iterator it = first; it != last; ++it)
361 typename unordered_map<node_type*, FM_node_type*>::const_iterator found =
m_hNode.find(*it);
369 pFMNet->
vNode.push_back(found->second);
372 for (
typename vector<FM_node_type*>::const_iterator itNode = pFMNet->
vNode.begin();
373 itNode != pFMNet->
vNode.end(); ++itNode)
374 (*itNode)->vNet.push_back(pFMNet);
399 cout <<
"------- partitions -------" << endl;
400 vector<typename FM_node_traits<node_type>::tie_id_type> vPartition[2];
402 for (
typename unordered_map<node_type*, FM_node_type*>::const_iterator it =
m_hNode.begin();
410 for (
typename vector<
typename FM_node_traits<node_type>::tie_id_type>::const_iterator it = vPartition[0].begin();
411 it != vPartition[0].end(); ++it)
412 cout << (*it) <<
" ";
414 for (
typename vector<
typename FM_node_traits<node_type>::tie_id_type>::const_iterator it = vPartition[1].begin();
415 it != vPartition[1].end(); ++it)
416 cout << (*it) <<
" ";
463 net_weight_type
run(
double ratio1,
double ratio2)
465 net_weight_type prev_cutsize;
466 net_weight_type cur_cutsize = this->
cutsize();
468 unsigned int iter_cnt = 0;
471 cout <<
"######### iteration #" << iter_cnt++ <<
" #########" << endl;
473 prev_cutsize = cur_cutsize;
475 pair<net_weight_type, int> trial_pass = this->
single_pass(ratio1, ratio2, -1);
479 pair<net_weight_type, int> actual_pass = this->
single_pass(ratio1, ratio2, trial_pass.second);
483 assert(trial_pass == actual_pass &&
limbo::abs(actual_pass.first-this->cutsize()) < 1e-6);
486 cur_cutsize = actual_pass.first;
487 }
while (cur_cutsize < prev_cutsize);
496 pair<net_weight_type, int>
single_pass(
double ratio1,
double ratio2,
int target_cnt)
501 cout <<
"======= trial phase =======" << endl;
502 for (
typename unordered_map<node_type*, FM_node_type*>::const_iterator it =
m_hNode.begin();
509 else cout <<
"======= actual phase w. target_cnt = " << target_cnt <<
" =======" << endl;
515 node_weight_type total_weight[2] = {0, 0};
516 net_weight_type cur_cutsize = this->
cutsize();
517 net_weight_type best_cutsize = cur_cutsize;
518 for (
typename unordered_map<node_type*, FM_node_type*>::const_iterator it =
m_hNode.begin();
524 gain_bucket.
insert(pFMNode);
532 for (
typename unordered_map<node_type*, FM_node_type*>::const_iterator it =
m_hNode.begin();
541 cout <<
"initial cutsize = " << this->
cutsize() << endl;
546 while (!gain_bucket.empty())
548 if (cur_cnt == target_cnt)
break;
554 for (
typename gain_bucket_type::const_iterator it1 = gain_bucket.begin();
555 it1 != gain_bucket.end(); ++it1)
557 for (
typename gain_bucket_type::nested_type::const_iterator it2 = it1->second.begin();
558 it2 != it1->second.end(); ++it2)
562 node_weight_type tmp_total_weight[2] = {
571 double cur_ratio = (double)total_weight[0]/total_weight[1];
572 double tmp_ratio = (double)tmp_total_weight[0]/tmp_total_weight[1];
578 pFMNodeBest = pFMNode;
582 if (pFMNodeBest)
break;
585 if (!pFMNodeBest)
break;
596 gain_bucket.
erase(pFMNodeBest);
597 for (
typename vector<FM_net_type*>::const_iterator itNet = pFMNodeBest->
vNet.begin();
598 itNet != pFMNodeBest->
vNet.end(); ++itNet)
600 for (
typename vector<FM_node_type*>::const_iterator itNode = (*itNet)->vNode.begin();
601 itNode != (*itNet)->vNode.end(); ++itNode)
604 if (*itNode == pFMNodeBest || (*itNode)->
locked)
continue;
608 gain_bucket.
erase(*itNode);
618 for (
typename vector<FM_net_type*>::const_iterator itNet = pFMNodeBest->
vNet.begin();
619 itNet != pFMNodeBest->
vNet.end(); ++itNet)
622 for (
typename vector<FM_node_type*>::const_iterator itNode = (*itNet)->vNode.begin();
623 itNode != (*itNet)->vNode.end(); ++itNode)
626 if (*itNode == pFMNodeBest)
continue;
628 if (pFMNodeBest->
partition == (*itNode)->partition)
629 cur_cutsize += (*itNet)->weight;
631 cur_cutsize -= (*itNet)->weight;
634 int exclusivePartition = (*itNet)->exclusive_partition(*pFMNodeBest);
635 if (exclusivePartition != 2)
638 if (pFMNodeBest->
partition == exclusivePartition)
639 cur_cutsize += (*itNet)->weight;
642 cur_cutsize -= (*itNet)->weight;
648 pFMNodeBest->
locked =
true;
650 for (
typename vector<FM_net_type*>::const_iterator itNet = pFMNodeBest->
vNet.begin();
651 itNet != pFMNodeBest->
vNet.end(); ++itNet)
653 for (
typename vector<FM_node_type*>::const_iterator itNode = (*itNet)->vNode.begin();
654 itNode != (*itNet)->vNode.end(); ++itNode)
656 if (*itNode == pFMNodeBest || (*itNode)->
locked)
continue;
657 gain_bucket.
insert(*itNode);
668 cout <<
"move cnt = " << cur_cnt <<
", current cutsize = " << this->
cutsize() << endl;
671 if (cur_cutsize < best_cutsize)
673 best_cutsize = cur_cutsize;
680 for (
typename unordered_map<node_type*, FM_node_type*>::const_iterator it =
m_hNode.begin();
688 return make_pair(best_cutsize, best_cnt);