OrcaSlicer latest
OrcaSlicer
Loading...
Searching...
No Matches
Slic3r::GeneralMinCostLowerBoundsSolver Class Reference

#include </home/runner/work/OrcaSlicer/OrcaSlicer/src/libslic3r/GCode/ToolOrderUtils.hpp>

Collaboration diagram for Slic3r::GeneralMinCostLowerBoundsSolver:

Classes

struct  LowerBoundEdge

Public Member Functions

 GeneralMinCostLowerBoundsSolver (const std::vector< FlushMatrix > &matrix_, const std::vector< int > &u_nodes, const std::vector< int > &v_nodes, const std::vector< int > &v_nodes_group, const std::unordered_map< int, std::vector< int > > &uv_link_limits={}, const std::unordered_map< int, std::vector< int > > &uv_unlink_limits={})
std::vector< int > solve ()
 ~GeneralMinCostLowerBoundsSolver ()

Private Member Functions

void build_feasible_graph (const std::unordered_set< int > &no_lower_groups)
void build_graph_with_feasible_result ()
void add_edge_with_lower_bound (int from, int to, int lower, int upper, int cost)
int get_distance (const int idx_in_left, const int idx_in_right)

Private Attributes

std::unique_ptr< MaxFlowWithLowerBounds > m_solver_lower_bounds
std::unique_ptr< MinCostMaxFlow > m_solver_min_cost
std::vector< FlushMatrix > flush_matrix
std::vector< int > l_nodes
std::vector< int > r_nodes
std::vector< int > r_nodes_group
std::unordered_map< int, std::vector< int > > m_uv_link_limits
std::unordered_map< int, std::vector< int > > m_uv_unlink_limits
int num_groups = 0
std::vector< int > demand
std::vector< LowerBoundEdge > lower_bound_edges
int super_source = -1
int super_sink = -1
int source_id = -1
int sink_id = -1
int max_flow_edges = 0

Detailed Description


Class Documentation

◆ Slic3r::GeneralMinCostLowerBoundsSolver::LowerBoundEdge

struct Slic3r::GeneralMinCostLowerBoundsSolver::LowerBoundEdge
Class Members
int edge_id
int lower

Constructor & Destructor Documentation

◆ GeneralMinCostLowerBoundsSolver()

Slic3r::GeneralMinCostLowerBoundsSolver::GeneralMinCostLowerBoundsSolver ( const std::vector< FlushMatrix > & matrix_,
const std::vector< int > & u_nodes,
const std::vector< int > & v_nodes,
const std::vector< int > & v_nodes_group,
const std::unordered_map< int, std::vector< int > > & uv_link_limits = {},
const std::unordered_map< int, std::vector< int > > & uv_unlink_limits = {} )
390 {
391 flush_matrix = matrix_;
392 l_nodes = u_nodes;
393 r_nodes = v_nodes;
394 r_nodes_group = v_nodes_group;
395 m_uv_link_limits = uv_link_limits;
396 m_uv_unlink_limits = uv_unlink_limits;
397 num_groups = *std::max_element(r_nodes_group.begin(), r_nodes_group.end()) + 1;
398
399 m_solver_lower_bounds = std::make_unique<MaxFlowWithLowerBounds>();
400 m_solver_min_cost = std::make_unique<MinCostMaxFlow>();
401 }
std::vector< int > l_nodes
Definition ToolOrderUtils.hpp:103
std::vector< int > r_nodes
Definition ToolOrderUtils.hpp:104
std::unique_ptr< MaxFlowWithLowerBounds > m_solver_lower_bounds
Definition ToolOrderUtils.hpp:99
std::unordered_map< int, std::vector< int > > m_uv_link_limits
Definition ToolOrderUtils.hpp:106
int num_groups
Definition ToolOrderUtils.hpp:108
std::unique_ptr< MinCostMaxFlow > m_solver_min_cost
Definition ToolOrderUtils.hpp:100
std::vector< FlushMatrix > flush_matrix
Definition ToolOrderUtils.hpp:102
std::vector< int > r_nodes_group
Definition ToolOrderUtils.hpp:105
std::unordered_map< int, std::vector< int > > m_uv_unlink_limits
Definition ToolOrderUtils.hpp:107

References flush_matrix, l_nodes, m_solver_lower_bounds, m_solver_min_cost, m_uv_link_limits, m_uv_unlink_limits, num_groups, r_nodes, and r_nodes_group.

◆ ~GeneralMinCostLowerBoundsSolver()

Slic3r::GeneralMinCostLowerBoundsSolver::~GeneralMinCostLowerBoundsSolver ( )
default

Member Function Documentation

◆ add_edge_with_lower_bound()

void Slic3r::GeneralMinCostLowerBoundsSolver::add_edge_with_lower_bound ( int from,
int to,
int lower,
int upper,
int cost )
private
544 {
545 int eid = m_solver_lower_bounds->edges.size();
546 m_solver_lower_bounds->add_edge(from, to, upper - lower);
547
548 lower_bound_edges.push_back({eid, lower});
549 demand[from] -= lower;
550 demand[to] += lower;
551 }
std::vector< LowerBoundEdge > lower_bound_edges
Definition ToolOrderUtils.hpp:117
std::vector< int > demand
Definition ToolOrderUtils.hpp:116

References demand, lower_bound_edges, and m_solver_lower_bounds.

Referenced by build_feasible_graph().

Here is the caller graph for this function:

◆ build_feasible_graph()

void Slic3r::GeneralMinCostLowerBoundsSolver::build_feasible_graph ( const std::unordered_set< int > & no_lower_groups)
private
432 {
435 m_solver_lower_bounds->total_nodes = l_nodes.size() + r_nodes.size() + num_groups + 2;
436
437 m_solver_lower_bounds->source_id = m_solver_lower_bounds->total_nodes - 2;
438 m_solver_lower_bounds->sink_id = m_solver_lower_bounds->total_nodes - 1;
439 m_solver_lower_bounds->adj.resize(m_solver_lower_bounds->total_nodes);
440 demand.resize(m_solver_lower_bounds->total_nodes, 0);
441
442 const int L = m_solver_lower_bounds->l_nodes.size();
443 const int R = m_solver_lower_bounds->r_nodes.size();
444
445 // source -> l
446 for (int i = 0; i < L; ++i)
447 m_solver_lower_bounds->add_edge(m_solver_lower_bounds->source_id, i, 1);
448
449 // u -> v (with link/unlink limits)
450 for (int i = 0; i < L; ++i) {
451 if (auto it = m_uv_link_limits.find(i); it != m_uv_link_limits.end()) {
452 for (int j : it->second)
453 m_solver_lower_bounds->add_edge(i, L + j, 1);
454 continue;
455 }
456
457 std::optional<std::vector<int>> unlink_limits;
458 if (auto it = m_uv_unlink_limits.find(i); it != m_uv_unlink_limits.end())
459 unlink_limits = it->second;
460
461 for (int j = 0; j < R; ++j) {
462 if (unlink_limits.has_value() && std::find(unlink_limits->begin(), unlink_limits->end(), j) != unlink_limits->end())
463 continue;
464 m_solver_lower_bounds->add_edge(i, L + j, 1);
465 }
466 }
467
468 // r -> group
469 for (int j = 0; j < R; ++j) {
470 int g = r_nodes_group[j];
471 m_solver_lower_bounds->add_edge(L + j, L + R + g, 1);
472 }
473
474 // group -> sink (lower bound = 1)
475 for (int g = 0; g < num_groups; ++g) {
476 if (no_lower_groups.count(g))
477 m_solver_lower_bounds->add_edge(L + R + g, m_solver_lower_bounds->sink_id, R);
478 else
479 add_edge_with_lower_bound(L + R + g, m_solver_lower_bounds->sink_id, 1, R, 0);
480 }
481
483
484 // support lower bounds, add super source super sink
485 super_source = m_solver_lower_bounds->total_nodes++;
486 super_sink = m_solver_lower_bounds->total_nodes++;
487
488 m_solver_lower_bounds->adj.resize(m_solver_lower_bounds->total_nodes);
489 demand.resize(m_solver_lower_bounds->total_nodes, 0);
490
491 for (int i = 0; i < super_source; ++i) {
492 if (demand[i] > 0) {
493 m_solver_lower_bounds->add_edge(super_source, i, demand[i]);
494 } else if (demand[i] < 0) {
495 m_solver_lower_bounds->add_edge(i, super_sink, -demand[i]);
496 }
497 }
499 source_id = m_solver_lower_bounds->source_id;
503 }
#define L(s)
Definition ExtrusionEntity.cpp:25
int super_source
Definition ToolOrderUtils.hpp:119
int max_flow_edges
Definition ToolOrderUtils.hpp:123
void add_edge_with_lower_bound(int from, int to, int lower, int upper, int cost)
Definition ToolOrderUtils.cpp:543
int sink_id
Definition ToolOrderUtils.hpp:122
int source_id
Definition ToolOrderUtils.hpp:121
int super_sink
Definition ToolOrderUtils.hpp:120
const int INF
Definition ToolOrderUtils.hpp:20

References add_edge_with_lower_bound(), demand, Slic3r::MaxFlowGraph::INF, L, l_nodes, m_solver_lower_bounds, m_uv_link_limits, m_uv_unlink_limits, max_flow_edges, num_groups, r_nodes, r_nodes_group, sink_id, source_id, super_sink, and super_source.

Referenced by solve().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ build_graph_with_feasible_result()

void Slic3r::GeneralMinCostLowerBoundsSolver::build_graph_with_feasible_result ( )
private
506 {
507 for (auto&lb:lower_bound_edges){
508 m_solver_lower_bounds->edges[lb.edge_id].flow += lb.lower;
509 m_solver_lower_bounds->edges[lb.edge_id ^ 1].flow -= lb.lower;
510 }
511
512 m_solver_min_cost->l_nodes = m_solver_lower_bounds->l_nodes;
513 m_solver_min_cost->r_nodes = m_solver_lower_bounds->r_nodes;
514
515 m_solver_min_cost->source_id = source_id;
516 m_solver_min_cost->sink_id = sink_id;
517 m_solver_min_cost->total_nodes = sink_id + 1;
518
520 m_solver_min_cost->edges.erase(m_solver_min_cost->edges.begin() + max_flow_edges, m_solver_min_cost->edges.end());
521
523 m_solver_min_cost->adj.resize(m_solver_min_cost->total_nodes);
524 for (auto &node_edges : m_solver_min_cost->adj) {
525 node_edges.erase(std::remove_if(node_edges.begin(), node_edges.end(), [this](int val) {return val >= this->max_flow_edges;}), node_edges.end());
526 }
527
528
529 for (auto& e : m_solver_min_cost->edges) {
530 int L = m_solver_min_cost->l_nodes.size();
531 int R = m_solver_min_cost->r_nodes.size();
532
533 if (e.from < L && e.to >= L && e.to < L + R) {
534 int idx_in_left = e.from;
535 int idx_in_right = e.to - L;
536 int group_id = r_nodes_group[idx_in_right];
537
538 if (r_nodes[idx_in_right] == -1) continue;
539 e.cost = flush_matrix[group_id][l_nodes[idx_in_left]][r_nodes[idx_in_right]];
540 }
541 }
542 }
uint32_t group_id(std::vector< Bridge > &bridges, uint32_t src_id)
Definition LayerRegion.cpp:214

References flush_matrix, Slic3r::group_id(), L, l_nodes, lower_bound_edges, m_solver_lower_bounds, m_solver_min_cost, max_flow_edges, r_nodes, r_nodes_group, sink_id, and source_id.

Referenced by solve().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_distance()

int Slic3r::GeneralMinCostLowerBoundsSolver::get_distance ( const int idx_in_left,
const int idx_in_right )
private

◆ solve()

std::vector< int > Slic3r::GeneralMinCostLowerBoundsSolver::solve ( )
404 {
405 // group nodes that do not need a lower-bound constraint
406 std::unordered_set<int> no_lower_group;
407 for (int i = 0; i < r_nodes.size(); i++) {
408 if (r_nodes[i] >= 0)
409 no_lower_group.insert(r_nodes_group[i]);
410 }
411
412 // 1. build the lower-bound network graph
413 build_feasible_graph(no_lower_group);
414
415 // 2. compute the max flow
416 int need = 0;
417 for (int d : demand)
418 if (d > 0) need += d;
419 std::vector<int> feasible_matching;
420 int pushed_flow = m_solver_lower_bounds->solve(feasible_matching);
421 assert(need == pushed_flow);
422
423 // 3. convert the lower-bound max-flow network into a min-cost-max-flow network
425 // 4. compute the min-cost max-flow
426 auto min_cost_matching = m_solver_min_cost->solve();
427
428 return min_cost_matching;
429 }
void build_feasible_graph(const std::unordered_set< int > &no_lower_groups)
Definition ToolOrderUtils.cpp:431
void build_graph_with_feasible_result()
Definition ToolOrderUtils.cpp:505

References build_feasible_graph(), build_graph_with_feasible_result(), demand, m_solver_lower_bounds, m_solver_min_cost, r_nodes, and r_nodes_group.

Here is the call graph for this function:

Member Data Documentation

◆ demand

std::vector<int> Slic3r::GeneralMinCostLowerBoundsSolver::demand
private

◆ flush_matrix

std::vector<FlushMatrix> Slic3r::GeneralMinCostLowerBoundsSolver::flush_matrix
private

◆ l_nodes

std::vector<int> Slic3r::GeneralMinCostLowerBoundsSolver::l_nodes
private

◆ lower_bound_edges

std::vector<LowerBoundEdge> Slic3r::GeneralMinCostLowerBoundsSolver::lower_bound_edges
private

◆ m_solver_lower_bounds

std::unique_ptr<MaxFlowWithLowerBounds> Slic3r::GeneralMinCostLowerBoundsSolver::m_solver_lower_bounds
private

◆ m_solver_min_cost

std::unique_ptr<MinCostMaxFlow> Slic3r::GeneralMinCostLowerBoundsSolver::m_solver_min_cost
private

◆ m_uv_link_limits

std::unordered_map<int, std::vector<int> > Slic3r::GeneralMinCostLowerBoundsSolver::m_uv_link_limits
private

◆ m_uv_unlink_limits

std::unordered_map<int, std::vector<int> > Slic3r::GeneralMinCostLowerBoundsSolver::m_uv_unlink_limits
private

◆ max_flow_edges

int Slic3r::GeneralMinCostLowerBoundsSolver::max_flow_edges = 0
private

◆ num_groups

int Slic3r::GeneralMinCostLowerBoundsSolver::num_groups = 0
private

◆ r_nodes

std::vector<int> Slic3r::GeneralMinCostLowerBoundsSolver::r_nodes
private

◆ r_nodes_group

std::vector<int> Slic3r::GeneralMinCostLowerBoundsSolver::r_nodes_group
private

◆ sink_id

int Slic3r::GeneralMinCostLowerBoundsSolver::sink_id = -1
private

◆ source_id

int Slic3r::GeneralMinCostLowerBoundsSolver::source_id = -1
private

◆ super_sink

int Slic3r::GeneralMinCostLowerBoundsSolver::super_sink = -1
private

Referenced by build_feasible_graph().

◆ super_source

int Slic3r::GeneralMinCostLowerBoundsSolver::super_source = -1
private

Referenced by build_feasible_graph().


The documentation for this class was generated from the following files: