ENH: add greedy algorithm for filament reorder

1.When n becomes large,the original algorithm to get best filament
sequence will cost too much time and memory.Use a greedy algorithm
instead.Always select the next filament with fewest flush

jira:NONE

Signed-off-by: xun.zhang <xun.zhang@bambulab.com>
Change-Id: Iabc924e1bdb0a07af0a6ef0bbdd62e54ce54f052
This commit is contained in:
xun.zhang 2024-07-18 16:38:26 +08:00 committed by lane.wei
parent adf208dbb9
commit 3167e34e60
1 changed files with 42 additions and 2 deletions

View File

@ -26,8 +26,46 @@ const static bool g_wipe_into_objects = false;
static std::vector<unsigned int>solve_extruder_order_with_greedy(const std::vector<std::vector<float>>& wipe_volumes,
const std::vector<unsigned int> curr_layer_extruders,
const std::optional<unsigned int>&start_extruder_id,
float* min_cost)
{
float cost = 0;
std::vector<unsigned int> best_seq;
std::vector<bool>is_visited(curr_layer_extruders.size(), false);
std::optional<unsigned int>prev_filament = start_extruder_id;
int idx = curr_layer_extruders.size();
while (idx > 0) {
if (!prev_filament) {
auto iter = std::find_if(is_visited.begin(), is_visited.end(), [](auto item) {return item == 0; });
assert(iter != is_visited.end());
prev_filament = curr_layer_extruders[iter - is_visited.begin()];
}
int target_idx = -1;
int target_cost = std::numeric_limits<int>::max();
for (size_t k = 0; k < is_visited.size(); ++k) {
if (!is_visited[k]) {
if (wipe_volumes[*prev_filament][curr_layer_extruders[k]] < target_cost) {
target_idx = k;
target_cost = wipe_volumes[*prev_filament][curr_layer_extruders[k]];
}
}
}
assert(target_idx != -1);
cost += target_cost;
best_seq.emplace_back(curr_layer_extruders[target_idx]);
prev_filament = curr_layer_extruders[target_idx];
is_visited[target_idx] = true;
idx -= 1;
}
if (min_cost)
*min_cost = cost;
return best_seq;
}
//solve the probleme by forcasting one layer
static std::vector<unsigned int>solve_extruder_order_with_forcast(const std::vector<std::vector<float>>wipe_volumes,
static std::vector<unsigned int>solve_extruder_order_with_forcast(const std::vector<std::vector<float>>& wipe_volumes,
std::vector<unsigned int> curr_layer_extruders,
std::vector<unsigned int> next_layer_extruders,
const std::optional<unsigned int>& start_extruder_id,
@ -162,8 +200,10 @@ std::vector<unsigned int> get_extruders_order(const std::vector<std::vector<floa
if (use_forcast)
return solve_extruder_order_with_forcast(wipe_volumes, curr_layer_extruders, next_layer_extruders, start_extruder_id, cost);
else
else if(curr_layer_extruders.size() <= 20)
return solve_extruder_order(wipe_volumes, curr_layer_extruders, start_extruder_id, cost);
else
return solve_extruder_order_with_greedy(wipe_volumes,curr_layer_extruders,start_extruder_id,cost);
}
int reorder_filaments_for_minimum_flush_volume(const std::vector<unsigned int>&filament_lists,