Commit 50a3f7f9 by bo

Initial commit

parents
[submodule "src/base"]
path = src/base
url = http://code.kfw.net/bo/macarons
import logging
logging.basicConfig(level=logging.INFO, format='%(asctime)19.19s %(levelname)1.1s %(process)5d %(module)10.10s:%(lineno)04d:%(funcName)s $$ %(message)s')
# tornado资源配置
settings = {
"gzip": True,
"debug": False,
}
LOAD_MODULE = REJECT_MODULE = []
LOGFILE = None
BASE_DB = "online"
# 单库
database = {
"online": {
'engine' : 'pg',
'db' : 'fire',
'host' : '127.0.0.1',
'port' : 5432,
'user' : 'postgres',
'passwd' : 'xyzj',
'charset' : 'utf8mb4',
'conn' : 10
}
}
from conf.settings import *
settings["debug"] = True
Subproject commit 152d7f6d0f43545b17a5509328c214a0df809d2e
# coding: utf-8
import sys
import os
new_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
if new_path not in sys.path:
sys.path.append(new_path)
new_path = os.path.dirname(new_path)
if new_path not in sys.path:
sys.path.append(new_path)
if __name__ == "__main__":
from src.base.main import run
path = os.path.dirname(__file__)
run(path, 8800, url_prefix="", use_session=False)
# coding: utf-8
import sys
import os
new_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
if new_path not in sys.path:
sys.path.append(new_path)
new_path = os.path.dirname(new_path)
if new_path not in sys.path:
sys.path.append(new_path)
print(sys.path)
if __name__ == "__main__":
import conf.settings_debug
import conf.settings
conf.settings = conf.settings_debug
sys.modules.update({"conf.settings": conf.settings_debug})
from src.base.main import run
path = os.path.dirname(__file__)
run(path, 8800, url_prefix="", use_session=False)
# coding: utf-8
__author__ = "bozyao"
from src.base.base_lib.app_route import route, RequestHandler
from src.lib.recm_path import get_order_path
@route()
class orders_sort_rcmdHandler(RequestHandler):
def get(self):
"""
获取对应城市信息
url: /api/v1/path/orders_sort_rcmd
get
@:param
cur_poi: lng,lat # 当前位置
next_order: id # 指定下一单id
orders: id,lng,lat,lng,lat;id,lng,lat;id,lng,lat
# 单子id关联经纬度,可以有多组组成,每组之间分号分隔
# 一组有 已经取货订单 和 未取货订单 两种状态,已取货订单 由id标记和纬经度组成
# 单子id在此处无意义,只是作为返回前台的标记
@:return
{
"error_code": 0,
"data": {
"path": "id,lng,lat,2;id,lng,lat,2;id,lng,lat,1;id,lng,lat,2",
"total_line_distance": 20009.40
}
}
"""
cur_poi = self.get_argument("cur_poi", "")
next_order = self.get_argument("next_order", "")
orders = self.get_argument("orders", "")
order_path, total_dist = get_order_path(orders, cur_poi)
ret = {
"path": order_path,
"total_line_distance": total_dist
}
self.ret_data(data={"data": ret}, max_age=60 * 60 * 24)
# coding: utf-8
def generate_possible_path(arrays):
'''
生成所有可能的组合
'''
numbers = []
for subarray in arrays:
numbers.extend(subarray)
# print(numbers)
# numbers = sorted(list(set(numbers)))
# numbers = set(numbers)
constraints = [(subarray[0], subarray[1]) for subarray in arrays if len(subarray) == 2]
# print(constraints)
result = []
def backtrack(curr_perm, used, seen_first):
if len(curr_perm) == len(numbers):
result.append(curr_perm[:])
return
for num in numbers:
if num not in used:
# Check constraints
can_add = True
for first, second in constraints:
if num == second and first not in seen_first:
can_add = False # 判断送货点在取货点之前
break
if can_add:
curr_perm.append(num)
used.append(num)
if num in [first for first, _ in constraints]:
seen_first.append(num)
backtrack(curr_perm, used, seen_first)
curr_perm.pop()
used.remove(num)
if num in [first for first, _ in constraints]:
seen_first.remove(num)
# backtrack([], set(), set())
backtrack([], [], [])
return result
def str2orders(strs):
'''
strs = 'id,lng,lat,lng1,lat2;id,lng,lat;id,lng,lat'
'''
tmp_orders = [tmp for tmp in strs.split(';') if tmp]
ret_orders = {}
for tmp in tmp_orders:
tmp_arr = tmp.split(',')
if len(tmp_arr) == 3: ret_orders[tmp_arr[0]] = [[tmp_arr[1], tmp_arr[2]]]
if len(tmp_arr) == 5: ret_orders[tmp_arr[0]] = [[tmp_arr[1], tmp_arr[2]], [tmp_arr[3], tmp_arr[4]]]
return ret_orders
if __name__ == '__main__':
strs = 'id1,lng,lat,lng1,lat1;id2,lng2,lat2;id3,lng3,lat3'
strs = 'id1,lng,lat,lng1,lat1;id2,lng2,lat2;id3,lng,lat'
orders = str2orders(strs)
locs = orders.values()
print(locs)
all_path = generate_possible_path(locs)
print(all_path)
print(generate_possible_path([['lng2,lat2'], ['lng,lat'], ['lng,lat', 'lng1,lat1']]))
# coding: utf-8
import math
def generate_possible_path(arrays):
'''
生成所有可能的组合
'''
numbers = []
for subarray in arrays:
numbers.extend(subarray)
numbers = sorted(list(set(numbers)))
constraints = [(subarray[0], subarray[1]) for subarray in arrays if len(subarray) == 2]
result = []
def backtrack(curr_perm, used, seen_first):
if len(curr_perm) == len(numbers):
result.append(curr_perm[:])
return
for num in numbers:
if num not in used:
# Check constraints
can_add = True
for first, second in constraints:
if num == second and first not in seen_first:
can_add = False # 判断送货点在取货点之前
break
if can_add:
curr_perm.append(num)
used.add(num)
if num in [first for first, _ in constraints]:
seen_first.add(num)
backtrack(curr_perm, used, seen_first)
curr_perm.pop()
used.remove(num)
if num in [first for first, _ in constraints]:
seen_first.remove(num)
backtrack([], set(), set())
return result
def str2orders(strs):
'''
strs = 'id,lng,lat,lng,lat;id,lng,lat;id,lng,lat'
'''
tmp_orders = [tmp for tmp in strs.split(';') if tmp]
ret_orders = {}
for tmp in tmp_orders:
tmp_arr = tmp.split(',')
if len(tmp_arr) == 3: ret_orders[tmp_arr[0]] = ["%s,%s"%(tmp_arr[1], tmp_arr[2])]
if len(tmp_arr) == 5: ret_orders[tmp_arr[0]] = ["%s,%s"%(tmp_arr[1], tmp_arr[2]), "%s,%s"%(tmp_arr[3], tmp_arr[4])]
return ret_orders
def get_dis(poi1, poi2):
'''
@params:
poi1 str 116,98743,39.099823
poi2 str 116,98343,39.09932
@return:
distance 单位米
'''
# 地球半径
R = 6371.0 * 1000
lon1, lat1 = poi1.strip().split(',')
lon2, lat2 = poi2.strip().split(',')
# 转换为弧度
lat1_rad = math.radians(float(lat1))
lon1_rad = math.radians(float(lon1))
lat2_rad = math.radians(float(lat2))
lon2_rad = math.radians(float(lon2))
# 经纬度差值
dlat = lat2_rad - lat1_rad
dlon = lon2_rad - lon1_rad
# Haversine公式
a = math.sin(dlat/2)**2 + math.cos(lat1_rad) * math.cos(lat2_rad) * math.sin(dlon/2)**2
c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a))
distance = R * c
return distance
def get_best_path(all_path, start_poi=''):
dscs = {} # 待优化
closest_dis = 999999000
best_path = None
for path in all_path:
tmp_dis = 0
if start_poi: tmp_dis = get_dis(start_poi, path[0])
for i in range(len(path) - 1):
tk = [path[i], path[i+1]]
tk.sort()
if ''.join(tk) not in dscs:
dscs[''.join(tk)] = get_dis(path[i], path[i+1])
tmp_dis += dscs[''.join(tk)]
if tmp_dis > closest_dis: continue
best_path = path
closest_dis = tmp_dis
return best_path, closest_dis
def match_order(orders, path):
path_strs = []
for llstr in path:
for _id_, ll in orders.items():
if llstr in ll:
idx = ll.index(llstr) + 1
if len(ll) == 1: idx = 2
path_strs.append('%s,%s,%s' % (_id_, llstr, idx))
return ';'.join(path_strs)
def get_order_path(order_strs, start_poi_str=''):
orders = str2orders(order_strs)
locs = orders.values()[:5]
all_path = generate_possible_path(locs)
best_path, closest_dis = (get_best_path(all_path, start_poi_str))
fn_path = match_order(orders, best_path)
return fn_path, closest_dis
if __name__ == '__main__':
tmpc = 0
tmpcd = 0
strs = 'id1,116,39,116.4,39.9;id2,116.3,39.97;id3,116.60,39.67'
# strs = '1551101515,110.47847748,29.12586975,110.47585113,29.13276902;1551101443,110.49884945,29.13684405,110.49618740,29.13216188;1551100204,110.46364600,29.13979500,110.43194723,29.13712246;1551100127,110.49648300,29.11439100,110.49784583,29.11305473;1551099953,110.49297600,29.13722200,110.47381488,29.13417613;1551099949,110.49889237,29.13005353,110.48189045,29.13802390;1551099684,110.48303223,29.13754845,110.48199650,29.14022133;1551099589,110.49887627,29.13003832,110.48528137,29.13825283;1551098955,110.49852200,29.13588100,110.49852926,29.13586055;1551098182,110.48904419,29.13865852,110.49150540,29.11542065'
strs = '1551103134,110.47121600,29.13402500,110.48718800,29.13851600;1551102629,110.46813279,29.13366297,110.45269720,29.13795196;1551102202,110.49289800,29.13730100,110.49726539,29.12888991;1551102191,110.47121600,29.13402500,110.48213100,29.13675800;1551101768,110.50223541,29.13923073,110.49040770,29.11378568;1551101515,110.47136000,29.13393000,110.47585113,29.13276902;1551101443,110.49672300,29.13168700,110.49618740,29.13216188'
# strs = '1551101768,110.50223541,29.13923073,110.49040770,29.11378568;1551101515,110.47136000,29.13393000,110.47585113,29.13276902;1551101443,110.49291300,29.13725500,110.49618740,29.13216188'
#`strs = ''
# strs = '1551101768,110.50223541,29.13923073,110.49040770,29.11378568;1551101515,110.47136000,29.13393000,110.47585113,29.13276902;1551101443,110.49291300,29.13725500,110.49618740,29.13216188;1551102191,110.47121600,29.13402500,110.48213100,29.13675800;1551101768,110.50223541,29.13923073,110.49040770,29.11378568'
print(get_order_path(strs, '116,39'))
# print(tmpc)
exit(0)
orders = str2orders(strs)
print(orders)
locs = orders.values()
all_path = generate_possible_path(locs)
best_path, closest_dis = (get_best_path(all_path))
print(match_order(orders, best_path))
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment