Rename decision nodes to shipping nodes

v0.1
Alinson S. Xavier 6 years ago
parent cc49268ce4
commit ba28c350e0

@ -7,7 +7,7 @@ mutable struct ReverseManufacturingModel
mip::JuMP.Model mip::JuMP.Model
vars::DotDict vars::DotDict
arcs arcs
decision_nodes shipping_nodes
process_nodes process_nodes
end end
@ -49,11 +49,14 @@ end
mutable struct Arc mutable struct Arc
# Origin of the arc # Origin of the arc
source::Node source::Node
# Destination of the arc # Destination of the arc
dest::Node dest::Node
# Costs dictionary. Each value in this dictionary is multiplied by the arc flow variable # Costs dictionary. Each value in this dictionary is multiplied by the arc flow variable
# and added to the objective function. # and added to the objective function.
costs::Dict costs::Dict
# Values dictionary. This dictionary is used to store extra information about the # Values dictionary. This dictionary is used to store extra information about the
# arc. They are not used automatically by the model. # arc. They are not used automatically by the model.
values::Dict values::Dict
@ -69,16 +72,16 @@ function build_model(instance::ReverseManufacturingInstance,
println("Building optimization model...") println("Building optimization model...")
mip = Model(optimizer) mip = Model(optimizer)
decision_nodes, process_nodes, arcs = create_nodes_and_arcs(instance) shipping_nodes, process_nodes, arcs = create_nodes_and_arcs(instance)
println(" $(length(decision_nodes)) decision nodes") println(" $(length(shipping_nodes)) shipping nodes")
println(" $(length(process_nodes)) process nodes") println(" $(length(process_nodes)) process nodes")
println(" $(length(arcs)) arcs") println(" $(length(arcs)) arcs")
vars = DotDict() vars = DotDict()
vars.flow = Dict(a => @variable(mip, lower_bound=0) for a in arcs) vars.flow = Dict(a => @variable(mip, lower_bound=0) for a in arcs)
vars.node = Dict(n => @variable(mip, binary=true) for n in values(process_nodes)) vars.node = Dict(n => @variable(mip, binary=true) for n in values(process_nodes))
create_decision_node_constraints!(mip, decision_nodes, vars) create_shipping_node_constraints!(mip, shipping_nodes, vars)
create_process_node_constraints!(mip, process_nodes, vars) create_process_node_constraints!(mip, process_nodes, vars)
println(" Creating objective function...") println(" Creating objective function...")
@ -96,12 +99,12 @@ function build_model(instance::ReverseManufacturingInstance,
return ReverseManufacturingModel(mip, return ReverseManufacturingModel(mip,
vars, vars,
arcs, arcs,
decision_nodes, shipping_nodes,
process_nodes) process_nodes)
end end
function create_decision_node_constraints!(mip, nodes, vars) function create_shipping_node_constraints!(mip, nodes, vars)
println(" Creating decision-node constraints...") println(" Creating shipping-node constraints...")
for (id, n) in tqdm(nodes) for (id, n) in tqdm(nodes)
@constraint(mip, @constraint(mip,
sum(vars.flow[a] for a in n.incoming_arcs) + n.balance == sum(vars.flow[a] for a in n.incoming_arcs) + n.balance ==
@ -125,18 +128,18 @@ end
function create_nodes_and_arcs(instance) function create_nodes_and_arcs(instance)
println(" Creating nodes and arcs...") println(" Creating nodes and arcs...")
arcs = Arc[] arcs = Arc[]
decision_nodes = Dict() shipping_nodes = Dict()
process_nodes = Dict() process_nodes = Dict()
# Create all nodes # Create all nodes
for (product_name, product) in instance.products for (product_name, product) in instance.products
# Decision nodes for initial amounts # Shipping nodes for initial amounts
if haskey(product, "initial amounts") if haskey(product, "initial amounts")
for location_name in keys(product["initial amounts"]) for location_name in keys(product["initial amounts"])
amount = product["initial amounts"][location_name]["amount"] amount = product["initial amounts"][location_name]["amount"]
n = Node(product_name, "Origin", location_name, balance=amount) n = Node(product_name, "Origin", location_name, balance=amount)
decision_nodes[n.product_name, n.plant_name, n.location_name] = n shipping_nodes[n.product_name, n.plant_name, n.location_name] = n
end end
end end
@ -149,11 +152,11 @@ function create_nodes_and_arcs(instance)
end end
end end
# Decision nodes for each plant # Shipping nodes for each plant
for plant in product["output plants"] for plant in product["output plants"]
for location_name in keys(plant["locations"]) for location_name in keys(plant["locations"])
n = Node(product_name, plant["name"], location_name) n = Node(product_name, plant["name"], location_name)
decision_nodes[n.product_name, n.plant_name, n.location_name] = n shipping_nodes[n.product_name, n.plant_name, n.location_name] = n
end end
end end
end end
@ -168,7 +171,7 @@ function create_nodes_and_arcs(instance)
for dest_plant in product["input plants"] for dest_plant in product["input plants"]
for dest_location_name in keys(dest_plant["locations"]) for dest_location_name in keys(dest_plant["locations"])
dest_location = dest_plant["locations"][dest_location_name] dest_location = dest_plant["locations"][dest_location_name]
source = decision_nodes[product_name, "Origin", source_location_name] source = shipping_nodes[product_name, "Origin", source_location_name]
dest = process_nodes[product_name, dest_plant["name"], dest_location_name] dest = process_nodes[product_name, dest_plant["name"], dest_location_name]
distance = calculate_distance(source_location["latitude"], distance = calculate_distance(source_location["latitude"],
source_location["longitude"], source_location["longitude"],
@ -193,7 +196,7 @@ function create_nodes_and_arcs(instance)
# Process arcs (conversions within a plant) # Process arcs (conversions within a plant)
source = process_nodes[source_plant["input"], source_plant["name"], source_location_name] source = process_nodes[source_plant["input"], source_plant["name"], source_location_name]
dest = decision_nodes[product_name, source_plant["name"], source_location_name] dest = shipping_nodes[product_name, source_plant["name"], source_location_name]
costs = Dict() costs = Dict()
values = Dict("weight" => source_plant["outputs"][product_name]) values = Dict("weight" => source_plant["outputs"][product_name])
a = Arc(source, dest, costs, values) a = Arc(source, dest, costs, values)
@ -205,7 +208,7 @@ function create_nodes_and_arcs(instance)
for dest_plant in product["input plants"] for dest_plant in product["input plants"]
for dest_location_name in keys(dest_plant["locations"]) for dest_location_name in keys(dest_plant["locations"])
dest_location = dest_plant["locations"][dest_location_name] dest_location = dest_plant["locations"][dest_location_name]
source = decision_nodes[product_name, source_plant["name"], source_location_name] source = shipping_nodes[product_name, source_plant["name"], source_location_name]
dest = process_nodes[product_name, dest_plant["name"], dest_location_name] dest = process_nodes[product_name, dest_plant["name"], dest_location_name]
distance = calculate_distance(source_location["latitude"], distance = calculate_distance(source_location["latitude"],
source_location["longitude"], source_location["longitude"],
@ -223,7 +226,7 @@ function create_nodes_and_arcs(instance)
end end
end end
end end
return decision_nodes, process_nodes, arcs return shipping_nodes, process_nodes, arcs
end end
function calculate_distance(source_lat, source_lon, dest_lat, dest_lon)::Float64 function calculate_distance(source_lat, source_lon, dest_lat, dest_lon)::Float64
@ -336,8 +339,8 @@ function get_solution(instance::ReverseManufacturingInstance,
for output_product_name in keys(plant["outputs"]) for output_product_name in keys(plant["outputs"])
plant_loc_dict["total output"][output_product_name] = 0.0 plant_loc_dict["total output"][output_product_name] = 0.0
plant_loc_dict["output"][output_product_name] = product_dict = Dict() plant_loc_dict["output"][output_product_name] = product_dict = Dict()
decision_node = model.decision_nodes[output_product_name, plant_name, location_name] shipping_node = model.shipping_nodes[output_product_name, plant_name, location_name]
for a in decision_node.outgoing_arcs for a in shipping_node.outgoing_arcs
if vals[a] <= 0 if vals[a] <= 0
continue continue
end end

@ -8,17 +8,17 @@ using ReverseManufacturing, Cbc, JuMP, Printf
model = ReverseManufacturing.build_model(instance, Cbc.Optimizer) model = ReverseManufacturing.build_model(instance, Cbc.Optimizer)
# Verify nodes # Verify nodes
@test ("P1", "Origin", "C1") in keys(model.decision_nodes) @test ("P1", "Origin", "C1") in keys(model.shipping_nodes)
@test ("P1", "Origin", "C3") in keys(model.decision_nodes) @test ("P1", "Origin", "C3") in keys(model.shipping_nodes)
@test ("P1", "Origin", "C8") in keys(model.decision_nodes) @test ("P1", "Origin", "C8") in keys(model.shipping_nodes)
@test ("P2", "F1", "L1") in keys(model.decision_nodes) @test ("P2", "F1", "L1") in keys(model.shipping_nodes)
@test ("P2", "F1", "L2") in keys(model.decision_nodes) @test ("P2", "F1", "L2") in keys(model.shipping_nodes)
@test ("P3", "F1", "L1") in keys(model.decision_nodes) @test ("P3", "F1", "L1") in keys(model.shipping_nodes)
@test ("P3", "F1", "L2") in keys(model.decision_nodes) @test ("P3", "F1", "L2") in keys(model.shipping_nodes)
@test ("P3", "F2", "L3") in keys(model.decision_nodes) @test ("P3", "F2", "L3") in keys(model.shipping_nodes)
@test ("P3", "F2", "L4") in keys(model.decision_nodes) @test ("P3", "F2", "L4") in keys(model.shipping_nodes)
@test ("P4", "F2", "L3") in keys(model.decision_nodes) @test ("P4", "F2", "L3") in keys(model.shipping_nodes)
@test ("P4", "F2", "L4") in keys(model.decision_nodes) @test ("P4", "F2", "L4") in keys(model.shipping_nodes)
@test ("P1", "F1", "L1") in keys(model.process_nodes) @test ("P1", "F1", "L1") in keys(model.process_nodes)
@test ("P1", "F1", "L2") in keys(model.process_nodes) @test ("P1", "F1", "L2") in keys(model.process_nodes)
@test ("P2", "F2", "L3") in keys(model.process_nodes) @test ("P2", "F2", "L3") in keys(model.process_nodes)
@ -27,7 +27,7 @@ using ReverseManufacturing, Cbc, JuMP, Printf
@test ("P4", "F3", "L5") in keys(model.process_nodes) @test ("P4", "F3", "L5") in keys(model.process_nodes)
# Verify some arcs # Verify some arcs
p1_orig_c1 = model.decision_nodes["P1", "Origin", "C1"] p1_orig_c1 = model.shipping_nodes["P1", "Origin", "C1"]
p1_f1_l1 = model.process_nodes["P1", "F1", "L1"] p1_f1_l1 = model.process_nodes["P1", "F1", "L1"]
@test length(p1_orig_c1.outgoing_arcs) == 2 @test length(p1_orig_c1.outgoing_arcs) == 2
@test length(p1_f1_l1.incoming_arcs) == 10 @test length(p1_f1_l1.incoming_arcs) == 10
@ -38,7 +38,7 @@ using ReverseManufacturing, Cbc, JuMP, Printf
@test round(arc.costs["transportation"], digits=2) == 1643.43 @test round(arc.costs["transportation"], digits=2) == 1643.43
@test arc.costs["variable"] == 70.0 @test arc.costs["variable"] == 70.0
p2_f1_l1 = model.decision_nodes["P2", "F1", "L1"] p2_f1_l1 = model.shipping_nodes["P2", "F1", "L1"]
p2_f2_l3 = model.process_nodes["P2", "F2", "L3"] p2_f2_l3 = model.process_nodes["P2", "F2", "L3"]
@test length(p2_f1_l1.incoming_arcs) == 1 @test length(p2_f1_l1.incoming_arcs) == 1
@test length(p2_f1_l1.outgoing_arcs) == 2 @test length(p2_f1_l1.outgoing_arcs) == 2

Loading…
Cancel
Save