-
Notifications
You must be signed in to change notification settings - Fork 1
/
nrp.py
136 lines (112 loc) · 4.91 KB
/
nrp.py
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
from __future__ import division
from random import random, randint
import sys, os, inspect
from jmoo_objective import *
from jmoo_decision import *
from jmoo_problem import jmoo_problem
from Requirement import Requirement
from Client import Client
from Release import Release
class NRP(jmoo_problem):
def __init__(self, requirements, releases, clients, density, budget):
self.name = "NRP_" + str(requirements) + "_" + str(releases) + "_" + str(clients) + "_" +str(density) \
+ "_" + str(budget)
names = ["x"+str(i+1) for i in range(requirements)] # |x_i + y_i|
lows = [-1 for i in xrange(requirements)]
ups = [(releases-1) for _ in xrange(requirements)]
self.decisions = [jmoo_decision(names[i], lows[i], ups[i]) for i in range(requirements)]
self.objectives = [jmoo_objective("f1", False)]#, jmoo_objective("f2", False)] # single objective nrp
self.trequirements = requirements
self.treleases = releases
self.tclients = clients
self.tdensity = density
self.tbudget = budget
self.requirement = None
self.client = None
self.release = None
self.precedence = []
self.generate_data()
def generate_precedence(self):
precedence = [[0 for _ in xrange(self.trequirements)] for _ in xrange(self.trequirements)]
temp = []
for _ in xrange(int(self.tdensity * self.trequirements * 0.01)):
while True:
row = randint(0, self.trequirements -1)
col = randint(0, self.trequirements -1)
t = row * 1000 + col
if t not in temp:
temp.append(t)
break
# print "Done"
for t in temp:
precedence[int(t/1000)][int(t%1000)] = 1
return precedence
def generate_data(self):
self.requirement = [Requirement(i) for i in xrange(self.trequirements)]
self.client = [Client(i, self.trequirements) for i in xrange(self.tclients)]
budget_release = int((sum(req.cost for req in self.requirement) * (self.tbudget/100))/self.treleases)
self.release = [Release(i, budget_release) for i in xrange(self.treleases)]
self.precedence = self.generate_precedence()
def print_data(i):
print [c.weight for c in i.client]
for p in i.precedence:
print p
for r in i.requirement:
print r.cost, r.risk
for c in i.client:
print c.importance
print [r.budget for r in i.release]
def constraint1(self, x_i, y_i):
cost = [0 for _ in xrange(self.treleases)]
for i, y in enumerate(y_i):
if y != 0:
assert(self.requirement[y].id == y), "Indexing Error!"
assert(x_i[i] <= self.treleases)
cost[x_i[i]] += self.requirement[i].cost
# print cost, [b.budget for b in self.release], sum(cost), sum([b.budget for b in self.release])
extra = 0
for c, b in zip(cost, self.release):
if c > b.budget:
extra -= (c - b.budget)
return extra
def constraint2(self, x_i, y_i):
for y in y_i:
if y != 0:
relation = self.precedence[y]
if sum(relation) == 0: # no dependencies
return True
else:
current_release = x_i[y] # when was y implement
for count, p in enumerate(relation):
if p != 0:
# the dependency 'count' wasn't implemented before current release
if x_i[count] > current_release:
return False
return True
def evaluate(self, input = None):
if input:
input = input[:self.trequirements]
x_i = [int(round(float(no), 0)) for no in input] # when is r_i is implemented
y_i = [1 if x != -1 else 0 for x in x_i] # whether r_i would be implemented
assert(len(x_i) == len(y_i)), "Both the list should be of the same size"
temp = self.constraint1(x_i, y_i) # This is dirty need to know a better trick
if temp != 0:
return [temp]
elif self.constraint2(x_i, y_i) is False:
return [0]
else:
return_score = 0
for i in xrange(self.trequirements):
score = sum([j.importance[i] * j.weight for j in self.client])
x = x_i[i]
return_score += (score * (self.treleases - x + 1) - self.requirement[i].risk) * y_i[i]
return [return_score]
else:
assert(False), "BOOM"
exit()
def evalConstraints(prob,input = None):
return False
if __name__ == "__main__":
problem = NRP(50, 5, 5, 0, 80)
problem.generate_data()
problem.print_data()