Пример #1
0
def gen_initial_solution(data_points, offices, customers, n_offices):
    tot_iteration = 100
    [cluster_label, new_centroids] = k_means(data_points, n_offices,
                                             tot_iteration)

    new_solution = list()
    clusters = list()

    for i in range(len(new_centroids)):
        clusters.append(list())

    for label in cluster_label:
        clusters[label[0]].append(label)

    office = None
    for cluster in clusters:
        customers_id = list()
        for elem in cluster:
            cust = NodeUtils.closest_node(
                Node(None, elem[1][0], elem[1][1], None), customers)
            customers_id.append(cust.index)
            office = NodeUtils.closest_node(
                Node(None, elem[2][0], elem[2][1], None), offices)

        office_sol = InitialSolution()
        office_sol.office = office
        office_sol.customers_id = customers_id

        new_solution.append(office_sol)

    return new_solution
Пример #2
0
def path_to_charging(sourcedId):
    min = -1
    targetId = -1
    chargings = DataOperate.get_chargings()

    for charging in chargings:
        dist = NodeUtils.get_dist(sourcedId, charging)
        if min == -1 or min < dist:
            min = dist
            targetId = charging

    return NodeUtils.get_path(sourcedId, targetId), min
Пример #3
0
def get_first_path(Gj, request_Ls, request_Ld):
    first_path = []
    # 1.获取Gj到request_Ls的路径规划
    pathj_Ls = NodeUtils.get_path(Gj, request_Ls)
    # 2.获取request_Ls到request_Ld的路径规划
    pathLs_Ld = NodeUtils.get_path(request_Ls, request_Ld)

    first_path.extend(pathj_Ls)

    if first_path:
        first_path.extend(pathLs_Ld[1:])
    else:
        first_path.extend(pathLs_Ld)

    return first_path
Пример #4
0
def others_to_cur_dist_sort(size=1426):
    print('开始计算其他节点到本节点的距离的排序,共有%s个节点' % size)
    for cur in range(size):
        print('开始计算其他节点到第%s个节点的距离的排序' % cur)
        others_to_cur_dists = []

        for other in range(size):
            dist = NodeUtils.get_dist(other, cur)
            others_to_cur_dists.append(dist)

        new_others_to_cur_dists = sorted(others_to_cur_dists)
        res = []
        exist = np.zeros(1426, dtype='int16')
        for others_to_cur_dist in new_others_to_cur_dists:
            index = others_to_cur_dists.index(others_to_cur_dist)
            while exist[index] == 1:
                index = others_to_cur_dists.index(others_to_cur_dist,
                                                  index + 1)
            exist[index] = 1
            res.append(index)
        print('开始写入第%s个节点的距离的排序' % cur)
        # print('res = %s' %res[:20])
        #将res写入到文件中
        with open('sortdistances/sortdistance' + str(cur) + '.txt', 'w') as f:
            f.write(str(res) + '\n')
Пример #5
0
def optimal_solution(car_end, request):
    # print('开始寻找最优解')
    max_detour_dist = None
    car_best = None
    min_dist_Gj_Ls = None
    for car_e in car_end:
        car = car_e[0]
        #判断车辆状态信息是否已经改变了
        if is_carstate_change(car, DataOperate.get_car(car.id)):
            continue
        Gj = car_e[1]
        arrive_Gj_datetime = car_e[2]
        situation = car_e[3]

        # 1.算出从Gj节点到请求出发地request.Ls节点的距离distj_Ls
        distj_Ls = NodeUtils.get_dist(Gj, request.Ls)

        # 2.判断是否是第一批乘客,是的话没有拼车这一说,如果可以拼车的话,优先拼车
        if situation == 0:
            if max_detour_dist == None and (min_dist_Gj_Ls == None or min_dist_Gj_Ls > distj_Ls):
                    min_dist_Gj_Ls = distj_Ls
                    car_best = [car, Gj, arrive_Gj_datetime, 0, distj_Ls + NodeUtils.get_dist(request.Ls, request.Ld)]
            continue

        # TODO 考虑是否还需要 1.获取每辆车从Gj节点到它当前目的地car.Ld节点的距离distj_Ld
        # distj_Ld = NodeUtils.get_dist(Gj, car[4])

        # 3.分别算出从request.Ls节点到request.Ld节点的距离distLs_Ld1和car.Ld节点的距离distLs_Ld2
        distLs_Ld1 = NodeUtils.get_dist(request.Ls, request.Ld)
        distLs_Ld2 = NodeUtils.get_dist(request.Ls, car.Ld)
        # 4.算出request.Ls节点到request.Ld(car.Ld)节点再到car.Ld(request.Ld)节点的距离distLs_Ld
        # distLs_Ld = None
        if situation == 1:
            # 4.1 先送拼车乘客去目的地
            distLs_Ld = get_sharedist(request.Ls, request.Ld, car.Ld)
        else:
            # 4.2先送原始乘客去目的地
            distLs_Ld = get_sharedist(request.Ls, car.Ld, request.Ld)
        # 5.算出绕路的距离 detour_dist = (distLs_Ld1 + distLs_Ld2) - distLs_Ld + distj_Ls
        detour_dist = (distLs_Ld1 + distLs_Ld2) - distLs_Ld + distj_Ls
        detour_dist = (distLs_Ld1 + distLs_Ld2) - distLs_Ld - distj_Ls
        # 6.找到最小的绕路距离车辆
        if max_detour_dist == None or max_detour_dist > detour_dist:
            max_detour_dist = detour_dist
            car_best = [car, Gj, arrive_Gj_datetime, situation, distj_Ls + distLs_Ld]
    # print('car_best = %s' % car_best)
    return car_best
Пример #6
0
def origin_match(request):
    # print('开始进行出发地匹配')
    #结果集
    car_start = []
    #标记一辆车是否已经访问过
    vis = np.zeros(1200, dtype="int16")
    #1.获取请求的出发地和目的地
    request_Ls = request.Ls
    can_endure_datetime = str(DatetimeUtils.datetime_add(request.Tp, 10))
    # 2.获取距离request.Ls节点由近到远的节点list结合
    sort_node = DataOperate.get_sort_node(request_Ls)

    # 3.对于其中的每个可达节点,选出能在用户要求时间内接到用户的车辆:
    for i in sort_node:
        # 节点i到节点Ls的最短距离 单位:m
        dist = NodeUtils.get_dist(i, request_Ls)
        #判断i节点是否能到达request.Ls节点,即用户的出发节点, and 两个节点的距离小于等于 5000m
        if dist > 5000:
            break
        #拿到i节点的车辆状态表[[车辆编号, 预计到达该节点时间,该节点是否为目的地(0:否,1:是)], ...]
        carstate = DataOperate.get_carstate(i)
        for state in carstate:
            carid = state[0]
            arrive_datetime = state[1]
            # is_target = state[2]
            #不同节点间肯定有重复的车辆信息,如果一辆车在G1节点不能到当前节点,那么在G2节点也不能到达
            if vis[carid] == 1:
                continue
            #标记车辆为已访问
            vis[carid] = 1
            #获取车辆信息
            car = DataOperate.get_car(carid)
            #判断车辆是否正在充电
            if car.is_recharge == 1:
                continue
            # 车辆从节点i到节点Ls所需行驶时间 假设速度恒定为:60km/h -> 1000m/min
            ti_Ls = dist / 1000
            #车辆到达request.Ls节点的时间
            arrive_Ls_datetime = str(DatetimeUtils.datetime_add(arrive_datetime, ti_Ls))
            #如果车辆当前的乘客批数为0,即没有乘客的话,那么只需判断能否按时到达请求出发地,不需要进行其他的判断了
            if car.batch_numbers == 0:
                # 判断能否在规定时间到达request.Ls节点
                if arrive_Ls_datetime <= can_endure_datetime:
                    car_start.append([car, i, DatetimeUtils.cur_datetime()])
                continue
            #如果车辆已有两批乘客在拼车,则不考虑
            if car.batch_numbers > 1:
                continue
            #如果车辆的座位数不能满足乘客的要求
            if car.Pc + request.Pr > 3:
                continue


            #判断车辆carid到i节点的时间 + 车辆从节点i到节点Ls所需的行驶时间 <= 用户请求的出发时间Tp + 用户可以容忍的等待时间Ts(定值 10min)

            if arrive_Ls_datetime <= can_endure_datetime:
                car_start.append([car, i, arrive_datetime])
    # print('car_start = %s' % car_start)
    return car_start
Пример #7
0
def evaluate_sol(offices_id, offices, customers):
    tot_dist = 0
    tot_reward = 0

    offices_sol = list()
    for index in offices_id:
        offices_sol.append(offices[index])

    built_offices = list()
    for customer in customers:
        office = NodeUtils.closest_node(customer, offices_sol)
        tot_dist += NodeUtils.euclidean_dist(office,
                                             customer) + offices[index].value
        tot_reward += customer.value

        if office not in built_offices:
            built_offices.append(office)

    return tot_reward - int(tot_dist), len(built_offices)
Пример #8
0
def get_rand_neighbor(sol, offices, area=10):
    swap_id = r.randrange(len(sol))
    new_x = offices[swap_id].x + r.uniform(-area, area)
    new_y = offices[swap_id].y + r.uniform(-area, area)

    new_office = NodeUtils.closest_node(Node(None, new_x, new_y, None),
                                        offices)
    sol[swap_id] = new_office.index

    return sol
Пример #9
0
def get_share_path(Gj, request_Ls, Ld1, Ld2):
    share_path = []
    #1.获取从Gj到request_Ls的路径pathj_Ls
    pathj_Ls = NodeUtils.get_path(Gj, request_Ls)
    #2.获取从request_Ls到Ld1的路径pathLs_Ld1
    pathLs_Ld1 = NodeUtils.get_path(request_Ls, Ld1)
    #3.获取从Ld1到Ld2的路径pathLs_Ld2
    pathLs_Ld2 = NodeUtils.get_path(Ld1, Ld2)
    #4.合并三个路径
    share_path.extend(pathj_Ls)

    if share_path:
        share_path.extend(pathLs_Ld1[1:])
    else:
        share_path.extend(pathLs_Ld1)

    if share_path:
        share_path.extend(pathLs_Ld2[1:])
    else:
        share_path.extend(pathLs_Ld2)

    return share_path
Пример #10
0
def after_match(car_best, request):
    # print('匹配成功后相关处理')
    car = car_best[0]
    #判断车辆状态信息是否已经改变了
    if is_carstate_change(car, DataOperate.get_car(car.id)):
        return False
    Gj = car_best[1]
    arrive_Gj_datetime = car_best[2]
    situation = car_best[3]
    distGj_Ld1_Ld2 = car_best[4]

    #1.修改乘客批数
    car.batch_numbers += 1
    car.Pc += request.Pr

    #移除Gj节点到car.Ld节点路径上的节点的车辆状态表
    if situation != 0:
        # 拿到车辆从Gj节点到car.Ld节点的路径,修改路径上节点的车辆状态表
        pathj_Ld = NodeUtils.get_path(Gj, car.Ld)
        NodeUtils.remove_carstate(pathj_Ld, car.id)


    #拿到Gj节点->request.Ls节点->request.Ld节点的路径
    if situation == 0:
        share_path = get_first_path(Gj, request.Ls, request.Ld)
        car.Ld = request.Ld
    # 拿到车辆从Gj到request.Ls再到request.Ld(car.Ld)再到car.Ld(request.Ld)节点的路径规划,修改路径上节点的车辆状态表,修改车辆的当前目的地
    elif situation == 1:
        share_path = get_share_path(Gj, request.Ls, request.Ld, car.Ld)
    elif situation == 2:
        share_path = get_share_path(Gj, request.Ls, car.Ld, request.Ld)
        #修改车辆目的地
        car.Ld = request.Ld
    #在新的路径上的节点的车辆状态表上加上一行新的行车记录
    NodeUtils.add_carstate(share_path, car.id, Gj, arrive_Gj_datetime)


    #获取车辆出发地car.Ls到Gj节点的距离distLs_Gj
    distLs_Gj = NodeUtils.get_dist(car.Ls, Gj)
    #算出car.Ls -> 新的目的地的距离 distLs_Ld
    distLs_Ld = distLs_Gj + distGj_Ld1_Ld2
    #计算到达目的地的时间
    arrive_target_datetime = str(DatetimeUtils.datetime_add(arrive_Gj_datetime, distGj_Ld1_Ld2 / 1000))

    # 更新车辆信息,特别是batch_numbers
    DataOperate.update_car(car)

    #更新请求为已匹配成功
    request.is_match_successful = 1
    DataOperate.update_request(request)

    #提交定时任务,在车辆到达新目的地的时候执行
    ApschedulerClient.arrival_job(arrive_target_datetime, car.id, distLs_Ld)

    return True
Пример #11
0
def fastest_charging_datetime(sourcedId, soc):
    #获取充电站所有的节点位置id,为list类型
    chargings = DataOperate.get_chargings()
    # print('chargings = ', chargings)
    '''
    获取每个充电站的状态信息
        chargings_state_donedatetime:每个充电站什么时间完成对当前充电站最后一辆车的充电
    '''
    chargings_state_donedatetime = DataOperate.get_chargings_state()
    # print('chargings_state_donedatetime = ', chargings_state_donedatetime)
    # print('typeof chargings_state_donedatetime is ', type(chargings_state_donedatetime))

    fastest_charging_datetime = None
    target_index = -1
    i = 0
    for charging in chargings:
        #获取起始地到充电站的距离
        dist = NodeUtils.get_dist(sourcedId, charging)
        #判断是否能够到达充电站
        if not enough_battery_to_target(dist, soc):
            continue
        # print('charging = ', charging)
        # print('chargings_state_donedatetime[%s] is %s' % (i, chargings_state_donedatetime[i]))
        # print('typeof chargings_state_donedatetime[%s] is %s' % (i, type(chargings_state_donedatetime[i])))
        #计算出 若到该充电站充电的话,完成充电的时间
        cd = charging_datetime(dist, soc, chargings_state_donedatetime[i])
        # print('cd = ', cd)
        # print('type of cd is', cd)
        #如果最少时间为None或者比cd大的话,更新最小时间
        if fastest_charging_datetime == None or fastest_charging_datetime > cd:
            fastest_charging_datetime = cd
            target_index = i
        i += 1

    #修改充电站状态信息
    chargings_state_donedatetime[target_index] = fastest_charging_datetime
    DataOperate.update_chargings_state(chargings_state_donedatetime)

    return fastest_charging_datetime,chargings[target_index]
Пример #12
0
import datetime as dt
import DataOperate
import NodeUtils


def test():
    test = 1
    print(test)


if __name__ == "__main__":
    pass

    for sour in range(1426):
        for targ in range(1426):
            path = NodeUtils.get_path(sour, targ)
            dist = NodeUtils.get_dist(sour, targ)
            cur_dist = 0
            pre = path[0]
            for Gc in path[1:]:
                cur_dist += NodeUtils.get_dist(pre, Gc)
                pre = Gc

            # print(path)
            # print(dist)
            # print(cur_dist)
            if (cur_dist != dist):

                print('%s -> %s' % (sour, targ))

    #测试cars修改是否起作用
Пример #13
0
def target_match(request, car_start):
    # print('开始进行目的地匹配')
    #结果集
    car_end = []

    for car_s in car_start:
        car = car_s[0]
        #判断车辆状态信息是否已经改变了
        if is_carstate_change(car, DataOperate.get_car(car.id)):
            continue
        Gj = car_s[1]
        arrive_Gj_datetime = car_s[2]

        #如果为空车状态,不用进行目的地匹配
        if car.batch_numbers == 0:
            car_end.append([car, Gj, arrive_Gj_datetime, 0])
            continue
        '''
        在进行匹配时,有以下两种情况下可以认为匹配是成功的:
            1.拼车乘客所要去的目的地离车辆当前行驶路径上的某一点距离不远
            2.车辆当前的目的地离拼车乘客所要行驶的路径上的某一点不远
            分别对应了:
            1.车辆先将拼车乘客送达目的地,再将原始乘客送达目的地
            2.车辆先将原始乘客送达目的地,再将拼车乘客送达目的地     
        '''
        '''
        对于第一种情况,遍历Rc路径上的所有节点Gc,检查Gc节点到request.Ld节点的所需时间tc_Ld * 2 <= 10
        '''
        min = None
        situation = None
        # 获取请求的起点request.Ls到车辆当前的目的地car.Ld的路径Rc = [request.Ls, ..., car.Ld]
        Rc = NodeUtils.get_path(request.Ls, car.Ld)
        for Gc in Rc:
            #判断min是否小于等于300m,若是,直接退出循环
            if min != None and min <= 300:
                break
            #Rc路径上每个节点Gc到请求的目的地request.Ld的距离
            dist = NodeUtils.get_dist(Gc, request.Ld)
            #考虑用户可忍受的时间为10min,那么这个距离最远不能超过5000m
            if dist >= 0 and dist <= 5000:
                if min == None or dist < min:
                    min = dist
                    situation = 1


        '''
        对于第二种情况,对于请求的起始位置request.Ls,和目的地request.Ld的路径规划Rp<Ls,...,Ld>,遍历Rp路径上的所有节点Gc,
        检查节点Gc到车辆当前目的地Ci.Ld节点所需的时间tc_carLd * 2 <= 10
        '''
        Rp = NodeUtils.get_path(request.Ls, request.Ld)
        for Gc in Rp:
            # 判断min是否小于等于300m,若是,直接退出循环
            if min != None and min <= 300:
                break
            # Rp路径上每个节点Gc到车辆当前的目的地car.Ld的距离
            dist = NodeUtils.get_dist(Gc, car.Ld)
            if dist >= 0 and dist <= 5000:
                if min == None or dist < min:
                    min = dist
                    # Gi = Gc
                    situation = 2

        if min != None:
            #[[车辆对象,在Gj节点去接拼车乘客,到达Gj节点的时间,先送原始乘客或先送拼车乘客(1:先送拼车乘客,2:先送原始乘客)], ...]
            car_end.append([car, Gj, arrive_Gj_datetime, situation])
    # print('car_end = %s' % car_end)
    return car_end
Пример #14
0
def get_sharedist(request_Ls, Ld1, Ld2):
    return NodeUtils.get_dist(request_Ls, Ld1) + NodeUtils.get_dist(Ld1, Ld2)