Parcourir la source

make clusters grid

Florian il y a 6 ans
Parent
commit
bbba212c9d
2 fichiers modifiés avec 65 ajouts et 22 suppressions
  1. 53 9
      plan_gen/plan_gen.py
  2. 12 13
      plan_gen/plan_gen_cli.py

+ 53 - 9
plan_gen/plan_gen.py

@@ -41,9 +41,41 @@ def get_seconds(time_str):
     h, m, s = time_str.split(':')
     return int(h) * 3600 + int(m) * 60 + int(s)
 
+def make_gaussian(size, radius=10, center=None):
+    ''' make a square gaussian kernel '''
+    x = np.arange(0, size, 1, float)
+    y = x[:, np.newaxis]
+    if center is None:
+        x0 = y0 = size // 2
+    else:
+        x0 = center[0]
+        y0 = center[1]
+    return np.exp(-4*np.log(2) * ((x-x0)**2 + (y-y0)**2) / radius**2)
+
 # main functions
 # ------------------
 
+def make_clusters(nb_clusters, nodes):
+    ''' make a grid of (nb_clusters*nb_clusters) from a nodes list '''
+    xmin, xmax, ymin, ymax = get_extrem_nodes(nodes)
+    dx = (xmax - xmin) / nb_clusters
+    dy = (ymax - ymin) / nb_clusters
+    clusters = np.empty((nb_clusters, nb_clusters), dtype=object)
+    for node in nodes:
+        x, y = (float(node.get('x')) - xmin, float(node.get('y')) - ymin)
+        i, j = (int(x/dx), int(y/dy))
+        if i >= nb_clusters:
+            i -= 1
+        if j >= nb_clusters:
+            j -= 1
+        if clusters[i][j] is None:
+            clusters[i][j] = []
+        clusters[i][j] += [node]
+    return clusters
+
+# random generators
+# ------------------
+
 def rand_time(low, high):
     ''' returns a random time between low and high bounds '''
     low_s = get_seconds(low)
@@ -67,7 +99,10 @@ def rand_person(nodes, home_clusters, work_clusters):
     home_departure = rand_time(MIN_DEPARTURE_TIME, MAX_DEPARTURE_TIME)
     return {'home': home_xy, 'work': work_xy, 'home_departure': home_departure}
 
-def create_child(parent_node, child_name, child_attrs=None):
+# xml builders
+# ------------------
+
+def make_child(parent_node, child_name, child_attrs=None):
     ''' creates an xml child element and set its attributes '''
     child = etree.SubElement(parent_node, child_name)
     if child_attrs is None:
@@ -80,19 +115,28 @@ def make_plans(persons):
     ''' makes xml tree of plans based on persons list '''
     plans = etree.Element('plans')
     for n, p in enumerate(persons):
-        person = create_child(plans, 'person', {'id': str(n+1)})
-        plan = create_child(person, 'plan')
+        person = make_child(plans, 'person', {'id': str(n+1)})
+        plan = make_child(person, 'plan')
         # plan
-        create_child(plan, 'act', {'type': 'h', 'x': p['home'][0], 'y': p['home'][1], 'end_time': p['home_departure']})
-        create_child(plan, 'leg', {'mode': 'car'})
-        create_child(plan, 'act', {'type': 'w', 'x': p['work'][0], 'y': p['work'][1], 'dur': WORK_DURATION})
-        create_child(plan, 'leg', {'mode': 'car'})
-        create_child(plan, 'act', {'type': 'h', 'x': p['home'][0], 'y': p['home'][1]})
+        make_child(plan, 'act', {'type': 'h', 'x': p['home'][0], 'y': p['home'][1], 'end_time': p['home_departure']})
+        make_child(plan, 'leg', {'mode': 'car'})
+        make_child(plan, 'act', {'type': 'w', 'x': p['work'][0], 'y': p['work'][1], 'dur': WORK_DURATION})
+        make_child(plan, 'leg', {'mode': 'car'})
+        make_child(plan, 'act', {'type': 'h', 'x': p['home'][0], 'y': p['home'][1]})
     return plans
 
-def read_nodes(input_network):
+# xml readers
+# ------------------
+
+def get_nodes(input_network):
     ''' returns all network nodes as a list '''
     if not input_network:
         return None
     tree = etree.parse(input_network)
     return [node for node in tree.xpath("/network/nodes/node")]
+
+def get_extrem_nodes(nodes):
+    ''' returns extremum coordinates of a nodeslist '''
+    x = [float(node.get('x')) for node in nodes]
+    y = [float(node.get('y')) for node in nodes]
+    return min(x), max(x), min(y), max(y)

+ 12 - 13
plan_gen/plan_gen_cli.py

@@ -3,6 +3,7 @@
 
 import sys
 import lxml.etree as etree
+import numpy as np
 import plan_gen.plan_gen as pg
 
 if __name__ == '__main__':
@@ -13,21 +14,19 @@ if __name__ == '__main__':
         sys.exit(-1)
     DICT_PARAMS = pg.parse_params(sys.argv[1])
 
+    NB_CLUSTERS = DICT_PARAMS['nc']
     NB_PERSONS = DICT_PARAMS['np']
     INPUT_NETWORK = DICT_PARAMS['nw']
-    INPUT_HOME_CLUSTERS = DICT_PARAMS['hc'] if 'hc' in DICT_PARAMS else ''
-    INPUT_WORK_CLUSTERS = DICT_PARAMS['wc'] if 'wc' in DICT_PARAMS else ''
 
-    # get data
-    NODES = pg.read_nodes(INPUT_NETWORK)
-    HOME_CLUSTERS = [pg.read_nodes(cluster) for cluster in INPUT_HOME_CLUSTERS]
-    WORK_CLUSTERS = [pg.read_nodes(cluster) for cluster in INPUT_WORK_CLUSTERS]
+    # prepare data
+    NODES = pg.get_nodes(INPUT_NETWORK)
+    CLUSTERS = pg.make_clusters(NB_CLUSTERS, NODES)
 
-    # make xml
-    PERSONS = [pg.rand_person(NODES, HOME_CLUSTERS, WORK_CLUSTERS) for _ in range(NB_PERSONS)]
-    PLANS = pg.make_plans(PERSONS)
+    # # make xml
+    # PERSONS = [pg.rand_person(NODES, HOME_CLUSTERS, WORK_CLUSTERS) for _ in range(NB_PERSONS)]
+    # PLANS = pg.make_plans(PERSONS)
 
-    # print XML
-    print('<?xml version="1.0" ?>')
-    print('<!DOCTYPE plans SYSTEM "http://www.matsim.org/files/dtd/plans_v4.dtd">')
-    print(etree.tostring(PLANS, pretty_print=True).decode('utf-8'))
+    # # print XML
+    # print('<?xml version="1.0" ?>')
+    # print('<!DOCTYPE plans SYSTEM "http://www.matsim.org/files/dtd/plans_v4.dtd">')
+    # print(etree.tostring(PLANS, pretty_print=True).decode('utf-8'))