Эх сурвалжийг харах

[research/lotterysim] reward auto crawler

police 3 жил өмнө
parent
commit
1319d72e2d

+ 1 - 1
script/research/lotterysim/highest_gain.txt

@@ -1 +1 @@
-accuracy:0.748666072596457, kp: 0.067400000000246, ki:-0.03319999929237562, kd:-0.0015999999999950568
+accuracy:0.5613850265422056, kp: 1.5000000000000024, ki:1, kd:-1

+ 4 - 4
script/research/lotterysim/lottery.py

@@ -7,7 +7,7 @@ from pid import PID
 from RPID import RPID
 
 class DarkfiTable:
-    def __init__(self, airdrop, running_time, controller_type=CONTROLLER_TYPE_DISCRETE, kp=0, ki=0, kd=0, dt=1, target=1, reward_target=15, kc=0, ti=0, td=0, ts=0, debug=False):
+    def __init__(self, airdrop, running_time, controller_type=CONTROLLER_TYPE_DISCRETE, kp=0, ki=0, kd=0, dt=1, target=1, reward_target=15, kc=0, ti=0, td=0, ts=0, debug=False, r_kp=0, r_ki=0, r_kd=0):
         self.Sigma=airdrop
         self.darkies = []
         self.running_time=running_time
@@ -15,7 +15,7 @@ class DarkfiTable:
         self.end_time=None
         self.pid = None
         self.pid = PID(kp=kp, ki=ki, kd=kd, dt=dt, target=target, Kc=kc, Ti=ti, Td=td, Ts=ts)
-        self.rpid = RPID(kp=3, ki=2, kd=-1, target=reward_target)
+        self.rpid = RPID(kp=r_kp, ki=r_ki, kd=r_kd, target=reward_target)
         self.controller_type=controller_type
         self.debug=debug
 
@@ -36,7 +36,7 @@ class DarkfiTable:
         while count < self.running_time:
             winners=0
             total_vesting_stake = 0
-            f = self.pid.pid_clipped(feedback, self.controller_type, debug)
+            f = self.pid.pid_clipped(float(feedback), self.controller_type, debug)
             #note! thread overhead is 10X slower than sequential node execution!
             for i in range(len(self.darkies)):
                 self.darkies[i].set_sigma_feedback(self.Sigma, feedback, f, count, hp)
@@ -45,7 +45,7 @@ class DarkfiTable:
             for i in range(len(self.darkies)):
                 winners += self.darkies[i].won
                 apy = self.darkies[i].apy()
-                reward = self.rpid.pid_clipped(apy, self.controller_type, debug)
+                reward = self.rpid.pid_clipped(float(apy), self.controller_type, debug)
                 self.darkies[i].update_stake(reward)
             feedback = winners
             if winners==1:

+ 154 - 0
script/research/lotterysim/reward_auto_crawler.py

@@ -0,0 +1,154 @@
+from lottery import *
+from threading import Thread
+from argparse import ArgumentParser
+
+AVG_LEN = 5
+
+KP_STEP=0.5
+KP_SEARCH=1
+
+KI_STEP=0.5
+KI_SEARCH=1
+
+KD_STEP=0.5
+KD_SEARCH=-1
+
+EPSILON=0.0001
+RUNNING_TIME=1000
+NODES = 1000
+
+highest_acc = 0
+
+KP='kp'
+KI='ki'
+KD='kd'
+
+KP_RANGE_MULTIPLIER = 2
+KI_RANGE_MULTIPLIER = 2
+KD_RANGE_MULTIPLIER = 2
+
+highest_gain = (KP_SEARCH, KI_SEARCH, KD_SEARCH)
+
+parser = ArgumentParser()
+parser.add_argument('-p', '--high-precision', action='store_true')
+parser.add_argument('-r', '--randomize-nodes', action='store_false')
+parser.add_argument('-t', '--rand-running-time', action='store_false')
+parser.add_argument('-d', '--debug', action='store_false')
+args = parser.parse_args()
+high_precision = args.high_precision
+randomize_nodes = args.randomize_nodes
+rand_running_time = args.rand_running_time
+debug = args.debug
+
+def experiment(accs=[], controller_type=CONTROLLER_TYPE_DISCRETE, kp=0, ki=0, kd=0, distribution=[], hp=True):
+    dt = DarkfiTable(ERC20DRK, RUNNING_TIME, controller_type, kp=-0.010399999999938556, ki=-0.0365999996461878, kd=0.03840000000000491, r_kp=kp, r_ki=ki, r_kd=kd)
+    RND_NODES = random.randint(5, NODES) if randomize_nodes else NODES
+    for idx in range(0,RND_NODES):
+        darkie = Darkie(distribution[idx])
+        dt.add_darkie(darkie)
+    acc = dt.background(rand_running_time, hp)
+    accs+=[acc]
+    return acc
+
+def multi_trial_exp(kp, ki, kd, distribution = [], hp=True):
+    global highest_acc
+    global highest_gain
+    new_record=False
+    exp_threads = []
+    accs = []
+    for i in range(0, AVG_LEN):
+        acc = experiment(accs, CONTROLLER_TYPE_DISCRETE, kp=kp, ki=ki, kd=kd, distribution=distribution, hp=hp)
+        accs += [acc]
+    avg_acc = sum(accs)/float(AVG_LEN)
+    buff = 'accuracy:{}, kp: {}, ki:{}, kd:{}'.format(avg_acc, kp, ki, kd)
+    if avg_acc > 0:
+        gain = (kp, ki, kd)
+        acc_gain = (avg_acc, gain)
+        if avg_acc > highest_acc:
+            new_record = True
+            highest_acc = avg_acc
+            highest_gain = (kp, ki, kd)
+            with open("highest_gain.txt", 'w') as f:
+                f.write(buff)
+    return buff, new_record
+
+SHIFTING = 0.05
+
+def crawler(crawl, range_multiplier, step=0.1):
+    start = None
+    if crawl==KP:
+        start = highest_gain[0]
+    elif crawl==KI:
+        start = highest_gain[1]
+    elif crawl==KD:
+        start = highest_gain[2]
+
+    range_start = (start*range_multiplier if start <=0 else -1*start)
+    range_end = (-1*start if start<=0 else range_multiplier*start)
+    # if number of steps under 10 step resize the step to 50
+    while (range_end-range_start)/step < 10:
+        range_start -= SHIFTING
+        range_end += SHIFTING
+        step /= 10
+
+    crawl_range = np.arange(range_start, range_end, step)
+    np.random.shuffle(crawl_range)
+    crawl_range = tqdm(crawl_range)
+    distribution = [random.gauss(ERC20DRK/NODES, ERC20DRK/NODES*0.1) for i in range(NODES)]
+    for i in crawl_range:
+        kp = i if crawl==KP else highest_gain[0]
+        ki = i if crawl==KI else highest_gain[1]
+        kd = i if crawl==KD else highest_gain[2]
+        buff, new_record = multi_trial_exp(kp, ki, kd, distribution, hp=high_precision)
+        crawl_range.set_description('highest:{} / {}'.format(highest_acc, buff))
+        if new_record:
+            break
+
+while True:
+    prev_highest_gain = highest_gain
+    # kp crawl
+    crawler(KP, KP_RANGE_MULTIPLIER, KP_STEP)
+    if highest_gain[0] == prev_highest_gain[0]:
+        KP_RANGE_MULTIPLIER+=1
+        KP_STEP/=10
+    else:
+        start = highest_gain[0]
+        range_start = (start*KP_RANGE_MULTIPLIER if start <=0 else -1*start) - SHIFTING
+        range_end = (-1*start if start<=0 else KP_RANGE_MULTIPLIER*start) + SHIFTING
+        while (range_end - range_start)/KP_STEP >500:
+            if KP_STEP < 0.1:
+                KP_STEP*=10
+            KP_RANGE_MULTIPLIER-=1
+            #TODO (res) shouldn't the range also shrink?
+            # not always true.
+            # how to distinguish between thrinking range, and large step?
+            # good strategy is step shoudn't > 0.1
+            # range also should be > 0.8
+            # what about range multiplier?
+
+    # ki crawl
+    crawler(KI, KI_RANGE_MULTIPLIER, KI_STEP)
+    if highest_gain[1] == prev_highest_gain[1]:
+        KI_RANGE_MULTIPLIER+=1
+        KI_STEP/=10
+    else:
+        start = highest_gain[1]
+        range_start = (start*KI_RANGE_MULTIPLIER if start <=0 else -1*start) - SHIFTING
+        range_end = (-1*start if start<=0 else KI_RANGE_MULTIPLIER*start) + SHIFTING
+        while (range_end - range_start)/KI_STEP >500:
+            if KP_STEP < 0.1:
+                KI_STEP*=10
+            KI_RANGE_MULTIPLIER-=1
+    # kd crawl
+    crawler(KD, KD_RANGE_MULTIPLIER, KD_STEP)
+    if highest_gain[2] == prev_highest_gain[2]:
+        KD_RANGE_MULTIPLIER+=1
+        KD_STEP/=10
+    else:
+        start = highest_gain[2]
+        range_start = (start*KD_RANGE_MULTIPLIER if start <=0 else -1*start) - SHIFTING
+        range_end = (-1*start if start<=0 else KD_RANGE_MULTIPLIER*start) + SHIFTING
+        while (range_end - range_start)/KD_STEP >500:
+            if KD_STEP < 0.1:
+                KD_STEP*=10
+            KD_RANGE_MULTIPLIER-=1