コード例 #1
0
    def energy(self):
        """Calculates the costs of the restoration."""
        e = 0

        restoration = RestorationModel(self.graph_damaged)
        restoration.run(self.state)
        restoration_graphs = restoration.get_restoration_graphs()
        restoration_times = restoration.get_restoration_times()
        restoration_costs = restoration.get_restoration_costs()

        damaged = []
        damaged.append(get_delta(self.no_damage, self.initial_damage))

        sim_results = Parallel(n_jobs=4)(
            delayed(parallel_model)(graph, self.od_graph, self.od_matrix)
            for graph in restoration_graphs[:-1])
        for values in sim_results:
            damaged.append(get_delta(self.no_damage, values))

        for idx, values in enumerate(damaged):
            dt = restoration_times[idx] if idx == 0 else restoration_times[idx] - \
                restoration_times[idx-1]
            e += sum(restoration_costs[idx]) + dt * (
                self.day_factor * values[2] * np.sum(self.mu * self.xi) +
                values[3] * np.sum(self.mu * (self.nu * self.F_w + self.rho)) +
                values[4] * self.upsilon)
        with open(self.fdir + 'energy.csv', 'a') as f:
            f.write('\n' + str(e))

        return e
コード例 #2
0
class PpEngine(object):
    """ Postprocessing Simulation Engine
    """
    def __init__(self, filepath='./', bTest=None):

        self.filepath = filepath
        self.test = bTest

        # TODO: What are these I do not think they are needed!
        self.a = 25.5
        self.b = 10
        self.c = 1240

        self.mu = np.array([0.94,
                            0.06])  # % of distribution of cars vs. trucks
        self.xi = np.array([23.02,
                            130.96])  # value of travel for cars vs. trucks
        self.F_w = np.array(
            [6.7, 33]) / 100  # mean fuel consumption for cars vs. trucks
        self.nu = 1.88  # mean fuel price
        self.rho = np.array([
            14.39, 32.54
        ]) / 100  # Operating costs (without fuel) for cars vs. trucks/ 100 km
        self.upsilon = 83.27 * 8  # hourly wage [when lost or delayed trips]* 8 hours/day
        # factor to find the area under the trip distribution curve(average value*9= total trips per day for a zone)
        self.day_factor = 9
        self.gamma = 1  # weight factor for indirect costs

        # self.capacity_losses = {'Bridge': {0: 0, 1: .5, 2: 1, 3: 1}, 'Road': {
        #     0: 0, 1: .7, 2: 1, 3: 1}, 'Tunnel': {0: 0}}
        self.capacity_losses = {}
        data = csv.DictReader(open("capacity_losses.csv", 'r'), delimiter=",")
        for row in data:
            item = self.capacity_losses.get(row["Objects"], dict())
            item[int(row["Damage_Level"])] = float(row["Capacity_Loss"])
            self.capacity_losses[row["Objects"]] = item

        # TODO: Load data from csv file: Done but needs confirmation
        # type 1: normal
        # type 2: emergency
        # type 3: partial
        # self.restoration_names = {0: 'high priority', 1: 'normal', 2: 'low priority'}
        self.restoration_names = {}
        reader = csv.reader(open('./restoration_names.csv'))
        for row in reader:
            self.restoration_names[int(row[0])] = (row[1])

        # self.restoration_types = [0, 1, 2]
        # # self.restoration_types = [2,2,2]
        self.restoration_types = list(
            self.restoration_names.keys())  # TODO: check to make sure

    def initialize_network(self):

        if self.test:
            self.road_graph = read_shp('./test_data/roads.shp')
            self.od_graph = create_od_graph('./test_data/centroids.shp')
            self.con_edges = read_shp('./test_data/connections.shp')
            self.od_matrix = np.genfromtxt('./test_data/od.csv', delimiter=',')
        else:
            self.road_graph = read_shp('./data/roads_clean.shp')
            self.od_graph = create_od_graph('./data/centroids.shp')
            self.con_edges = read_shp('./data/connections.shp')
            self.od_matrix = np.genfromtxt('./data/od.csv', delimiter=',')

        self.graph = create_network_graph(self.road_graph, self.od_graph,
                                          self.con_edges)
        pass

    def initialize_damage(self):
        self.damage = DamageModel(self.graph, self.capacity_losses)
        self.damage.run()
        self.graph_damaged = self.damage.get_graph()
        self.damage_dict = self.damage.get_damage_dict(directed=False)
        pass

    def load_state(self, filename):
        with open(filename, 'r') as f:
            state = ast.literal_eval(f.read())
        return state

    def calculate_damage(self):
        print('--- initialization ---')
        self.initialize_network()
        self.initialize_damage()

        # init_state = self.initialize_state()
        init_state = self.load_state(self.filepath + 'state.txt')

        print('--- no and initial damage ---')
        no_damage = self.run_traffic_model(self.graph, self.od_graph)
        initial_damage = self.run_traffic_model(self.graph_damaged.copy(),
                                                self.od_graph.copy())

        self.damaged = []
        self.damaged.append(get_delta(no_damage, initial_damage))

        print('--- restoration ---')
        self.run_restoration_model(init_state)

        print('--- simulated annealing ---')
        sim_results = Parallel(n_jobs=6)(
            delayed(parallel_model)(graph, self.od_graph, self.od_matrix)
            for graph in self.restoration_graphs[:-1])

        for damaged in sim_results:
            self.damaged.append(get_delta(no_damage, damaged))

        with open(self.filepath + 'damaged.txt', 'w') as f:
            f.write(str(self.damaged))
        pass

    def run_traffic_model(self, graph, od_graph):
        self.traffic = TrafficModel(graph, od_graph, self.od_matrix)
        self.traffic.run()
        # self.traffic.print_results()
        t_k = sum(self.traffic.get_traveltime())
        flow = sum(self.traffic.get_flow())
        hours = sum(self.traffic.get_car_hours())
        distances = sum(self.traffic.get_car_distances())
        lost_trips = sum(self.traffic.get_lost_trips().values())
        # graph_result = self.traffic.get_graph()
        return t_k, flow, hours, distances, lost_trips

    def run_restoration_model(self, sequence=None):
        self.restoration = RestorationModel(self.graph_damaged, self.filepath)
        self.restoration.run(sequence)
        self.restoration_graphs = self.restoration.get_restoration_graphs()
        self.restoration_times = self.restoration.get_restoration_times()
        self.restoration_costs = self.restoration.get_restoration_costs()
        pass

    def load_damage(self, filename):
        with open(filename, 'r') as f:
            damaged = ast.literal_eval(f.read())
        return damaged

    def load_costs(self, filename):
        with open(filename, 'r') as f:
            costs = ast.literal_eval(f.read())
        return costs

    def run(self, scenario):
        print('--- initialization ---')
        self.initialize_network()
        self.initialize_damage()
        init_state = self.load_state(self.filepath + 'state.txt')

        print('--- calculate damage ---')
        if not os.path.isfile(self.filepath + 'damaged.txt'):
            self.calculate_damage()
        else:
            self.damaged = self.load_damage(self.filepath + 'damaged.txt')

        # t_k, flow, hours, distances, lost_trips
        names_dict = {}
        for object in init_state:
            names_dict[object[0]] = get_edge_attribute(
                self.graph, object[0], 'name') + '-' + get_edge_attribute(
                    self.graph, object[0], 'object')[0]

        self.restoration_results = RestorationModel(self.graph_damaged,
                                                    self.filepath)
        # (object,schedule time,needed time,#resources,intervention type, assigned resource)
        sequence_formated = self.restoration_results.format(init_state)

        sort_names = []
        for s in sequence_formated:
            for t in s:
                sort_names.append([
                    t[1] - t[2], t[-1],
                    get_edge_attribute(self.graph, t[0], 'name')[2:]
                ])

        # remove dopples
        seen = set()
        sort_names = [
            x for x in sort_names if x[2] not in seen and not seen.add(x[2])
        ]
        sort_names = sorted(sort_names, key=itemgetter(1))
        sort_names = sorted(sort_names, key=itemgetter(0))

        name_dict = {}
        for name, key in enumerate(sort_names):
            name_dict[key[2]] = str(name + 1)

        print(name_dict)

        #name_dict = {'b-d': '1', ':a-g': '2', 'd-g': '3', 'd-e': '4'}
        # Keys: Object ID , Values: Nr in the table (8) of the paper
        # name_dict = {'1095': '6', '460': '10', '1703': '14', '1237': '20', '562': '11', '2069': '12', '1798': '24', '471': '28', '1371': '29', '1692': '15', '2043': '26', '1802': '8', '1907': '18', '1233': '23',
        #               '1913': '13', '2042': '1', '2052': '7', '2131': '17', '554': '2', '1276': '21', '1202': '22', '1706': '9', '1803': '5', '1905': '19', '1279': '16', '1814': '25', '332': '3', '1498': '27', '461': '4'}

        i = 0
        lines = []

        # TODO : is this  extra? I do not find any other places it is used
        name_list = []
        for s in sequence_formated:
            for t in s:
                name_list.append(
                    get_edge_attribute(self.graph, t[0], 'name')[2:])

        new_name_list = []
        for name in name_list:
            if name not in new_name_list:
                new_name_list.append(name)

        name_list = list(set(name_list))

        program_list = []
        for s in sequence_formated:
            for t in s:
                crew = t[5]
                task_end = t[1]
                task_duration = t[2]
                task_start = task_end - task_duration
                object_type = get_edge_attribute(self.graph, t[0], 'object')
                damage = get_edge_attribute(self.graph, t[0], 'damage')

                condition_state = {1: 'cs1', 2: 'cs2'}
                intervention_type = {
                    10: 'cs1i0',
                    11: 'cs1i1',
                    12: 'cs1i2',
                    20: 'cs2i0',
                    21: 'cs2i1',
                    22: 'cs2i2'
                }
                resources = {1: 'res1', 2: 'res2'}
                x_scale = .4012 / 2
                y_scale = .45
                start_point = (task_start * x_scale, crew * y_scale)
                end_point = (task_end * x_scale, (crew + 1) * y_scale)
                name = get_edge_attribute(self.graph, t[0], 'name')[2:]
                lines.append('\draw[normal,' + resources[t[3]] + ',' +
                             condition_state[damage] + ',' +
                             intervention_type[int(str(damage) + str(t[4]))] +
                             '] ' + str(start_point) + ' rectangle ' +
                             str(end_point) + ' node[mynode,pos=.5] {' +
                             name_dict[name] + ' \\\ ' + object_type[0] + '};')
                #lines.append('\draw[normal,'+resources[t[3]]+','+condition_state[damage]+','+intervention_type[int(str(damage)+str(t[4]))]+'] '+str(start_point)+' rectangle '+str(end_point)+ ' node[mynode,pos=.5] {'+name+' \\\ '+object_type[0]+'};')

                condition_state = {1: '1 minor', 2: '2 major'}
                intervention_type = {
                    10: 'level 1',
                    11: 'level 2',
                    12: 'level 3',
                    20: 'level 1',
                    21: 'level 2',
                    22: 'level 3'
                }
                intervention_nr = {
                    10: 'i',
                    11: 'ii',
                    12: 'iii',
                    20: 'i',
                    21: 'ii',
                    22: 'iii'
                }
                crew_type = {0: 'A', 1: 'B', 2: 'C'}
                sp = ' & '
                nl = '\\'

                program_list.append([
                    int(name_dict[name]), name, object_type,
                    condition_state[damage],
                    intervention_type[int(str(damage) + str(t[4]))],
                    str(task_start / 2),
                    str(task_end / 2),
                    str(task_duration / 2), crew_type[crew]
                ])
                # print(name_dict[name]+sp+name+sp+object_type+sp+condition_state[damage]+sp+intervention_nr[int(str(damage)+str(t[4]))]+sp+intervention_type[int(str(damage)+str(t[4]))]+sp+str(task_start/2)+sp+str(task_end/2)+sp+str(task_duration/2)+sp+crew_type[crew]+sp)
                i += 1

        costs_list = self.load_costs(self.filepath + 'costs.txt')
        for row in costs_list:
            del row[0]

        for i, l in enumerate(program_list):
            a = int(round(costs_list[i][0], 0))
            b = int(round(costs_list[i][1], 0))
            c = int(round(costs_list[i][2], 0))
            d = a + b + c
            l.extend([a, b, c, d])

        seen = set()
        program = [
            x for x in program_list if x[0] not in seen and not seen.add(x[0])
        ]

        sum_fixed = sum(row[-4] for row in program)
        sum_variable = sum(row[-3] for row in program)
        sum_resources = sum(row[-2] for row in program)
        sum_total = sum(row[-1] for row in program)

        program.sort(key=lambda x: x[0])

        program.append([
            '', '', '', '', '', '', '', '', '', sum_fixed, sum_variable,
            sum_resources, sum_total
        ])

        if not os.path.exists(self.filepath + 'tex/'):
            os.makedirs(self.filepath + 'tex/')
            print("Path is created")

        with open(self.filepath + 'tex/program_0' + scenario + '.tex',
                  mode='wt',
                  encoding='utf-8') as f:
            for p in program:
                for i in range(9, 13):
                    p[i] = '\\numprint{' + str(p[i]) + '}'
                f.write(' & '.join(str(e) for e in p) + ' \\\ \n')

        # TODO: I commented this part to avoid double results *check again for other figures
        # with open(self.filepath + 'tex/resources_0'+scenario+'.tex', mode='wt', encoding='utf-8') as myfile:
        #     myfile.write('\n'.join(lines))

        with open(self.filepath + 'tex/resources_01.tex',
                  mode='wt',
                  encoding='utf-8') as myfile:
            myfile.write('\n'.join(lines))

        #print('t_k, flow, hours, distances, lost_trips')
        # for damage in damaged:
        #     print(damage)
        # TODO: What are these I do not think they are needed!
        fix_costs = [0]
        variable_costs = [0]
        resources_costs = [0]
        all_costs = [0]
        time = [0]

        self.run_restoration_model(init_state)

        #print(self.restoration_costs)

        # print(self.damaged)
        result_matrix = np.zeros((9, len(self.damaged) + 1))
        result_matrix_t = np.zeros((3, len(self.damaged) + 1))
        x = np.zeros(len(self.damaged) + 1)

        self.consequences = []
        for idx, damage in enumerate(self.damaged):
            if idx == 0:
                delta_t = self.restoration_times[idx]
            else:
                delta_t = (self.restoration_times[idx] -
                           self.restoration_times[idx - 1])

            result_matrix[0][idx + 1] = self.restoration_costs[idx][0]
            result_matrix[1][idx + 1] = self.restoration_costs[idx][1]
            result_matrix[2][idx + 1] = self.restoration_costs[idx][2]

            result_matrix[4][idx + 1] = (damage[2] * np.sum(
                self.mu * self.xi)) * delta_t * self.day_factor
            result_matrix[5][idx + 1] = (
                damage[3] * np.sum(self.mu *
                                   (self.nu * self.F_w + self.rho))) * delta_t
            result_matrix[6][idx + 1] = (damage[4] * self.upsilon) * delta_t

            result_matrix_t[0][idx + 1] = damage[2]
            result_matrix_t[1][idx + 1] = damage[3]
            result_matrix_t[2][idx + 1] = damage[4]

            #            print(damage[2], delta_t * (damage[2] * np.sum(self.mu*self.xi)))
            #            print(damage[3], delta_t * (damage[3] * np.sum(self.mu * (self.nu * self.F_w + self.rho))))
            #            print(damage[4], delta_t * (damage[4] * self.upsilon))
            #            print(damage[2])
            x[idx + 1] = self.restoration_times[idx]

            self.consequences.append(
                self.gamma * delta_t *
                (self.day_factor * damage[2] * np.sum(self.mu * self.xi) +
                 damage[3] * np.sum(self.mu *
                                    (self.nu * self.F_w + self.rho)) +
                 damage[4] * self.upsilon) + sum(self.restoration_costs[idx]))

        print('consequences: ', sum(self.consequences))

        result_matrix_t[0:3, 0] = result_matrix_t[0:3, 1]
        result_matrix[3] = np.sum(result_matrix[0:3, :], axis=0)
        #result_matrix[4:7,0] = result_matrix[4:7,1]
        result_matrix[7] = np.sum(result_matrix[4:7, :], axis=0)
        result_matrix = np.cumsum(result_matrix, axis=1)
        #        result_matrix_id = np.cumsum(result_matrix_id,axis=1)
        # result_rev = np.fliplr(result_matrix_id)
        # result_rev = np.cumsum(result_rev,axis=1)
        # result_matrix_id = np.fliplr(result_rev)

        print('direct:', result_matrix[3, -1])

        print(result_matrix[3, -1] + result_matrix[7, -1])
        # print(result_matrix[7,-1])
        #        print(result_matrix)
        result_matrix[8] = result_matrix[3] + result_matrix[7]

        lines = []
        for i in range(4):
            lines.append(
                '\\addplot+[const plot, no marks, thick] coordinates {')
            for j in range(result_matrix.shape[1]):
                lines.append('(' + str(x[j]) + ',' + str(result_matrix[i, j]) +
                             ')')
            lines.append('};')

        for i in range(4, 8):
            xvals = np.arange(0, x[-1] + 0.5, 0.5)
            y = result_matrix[i]
            yinterp = np.interp(xvals, x, y)

            lines.append(
                '\\addplot+[const plot, no marks, thick] coordinates {')
            for j in range(xvals.shape[0]):
                lines.append('(' + str(xvals[j]) + ',' + str(yinterp[j]) + ')')
            lines.append('};')

        # TODO: I commented this part to avoid double results *check again for other figures

        # with open(self.filepath + 'tex/costs_0'+scenario+'.tex', mode='wt', encoding='utf-8') as myfile:
        #     myfile.write('\n'.join(lines))

        with open(self.filepath + 'tex/costs_01.tex',
                  mode='wt',
                  encoding='utf-8') as myfile:
            myfile.write('\n'.join(lines))

        xvals = np.arange(0, x[-1] + 0.5, 0.5)
        dc_vec = np.zeros(xvals.shape[0])
        for i in range(xvals.shape[0]):
            try:
                dc_vec[i] = result_matrix[3, list(x).index(xvals[i])]
            except ValueError:
                pass

        for i in range(dc_vec.shape[0] - 1):
            if dc_vec[i + 1] == 0.0 and dc_vec[i] > 0.0:
                dc_vec[i + 1] = dc_vec[i]

        y = result_matrix[7]
        ic_vec = np.interp(xvals, x, y)

        vecs = [dc_vec, ic_vec, ic_vec + dc_vec]

        lines = []
        for vec in vecs:
            if scenario == '1':
                lines.append(
                    '\\addplot+[const plot, mymark={text}{text mark=1,text mark as node, text mark style={font=\\tiny,circle,inner sep=0pt,fill=myblue!10!white,},}, thick] coordinates {'
                )
            elif scenario == '2':
                lines.append(
                    '\\addplot+[const plot, mymark={text}{text mark=2,text mark as node, text mark style={font=\\tiny,circle,inner sep=0pt,fill=damage2!10!white,},}, thick] coordinates {'
                )
            else:
                lines.append(
                    '\\addplot+[const plot, mymark={text}{text mark=3,text mark as node, text mark style={font=\\tiny,circle,inner sep=0pt,fill=mygreen!10!white,},}, thick] coordinates {'
                )


#            lines.append('\\addplot+[const plot, no marks, thick] coordinates {')
            for j in range(vec.shape[0]):
                lines.append('(' + str(xvals[j]) + ',' + str(vec[j]) + ')')
            lines.append('};')

        # TODO: I commented this part to avoid double results *check again for other figures

        # with open(self.filepath + 'tex/sum_0'+scenario+'.tex', mode='wt', encoding='utf-8') as myfile:
        #     myfile.write('\n'.join(lines))

        with open(self.filepath + 'tex/sum_01.tex',
                  mode='wt',
                  encoding='utf-8') as myfile:
            myfile.write('\n'.join(lines))

        #x = np.append(x,x[-1])
        mat1 = np.append(result_matrix_t[0], result_matrix_t[0][-1])
        # for i in range(len(mat1)-1):
        #     print(mat1[i+1],x[i])

        mat2 = np.append(result_matrix_t[2], result_matrix_t[2][-1])
        # for i in range(len(mat2)-1):
        #     print(mat2[i+1],x[i])

        mat = np.zeros((2, len(mat1) - 1))
        for i in range(len(mat1) - 1):
            mat[0][i] = mat1[i + 1]
            mat[1][i] = mat2[i + 1]

        lines = []
        for i in [0, 1]:
            lines.append(
                '\\addplot+[const plot, no marks, thick] coordinates {')
            for j in range(mat.shape[1]):
                lines.append('(' + str(x[j]) + ',' + str(mat[i, j]) + ')')
            lines.append('};')

        # TODO: I commented this part to avoid double results *check again for other figures
        # with open(self.filepath + 'tex/los_0'+scenario+'.tex', mode='wt', encoding='utf-8') as myfile:
        #     myfile.write('\n'.join(lines))

        with open(self.filepath + 'tex/los_01.tex',
                  mode='wt',
                  encoding='utf-8') as myfile:
            myfile.write('\n'.join(lines))

        pass
コード例 #3
0
class Engine(object):
    """ Simulation engine
    """
    def __init__(self, output_directory='./'):
        self.capacity_losses = {
            'Bridge': {
                0: 0,
                1: .5,
                2: 1,
                3: 1
            },
            'Road': {
                0: 0,
                1: .7,
                2: 1,
                3: 1
            },
            'Tunnel': {
                0: 0
            }
        }

        # TODO: Load data from csv file
        self.restoration_types = [0, 1, 2]

        self.restoration_constraint = False
        self.output_directory = output_directory

    def initialize_network(self):
        self.road_graph = read_shp('./data/roads.shp')
        self.od_graph = create_od_graph('./data/centroids.shp')
        self.con_edges = read_shp('./data/connections.shp')
        self.od_matrix = np.genfromtxt('./data/od.csv', delimiter=',')

        self.graph = create_network_graph(self.road_graph, self.od_graph,
                                          self.con_edges)
        pass

    def initialize_damage(self):
        self.damage = DamageModel(self.graph, self.capacity_losses)
        self.damage.run()
        self.graph_damaged = self.damage.get_graph()
        self.damage_dict = self.damage.get_damage_dict(directed=False)
        #self.damage_dict = self.damage.get_damage_dict(directed=True)
        pass

    def run_restoration_model(self, sequence=None):
        self.restoration = RestorationModel(self.graph_damaged)
        self.restoration.run(sequence)
        self.restoration_graphs = self.restoration.get_restoration_graphs()
        self.restoration_times = self.restoration.get_restoration_times()
        self.restoration_costs = self.restoration.get_restoration_costs()
        pass

    def run_traffic_model(self, graph, od_graph):
        # set up traffic model
        self.traffic = TrafficAssignment(graph, od_graph, self.od_matrix)
        # run traffic simulation
        self.traffic.run()
        t_k = sum(self.traffic.get_traveltime())
        flow = sum(self.traffic.get_flow())
        hours = sum(self.traffic.get_car_hours())
        distances = sum(self.traffic.get_car_distances())
        lost_trips = sum(self.traffic.get_lost_trips().values())
        return t_k, flow, hours, distances, lost_trips

    def initialize_state(self):
        init_edges = list(self.damage_dict.keys())
        random.shuffle(init_edges)

        init_state = []

        for edge in init_edges:
            if self.restoration_constraint:
                init_state.append((edge, 0))
            else:
                init_state.append(
                    (edge, random.choice(self.restoration_types)))
        return init_state

    def load_state(self, filename):
        with open(filename, 'r') as f:
            state = ast.literal_eval(f.read())
        return state

    def load_damage(self, filename):
        with open(filename, 'r') as f:
            damaged = ast.literal_eval(f.read())
        return damaged

    def run(self):
        self.initialize_network()
        self.initialize_damage()
        init_state = self.initialize_state()

        no_damage = self.run_traffic_model(self.graph, self.od_graph)
        initial_damage = self.run_traffic_model(self.graph_damaged.copy(),
                                                self.od_graph.copy())

        damage = [no_damage, initial_damage]

        optimize = SimAnnealer(init_state, self.graph, self.od_graph,
                               self.od_matrix, self.graph_damaged, damage,
                               self.output_directory)

        optimize.copy_strategy = "slice"

        state, e = optimize.anneal()

        print("consequences: %i" % e)

        self.restoration_results = RestorationModel(self.graph_damaged)
        # (object,schedule time,needed time,#resources,intervention type, assignd resource)
        sequence_formated = self.restoration_results.format(state)

        with open(self.output_directory + 'state.txt', 'w') as f:
            f.write(str(state))

        with open(self.output_directory + 'state_formated.txt', 'w') as f:
            f.write(str(sequence_formated))
        pass