seed_generator.py 4.47 KB
Newer Older
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import gurobipy as gp
import random
from mps_util import VerbosePrint

class SeedGenerator:
    def __init__(self, mpsf: str, verbose = False):
        self.mpsf = mpsf
        self.seedct = 0
        self.exceeded_time = False
        self.verbose = verbose

    def generate(self):
        with VerbosePrint(self.verbose):
            m = gp.read(self.mpsf)
        
        #Remove additional variables
        var_count = len(m.getVars())
        if(var_count < 300):
            want_var_count = (int)(var_count /100.0 * random.randint(60,80))
        else:
            want_var_count = random.randint(300,500)
        remove_var_count = var_count - want_var_count

        self.remove_vars(m, var_count, remove_var_count)
        
        
        # Randomly remove further constraints
        constraint_count = len(m.getConstrs())
        
        if(constraint_count < 400):
            want_count = (int)(constraint_count /100.0 * random.randint(60,80))
        else:
            # keep around 400-900 constraints
            want_count = random.randint(400,900)
        remove_count = constraint_count - want_count
        self.remove_constraints(m, constraint_count, remove_count)

        #save the mps file
        with VerbosePrint(self.verbose):
            m.setParam(gp.GRB.Param.TimeLimit, 5.0)
            m.optimize()

        if m.Status == 2:
            self.write_to_file(m, str(m.ObjVal))
        elif m.Status == 3:
            self.write_to_file(m, 'Infeasible')
        elif m.Status == 5:
            self.write_to_file(m, 'Unbounded')
        elif m.Status == 4:
            self.write_to_file(m, 'Infeasible or Unbounded')
        elif m.Status == 9:
            #time limit of 5 seconds exceeded. Chuck this seed
            self.exceeded_time = True


    def write_to_file(self, m: gp.Model, optimal_val: str):
        self.seedct = self.seedct + 1
        edit = '-' + str(self.seedct) + '.mps'
        edited_file_name = self.mpsf.replace('.mps', edit)
        edited_file_name = edited_file_name.replace('mps/', 'mps/seeds_all/')
        print('Writing file - ' + edited_file_name)
        m.write(edited_file_name)

        #update log with stats
        with open("generated_seeds_stats_all.csv", "a") as log:
            line = edited_file_name.replace('mps_seeds/seeds_all/', '') + ',' + str(len(m.getVars())) + ',' + str(len(m.getConstrs())) + ','
            line = line + str(optimal_val) + '\n'
            log.write(line)



    def remove_vars(self, m: gp.Model, var_count: int, remove_count: int):
        if (remove_count < 1):
            return

        to_remove_indices = random.sample(range(var_count), remove_count)
        vars = m.getVars()

        for x in to_remove_indices:
            m.remove(vars[x])

        m.update()

        #Clean up any constraints that dont have variables anymore
        constrs = m.getConstrs()
        for con in constrs:
            row_size = m.getRow(con).size()
            if row_size == 0:
                m.remove(con)

        m.update()
        

    def remove_constraints(self, m: gp.Model, constraint_count: int, remove_count: int):
        if (remove_count < 1):
            return

        to_remove_indices = random.sample(range(constraint_count), remove_count)
        constraints = m.getConstrs()

        for x in to_remove_indices:
            m.remove(constraints[x])

        m.update()

        #Clean up any vars that dont have a constraint anymore
        vars = m.getVars()
        for var in vars:
            col_size = m.getCol(var).size()
            if col_size == 0:
                m.remove(var)
        
        m.update()

if __name__ == "__main__":
    print('Starting')
    fnames = ['ex9.mps','ex10.mps','cod105.mps','neos-3024952-loue.mps', 'neos-911970.mps', 'roll3000.mps', 'app1-1.mps', 'enlight_hard.mps', 'germanrr.mps', 'neos-3381206-awhea.mps', 'ns1952667.mps', 'timtab1.mps', 'ic97_potential.mps', 'neos-4738912-atrato.mps']
    for fname in fnames:
        path = 'mps_seeds/' + fname
        sg = SeedGenerator(path)
        notFound = True
        for i in range(1000):
            if(i<30 or i%100==0):
                print('Still running - ' + str(i))
            sg.generate()
            if sg.seedct == 10:
                notFound = False
                break
            if sg.exceeded_time:
                print ('Exceeded time limit. Cancelling generation for seed file - ' + fname)
                break
        if(notFound):
            print('Couldnt generate 10 files. Only generated ' + str(sg.seedct-10) + ' files')