stanley-king 2 years atrás
parent
commit
aa1e3372eb

+ 3 - 3
plot/refill/ChSpeedControlCalc.py

@@ -23,8 +23,8 @@ class ChSpeedControlCalc(ChannelCalc):
         start_period, ratio_period, speed_period, monitor_period, cdf_speed_period = ch_calc_cfgs()
 
         reader = self._reader()
-        # end_time = int(time.time())
-        end_time = mktime('2022-11-06 20:00:00')
+        end_time = int(time.time())
+        # end_time = mktime('2022-11-06 20:00:00')
         days, start_time, end_time = self.calc_time(reader, end_time - start_period, end_time)
 
         day_stamp = days[0]
@@ -35,9 +35,9 @@ class ChSpeedControlCalc(ChannelCalc):
 
         manager = chs_manager()
         for _name, _card_type, _spec, _data in gen:
-            if _card_type != 4 or _spec != 50: continue
             manager.add(_name, _card_type, _spec, _data, end_pos)
         manager.cur_speed()
+        manager.normal_speed()
         manager.optimize()
         reckons = manager.get_reckon()
         return reckons

+ 78 - 11
plot/refill/ch_type_spec.py

@@ -2,12 +2,15 @@ from .algorithm import calc_chspeed, calc_chratio, calc_commit, calc_chprice, ca
 from .DataStream import EChPosmap as pos_map
 from .DataStream import ch_calc_cfgs
 import numpy as np
+import math
 from itertools import product
 from enum import IntEnum
 
 import logging
+
 logger = logging.getLogger('ch_type_spec')
 
+
 # 总提单量,总成功单量,成功率,每分钟提单平均数,每分钟成单量
 class EDetailPosmap(IntEnum):
     cur_commit = 0
@@ -15,12 +18,15 @@ class EDetailPosmap(IntEnum):
     per_commit = 2
     per_succ = 3
     per_profit = 4
+    radio_log = 5
 
     @staticmethod
     def dim():
-        return 5
+        return 6
+
     pass
 
+
 class ch_type_spec(object):
     def __init__(self, name):
         self._name = name
@@ -52,13 +58,14 @@ class ch_type_spec(object):
         return self._speed
 
     def add_reckon_speed(self, speed):
-        self._reckon_speed += int(round(speed,0))
+        self._reckon_speed += int(round(speed, 0))
+
     def reckon_speed(self):
         return self._reckon_speed
 
     def detail_dim(self):
         result = []
-        for key,item in self._detail.items():
+        for key, item in self._detail.items():
             if key is not 0:
                 result.append(key)
         return result
@@ -69,19 +76,72 @@ class ch_type_spec(object):
         else:
             return False
 
-    def detail(self,dim):
+    def detail(self, dim):
         if dim in self._detail:
             return self._detail[dim]
         else:
             return None
 
-    def detail_speed(self,dim):
+    def detail_speed(self, dim):
         if dim in self._detail:
             return self._detail[dim][EDetailPosmap.per_commit]
         else:
             return None
 
-    def per_commit(self,dim):
+    def best_speed(self):
+        fetch_log = lambda x: x[EDetailPosmap.radio_log]
+
+        def log_dim():
+            ilog_dim = {}
+            ilogs = []
+            for dim, detail in self._detail.items():
+                ilog = fetch_log(tuple(detail))
+                if ilog == -100:
+                    continue
+                if ilog not in ilog_dim:
+                    ilog_dim[ilog] = []
+                    ilogs.append(ilog)
+                ilog_dim[ilog].append(dim)
+            ilogs = sorted(ilogs, reverse=True)
+            return ilog_dim, ilogs
+
+        def max_speed(dims):
+            fetch_commit = lambda x: x[EDetailPosmap.per_commit]
+
+            speeds = []
+            for dim in dims:
+                detail = self._detail[dim]
+                per_commit = fetch_commit(detail)
+                speeds.append(per_commit)
+            speeds = sorted(speeds, reverse=True)
+            return speeds[0]
+
+        def increaseable(ilog_dim, dims, ilog):
+            dim_ilog = {}
+            dims = sorted(dims)
+            for _ilog, _dims in ilog_dim.items():
+                for dim in _dims:
+                    dim_ilog[dim] = _ilog
+            maxdim = dims[-1]
+            for dim in range(dim, 6, 1):
+                if dim in dim_ilog:
+                    log = dim_ilog[dim]
+                    if log < ilog:
+                        return False
+            return True
+
+        ilog_dim, ilogs = log_dim()
+        if len(ilogs) > 0:
+            ilog = ilogs[0]
+            dims = ilog_dim[ilog]
+            max_speed = max_speed(dims)
+            can_increase = increaseable(ilog_dim, dims, ilog)
+            return max_speed, can_increase
+        else:
+            return None, False
+        pass
+
+    def per_commit(self, dim):
         if dim in self._detail:
             return self._detail[dim][EDetailPosmap.per_commit]
         else:
@@ -96,7 +156,7 @@ class ch_type_spec(object):
         self._speed = calc_chspeed(data, pos_map, end_pos - speed_period, end_pos) / mins
         ratio, ratio_commit, self._notify_time, succ_time = calc_chratio(data, pos_map, end_pos - start_period, end_pos)
         _commits, _succs, _ratios = calc_chspeed_ratio(data, pos_map, end_pos - monitor_period, end_pos, cdf_speed_period)
-        self.calculate(_commits,_succs)
+        self.calculate(_commits, _succs)
         pass
 
     def _prepare_data(self, datas):
@@ -117,7 +177,7 @@ class ch_type_spec(object):
 
         datas = np.concatenate([[commits], [succs]], axis=0)
         indexer = datas[0].argsort()
-        datas = datas[:,indexer]
+        datas = datas[:, indexer]
 
         avg = np.average(datas, axis=1)
         self._commit_min = round(avg[0], 5)
@@ -153,12 +213,19 @@ class ch_type_spec(object):
                 cur_succ = delta[1]
                 cur_ratio = round(delta[1] / (delta[0] + 0.000001), 5)
                 per_commit = round(avg[0], 5)
-                per_succ   = round(avg[1], 5)
+                per_succ = round(avg[1], 5)
+
+                try:
+                    ilog = round(math.log(cur_ratio))
+                except ValueError:
+                    ilog = -100
+                    pass
+                logger.debug(f'ilog={ilog} ratio={cur_ratio}')
 
                 per_pratio = 0 if self._pratio is None else self._pratio
                 per_profit = per_pratio * per_succ
-                #每分钟提单平均数,每分钟成单量,每分钟利润
-                detail[i] = [cur_commit, cur_succ, per_commit, per_succ, per_profit]
+                # 每分钟提单平均数,每分钟成单量,每分钟利润
+                detail[i] = [cur_commit, cur_succ, per_commit, per_succ, per_profit, ilog]
                 logger.debug(f'{self._name} i={i} detail={detail[i]}')
         self._detail = detail
         pass

+ 8 - 1
plot/refill/chs_manager.py

@@ -28,7 +28,14 @@ class chs_manager(object):
         total = 0
         for key, item in self.channels.items():
             total += item.cur_speed()
-        logger.debug(f'total = {total}')
+        logger.debug(f'total speed = {total}')
+        return total
+
+    def normal_speed(self):
+        total = 0
+        for key, item in self.channels.items():
+            total += item.normal_speed()
+        logger.debug(f'normal speed = {total}')
         return total
 
     def get_reckon(self):

+ 71 - 45
plot/refill/chs_type_spec.py

@@ -84,43 +84,65 @@ class type_spec_chs(object):
                 return 1
             pass
 
-        def adjust_combine(names, count, cost):
-            rate = count / (cost + 0.0000001)
-            for chname in names:
+        def costor(ch_costes):
+            total = 0
+            for chname,maxspeed in ch_costes:
+                total += maxspeed
+            return total
+
+        def arrange(ch_costes,cost):
+            if len(ch_costes) == 0:
+                return 0
+
+            all = costor(ch_costes)
+            all = len(ch_costes) if all == 0 else all
+            cost = 0 if cost < 0 else cost
+            rate = cost / all
+
+            for chname,maxspeed in ch_costes:
+                speed = round(maxspeed * rate)
                 ch_item = self._chs[chname]
-                speed = ch_item.reckon_speed()
-                append = round(speed * rate)
-                ch_item.add_reckon_speed(append)
-            pass
+                ch_item.add_reckon_speed(speed)
+            return cost
 
-        total = self.cur_speed()
+        total = self.normal_speed()
         rate = split_order(total)
 
-        feed_count = round(total * (1 - rate))
-        combine_count = total - feed_count
-
         logger.debug(f'{self._spec}-{self._card_type} total={total}')
         feeds, chpos, combination = self._looper()
         feeds.extend(self._no_price)
         if len(combination) > 0:
             item = self._op_maxsuccs(combination, chpos, rate)
-            cost, combines, _feeds = self._distribute(chpos, item, total, rate)
+            _feeds, increase, decrease = self._distribute(chpos, item, total, rate)
             feeds.extend(_feeds)
         else:
-            cost = 0
-            combines = []
+            increase = []
+            decrease = []
 
-        if cost < combine_count and len(combines) > 0:
-            adjust_combine(combines, combine_count - cost, cost)
-            left = total - combine_count
-            cost = combine_count
+        if len(feeds) > 0:
+            feed_count = round(total * (1 - rate))
+        else:
+            feed_count = 0
+
+        left = total - feed_count
+        cost_de = costor(decrease)
+        cost_in = costor(increase)
+        cost = costor(decrease) + costor(increase)
+        if cost > left:
+            cost_in = round(cost_in * 1.1)
+            cost_de = cost - cost_in
+            cost_de = cost_de if cost_de > 0 else 0
+        else:
+            cost_in = left - cost_de
+            pass
 
-        left = total - cost
-        left = 0 if left < 0 else left
+        arrange(decrease,cost_de)
+        arrange(increase,cost_in)
 
-        logger.debug(f'{self._spec}-{self._card_type} total={total} cost={cost} left={left}')
-        feeds = self._feed_check(feeds, total)
-        self._handle_feed(feeds, left)
+        logger.debug(f'{self._spec}-{self._card_type} total={total} cost={cost_in + cost_de} left={feed_count}')
+        if len(feeds) > 0:
+            feeds = self._feed_check(feeds, total)
+            self._handle_feed(feeds, feed_count)
         pass
 
     def _classify_combine(self, chpos, item):
@@ -162,7 +184,7 @@ class type_spec_chs(object):
                     feeds.append(chname)
                 else:
                     detail = ch_item.detail(dim)
-                    ratio_fun = lambda cur_commit, cur_succ, per_commit, per_succ, per_profit: cur_succ / cur_commit
+                    ratio_fun = lambda cur_commit, cur_succ, per_commit, per_succ, per_profit, radio_log: cur_succ / cur_commit
                     ratios[chname] = ratio_fun(*detail)
             return feeds, ratios
 
@@ -184,28 +206,31 @@ class type_spec_chs(object):
                     result.append((chname, dim))
             return result
 
-        def calc_cost(name_dimses):
-            cost = 0
-            for chname, dim in name_dimses:
-                ch_item = self._chs[chname]
-                speed = round(ch_item.detail_speed(dim))
-                cost += speed
-            return cost
+        def find_increase_channel(name_dimses):
+            feeds = []
+            increase = []
+            uncrease = []
 
-        def arrage_high(name_dimses):
             for chname, dim in name_dimses:
                 ch_item = self._chs[chname]
-                speed = round(ch_item.detail_speed(dim))
-                ch_item.add_reckon_speed(speed)
-            pass
+                max_speed, can_increase = ch_item.best_speed()
+                if max_speed is None:
+                    feeds.append(name)
+                    continue
+
+                max_speed = round(max_speed)
+                if can_increase == False:
+                    uncrease.append((chname, max_speed))
+                else:
+                    increase.append((chname, max_speed))
+            return feeds, increase, uncrease
 
         combines, feeds = self._classify_combine(chpos, item)
         logger.debug(f'high={combines},low={feeds}')
-
         name_dimses = name_dims(chpos, item, combines)
-        cost = calc_cost(name_dimses)
-        arrage_high(name_dimses)
-        return cost, combines, feeds
+        _feeds, increase, uncrease = find_increase_channel(name_dimses)
+        feeds.extend(feeds)
+        return feeds, increase, uncrease
 
     def _op_maxsuccs(self, combination, chpos, rate):
         def fill_data(combination, chpos, detail_length):
@@ -258,11 +283,10 @@ class type_spec_chs(object):
             logger.debug(f'card_type={self._card_type} spec={self._spec}')
             item = combination[index]
             return item
-
         ##############################################################################################################################################
         datas = fill_data(combination, chpos, dposmap.dim())
         # 按找利润排序,再在里面找满足提单量的
-        total = self.cur_speed() * rate
+        total = self.normal_speed() * rate
         sumview, combination = sort_per_profit(datas, combination)
         item = sort_nearst(sumview, combination, total)
         return item
@@ -324,17 +348,19 @@ class type_spec_chs(object):
             cur_speed = item.cur_speed()
             logger.debug(f'{name}-{self._spec}-{self._card_type} speed={cur_speed}')
             total += cur_speed
-        logger.debug(f'{self._spec}-{self._card_type} total={total}')
+        logger.debug(f'{self._spec}-{self._card_type} total speed ={total}')
         return total
 
     def normal_speed(self):
         total = 0
-        for name in self._normal_price:
+        datas = self._normal_price
+        datas.extend(self._no_price)
+        for name in datas:
             item = self._chs[name]
             cur_speed = item.cur_speed()
             logger.debug(f'{name}-{self._spec}-{self._card_type} speed={cur_speed}')
             total += cur_speed
-        logger.debug(f'{self._spec}-{self._card_type} total={total}')
+        logger.debug(f'{self._spec}-{self._card_type} normal speed={total}')
         return total
 
     def get_reckon(self):
@@ -342,4 +368,4 @@ class type_spec_chs(object):
         for key, item in self._chs.items():
             speed = item.reckon_speed()
             result[key] = speed
-        return result
+        return result