Program Listing for File netlist_algo.hpp¶
↰ Return to documentation for file (ckpttncpp/netlist_algo.hpp)
#include <algorithm>
// #include <range/v3/algorithm/any_of.hpp>
// #include <range/v3/algorithm/min_element.hpp>
#include <tuple>
template <typename Netlist, typename C1, typename C2>
auto min_vertex_cover(const Netlist& H, const C1& weight, C2& coverset) ->
typename C1::mapped_type
{
using T = typename C1::mapped_type;
auto in_coverset = [&](const auto& v) { return coverset.contains(v); };
[[maybe_unused]] auto total_dual_cost = T(0);
auto total_primal_cost = T(0);
auto gap = weight;
for (const auto& net : H.nets)
{
if (std::any_of(H.G[net].begin(), H.G[net].end(), in_coverset))
{
continue;
}
auto min_vtx = *std::min_element(H.G[net].begin(), H.G[net].end(),
[&](const auto& v1, const auto& v2) { return gap[v1] < gap[v2]; });
auto min_val = gap[min_vtx];
coverset.insert(min_vtx);
total_primal_cost += weight[min_vtx];
total_dual_cost += min_val;
for (const auto& u : H.G[net])
{
gap[u] -= min_val;
}
}
assert(total_dual_cost <= total_primal_cost);
return total_primal_cost;
}
template <typename Netlist, typename C1, typename C2>
auto min_maximal_matching(const Netlist& H, const C1& weight, C2&& matchset,
C2&& dep) -> typename C1::mapped_type
{
auto cover = [&](const auto& net)
{
for (const auto& v : H.G[net])
{
dep.insert(v);
}
};
auto in_dep = [&](const auto& v) { return dep.contains(v); };
// auto any_of_dep = [&](const auto& net) {
// return ranges::any_of(
// H.G[net], [&](const auto& v) { return dep.contains(v); });
// };
using T = typename C1::mapped_type;
auto gap = weight;
[[maybe_unused]] auto total_dual_cost = T(0);
auto total_primal_cost = T(0);
for (const auto& net : H.nets)
{
if (std::any_of(H.G[net].begin(), H.G[net].end(), in_dep))
{
continue;
}
if (matchset.contains(net))
{ // pre-define independant
cover(net);
continue;
}
auto min_val = gap[net];
auto min_net = net;
for (const auto& v : H.G[net])
{
for (const auto& net2 : H.G[v])
{
if (std::any_of(H.G[net2].begin(), H.G[net2].end(), in_dep))
{
continue;
}
if (min_val > gap[net2])
{
min_val = gap[net2];
min_net = net2;
}
}
}
cover(min_net);
matchset.insert(min_net);
total_primal_cost += weight[min_net];
total_dual_cost += min_val;
if (min_net != net)
{
gap[net] -= min_val;
for (const auto& v : H.G[net])
{
for (const auto& net2 : H.G[v])
{
gap[net2] -= min_val;
}
}
}
}
// assert(total_dual_cost <= total_primal_cost);
return total_primal_cost;
}