-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
70 lines (50 loc) · 2.13 KB
/
Copy pathmain.py
File metadata and controls
70 lines (50 loc) · 2.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import time
from importlib.metadata import version
from typing import Any
import highspy
import nextmv
def main() -> None:
"""Entry point for the program."""
loaded_input = nextmv.load()
options = loaded_input.options
nextmv.log("Solving knapsack problem:")
nextmv.log(f" - items: {len(loaded_input.data.get('items', []))}")
nextmv.log(f" - capacity: {loaded_input.data.get('weight_capacity', 0)}")
solution, metrics = solve(loaded_input)
nextmv.write(solution=solution, metrics=metrics, options=options)
def solve(loaded_input: nextmv.Input) -> tuple[dict[str, Any], dict[str, Any]]:
"""Solves the given problem and returns the solution and metrics."""
start_time = time.time()
# Creates the solver.
solver = highspy.Highs()
solver.silent() # Solver output ignores stdout redirect, silence it.
solver.setOptionValue("time_limit", loaded_input.options.duration)
# Initializes the linear sums.
weights = 0.0
values = 0.0
# Creates the decision variables and adds them to the linear sums.
items = []
for item in loaded_input.data["items"]:
item_variable = solver.addVariable(0.0, 1.0, item["value"])
items.append({"item": item, "variable": item_variable})
weights += item_variable * item["weight"]
values += item_variable * item["value"]
# This constraint ensures the weight capacity of the knapsack will not be
# exceeded.
solver.addConstr(weights <= loaded_input.data["weight_capacity"])
# Sets the objective function: maximize the value of the chosen items.
status = solver.maximize(values)
# Determines which items were chosen.
chosen_items = [item["item"] for item in items if solver.val(item["variable"]) > 0.9]
solution = {"items": chosen_items}
metrics = {
"duration": time.time() - start_time,
"value": sum(item["value"] for item in chosen_items),
"status": str(status),
"variables": solver.numVariables,
"constraints": solver.numConstrs,
"solver_version": version("highspy"),
}
return solution, metrics
if __name__ == "__main__":
main()