Skip to content

Commit

Permalink
Support combining different diversity measures and constraining them (#…
Browse files Browse the repository at this point in the history
…189)

* Add support for combining different diversity measures and constrainting them.

* Fix formatting

---------

Co-authored-by: Jip J. Dekker <[email protected]>
  • Loading branch information
ilansen and Dekker1 authored Jan 29, 2025
1 parent ff0b84f commit 45fabec
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 4 deletions.
29 changes: 26 additions & 3 deletions src/minizinc/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ def _add_diversity_to_opt_model(
def _add_diversity_to_div_model(
inst: minizinc.Instance,
vars: List[Dict[str, Any]],
obj_sense: str,
div_anns: Dict[str, Any],
gap: Union[int, float],
sols: Dict[str, Any],
):
Expand Down Expand Up @@ -190,15 +190,38 @@ def _add_diversity_to_div_model(
f"array [1..{len(prevsol)}] of var {varprevtype}: dist_{varname} :: output = [{distfun}({varname}, {varprevname}[sol,{dotdots}]) | sol in 1..{len(prevsol)}];\n"
)

# Add minimum distance to the diversity distance measurement in the model code
if var["lb"] != "infinity":
inst.add_string(
f"constraint forall(sol in 1..{len(prevsol)})( dist_{varname}[sol] >= {var['lb']});"
)

# Add maximum distance to the diversity distance measurement in the model code
if var["ub"] != "infinity":
inst.add_string(
f"constraint forall(sol in 1..{len(prevsol)})( dist_{varname}[sol] <= {var['ub']});"
)

obj_sense = div_anns["objective"]["sense"]
aggregator = (
div_anns["aggregator"] if div_anns["aggregator"] != "" else "sum"
)
combinator = (
div_anns["combinator"] if div_anns["combinator"] != "" else "sum"
)

# Add the bound on the objective.
if obj_sense == "-1":
inst.add_string(f"constraint div_orig_objective <= {gap};\n")
elif obj_sense == "1":
inst.add_string(f"constraint div_orig_objective >= {gap};\n")

# Add new objective: maximize diversity.
dist_sum = "+".join([f'sum(dist_{var["name"]})' for var in vars])
inst.add_string(f"solve maximize {dist_sum};\n")
div_combinator = ", ".join(
[f'{var["coef"]} * dist_{var["name"]}[sol]' for var in vars]
)
dist_total = f"{aggregator}([{combinator}([{div_combinator}]) | sol in 1..{len(prevsol)}])"
inst.add_string(f"solve maximize {dist_total};\n")

return inst

Expand Down
2 changes: 1 addition & 1 deletion src/minizinc/instance.py
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@ async def diverse_solutions(
child = _add_diversity_to_div_model(
child,
variables,
obj_anns["sense"],
div_anns,
max_gap,
prev_solutions,
)
Expand Down

0 comments on commit 45fabec

Please sign in to comment.