-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.py
404 lines (333 loc) · 18.7 KB
/
main.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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
from Multi_Dimension import *
from HyperplaneConversion import *
from config import *
import numpy as np
import matplotlib.pyplot as plt
from itertools import combinations
import sys
import os
import timeit
from cplex.exceptions.errors import *
plt.switch_backend('agg')
def mainAlgorithm(outputDirectory, pointDimension, numOfComsumerPoints,numberOfStoryVectors, ci, runCount = 0) -> (
bool, int):
"""Parameter input: Output parameter. Return run time."""
#Already changed to storyVector hyperplane calculation.
functionStartTime = timeit.default_timer()
outputDirectory = os.path.join(outputDirectory, str(pointDimension)+"D"+str(numOfComsumerPoints)+"P")
if not os.path.isdir(outputDirectory):
os.mkdir(outputDirectory)
outputDirectory = os.path.join(outputDirectory, str(runCount))
if not os.path.isdir(outputDirectory):
os.mkdir(outputDirectory)
consumerPointList = []
storyVectorList = []
hyperplaneList = []
minimumDefenderUtilityList = []
adversaryMaximumUtilityList = []
adversaryMaximumUtility = 0
iter = 0 # Used to distinguish different iterations of the same consumer point number and dimension.
for i in range(numOfComsumerPoints):
consumerPointList.append([ 2*x-1 for x in np.random.ranf(pointDimension).tolist()])
originalConsumerPointList = consumerPointList
for i in range(numberOfStoryVectors):
storyVectorList.append([ 2*x-1 for x in np.random.ranf(pointDimension).tolist()])
unbiasedStoryHyperplane = getMeanHyperplane(storyVectorList)
counter = 0
while len(minimumDefenderUtilityList) <= 1 or ( len(minimumDefenderUtilityList) > 1 and abs(minimumDefenderUtilityList[-1] -
minimumDefenderUtilityList[-2]) >
epsilon and counter <= 100):
counter += 1
originalConvertedHyperplaneMatchList = [] # Used to store original and converted list. The element of the list is
# matched hyperplane pairs.
print("Running dimension " + str(pointDimension)+ " with point number: "+ str(numOfComsumerPoints))
# print("The Unbiased story vector is " + str(unbiasedStoryHyperplane.hyperPlaneEquation))
plotOutputDirectory = os.path.join(outputDirectory, str(iter))
if not os.path.isdir(plotOutputDirectory):
os.mkdir(plotOutputDirectory)
iterRange = [i for i in range(numOfComsumerPoints)]
allComb = combinations(iterRange, pointDimension)
for comb in allComb:
pointListUsedToGenerateHyperplane = []
for i in comb:
pointListUsedToGenerateHyperplane.append(consumerPointList[i])
#perturb the point list. Will work only for 2D
#TODO: Fix for N dimensions
pointListUsedToGenerateHyperplane[0] = [pointListUsedToGenerateHyperplane[0][0]+ 0.001, pointListUsedToGenerateHyperplane[0][1]+0.001]
pointListUsedToGenerateHyperplane[1] = [pointListUsedToGenerateHyperplane[1][0]- 0.001, pointListUsedToGenerateHyperplane[1][1]-0.001]
hyperplaneList.append(getHyperplaneEquation(pointListUsedToGenerateHyperplane))
print("Finished getting hyperplane list. The size of the list is " + str(len(hyperplaneList)) + ".")
hyperplaneList = getOriginalHyperplaneListWithUtilities2(hyperplaneList, consumerPointList,
unbiasedStoryHyperplane.hyperPlaneEquation)
#for hyperplane in hyperplaneList:
# print(hyperplane.pointSubscription)
print("Finished Getting Lines with Utilities")
#debug
iterRange = [i for i in range(numOfComsumerPoints)]
allComb = combinations(iterRange, pointDimension)
#debug
counter=0
for hyperplane in hyperplaneList:
#debug
comb_counter=0
for comb in allComb:
if (comb_counter==counter):
# print("Current combination of points being considered: ")
for nv in comb:
# print(consumerPointList[nv])
pass
break
comb_counter=comb_counter+1
counter=counter+1
#print(hyperplane.pointSubscription)
#print(hyperplane.hyperPlaneEquation)
for v in consumerPointList:
# print(v)
debugsinglePointSubscribeOfHyperplane2(hyperplane, v, ci)
#debug
try:
convertedHyperplane = hyperPlaneConversion(hyperplane, consumerPointList, storyVectorList)
originalConvertedHyperplaneMatchList.append([hyperplane, convertedHyperplane])
except CplexSolverError as e:
print("Failed to generated hyperplane.")
print("Error message: " + str(e) + "\n\n\n\n\n\n\n\n\n")
continue
print("Finished converting hyperplanes. The size of the convert hyperplanelist is:" + str(len(
originalConvertedHyperplaneMatchList)) + ".")
#The function will make sure mi is the same. Also, mi calculate is bigger than ci
# not 0,
hyperplaneList = getConvertedHyperplaneListWithUtilities(originalConvertedHyperplaneMatchList,
consumerPointList, unbiasedStoryHyperplane.hyperPlaneEquation, ci)
print("Finished generating converted hyperplane with utilities.")
# Now plot the original and converted hyperplane.
plotOriginalHyperplaneList = []
plotConvertedHyperplaneList = []
if len(originalConvertedHyperplaneMatchList) < 3:
print("Failed to convert enough hyperplane.")
break
for p in range(3):
matchedHyperplane = originalConvertedHyperplaneMatchList[p]
plotOriginalHyperplaneList.append(matchedHyperplane[0])
plotConvertedHyperplaneList.append(matchedHyperplane[1])
plotHyperplaneList(consumerPointList, plotOriginalHyperplaneList, unbiasedStoryHyperplane,
plotOutputDirectory, "original hyperplane with consumer points", "figure1.png")
plotHyperplaneList(consumerPointList, plotConvertedHyperplaneList, unbiasedStoryHyperplane,
plotOutputDirectory, "converted hyperplane with consumer points", "figure2.png")
print("Finished printing the original and converted hyperplane charts.")
# # After regenerating the hyperplane. Needs to recalculate the L2Norm.
# getHyperplaneListWithUtilities(hyperplaneList, consumerPointList, unbiasedStoryHyperplane.hyperPlaneEquation,
# inputStoryVector=storyVectorList, ci=ci)
#
# print("Finished Getting Lines with Utilities No2")
hyperplaneList.sort(key=lambda pair: pair.defenderUtility)
print("Finished Sorting Lines.")
#Find the best strategy for adversary.
adversaryHyperplane = Hyperplane([], [])
defenderHyperplane = Hyperplane([], [])
for hyperplane in hyperplaneList:
if hyperplane.adversaryUtility > adversaryHyperplane.adversaryUtility:
adversaryHyperplane = hyperplane
print("Finished finding the best strategy for adversary")
# Print the original graph.
if pointDimension == 2:
plotDefAdvHyperplane(consumerPointList, hyperplaneList[0].hyperPlaneEquation,
adversaryHyperplane.hyperPlaneEquation,
unbiasedStoryHyperplane.hyperPlaneEquation, plotOutputDirectory, "The Defender and "
"the Adversary "
"preference "
"hyperplane",
"figure3.png")
# Now iterate the hyperplane list and try to move points.
for i in range(len(hyperplaneList)):
if hyperplaneList[i] == adversaryHyperplane:
print("The defender hyperplane and the adversary hyperplane matched. List number: " + str(i))
break
#TODO: FIX MOVE POINTS.
isSucceed, movedPointList, defenderMaximumSubscription = movePoints(hyperplaneList[i],
adversaryHyperplane,
consumerPointList, originalConsumerPointList,
ci=ci)
# if i == len(hyperplaneList) - 2: # For testing and visualization purpose.
# print("Debug ploting mode.")
# temPointList = movedPointList
# if pointDimension == 2:
# fig = plt.subplot(2, 2, 3)
# plt.scatter(*zip(*temPointList))
# defenderPlotLineX, defenderPlotLineY = zip(*hyperplaneList[i].consumerPointList)
# adversaryPlotLineX, adversaryPlotLineY = zip(*adversaryHyperplane.consumerPointList)
# # fig.set_xlim(left=-1, right=2)
# # fig.set_ylim(bottom=-1, top=2)
# plt.plot(defenderPlotLineX, defenderPlotLineY)
# plt.plot(adversaryPlotLineX, adversaryPlotLineY)
# break
if isSucceed == False:
continue
else:
if movedPointList == consumerPointList:
print("Points not moving.")
raise Exception("Points not moving. But the code should not reach this point. Error.")
print("Found defender hyperplane " + str(i) + " that can do better than adversary hyperplane. \n" +
"The Defender maximum point count is " + str(defenderMaximumSubscription) + "\n")
defenderHyperplane = hyperplaneList[i]
# # For Debug purpose.
#print(hyperplaneList[0].defenderUtility, hyperplaneList[1].defenderUtility, hyperplaneList[2].defenderUtility)
#print(hyperplaneList[i].defenderUtility)
#print(hyperplaneList[-1].defenderUtility)
if pointDimension == 2:
plotDefAdvHyperplane(consumerPointList, defenderHyperplane.hyperPlaneEquation,
adversaryHyperplane.hyperPlaneEquation, unbiasedStoryHyperplane.hyperPlaneEquation,
plotOutputDirectory, "The defender hyperplane that can do better than the "
"adversary one",
"figure4.png")
consumerPointList = movedPointList
if pointDimension == 2:
plotDefAdvHyperplane(consumerPointList, defenderHyperplane.hyperPlaneEquation,
adversaryHyperplane.hyperPlaneEquation, unbiasedStoryHyperplane.hyperPlaneEquation,
plotOutputDirectory, "The defender and adversary hyperplane with moved "
"points" ,"figure5.png")
break
plt.show()
print("Finished Printing Charts.")
smallestL2Norm = defenderHyperplane.defenderUtility
print("Current minimum defender utility is " + str(smallestL2Norm) + ".\n\n\n")
#TODO: Will cause bugs. NOT sure why.
# if movedPointList == originalConsumerPointList:
# functionEndTime = timeit.default_timer()
# return False, (functionEndTime - functionStartTime)
iter += 1
minimumDefenderUtilityList.append(smallestL2Norm)
adversaryMaximumUtilityList.append(defenderHyperplane.adversaryUtility)
#end outer while loop.
functionEndTime = timeit.default_timer()
fig = plt.figure()
plt.plot([iteration + 1 for iteration in range(iter)], minimumDefenderUtilityList)
plt.xlabel("Iteration of moved points and defender lists.")
plt.ylabel("The Defender Utilities of Defender Hyperplane. (L2Norm)")
plt.title("Iter_VS_DefU")
plt.savefig(os.path.join(outputDirectory, "Iter_VS_Def.png"))
plt.close(fig)
fig = plt.figure()
plt.plot([iteration + 1 for iteration in range(iter)], adversaryMaximumUtilityList)
plt.xlabel("Iteration of moved points and defender lists.")
plt.ylabel("The Adversary Utilities of Defender Hyperplane.(Point subscriptions)")
plt.title("Iter_VS_AdvU")
plt.savefig(os.path.join(outputDirectory, "Iter_VS_Adv.png"))
plt.close(fig)
return True, (functionEndTime - functionStartTime)
def plotDefAdvHyperplane(pointList, defenderHyperplaneEquation, adversaryHyperplaneEquation,
unbiasedStoryEquation, plotOutputDirectory, title, plotFileName):
"""Attension: Only works in two dimension..."""
if not pointList:
if len(pointList[0]) != 2:
return
fig = plt.figure()
plt.scatter(*zip(*pointList))
defenderPlotLineX = [-1, 1]
adversaryPlotLineX = [-1, 1]
unbiasedStoryVectorPlotLineX = [-1,1]
#TODO: Will crash if hyperplane's parameter at y axis equal to 0.
defenderPlotLineY = [defenderHyperplaneEquation[0] / defenderHyperplaneEquation[1] - defenderHyperplaneEquation[
2] / defenderHyperplaneEquation[1], -defenderHyperplaneEquation[0] / defenderHyperplaneEquation[1] -
defenderHyperplaneEquation[
2] / defenderHyperplaneEquation[1]]
adversaryPlotLineY = [
adversaryHyperplaneEquation[0] / adversaryHyperplaneEquation[1] - adversaryHyperplaneEquation[
2] / adversaryHyperplaneEquation[1],
-adversaryHyperplaneEquation[0] / adversaryHyperplaneEquation[1] - adversaryHyperplaneEquation[
2] / adversaryHyperplaneEquation[1]]
unbiasedStoryVectorPlotLiney = [
unbiasedStoryEquation[0] / unbiasedStoryEquation[1] - unbiasedStoryEquation[
2] / unbiasedStoryEquation[1],
-unbiasedStoryEquation[0] / unbiasedStoryEquation[1] - unbiasedStoryEquation[
2] / unbiasedStoryEquation[1]]
defenderPlot, = plt.plot(defenderPlotLineX, defenderPlotLineY)
adversaryPlot, = plt.plot(adversaryPlotLineX, adversaryPlotLineY)
unbiasedStoryVectorPlot, = plt.plot(unbiasedStoryVectorPlotLineX, unbiasedStoryVectorPlotLiney)
plt.legend([defenderPlot, adversaryPlot, unbiasedStoryVectorPlot], ["Defender Hyperplane", "Adversary "
"Hyperplane",
"Unbiased Story Vector"])
plt.xlim(-1.5,1.5)
plt.ylim(-1.5,1.5)
plt.xlabel("x axis in the coordinate system")
plt.ylabel("y axis in the coordinate system")
plt.title(title)
plt.savefig(os.path.join(plotOutputDirectory, plotFileName))
plt.close(fig)
return
def plotHyperplaneList(pointList, hyperplaneList, unbiasedStoryHyperplane, plotOutputDirectory, title, plotFileName):
"""Attension: Only works in two dimension..."""
if not pointList:
if len(pointList[0]) != 2:
return
fig = plt.figure()
plt.scatter(*zip(*pointList))
plotLineListX = []
plotLineListY = []
for hyperplane in hyperplaneList:
hyperplaneEquation = hyperplane.hyperPlaneEquation
plotLineListX.append([-1,1])
# TODO: Will crash if hyperplane's parameter at y axis equal to 0.
plotLineListY.append([hyperplaneEquation[0] / hyperplaneEquation[1] - hyperplaneEquation[
2] / hyperplaneEquation[1], -hyperplaneEquation[0] / hyperplaneEquation[1] -
hyperplaneEquation[
2] / hyperplaneEquation[1]])
unbiasedStoryEquation = unbiasedStoryHyperplane.hyperPlaneEquation
plotLineListX.append([-1, 1])
plotLineListY.append([unbiasedStoryEquation[0] / unbiasedStoryEquation[1] - unbiasedStoryEquation[
2] / unbiasedStoryEquation[1], -unbiasedStoryEquation[0] / unbiasedStoryEquation[1] -
unbiasedStoryEquation[
2] / unbiasedStoryEquation[1]])
plots = []
for i in range(len(plotLineListX)):
plot, = plt.plot(plotLineListX[i],plotLineListY[i])
plots.append(plot)
plt.xlim(-1.5, 1.5)
plt.ylim(-1.5, 1.5)
plt.xlabel("x axis in the coordinate system")
plt.ylabel("y axis in the coordinate system")
plt.title(title)
plt.legend(plots, ["First Hyperplane", "Second Hyperplane", "Third Hyperplane", "Unbiased Story Vector"])
plt.savefig(os.path.join(plotOutputDirectory, plotFileName))
plt.close(fig)
return
# Run
dimensionRunTimeList = []
pointNumRunTimeList = []
outputDirectory = sys.argv[1]
#outputDirectory = ("/Users/auy212-admin/Downloads/FakeNewsOutput")
if not os.path.isdir(outputDirectory):
raise Exception("Output Directory not accessible.")
# for dimemsion in dimensionList:
# # isSucceed = False
# runtimeList = []
# # while not isSucceed or len(runtimeList) <= 3:
# while len(runtimeList) <= 3:
# isSucceed, runtime = mainAlgorithm(outputDirectory= outputDirectory, pointDimension=dimemsion,
# numOfComsumerPoints=20, numberOfStoryVectors=50, ci = ci, runCount=len(
# runtimeList))
# # if isSucceed:
# runtimeList.append(runtime)
# dimensionRunTimeList.append(sum(runtimeList)/len(runtimeList))
for pointNum in consumerTotalPointNumberList:
# isSucceed = False
runtimeList = []
# while not isSucceed or len(runtimeList) <= 10:
while len(runtimeList) <= 3:
isSucceed, runtime = mainAlgorithm(outputDirectory=outputDirectory, pointDimension=2, numOfComsumerPoints
=pointNum, numberOfStoryVectors= numberOfStoryVectors, ci=ci,
runCount=len(runtimeList))
# if isSucceed:
runtimeList.append(runtime)
pointNumRunTimeList.append(sum(runtimeList)/len(runtimeList))
print(pointNumRunTimeList)
# fig = plt.figure()
# plt.plot( dimensionList , dimensionRunTimeList)
# plt.savefig(os.path.join(outputDirectory, "Dimension_VS_Runtime.png"))
# plt.close(fig)
#
# fig = plt.figure()
# plt.plot( pointNumList , pointNumRunTimeList)
# plt.savefig(os.path.join(outputDirectory, "PointNum_VS_Runtime.png"))
# plt.close(fig)
# isSucceed, runtime = mainAlgorithm(outputDirectory= outputDirectory, pointDimension=2, numOfComsumerPoints= 20,
# numberOfStoryVectors=50)