|
Shinya Kitaoka |
810553 |
#pragma once
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifndef TCG_SEQUENCE_OPS_HPP
|
|
Toshihiro Shimizu |
890ddd |
#define TCG_SEQUENCE_OPS_HPP
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "../sequence_ops.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef min
|
|
Toshihiro Shimizu |
890ddd |
#undef min
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
namespace tcg {
|
|
Shinya Kitaoka |
120a6e |
namespace sequence_ops {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//***********************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//***********************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <typename containers_reader="" edge_eval,="" ranit_type,="" typename=""></typename>
|
|
Shinya Kitaoka |
120a6e |
bool minimalPath(ranit_type begin, ranit_type end, edge_eval &eval,
|
|
Shinya Kitaoka |
120a6e |
containers_reader &output) {
|
|
Shinya Kitaoka |
120a6e |
typedef typename ranit_type::difference_type diff_type;
|
|
Shinya Kitaoka |
120a6e |
typedef typename edge_eval::penalty_type penalty_type;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
ranit_type a, b;
|
|
Shinya Kitaoka |
120a6e |
diff_type i, j, m, n = end - begin, last = n - 1;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::vector<diff_type> furthest(n);</diff_type>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
diff_type currFurthest = furthest[last] = last;
|
|
Shinya Kitaoka |
120a6e |
for (i = last - 1; i >= 0;
|
|
Shinya Kitaoka |
120a6e |
currFurthest = furthest[i] =
|
|
Shinya Kitaoka |
120a6e |
std::min(eval.furthestFrom(begin + i) - begin, currFurthest);
|
|
Shinya Kitaoka |
120a6e |
if (currFurthest == i)
|
|
Shinya Kitaoka |
120a6e |
return false; // There exists no path from start to end - quit
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Iterate from begin to end, using the maximum step allowed. The number of
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (i = 0, m = 0; i < last; i = furthest[i], ++m)
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::vector<diff_type> upperBound(m + 1);</diff_type>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (i = 0, j = 0; i <= m; j = furthest[j], ++i) upperBound[i] = j;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::vector<penalty_type> minPenaltyToEnd(n);</penalty_type>
|
|
Shinya Kitaoka |
120a6e |
std::vector<diff_type> minPenaltyNext(last);</diff_type>
|
|
Shinya Kitaoka |
120a6e |
diff_type aIdx, bIdx;
|
|
Shinya Kitaoka |
120a6e |
penalty_type newPenalty;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
minPenaltyToEnd[last] = 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
diff_type nextLowerBound;
|
|
Shinya Kitaoka |
120a6e |
for (j = m - 1, nextLowerBound = last; j >= 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (aIdx = upperBound[j]; aIdx >= 0 && furthest[aIdx] >= nextLowerBound;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
a = begin + aIdx;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
minPenaltyToEnd[aIdx] = (std::numeric_limits<penalty_type>::max)();</penalty_type>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (bIdx = nextLowerBound, b = begin + nextLowerBound;
|
|
Shinya Kitaoka |
120a6e |
furthest[aIdx] >= bIdx; ++b, ++bIdx) {
|
|
Shinya Kitaoka |
120a6e |
assert(minPenaltyToEnd[bIdx] <
|
|
Shinya Kitaoka |
120a6e |
(std::numeric_limits<penalty_type>::max)());</penalty_type>
|
|
Shinya Kitaoka |
120a6e |
newPenalty = eval.penalty(a, b) + minPenaltyToEnd[bIdx];
|
|
Shinya Kitaoka |
120a6e |
if (newPenalty < minPenaltyToEnd[aIdx]) {
|
|
Shinya Kitaoka |
120a6e |
minPenaltyToEnd[aIdx] = newPenalty;
|
|
Shinya Kitaoka |
120a6e |
minPenaltyNext[aIdx] = bIdx;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
nextLowerBound = aIdx;
|
|
Shinya Kitaoka |
120a6e |
++nextLowerBound;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
output.openContainer(begin);
|
|
Shinya Kitaoka |
120a6e |
for (i = minPenaltyNext[0], j = 1; j < m; i = minPenaltyNext[i], ++j)
|
|
Shinya Kitaoka |
120a6e |
output.addElement(begin + i);
|
|
Shinya Kitaoka |
120a6e |
output.addElement(begin + last);
|
|
Shinya Kitaoka |
120a6e |
output.closeContainer();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
#endif
|