mirror of
https://github.com/ANL-CEEESA/MIPLearn.git
synced 2025-12-06 01:18:52 -06:00
Use NumPy to compute AlvLouWeh2017 features
This commit is contained in:
@@ -127,7 +127,9 @@ class FeaturesExtractor:
|
|||||||
]:
|
]:
|
||||||
if f is not None:
|
if f is not None:
|
||||||
lp_var_features_list.append(f.reshape(-1, 1))
|
lp_var_features_list.append(f.reshape(-1, 1))
|
||||||
sample.put_array("lp_var_features", np.hstack(lp_var_features_list))
|
lp_var_features = np.hstack(lp_var_features_list)
|
||||||
|
_fix_infinity(lp_var_features)
|
||||||
|
sample.put_array("lp_var_features", lp_var_features)
|
||||||
|
|
||||||
# Constraint features
|
# Constraint features
|
||||||
lp_constr_features_list = []
|
lp_constr_features_list = []
|
||||||
@@ -142,7 +144,9 @@ class FeaturesExtractor:
|
|||||||
]:
|
]:
|
||||||
if f is not None:
|
if f is not None:
|
||||||
lp_constr_features_list.append(f.reshape(-1, 1))
|
lp_constr_features_list.append(f.reshape(-1, 1))
|
||||||
sample.put_array("lp_constr_features", np.hstack(lp_constr_features_list))
|
lp_constr_features = np.hstack(lp_constr_features_list)
|
||||||
|
_fix_infinity(lp_constr_features)
|
||||||
|
sample.put_array("lp_constr_features", lp_constr_features)
|
||||||
|
|
||||||
# Build lp_instance_features
|
# Build lp_instance_features
|
||||||
static_instance_features = sample.get_array("static_instance_features")
|
static_instance_features = sample.get_array("static_instance_features")
|
||||||
@@ -311,73 +315,83 @@ class FeaturesExtractor:
|
|||||||
obj_sa_down = sample.get_array("lp_var_sa_obj_down")
|
obj_sa_down = sample.get_array("lp_var_sa_obj_down")
|
||||||
obj_sa_up = sample.get_array("lp_var_sa_obj_up")
|
obj_sa_up = sample.get_array("lp_var_sa_obj_up")
|
||||||
values = sample.get_array("lp_var_values")
|
values = sample.get_array("lp_var_values")
|
||||||
|
|
||||||
assert obj_coeffs is not None
|
assert obj_coeffs is not None
|
||||||
|
obj_coeffs = obj_coeffs.astype(float)
|
||||||
|
_fix_infinity(obj_coeffs)
|
||||||
|
nvars = len(obj_coeffs)
|
||||||
|
|
||||||
pos_obj_coeff_sum = 0.0
|
if obj_sa_down is not None:
|
||||||
neg_obj_coeff_sum = 0.0
|
obj_sa_down = obj_sa_down.astype(float)
|
||||||
for coeff in obj_coeffs:
|
_fix_infinity(obj_sa_down)
|
||||||
if coeff > 0:
|
|
||||||
pos_obj_coeff_sum += coeff
|
|
||||||
if coeff < 0:
|
|
||||||
neg_obj_coeff_sum += -coeff
|
|
||||||
|
|
||||||
features = []
|
|
||||||
for i in range(len(obj_coeffs)):
|
|
||||||
f: List[float] = []
|
|
||||||
if obj_coeffs is not None:
|
|
||||||
# Feature 1
|
|
||||||
f.append(np.sign(obj_coeffs[i]))
|
|
||||||
|
|
||||||
# Feature 2
|
|
||||||
if pos_obj_coeff_sum > 0:
|
|
||||||
f.append(abs(obj_coeffs[i]) / pos_obj_coeff_sum)
|
|
||||||
else:
|
|
||||||
f.append(0.0)
|
|
||||||
|
|
||||||
# Feature 3
|
|
||||||
if neg_obj_coeff_sum > 0:
|
|
||||||
f.append(abs(obj_coeffs[i]) / neg_obj_coeff_sum)
|
|
||||||
else:
|
|
||||||
f.append(0.0)
|
|
||||||
|
|
||||||
if values is not None:
|
|
||||||
# Feature 37
|
|
||||||
f.append(
|
|
||||||
min(
|
|
||||||
values[i] - np.floor(values[i]),
|
|
||||||
np.ceil(values[i]) - values[i],
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
if obj_sa_up is not None:
|
if obj_sa_up is not None:
|
||||||
assert obj_sa_down is not None
|
obj_sa_up = obj_sa_up.astype(float)
|
||||||
assert obj_coeffs is not None
|
_fix_infinity(obj_sa_up)
|
||||||
|
|
||||||
# Convert inf into large finite numbers
|
if values is not None:
|
||||||
sd = max(-1e20, obj_sa_down[i])
|
values = values.astype(float)
|
||||||
su = min(1e20, obj_sa_up[i])
|
_fix_infinity(values)
|
||||||
obj = obj_coeffs[i]
|
|
||||||
|
|
||||||
# Features 44 and 46
|
pos_obj_coeffs_sum = obj_coeffs[obj_coeffs > 0].sum()
|
||||||
f.append(np.sign(obj_sa_up[i]))
|
neg_obj_coeffs_sum = -obj_coeffs[obj_coeffs < 0].sum()
|
||||||
f.append(np.sign(obj_sa_down[i]))
|
|
||||||
|
curr = 0
|
||||||
|
max_n_features = 8
|
||||||
|
features = np.zeros((nvars, max_n_features))
|
||||||
|
with np.errstate(divide="ignore", invalid="ignore"):
|
||||||
|
# Feature 1
|
||||||
|
features[:, curr] = np.sign(obj_coeffs)
|
||||||
|
curr += 1
|
||||||
|
|
||||||
|
# Feature 2
|
||||||
|
if abs(pos_obj_coeffs_sum) > 0:
|
||||||
|
features[:, curr] = np.abs(obj_coeffs) / pos_obj_coeffs_sum
|
||||||
|
curr += 1
|
||||||
|
|
||||||
|
# Feature 3
|
||||||
|
if abs(neg_obj_coeffs_sum) > 0:
|
||||||
|
features[:, curr] = np.abs(obj_coeffs) / neg_obj_coeffs_sum
|
||||||
|
curr += 1
|
||||||
|
|
||||||
|
# Feature 37
|
||||||
|
if values is not None:
|
||||||
|
features[:, curr] = np.minimum(
|
||||||
|
values - np.floor(values),
|
||||||
|
np.ceil(values) - values,
|
||||||
|
)
|
||||||
|
curr += 1
|
||||||
|
|
||||||
|
# Feature 44
|
||||||
|
if obj_sa_up is not None:
|
||||||
|
features[:, curr] = np.sign(obj_sa_up)
|
||||||
|
curr += 1
|
||||||
|
|
||||||
|
# Feature 46
|
||||||
|
if obj_sa_down is not None:
|
||||||
|
features[:, curr] = np.sign(obj_sa_down)
|
||||||
|
curr += 1
|
||||||
|
|
||||||
# Feature 47
|
# Feature 47
|
||||||
csign = np.sign(obj)
|
if obj_sa_down is not None:
|
||||||
if csign != 0 and ((obj - sd) / csign) > 0.001:
|
features[:, curr] = np.log(
|
||||||
f.append(log((obj - sd) / csign))
|
obj_coeffs - obj_sa_down / np.sign(obj_coeffs)
|
||||||
else:
|
)
|
||||||
f.append(0.0)
|
curr += 1
|
||||||
|
|
||||||
# Feature 48
|
# Feature 48
|
||||||
if csign != 0 and ((su - obj) / csign) > 0.001:
|
if obj_sa_up is not None:
|
||||||
f.append(log((su - obj) / csign))
|
features[:, curr] = np.log(obj_coeffs - obj_sa_up / np.sign(obj_coeffs))
|
||||||
else:
|
curr += 1
|
||||||
f.append(0.0)
|
|
||||||
|
|
||||||
for (i, v) in enumerate(f):
|
features = features[:, 0:curr]
|
||||||
if not isfinite(v):
|
_fix_infinity(features)
|
||||||
f[i] = 0.0
|
return features
|
||||||
|
|
||||||
features.append(f)
|
|
||||||
return np.array(features, dtype=float)
|
def _fix_infinity(m: np.ndarray) -> None:
|
||||||
|
masked = np.ma.masked_invalid(m)
|
||||||
|
max_values = np.max(masked, axis=0)
|
||||||
|
min_values = np.min(masked, axis=0)
|
||||||
|
m[:] = np.maximum(np.minimum(m, max_values), min_values)
|
||||||
|
m[np.isnan(m)] = 0.0
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
# Copyright (C) 2020-2021, UChicago Argonne, LLC. All rights reserved.
|
# Copyright (C) 2020-2021, UChicago Argonne, LLC. All rights reserved.
|
||||||
# Released under the modified BSD license. See COPYING.md for more details.
|
# Released under the modified BSD license. See COPYING.md for more details.
|
||||||
|
|
||||||
|
import os
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
from typing import Any
|
from typing import Any
|
||||||
@@ -63,11 +64,11 @@ def test_knapsack() -> None:
|
|||||||
sample.get_vector_list("static_var_features"),
|
sample.get_vector_list("static_var_features"),
|
||||||
np.array(
|
np.array(
|
||||||
[
|
[
|
||||||
[23.0, 505.0, 1.0, 0.32899, 0.0, 0.0, 505.0, 1.0],
|
[23.0, 505.0, 1.0, 0.32899, 0.0, 505.0, 1.0],
|
||||||
[26.0, 352.0, 1.0, 0.229316, 0.0, 0.0, 352.0, 1.0],
|
[26.0, 352.0, 1.0, 0.229316, 0.0, 352.0, 1.0],
|
||||||
[20.0, 458.0, 1.0, 0.298371, 0.0, 0.0, 458.0, 1.0],
|
[20.0, 458.0, 1.0, 0.298371, 0.0, 458.0, 1.0],
|
||||||
[18.0, 220.0, 1.0, 0.143322, 0.0, 0.0, 220.0, 1.0],
|
[18.0, 220.0, 1.0, 0.143322, 0.0, 220.0, 1.0],
|
||||||
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 67.0],
|
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 67.0],
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@@ -163,22 +164,20 @@ def test_knapsack() -> None:
|
|||||||
1.0,
|
1.0,
|
||||||
0.32899,
|
0.32899,
|
||||||
0.0,
|
0.0,
|
||||||
0.0,
|
|
||||||
505.0,
|
505.0,
|
||||||
1.0,
|
1.0,
|
||||||
1.0,
|
1.0,
|
||||||
0.32899,
|
0.32899,
|
||||||
0.0,
|
0.0,
|
||||||
0.0,
|
|
||||||
1.0,
|
1.0,
|
||||||
1.0,
|
1.0,
|
||||||
5.265874,
|
5.265874,
|
||||||
46.051702,
|
0.0,
|
||||||
193.615385,
|
193.615385,
|
||||||
-inf,
|
-0.111111,
|
||||||
1.0,
|
1.0,
|
||||||
311.384615,
|
311.384615,
|
||||||
inf,
|
570.869565,
|
||||||
0.913043,
|
0.913043,
|
||||||
2.043478,
|
2.043478,
|
||||||
1.0,
|
1.0,
|
||||||
@@ -189,24 +188,22 @@ def test_knapsack() -> None:
|
|||||||
1.0,
|
1.0,
|
||||||
0.229316,
|
0.229316,
|
||||||
0.0,
|
0.0,
|
||||||
0.0,
|
|
||||||
352.0,
|
352.0,
|
||||||
1.0,
|
1.0,
|
||||||
1.0,
|
1.0,
|
||||||
0.229316,
|
0.229316,
|
||||||
0.0,
|
|
||||||
0.076923,
|
0.076923,
|
||||||
1.0,
|
1.0,
|
||||||
1.0,
|
1.0,
|
||||||
3.532875,
|
3.532875,
|
||||||
5.388476,
|
|
||||||
0.0,
|
0.0,
|
||||||
-inf,
|
0.0,
|
||||||
|
-0.111111,
|
||||||
0.923077,
|
0.923077,
|
||||||
317.777778,
|
317.777778,
|
||||||
570.869565,
|
570.869565,
|
||||||
0.923077,
|
0.923077,
|
||||||
inf,
|
69.0,
|
||||||
0.923077,
|
0.923077,
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
@@ -215,22 +212,20 @@ def test_knapsack() -> None:
|
|||||||
1.0,
|
1.0,
|
||||||
0.298371,
|
0.298371,
|
||||||
0.0,
|
0.0,
|
||||||
0.0,
|
|
||||||
458.0,
|
458.0,
|
||||||
1.0,
|
1.0,
|
||||||
1.0,
|
1.0,
|
||||||
0.298371,
|
0.298371,
|
||||||
0.0,
|
0.0,
|
||||||
0.0,
|
|
||||||
1.0,
|
1.0,
|
||||||
1.0,
|
1.0,
|
||||||
5.232342,
|
5.232342,
|
||||||
46.051702,
|
0.0,
|
||||||
187.230769,
|
187.230769,
|
||||||
-inf,
|
-0.111111,
|
||||||
1.0,
|
1.0,
|
||||||
270.769231,
|
270.769231,
|
||||||
inf,
|
570.869565,
|
||||||
0.9,
|
0.9,
|
||||||
2.2,
|
2.2,
|
||||||
1.0,
|
1.0,
|
||||||
@@ -241,24 +236,22 @@ def test_knapsack() -> None:
|
|||||||
1.0,
|
1.0,
|
||||||
0.143322,
|
0.143322,
|
||||||
0.0,
|
0.0,
|
||||||
0.0,
|
|
||||||
220.0,
|
220.0,
|
||||||
1.0,
|
1.0,
|
||||||
1.0,
|
1.0,
|
||||||
0.143322,
|
0.143322,
|
||||||
0.0,
|
0.0,
|
||||||
0.0,
|
|
||||||
1.0,
|
1.0,
|
||||||
-1.0,
|
-1.0,
|
||||||
46.051702,
|
5.453347,
|
||||||
3.16515,
|
0.0,
|
||||||
-23.692308,
|
-23.692308,
|
||||||
-0.111111,
|
-0.111111,
|
||||||
1.0,
|
1.0,
|
||||||
-inf,
|
-13.538462,
|
||||||
243.692308,
|
243.692308,
|
||||||
0.0,
|
0.0,
|
||||||
inf,
|
69.0,
|
||||||
0.0,
|
0.0,
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
@@ -268,21 +261,19 @@ def test_knapsack() -> None:
|
|||||||
0.0,
|
0.0,
|
||||||
0.0,
|
0.0,
|
||||||
0.0,
|
0.0,
|
||||||
0.0,
|
|
||||||
67.0,
|
67.0,
|
||||||
0.0,
|
0.0,
|
||||||
0.0,
|
0.0,
|
||||||
0.0,
|
0.0,
|
||||||
0.0,
|
|
||||||
1.0,
|
1.0,
|
||||||
-1.0,
|
-1.0,
|
||||||
0.0,
|
5.453347,
|
||||||
0.0,
|
0.0,
|
||||||
13.538462,
|
13.538462,
|
||||||
-inf,
|
-0.111111,
|
||||||
67.0,
|
67.0,
|
||||||
-13.538462,
|
-13.538462,
|
||||||
inf,
|
570.869565,
|
||||||
43.0,
|
43.0,
|
||||||
69.0,
|
69.0,
|
||||||
67.0,
|
67.0,
|
||||||
@@ -391,7 +382,7 @@ class MpsInstance(Instance):
|
|||||||
return gp.read(self.filename)
|
return gp.read(self.filename)
|
||||||
|
|
||||||
|
|
||||||
def main() -> None:
|
if __name__ == "__main__":
|
||||||
solver = GurobiSolver()
|
solver = GurobiSolver()
|
||||||
instance = MpsInstance(sys.argv[1])
|
instance = MpsInstance(sys.argv[1])
|
||||||
solver.set_instance(instance)
|
solver.set_instance(instance)
|
||||||
@@ -404,7 +395,4 @@ def main() -> None:
|
|||||||
extractor.extract_after_lp_features(solver, sample, lp_stats)
|
extractor.extract_after_lp_features(solver, sample, lp_stats)
|
||||||
|
|
||||||
cProfile.run("run()", filename="tmp/prof")
|
cProfile.run("run()", filename="tmp/prof")
|
||||||
|
os.system("flameprof tmp/prof > tmp/prof.svg")
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
|
|||||||
Reference in New Issue
Block a user