Exemple #1
0
                    field))
            sys.exit(0)
    logger.info(dict_pairwise_distance[1])

    dict_coverage = binary_mclp_distance_matrix.generate_binary_coverage_from_dist_matrix(
        list_dict_facility_demand_distance=dict_pairwise_distance,
        dl_id_field="demand_id",
        fl_id_field="facility_id",
        dist_threshold=service_dist,
        demand_field="demand",
        distance_field="distance",
        fl_variable_name=facility_variable_name)

    # formulate model
    logger.info("Creating MCLP model...")
    mclp = covering.create_mclp_model(dict_coverage, {"total": num_facility})

    # solve
    logger.info("Solving MCLP...")
    mclp.solve(pulp.GLPK())

    # Get the unique ids of the facilities chosen
    logger.info("Extracting results")

    # Get the id set of facilities chosen
    set_facility_id_chosen = set(
        utilities.get_ids(mclp, facility_variable_name))

    logger.info("Set of facility ids: {}".format(set_facility_id_chosen))
    logger.info("Number of facilities selected: {}".format(
        len(set_facility_id_chosen)))
Exemple #2
0
    # Facility service area polygon layer has 8 polygons, where each feature has a unique identifier (ORIG_ID)
    facility_service_areas_fl = arcpy.MakeFeatureLayer_management(
        r"../sample_data/facility_service_areas.shp").getOutput(0)

    # Create binary coverage (polygon) dictionary structure
    # Use population of each polygon as demand,
    # Use GEOID as the unique field
    # Ue ORIG_ID as the unique id for the facilities
    binary_coverage_polygon = arcpy_analysis.generate_binary_coverage(
        demand_polygon_fl, facility_service_areas_fl, "Population", "GEOID10",
        "ORIG_ID")

    # Create the mclp model
    # Maximize the total coverage (binary polygon) using at most 5 out of 8 facilities
    logger.info("Creating MCLP model...")
    mclp = covering.create_mclp_model(binary_coverage_polygon, {"total": 5},
                                      "mclp.lp")
    # Solve the model using GLPK
    logger.info("Solving MCLP...")
    mclp.solve(pulp.GLPK())
    # Get the unique ids of the 5 facilities chosen
    logger.info("Extracting results")
    ids = utilities.get_ids(mclp, "facility_service_areas")
    # Generate a query that could be used as a definition query or selection in arcpy
    select_query = arcpy_analysis.generate_query(ids,
                                                 unique_field_name="ORIG_ID")
    logger.info(
        "Output query to use to generate maps is: {}".format(select_query))
    # Determine how much demand is covered by the results
    facility_service_areas_fl.definitionQuery = select_query
    total_coverage = arcpy_analysis.get_covered_demand(
        demand_polygon_fl, "Population", "binary", facility_service_areas_fl)
Exemple #3
0
 def test_mclp(self):
     mclp = covering.create_mclp_model(self.binary_coverage_polygon,
                                       {"total": 5}, "mclp.lp")
     mclp.solve(pulp.GLPK())
     ids = utilities.get_ids(mclp, "facility_service_areas")
     self.assertEqual(['1', '4', '5', '6', '7'], ids)
def mclp_solver(env_path,
                demand_point,
                facility_service_area,
                attr_demand,
                id_demand_point,
                id_facility,
                num_facility,
                id_facility_as_string=True):
    """
    Solve a MCLP using the given inputs and parameters. This function will overwrite the FeatureClass called mclp_analysis_layer
    :param env_path: (string) Path of the env
    :param demand_point: (string) File name of the demand point layer
    :param facility_service_area: (string) File name of the facility service areas
    :param attr_demand: (int or float) the attribute of demand
    :param id_demand_point: (int or string) the ID attribute in demand_point
    :param id_facility: (int or string) the ID attribute in facility_service_area
    :param num_facility: (int) Number of facilities to site
    :param id_facility_as_string: (boolean) whether the ID attribute of facilities is string
    :return: (A dict of objects) [demand_coverage, n_facility, list_id_facility]
    """
    # demand layer
    demand_polygon_fl = arcpy.MakeFeatureLayer_management(
        os.path.join(env_path, demand_point)).getOutput(0)
    # service layer
    facility_service_areas_fl = arcpy.MakeFeatureLayer_management(
        os.path.join(env_path, facility_service_area)).getOutput(0)
    # Create binary coverage (polygon) dictionary structure
    # Use "demand" of each polygon as demand,
    # Use "id" as the unique field
    # Use "object_id" as the unique id for the facilities
    print(arcpy.Describe(facility_service_areas_fl).shapeType)
    binary_coverage_polygon = arcpy_analysis.generate_binary_coverage(
        demand_polygon_fl, facility_service_areas_fl, attr_demand,
        id_demand_point, id_facility)
    # Create the mclp model
    # Maximize the total coverage (binary polygon) using at most 5 out of 8 facilities
    # logger.info("Creating MCLP model...")
    mclp = covering.create_mclp_model(binary_coverage_polygon,
                                      {"total": num_facility})
    # Solve the model using GLPK
    print("Solving MCLP...")
    mclp.solve(pulp.GLPK())
    # print(mclp.variables())

    # get the ids not covered
    # print('Demand not covered: ')
    # for var in mclp.variables():
    #     if var.name.split("$")[0] == "Y":
    #         if var.varValue < 1.0:
    #             print(var.name)

    # get the ids covered
    print('Demand covered: ')
    list_objectid_dem_covered = []
    for var in mclp.variables():
        if var.name.split("$")[0] == "Y":
            if var.varValue >= 1.0:
                list_objectid_dem_covered.append(var.name.split("$")[1])
    print list_objectid_dem_covered

    # get rid of the file postfix: .shp
    # example: york_facility_sample_buffer_100
    facility_layer_name = os.path.splitext(facility_service_area)[0]
    # print(facility_layer_name)
    ids = utilities.get_ids(mclp, facility_layer_name)
    print 'List of selected facilities: ', ids

    # As the attribute object_id is a string type, the 'wrap_values_in_quotes' should be set as True
    select_query = arcpy_analysis.generate_query(
        ids,
        unique_field_name=id_facility,
        wrap_values_in_quotes=id_facility_as_string)
    logger.info(
        "Output query to use to generate maps is: {}".format(select_query))

    # Determine how much demand is covered by the results
    facility_service_areas_fl.definitionQuery = select_query

    total_coverage = arcpy_analysis.get_covered_demand(
        demand_polygon_fl, attr_demand, "binary", facility_service_areas_fl)

    logger.info(total_coverage)
    logger.info(binary_coverage_polygon["totalDemand"])
    # logger.info("{0:.2f}% of demand is covered".format((100 * total_coverage) / binary_coverage_polygon["totalDemand"]))
    result = {}
    result["demand_coverage"] = (
        total_coverage) / binary_coverage_polygon["totalDemand"]
    result["n_facility"] = num_facility
    result["list_id_facility"] = " ".join(str(x) for x in ids)
    print result["list_id_facility"]
    return result
 def test_mclp(self):
     mclp = covering.create_mclp_model(self.binary_coverage_polygon, {"total": 5})
     mclp.solve(pulp.GUROBI())
     ids = utilities.get_ids(mclp, "facility_service_areas")
     self.assertEqual(['1', '4', '5', '6', '7'], ids)
    # Facility service area polygon layer has 8 polygons, where each feature has a unique identifier (ORIG_ID)
    facility_service_areas_fl = arcpy.MakeFeatureLayer_management(
        r"../sample_data/facility_service_areas.shp").getOutput(0)

    # Create binary coverage (polygon) dictionary structure
    # Use population of each polygon as demand,
    # Use GEOID as the unique field
    # Ue ORIG_ID as the unique id for the facilities
    binary_coverage_polygon = arcpy_analysis.generate_binary_coverage(demand_polygon_fl, facility_service_areas_fl,
                                                                      "Population",
                                                                      "GEOID10", "ORIG_ID")

    # Create the mclp model
    # Maximize the total coverage (binary polygon) using at most 5 out of 8 facilities
    logger.info("Creating MCLP model...")
    mclp = covering.create_mclp_model(binary_coverage_polygon, {"total": 5})
    # Solve the model using GLPK
    logger.info("Solving MCLP...")
    mclp.solve(pulp.GLPK())
    # Get the unique ids of the 5 facilities chosen
    logger.info("Extracting results")
    ids = utilities.get_ids(mclp, "facility_service_areas")
    # Generate a query that could be used as a definition query or selection in arcpy
    select_query = arcpy_analysis.generate_query(ids, unique_field_name="ORIG_ID")
    logger.info("Output query to use to generate maps is: {}".format(select_query))
    # Determine how much demand is covered by the results
    facility_service_areas_fl.definitionQuery = select_query
    total_coverage = arcpy_analysis.get_covered_demand(demand_polygon_fl, "Population", "binary",
                                                       facility_service_areas_fl)
    logger.info("{0:.2f}% of demand is covered".format((100 * total_coverage) / binary_coverage_polygon["totalDemand"]))