#归一化pso
import math
import time
from itertools import combinations

import numpy as np
from matplotlib import pyplot as plt

import Users
from pso import PSO
from improvedPSO import CPSO
import tool
import GDOP
import ObjectiveFuction as OF
import constants as C
import dynamicProcess as dynamic

plt.style.use('seaborn-whitegrid')

# 设置字体为 Times New Roman
plt.rcParams['font.family'] = 'Times New Roman'


def ipso_convex(users,k,r_c,r_p):
    # users= Users.getUsers("./data.csv")
    uavs=tool.getUavInitialPos(k,users)
    pre_uavs=uavs
    # r_c,r_p=dynamic.random_r(users)
    c_association, p_association, p_all, b_all = OF.objective_resource_avg(uavs, users, r_c)
    # c_association, p_association, p_all, b_all = OF.objective_resource(uavs, users, r_c)
    pso = CPSO(pre_uavs, users, r_c, r_p, k, )
    pso.re_init(pre_uavs, users, r_c, r_p, c_association, p_association, p_all, b_all)
    X, V = pso.initParticle(users)
    global_pos, global_best, result = pso.pso(X, V, OF.linear_w, OF.objective, )
    c_association, p_association, p_all, b_all = OF.objective_resource(global_pos, users, r_c)
    f, e, rate, gdop = OF.real_objective(pre_uavs, global_pos, users, r_c,r_p, p_all, b_all, c_association,
                                         p_association, C.time_slot)
    print("real-f",f)
    r,g=OF.cal_satisfaction(global_pos,users,p_all,b_all,r_c,r_p, c_association,p_association)
    print("pso_convex",global_best,r,g)
    if f>global_best[0]:
        return f,r,g
    return global_best[0],r,g

def ipso_avg(users,k,r_c,r_p):
    uavs = tool.getUavInitialPos(k, users)
    pre_uavs = uavs
    # r_c,r_p=dynamic.random_r(users)
    c_association, p_association, p_all, b_all = OF.objective_resource_avg(uavs, users, r_c)
    pso = CPSO(pre_uavs, users, r_c, r_p, k, )
    pso.re_init(pre_uavs, users, r_c, r_p, c_association, p_association, p_all, b_all)
    X, V = pso.initParticle(users)
    global_pos, global_best, result = pso.pso(X, V, OF.linear_w, OF.objective, )
    f, e, rate, gdop = OF.real_objective(pre_uavs, global_pos, users, r_c, r_p, p_all, b_all, c_association,
                                         p_association, C.time_slot)
    r, g = OF.cal_satisfaction(global_pos, users, p_all, b_all, r_c, r_p, c_association, p_association)
    print("pso_avg",global_best,r,g)
    if global_best[0]<0:
        return f,r,g
    else:
        return global_best[0],r,g

def pso_convex(users,k,r_c,r_p):
    uavs = tool.getUavInitialPos(k, users)
    pre_uavs = uavs
    # r_c,r_p=dynamic.random_r(users)
    c_association, p_association, p_all, b_all = OF.objective_resource(uavs, users, r_c)
    pso = PSO(pre_uavs, users, r_c, r_p, k, )
    pso.re_init(pre_uavs, users, r_c, r_p, c_association, p_association, p_all, b_all)
    X, V = pso.initParticle(users)
    global_pos, global_best, result = pso.pso(X, V, OF.linear_w, OF.objective, )
    print(global_best)

def pso_avg(users,k,r_c,r_p):
    uavs = tool.getUavInitialPos(k, users)
    pre_uavs = uavs
    # r_c,r_p=dynamic.random_r(users)
    c_association, p_association, p_all, b_all = OF.objective_resource_avg(uavs, users, r_c)
    pso = PSO(pre_uavs, users, r_c, r_p, k, )
    pso.re_init(pre_uavs, users, r_c, r_p, c_association, p_association, p_all, b_all)
    X, V = pso.initParticle(users)
    global_pos, global_best, result = pso.pso(X, V, OF.linear_w, OF.objective, )
    print(global_best)

def kmeans_convex(users,k,r_c,r_p):
    uavs = tool.getUavInitialPos(k, users)
    pre_uavs = uavs
    # r_c,r_p=dynamic.random_r(users)
    c_association, p_association, p_all, b_all = OF.objective_resource(uavs, users, r_c)
    f, e, rate, gdop = OF.real_objective(pre_uavs, uavs, users, r_c,r_p, p_all, b_all, c_association,
                                         p_association, C.time_slot)
    r, g = OF.cal_satisfaction(uavs, users, p_all, b_all, r_c, r_p, c_association, p_association)
    # pso = PSO(pre_uavs, users, r_c, r_p, k, )
    # pso.re_init(pre_uavs, users, r_c, r_p, c_association, p_association, p_all, b_all)
    # X, V = pso.initParticle(users)
    # global_pos, global_best, result = pso.pso(X, V, OF.linear_w, OF.objective, )
    print("km_convex",f,r,g)
    return f,r,g

def kmeans_avg(users,k,r_c,r_p):
    uavs = tool.getUavInitialPos(k, users)
    pre_uavs = uavs
    # r_c,r_p=dynamic.random_r(users)
    c_association, p_association, p_all, b_all = OF.objective_resource_proportion(uavs, users, r_c)
    f, e, rate, gdop = OF.real_objective(pre_uavs, uavs, users,r_c, r_p, p_all, b_all, c_association,
                                         p_association, C.time_slot)
    r, g = OF.cal_satisfaction(uavs, users, p_all, b_all, r_c, r_p, c_association, p_association)
    # pso = PSO(pre_uavs, users, r_c, r_p, k, )
    # pso.re_init(pre_uavs, users, r_c, r_p, c_association, p_association, p_all, b_all)
    # X, V = pso.initParticle(users)
    # global_pos, global_best, result = pso.pso(X, V, OF.linear_w, OF.objective, )
    print("km_avg",f,r,g)
    return f,r,g

#
# users= Users.getUsers("./data.csv")
# df_c=dynamic.read_csv_to_df('r_c.csv')
# df_p = dynamic.read_csv_to_df('r_p.csv')
# index=0
# r_c,r_p=dynamic.get_r_c_and_r_p(df_c,df_p,index)
# # pso_convex(users,4,r_c,r_p)
# # pso_avg(users,4,r_c,r_p)
# kmeans_convex(users,4,r_c,r_p)
# kmeans_avg(users,4,r_c,r_p)

def compare():
    k=4
    r1,r2,r3,r4=[],[],[],[]
    r_satisfaction,g_satisfaction=[[] for i in range(4)],[[] for i in range(4)]
    num=17
    sum1,sum2,sum3,sum4=0,0,0,0
    time=10
    for i in range(0,time):
        users=Users.generate(num)
        r_c,r_p=dynamic.random_r(users)
        s=[0 for i in range(4)]
        g = [0 for i in range(4)]
        result1,s[0],g[0]=ipso_convex(users, k, r_c, r_p)
        result2,s[1],g[1]=ipso_avg(users, k, r_c, r_p)
        result3,s[2],g[2]=kmeans_convex(users, k, r_c, r_p)
        result4,s[3],g[3]=kmeans_avg(users, k, r_c, r_p)
        sum1 += result1
        sum2 += result2
        sum3 += result3
        sum4 += result4

        r1.append(result1)
        r2.append(result2)
        r3.append(result3)
        r4.append(result4)
        for i in range(4):
            r_satisfaction[i].append(s[i])
            g_satisfaction[i].append(g[i])
    print(r1,r2,r3,r4)
    print(r_satisfaction,g_satisfaction)
    print(sum1/time,sum2 /time,sum3 / time,sum4 / time)


compare()
# [[0.8, 0.5714285714285714, 0.5555555555555556, 0.5454545454545454, 0.46153846153846156, 0.6, 0.5294117647058824, 0.42105263157894735], [1.0, 1.0, 1.0, 1.0, 0.8461538461538461, 0.8666666666666667, 0.8823529411764706, 0.7368421052631579], [1.0, 1.0, 1.0, 1.0, 0.9230769230769231, 1.0, 0.8823529411764706, 0.42105263157894735], [1.0, 1.0, 1.0, 0.9090909090909091, 0.9230769230769231, 0.9333333333333333, 0.8823529411764706, 0.8421052631578947]] [[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 0.6666666666666666, 0.7272727272727273, 0.7692307692307693, 0.8, 0.8823529411764706, 0.8421052631578947], [1.0, 1.0, 0.6666666666666666, 0.7272727272727273, 0.7692307692307693, 0.8, 0.8823529411764706, 0.8421052631578947]]
