Use NumPy to compute AlvLouWeh2017 features

master
Alinson S. Xavier 4 years ago
parent e852d5cdca
commit 60b9a6775f

@ -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)
if obj_sa_down is not None:
obj_sa_down = obj_sa_down.astype(float)
_fix_infinity(obj_sa_down)
if obj_sa_up is not None:
obj_sa_up = obj_sa_up.astype(float)
_fix_infinity(obj_sa_up)
pos_obj_coeff_sum = 0.0 if values is not None:
neg_obj_coeff_sum = 0.0 values = values.astype(float)
for coeff in obj_coeffs: _fix_infinity(values)
if coeff > 0:
pos_obj_coeff_sum += coeff pos_obj_coeffs_sum = obj_coeffs[obj_coeffs > 0].sum()
if coeff < 0: neg_obj_coeffs_sum = -obj_coeffs[obj_coeffs < 0].sum()
neg_obj_coeff_sum += -coeff
curr = 0
features = [] max_n_features = 8
for i in range(len(obj_coeffs)): features = np.zeros((nvars, max_n_features))
f: List[float] = [] with np.errstate(divide="ignore", invalid="ignore"):
if obj_coeffs is not None:
# Feature 1 # Feature 1
f.append(np.sign(obj_coeffs[i])) features[:, curr] = np.sign(obj_coeffs)
curr += 1
# Feature 2 # Feature 2
if pos_obj_coeff_sum > 0: if abs(pos_obj_coeffs_sum) > 0:
f.append(abs(obj_coeffs[i]) / pos_obj_coeff_sum) features[:, curr] = np.abs(obj_coeffs) / pos_obj_coeffs_sum
else: curr += 1
f.append(0.0)
# Feature 3 # Feature 3
if neg_obj_coeff_sum > 0: if abs(neg_obj_coeffs_sum) > 0:
f.append(abs(obj_coeffs[i]) / neg_obj_coeff_sum) features[:, curr] = np.abs(obj_coeffs) / neg_obj_coeffs_sum
else: curr += 1
f.append(0.0)
if values is not None:
# Feature 37 # Feature 37
f.append( if values is not None:
min( features[:, curr] = np.minimum(
values[i] - np.floor(values[i]), values - np.floor(values),
np.ceil(values[i]) - values[i], np.ceil(values) - values,
)
) )
curr += 1
# Feature 44
if obj_sa_up is not None: if obj_sa_up is not None:
assert obj_sa_down is not None features[:, curr] = np.sign(obj_sa_up)
assert obj_coeffs is not None curr += 1
# Convert inf into large finite numbers
sd = max(-1e20, obj_sa_down[i])
su = min(1e20, obj_sa_up[i])
obj = obj_coeffs[i]
# Features 44 and 46 # Feature 46
f.append(np.sign(obj_sa_up[i])) if obj_sa_down is not None:
f.append(np.sign(obj_sa_down[i])) 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)
features = features[:, 0:curr]
_fix_infinity(features)
return features
for (i, v) in enumerate(f):
if not isfinite(v):
f[i] = 0.0
features.append(f) def _fix_infinity(m: np.ndarray) -> None:
return np.array(features, dtype=float) 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()

Loading…
Cancel
Save