import random
import math
import numpy as np
def compute_base_price(prices, a, b1, b2):
copy_prices = [price for price in prices]
copy_prices.sort()
return sum(copy_prices) / len(copy_prices) * b1 + copy_prices[1] * b2 + a * (1 - b1 - b2)
def raw_iteration(prices, a, b1, b2, error):
diff = error + 1
i = 0
while diff > error:
prices[i] = compute_base_price(prices, a, b1, b2)
diff_list = [abs(price - compute_base_price(prices, a, b1, b2)) for price in prices]
diff = max(diff_list)
i = (i + 1) % len(prices)
return prices
def cluster_size(prices, cluster_range, starting_price):
# return (size, next_price)
copy_prices = [price for price in prices]
copy_prices.sort()
starting_idx = copy_prices.index(starting_price)
cur_idx = starting_idx + 1
last_idx = starting_idx
while cur_idx < len(copy_prices):
if copy_prices[cur_idx] - copy_prices[last_idx] < cluster_range:
last_idx = cur_idx
cur_idx += 1
else:
break
if cur_idx == len(copy_prices):
return (last_idx - starting_idx + 1, None)
return (last_idx - starting_idx + 1, copy_prices[cur_idx])
def divide_by_cluster(prices, cluster_range):
# return (cluster_num, max_cluster_size)
cluster_num = 0
max_size = 0
first_price = min(prices)
cur_price = first_price
val = cluster_size(prices, cluster_range, cur_price)
cluster_num += 1
while val[1]:
if max_size < val[0]:
max_size = val[0]
cur_price = val[1]
val = cluster_size(prices, cluster_range, cur_price)
cluster_num += 1
if max_size < val[0]:
max_size = val[0]
return (cluster_num, max_size)
def concentration(prices, cluster_range):
w1 = 0.3
w2 = 0.7
min_val = 2 * math.sqrt(w1 * w2 / len(prices))
max_val = w2 + w1 / len(prices)
(cluster_num, max_size) = divide_by_cluster(prices, cluster_range)
val = w1 * cluster_num / len(prices) + w2 * max_size / len(prices)
return (val - min_val) / (max_val - min_val)
# range from 0 to 1
# w1 * cluster_num / n + w2 * max_cluster_size / n
# >= 2 * sqrt(w1 * w2 * cluster_num * max_cluster_size / n**2)
# >= 2 * sqrt(w1 * w2 / n)
# <= w2
def random_choose_A_B1_B2(A,B1,B2,a,b1,b2):
i = random.randrange(0,11)
while (A[i],B1[i],B2[i]) == (a,b1,b2):
i = random.randrange(0,11)
return (A[i],B1[i],B2[i])
def simulated_annealing_iteration(prices, a, b1, b2, error, max_iteration, cluster_range=10000):
diff = error + 1
i = 0
cnt = 0
concentration_deg = concentration(prices, cluster_range)
while (diff > error or concentration_deg > 0.5) and cnt <= max_iteration:
base_price1 = compute_base_price(prices, a, b1, b2)
(a_rand, b1_rand, b2_rand) = random_choose_A_B1_B2(A,B1,B2,a,b1,b2)
base_price2 = compute_base_price(prices, a_rand, b1_rand, b2_rand)
val = int(np.random.binomial(n=1, p=concentration_deg, size=1)[0])
temp = prices[i]
prices[i] = val * base_price2 + (1 - val) * base_price1
diff = abs(temp - prices[i])
i = (i + 1) % len(prices)
cnt += 1
concentration_deg = concentration(prices, cluster_range)
return prices
A_max = 4907459
A_min = 4649516
A = [4642976, 4668770.3, 4694564.6, 4720358.9, 4746153.2,
4771947.5, 4797741.8, 4823536.1, 4849330.4, 4875124.7, 4900919]
B1 = [0.15, 0.16, 0.17, 0.18 , 0.19 ,
0.20 , 0.21 , 0.22 , 0.23 , 0.24 ,0.25]
B2 = B1
n = int(input("n: "))
k = int(input("How many persons use strategy: "))
strategy_bidders = []
row_bidders = []
# initialize everyone's offer randomly
strategy_bidders = [random.randrange(A_min, A_max) for i in range(k)]
raw_bidders = [random.randrange(A_min, A_max) for i in range(n-k)]
# randomly choose 3th (A,B1,B2),
# and set error <= 1000
# and set max_iteration_cycle = 10000
simulated_annealing_iteration(strategy_bidders, A[3], B1[3], B2[3], \
1000, 10000)
final_ans = strategy_bidders + row_bidders
# get the final price distribution of all bidders
# except ourselves
# next we can simply apply
# compute_base_price(final_ans, A[rand], B1[rand], B2[rand])
# to get our ideal price