|
|
|
|
|
|
|
|
|
|
|
|
|
#include <boost/foreach.hpp> |
|
#include "Search.h" |
|
#include "../Manager.h" |
|
#include "../Hypothesis.h" |
|
#include "../../InputPaths.h" |
|
#include "../../InputPath.h" |
|
#include "../../System.h" |
|
#include "../../Sentence.h" |
|
#include "../../TranslationTask.h" |
|
#include "../../legacy/Util2.h" |
|
|
|
using namespace std; |
|
|
|
namespace Moses2 |
|
{ |
|
|
|
namespace NSCubePruningPerMiniStack |
|
{ |
|
|
|
|
|
Search::Search(Manager &mgr) |
|
:Moses2::Search(mgr) |
|
,m_stacks(mgr) |
|
|
|
,m_queue(QueueItemOrderer(), |
|
std::vector<QueueItem*>() ) |
|
|
|
,m_seenPositions() |
|
{ |
|
} |
|
|
|
Search::~Search() |
|
{ |
|
} |
|
|
|
void Search::Decode() |
|
{ |
|
|
|
m_stacks.Init(mgr.GetInput().GetSize() + 1); |
|
|
|
const Bitmap &initBitmap = mgr.GetBitmaps().GetInitialBitmap(); |
|
Hypothesis *initHypo = Hypothesis::Create(mgr.GetSystemPool(), mgr); |
|
initHypo->Init(mgr, mgr.GetInputPaths().GetBlank(), mgr.GetInitPhrase(), initBitmap); |
|
initHypo->EmptyHypothesisState(mgr.GetInput()); |
|
|
|
m_stacks.Add(initHypo, mgr.GetHypoRecycle()); |
|
|
|
for (size_t stackInd = 0; stackInd < m_stacks.GetSize() - 1; ++stackInd) { |
|
CreateSearchGraph(stackInd); |
|
} |
|
|
|
for (size_t stackInd = 1; stackInd < m_stacks.GetSize(); ++stackInd) { |
|
|
|
Decode(stackInd); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
void Search::Decode(size_t stackInd) |
|
{ |
|
NSCubePruningMiniStack::Stack &stack = m_stacks[stackInd]; |
|
BOOST_FOREACH(NSCubePruningMiniStack::Stack::Coll::value_type &val, stack.GetColl()) { |
|
NSCubePruningMiniStack::MiniStack &miniStack = *val.second; |
|
Decode(miniStack); |
|
} |
|
|
|
} |
|
|
|
void Search::Decode(NSCubePruningMiniStack::MiniStack &miniStack) |
|
{ |
|
Recycler<Hypothesis*> &hypoRecycler = mgr.GetHypoRecycle(); |
|
|
|
|
|
std::vector<QueueItem*> &container = Container(m_queue); |
|
|
|
BOOST_FOREACH(QueueItem *item, container) { |
|
|
|
Hypothesis *hypo = item->hypo; |
|
hypoRecycler.Recycle(hypo); |
|
|
|
|
|
m_queueItemRecycler.push_back(item); |
|
} |
|
container.clear(); |
|
|
|
m_seenPositions.clear(); |
|
|
|
|
|
CubeEdges &edges = *m_cubeEdges[&miniStack]; |
|
|
|
BOOST_FOREACH(CubeEdge *edge, edges) { |
|
|
|
edge->CreateFirst(mgr, m_queue, m_seenPositions, m_queueItemRecycler); |
|
} |
|
|
|
size_t pops = 0; |
|
while (!m_queue.empty() && pops < mgr.system.popLimit) { |
|
|
|
|
|
QueueItem *item = m_queue.top(); |
|
m_queue.pop(); |
|
|
|
CubeEdge *edge = item->edge; |
|
|
|
|
|
Hypothesis *hypo = item->hypo; |
|
|
|
m_stacks.Add(hypo, hypoRecycler); |
|
|
|
edge->CreateNext(mgr, item, m_queue, m_seenPositions, m_queueItemRecycler); |
|
|
|
++pops; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
void Search::CreateSearchGraph(size_t stackInd) |
|
{ |
|
NSCubePruningMiniStack::Stack &stack = m_stacks[stackInd]; |
|
MemPool &pool = mgr.GetPool(); |
|
|
|
BOOST_FOREACH(const NSCubePruningMiniStack::Stack::Coll::value_type &val, stack.GetColl()) { |
|
const Bitmap &hypoBitmap = *val.first.first; |
|
size_t hypoEndPos = val.first.second; |
|
|
|
|
|
|
|
const InputPaths &paths = mgr.GetInputPaths(); |
|
|
|
BOOST_FOREACH(const InputPath *path, paths) { |
|
const Range &pathRange = path->range; |
|
|
|
|
|
if (!path->IsUsed()) { |
|
continue; |
|
} |
|
if (!CanExtend(hypoBitmap, hypoEndPos, pathRange)) { |
|
continue; |
|
} |
|
|
|
const Bitmap &newBitmap = mgr.GetBitmaps().GetBitmap(hypoBitmap, pathRange); |
|
|
|
|
|
const NSCubePruningMiniStack::MiniStack &miniStack = *val.second; |
|
|
|
|
|
|
|
size_t numPt = mgr.system.mappings.size(); |
|
for (size_t i = 0; i < numPt; ++i) { |
|
const TargetPhrases *tps = path->targetPhrases[i]; |
|
if (tps && tps->GetSize()) { |
|
|
|
NSCubePruningMiniStack::MiniStack &nextMiniStack = m_stacks.GetMiniStack(newBitmap, pathRange); |
|
|
|
CubeEdge *edge = new (pool.Allocate<CubeEdge>()) CubeEdge(mgr, miniStack, *path, *tps, newBitmap); |
|
|
|
CubeEdges *edges; |
|
boost::unordered_map<NSCubePruningMiniStack::MiniStack*, CubeEdges*>::iterator iter = m_cubeEdges.find(&nextMiniStack); |
|
if (iter == m_cubeEdges.end()) { |
|
edges = new (pool.Allocate<CubeEdges>()) CubeEdges(); |
|
m_cubeEdges[&nextMiniStack] = edges; |
|
} else { |
|
edges = iter->second; |
|
} |
|
|
|
edges->push_back(edge); |
|
} |
|
} |
|
} |
|
} |
|
|
|
} |
|
|
|
|
|
const Hypothesis *Search::GetBestHypo() const |
|
{ |
|
const NSCubePruningMiniStack::Stack &lastStack = m_stacks.Back(); |
|
std::vector<const Hypothesis*> sortedHypos = lastStack.GetBestHypos(1); |
|
|
|
const Hypothesis *best = NULL; |
|
if (sortedHypos.size()) { |
|
best = sortedHypos[0]; |
|
} |
|
return best; |
|
} |
|
|
|
void Search::DebugCounts() |
|
{ |
|
std::map<size_t, size_t> counts; |
|
|
|
for (size_t stackInd = 0; stackInd < m_stacks.GetSize(); ++stackInd) { |
|
|
|
const NSCubePruningMiniStack::Stack &stack = m_stacks[stackInd]; |
|
BOOST_FOREACH(const NSCubePruningMiniStack::Stack::Coll::value_type &val, stack.GetColl()) { |
|
const NSCubePruningMiniStack::MiniStack &miniStack = *val.second; |
|
size_t count = miniStack.GetColl().size(); |
|
|
|
if (counts.find(count) == counts.end()) { |
|
counts[count] = 0; |
|
} else { |
|
++counts[count]; |
|
} |
|
} |
|
|
|
} |
|
|
|
std::map<size_t, size_t>::const_iterator iter; |
|
for (iter = counts.begin(); iter != counts.end(); ++iter) { |
|
cerr << iter->first << "=" << iter->second << " "; |
|
} |
|
cerr << endl; |
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|