notes/snippet/python/bid/bid4.py

95 lines
3.2 KiB
Python

# coding=utf-8
import argparse
import numpy as np
class Bid:
BID_LIMIT = 5
MAX_PRICE = 13000
def __init__(self, max_val, min_val, max_range, min_range,
num=10, score=60, max_iter=100000):
"""
:param max_val: 最高投标价, 每次生成的投标数据中包含大于此值视为作废
:param min_val: 最低投标价, 每次生成的投标数据中包含小于此值视为作废
:param max_range: 合理的投标上限
:param min_range: 合理的投标下限
:param num: 投标厂商数目
:param score: 投标得分
:param max_iter: 最大迭代次数
"""
self.max_val = max_val
self.min_val = min_val
self.max_range = max_range
self.min_range = min_range
self.num = num
self.score = score
self.max_iter = max_iter
self.base_price = 0
self.changed = False
def single_fit(self):
avg = (self.max_range + self.min_range) / 2
scale = (self.max_range - self.min_range) / 2
prices = np.random.normal(avg, scale, self.num)
prices = np.sort(prices)
if not self.changed:
if self.num > self.BID_LIMIT:
prices = prices[1:self.num - 1]
self.num = self.num - 2
self.changed = True
if self.num != len(prices):
raise Exception(
'Not Equal: {} != {}'.format(self.num, len(prices)))
avg_price = np.average(prices)
self.base_price = avg_price * 0.95
filtered_index = np.where((self.base_price <= prices) & (prices <= self.MAX_PRICE))
filtered_price = prices[filtered_index]
# print('base: {}, prices: {}, filtered_price: {}'.format(self.base_price, prices, filtered_price))
# 正态分布, 去掉不合理的投标数据
index = np.where(filtered_price < self.min_val)
if len(index[0]) > 0:
return
index = np.where(filtered_price > self.max_val)
if len(index[0]) > 0:
return
if len(filtered_price) < 1:
return
return filtered_price[0]
def fit(self):
winner = np.zeros(self.max_iter)
i = 0
while i < self.max_iter:
price = self.single_fit()
if price is None:
continue
else:
winner[i] = price
i += 1
return winner
def main(max_iter, num):
max_iter = int(max_iter)
num = int(num)
# print(max_iter)
b = Bid(13000, 9000, 13000, 9000, num=num, max_iter=max_iter)
winner = b.fit()
print(u'投标厂商数目 {}, 中标价平均值 {:.2f}, 最大值 {:.2f}, 最小值 {:.2f}, 标准差 {:.2f};'.format(
num, np.mean(winner), np.max(winner), np.min(winner), np.std(winner)))
if __name__ == '__main__':
info = """
usage: python bid4.py --num=8 --max_iter=30000
"""
parser = argparse.ArgumentParser(description=info)
parser.add_argument("--max_iter", type=int, help=u"maximum iteration times")
parser.add_argument("--num", type=int, help=u"maximum bid num")
args = parser.parse_args()
main(args.max_iter, args.num)