The cost of a solution produced by
the interactive dependency resolver is a value that
aptitude uses to determine how “bad” that
solution is. Solutions that are “better” are
always displayed before solutions that are
“worse”. The cost of solutions is defined in
the configuration option Aptitude::ProblemResolver::SolutionCost
.
Some typical costs are shown in Example 2.1, “Sample resolver costs”.
Example 2.1. Sample resolver costs
The default cost, sorting solutions by their safety cost, then by their apt pin priority:
safety, priority
Remove as few packages as possible, then cancel as few actions as possible:
removals, canceled-actions
Sort solutions by the number of packages they remove plus twice the number of actions they cancel.
removals + 2 * canceled-actions
As can be seen from the above examples, a cost is not
necessarily a single number. In fact, a cost consists of
one or more cost components, each
of which is a number associated with the solution. When
sorting solutions, the resolver examines cost components
in order, proceeding to later components only if the
earlier ones are equal. For instance, in the cost
“removals,
canceled-actions
”, solutions with fewer
removals always appear before solutions with more
removals, regardless of how many canceled actions they
have. However, solutions with the same number of removals
are sorted so that solutions with fewer canceled actions
appear first.
Cost components come in two flavors: basic cost components and compound cost components.
Basic components simply name some property of the
solution, such as
“upgrades
” or
“removals
”. A list of
built-in basic components provided by aptitude can be
found in Table 2.1, “Basic cost components”. You
can also create your own cost components using the
add-to-cost-component
and
raise-cost-component
hints; see the section called “Configuring resolver hints” for details.
Each basic component is either a counter or a level. Counters count how many of a solution's actions meet some condition (such as removing packages or installing new packages), while levels associate a number with each action and compute the highest number associated with any action in the solution.
Table 2.1. Basic cost components
Name | Type | Description |
---|---|---|
broken-holds | Counter |
Counts the number of holds that the solution
breaks, if the resolver is allowed to break holds
(Aptitude::ProblemResolver::Allow-Break-Holds ).
|
canceled-actions | Counter | Counts the number of pending actions that the solution cancels (keeping packages at their current version). |
installs | Counter | Counts the number of packages that the solution installs. |
non-default-versions | Counter | Counts the number of versions that the solution installs or upgrades from non-default sources. |
priority | Level | A value that increases as the apt pin priority of a version decreases. Specifically, this is computed by negating the pin priority (so, e.g., if the pin priority is 500, this component will compute -500). |
removals | Counter | Counts the number of packages that the solution removes. |
removals-of-manual | Counter | Counts the number of manually installed packages that the solution removes. |
safety | Level | A broad heuristic that increases as actions become less “safe”; see the section called “Safety costs” for details. |
upgrades | Counter | Counts the number of packages that the solution upgrades. |
Compound components are built by combining the values of
basic components. For instance, removals +
canceled-actions
adds the components
removal
and
canceled-actions
, resulting in a
component that counts the number of removals
and canceled actions. Compound
components combine counters by adding them together and
levels by taking their maximum value, as shown in Figure 2.11, “Syntax of compound cost components”.
Note | |
---|---|
It is an error to add two levels, or to take the maximum
of two counters, or to combine levels and counters in
any way. For instance, the costs |
Figure 2.11. Syntax of compound cost components
Add two or more basic costs:
[scale1
]*cost1
+ [scale2
]*cost2
+ ...
Take the maximum value of two or more basic costs:
max([scale1
]*cost1
, [scale2
]*cost2
, ...)
Note that each individual basic component can be
multiplied by a scaling factor before it is combined with
other components. This can be used to control the
trade-offs that the resolver makes between costs. For
instance, a cost of 2*removals +
3*upgrades
says that three removals are exactly as
“bad” as two upgrades. Solutions that
contain four removals and one upgrade will be considered
equivalent to solutions containing one removal and three
upgrades, since both have a cost of eleven.
The safety
cost component is a
heuristic estimate of how “safe” or
“unsafe” a solution is. Safety costs can be
thought of as a way of dividing solutions into several
numbered “levels”, where “less
safe” levels are given higher numbers. Figure 2.12, “Safety cost levels” shows how this works
with aptitude's default settings.
Tip | |
---|---|
Safety cost levels are just one way to control the order in which dependency solutions are returned. See the section called “Costs in the interactive dependency resolver” for a full description of how to change the order in which aptitude sorts solutions. |
By default, aptitude initializes the resolver with a “reasonable” set of safety cost levels. They are:
Table 2.2. Default safety cost levels
Cost level | Description | Configuration option |
---|---|---|
10,000 | Solutions that include only “safe” actions (installing the default target for a package or keeping a package at its current version) and package removals. | Aptitude::ProblemResolver::Safe-Level , Aptitude::ProblemResolver::Remove-Level |
10,000 |
The solution that cancels all the user's actions. It used
to be higher than Aptitude::ProblemResolver::Remove-Level ,
but removing packages was ranked higher than keeping the
same packages, even if the package was to be upgraded.
| Aptitude::ProblemResolver::Keep-All-Level |
40,000 | Solutions that break holds set by the user or install forbidden versions. | Aptitude::ProblemResolver::Break-Hold-Level |
50,000 |
Solutions that install packages from non-default
versions (such as
“experimental ”,
for instance).
| Aptitude::ProblemResolver::Non-Default-Level |
60,000 | Solutions that remove Essential packages. | Aptitude::ProblemResolver::Remove-Essential-Level |
If a solution qualifies for several safety cost levels, it will be placed in the highest one, that is, the one that appears last. For example, a solution that upgrades one package to its default version and breaks a hold on a second package will be placed at level 40,000. You can adjust the levels of individual versions using resolver hints; see the section called “Configuring resolver hints” for details. The default levels are illustrated in Figure 2.12, “Safety cost levels”.
Besides numbers you can also use the keywords
“maximum
” and
“minimum
” for cost
levels. They refer to the maximal respective minimal
integer value possible on the hardware architecture of
your system.
[13] This limit was imposed because more complex cost structures could make it difficult to optimize the resolver. Future versions of the program might remove some of the restrictions if they turn out to be unnecessary.