Porytiles
Loading...
Searching...
No Matches
packing_metrics.cpp
Go to the documentation of this file.
2
3#include <ranges>
4
5namespace porytiles {
6
7std::map<std::size_t, std::size_t>
8build_global_multiplicity_map(const std::vector<PackableTile> &tiles, const std::vector<PackableTile> &hints)
9{
10 std::map<std::size_t, std::size_t> multiplicity;
11
12 auto count_colors = [&multiplicity](const std::vector<PackableTile> &tile_list) {
13 for (const auto &tile : tile_list) {
14 for_each_color(tile.color_set(), [&multiplicity](std::size_t color_idx) { multiplicity[color_idx]++; });
15 }
16 };
17
18 count_colors(tiles);
19 count_colors(hints);
20
21 return multiplicity;
22}
23
24double compute_average_multiplicity(const std::vector<PackableTile> &tiles, const std::vector<PackableTile> &hints)
25{
26 auto global_mult = build_global_multiplicity_map(tiles, hints);
27
28 if (global_mult.empty()) {
29 return 0.0;
30 }
31
32 // Card(T) = sum of all multiplicities = sum of tile sizes
33 std::size_t cardinality = 0;
34 for (const auto &count : global_mult | std::views::values) {
35 cardinality += count;
36 }
37
38 // |A| = number of unique colors
39 const std::size_t num_colors = global_mult.size();
40
41 // Average multiplicity = Card(T) / |A|
42 return static_cast<double>(cardinality) / static_cast<double>(num_colors);
43}
44
45std::map<std::size_t, std::size_t> build_palette_local_multiplicity(
46 const PackedPalette &palette, const std::map<PackableTile::Id, ColorSet> &tile_colors_map)
47{
48 std::map<std::size_t, std::size_t> local_mult;
49
50 for (const auto &tile_id : palette.assigned_tile_ids()) {
51 if (auto it = tile_colors_map.find(tile_id); it != tile_colors_map.end()) {
52 for_each_color(it->second, [&local_mult](std::size_t color_idx) { local_mult[color_idx]++; });
53 }
54 }
55
56 return local_mult;
57}
58
60 const ColorSet &tile_colors,
61 const PackedPalette &palette,
62 const std::map<PackableTile::Id, ColorSet> &tile_colors_map)
63{
64 auto local_mult = build_palette_local_multiplicity(palette, tile_colors_map);
65
66 double weighted_cost = 0.0;
67 for_each_color(tile_colors, [&weighted_cost, &local_mult](std::size_t color_idx) {
68 std::size_t count = 0;
69 if (const auto it = local_mult.find(color_idx); it != local_mult.end()) {
70 count = it->second;
71 }
72 weighted_cost += 1.0 / static_cast<double>(1 + count);
73 });
74
75 return weighted_cost;
76}
77
78double
79compute_palette_local_efficiency(const ColorSet &tile_colors, const std::map<std::size_t, std::size_t> &local_mult)
80{
81 const std::size_t color_count = color_set_count(tile_colors);
82 if (color_count == 0) {
83 return 1.0;
84 }
85
86 // Compute weighted cost using palette-local multiplicity
87 // Note: Here we use count directly (not 1+count) because the tile IS in the palette,
88 // so its colors are already counted in local_mult
89 double weighted_cost = 0.0;
90 for_each_color(tile_colors, [&weighted_cost, &local_mult](std::size_t color_idx) {
91 std::size_t count = 1; // Default to 1 if color not found (this tile is the only one with it)
92 if (const auto it = local_mult.find(color_idx); it != local_mult.end()) {
93 count = it->second;
94 }
95 weighted_cost += 1.0 / static_cast<double>(count);
96 });
97
98 return 1.0 - (weighted_cost / static_cast<double>(color_count));
99}
100
101double compute_weighted_cost_in_palette_fast(const ColorSet &tile_colors, const PackedPalette &palette)
102{
103 double weighted_cost = 0.0;
104 for_each_color(tile_colors, [&weighted_cost, &palette](std::size_t color_idx) {
105 const std::size_t count = palette.color_multiplicity(color_idx);
106 weighted_cost += 1.0 / static_cast<double>(1 + count);
107 });
108 return weighted_cost;
109}
110
111double compute_palette_local_efficiency_fast(const ColorSet &tile_colors, const PackedPalette &palette)
112{
113 const std::size_t color_count = color_set_count(tile_colors);
114 if (color_count == 0) {
115 return 1.0;
116 }
117
118 // Compute weighted cost using palette's cached color counts
119 // Note: Here we use count directly (not 1+count) because the tile IS in the palette,
120 // so its colors are already counted in the palette's color_counts
121 double weighted_cost = 0.0;
122 for_each_color(tile_colors, [&weighted_cost, &palette](std::size_t color_idx) {
123 const std::size_t count = std::max(palette.color_multiplicity(color_idx), std::size_t{1});
124 weighted_cost += 1.0 / static_cast<double>(count);
125 });
126
127 return 1.0 - (weighted_cost / static_cast<double>(color_count));
128}
129
130} // namespace porytiles
A set of colors represented as a bitset.
Definition color_set.hpp:26
Represents a hardware palette after packing with accumulated colors and assigned tiles.
const std::vector< PackableTile::Id > & assigned_tile_ids() const
std::size_t color_multiplicity(std::size_t color_idx) const
void for_each_color(const ColorSet &set, Func &&func)
Iterates over each color index in a ColorSet.
double compute_palette_local_efficiency(const ColorSet &tile_colors, const std::map< std::size_t, std::size_t > &local_mult)
Computes the palette-local efficiency of a tile within its palette.
double compute_weighted_cost_in_palette_fast(const ColorSet &tile_colors, const PackedPalette &palette)
Computes the weighted cost of placing a tile in a palette using cached counts.
double compute_weighted_cost_in_palette(const ColorSet &tile_colors, const PackedPalette &palette, const std::map< PackableTile::Id, ColorSet > &tile_colors_map)
Computes the weighted cost of placing a tile in a specific palette.
std::map< std::size_t, std::size_t > build_global_multiplicity_map(const std::vector< PackableTile > &tiles, const std::vector< PackableTile > &hints)
Builds a GLOBAL multiplicity map from all input tiles.
std::map< std::size_t, std::size_t > build_palette_local_multiplicity(const PackedPalette &palette, const std::map< PackableTile::Id, ColorSet > &tile_colors_map)
Builds a PALETTE-LOCAL multiplicity map for a specific palette.
double compute_average_multiplicity(const std::vector< PackableTile > &tiles, const std::vector< PackableTile > &hints)
Computes the average multiplicity of the input tiles (problem difficulty metric).
constexpr std::size_t num_colors
Maximum allowable color count for GBA hardware.
Definition color_set.hpp:17
double compute_palette_local_efficiency_fast(const ColorSet &tile_colors, const PackedPalette &palette)
Computes the palette-local efficiency of a tile using cached counts.
std::size_t color_set_count(const ColorSet &set)
Counts the number of colors in a ColorSet.
Definition color_set.cpp:44
Metrics for Bin Packing with Overlapping Items (Pagination problem).