Created
May 6, 2021 14:08
-
-
Save IltaySaeedi/4c3b5553333cad0a8aeb1656c494ecf7 to your computer and use it in GitHub Desktop.
This is my first exprience with Linear Programming, I tried to solve a transportation problem by using Flips package.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#r "nuget: Flips, 2.4.5" | |
open Flips | |
open Flips.Types | |
// مساله حمل و نقل | |
// مساله: 2 کارخانه با ظرفیت های تولید کالای معین به 3 انبار کالاهای | |
// خود را ارسال می کنند تا تقاضای انبارها تامین شود نه بیشتر نه کمتر | |
// با توجه به هزینه هایی که رفت آمد در پی دارد بیابید که | |
// هر کارخانه به چه مقدار و به کدام انبار اجناس خود را ارسال کند | |
// تا کمترین هزینه ی رفت و آمد را داشته باشیم | |
// Transportation problem | |
// m Factories should send goods to n Storages based on | |
// demands of the storages no more, no less | |
// by considernig cost of eavh transport between factories and storages | |
// find best solution to minimize the cost of transportation | |
// ظرفیت کارخانه ها | |
// Capacity of each factory | |
let factory1Capacity = 240.0 | |
let factory2Capacity = 350.0 | |
// نیاز هر انبار | |
// Demand of each storage | |
let storage1Demand = 210.0 | |
let storage2Demand = 240.0 | |
let storage3Demand = 130.0 | |
// هزینه حمل و نقل از کارخانه به انبار | |
// Cost of transport from factories to storages | |
let costF1ToS1 = 14.0 | |
let costF1ToS2 = 17.0 | |
let costF1ToS3 = 13.0 | |
let costF2ToS1 = 10.0 | |
let costF2ToS2 = 16.0 | |
let costF2ToS3 = 14.0 | |
// تعداد جنس ارسال شده به هر انبار | |
// مینیمم صفر است و ماکسیمم به تقاضای هر انبار بستگی دارد | |
// number of supplies that factories send to each storage | |
// minimun is zero and maximum is demand of storage | |
let suppliesF1ToS1 = | |
Decision.createInteger | |
"Number of supplies from factory1 to storage1" 0.0 storage1Demand | |
let suppliesF1ToS2 = | |
Decision.createInteger | |
"Number of supplies from factory1 to storage2" 0.0 storage2Demand | |
let suppliesF1ToS3 = | |
Decision.createInteger | |
"Number of supplies from factory1 to storage3" 0.0 storage3Demand | |
let suppliesF2ToS1 = | |
Decision.createInteger | |
"Number of supplies from factory2 to storage1" 0.0 storage1Demand | |
let suppliesF2ToS2 = | |
Decision.createInteger | |
"Number of supplies from factory2 to storage2" 0.0 storage2Demand | |
let suppliesF2ToS3 = | |
Decision.createInteger | |
"Number of supplies from factory2 to storage3" 0.0 storage3Demand | |
// مجموع هزینه های حمل و نقل | |
// Total cost of Transports | |
let objectiveExpression = | |
costF1ToS1 * suppliesF1ToS1 | |
+ costF2ToS1 * suppliesF2ToS1 | |
+ costF1ToS2 * suppliesF1ToS2 | |
+ costF2ToS2 * suppliesF2ToS2 | |
+ costF1ToS3 * suppliesF1ToS3 | |
+ costF2ToS3 * suppliesF2ToS3 | |
// مینیمم کردن هزینه ها برای رسیدن به هدف | |
// Minimizing of total cost | |
let objective = | |
Objective.create "Minimize Cost" Minimize objectiveExpression | |
// محدودیت کارخانه ها در تولید | |
// Constraint of factories in production | |
let SentFromFactory1 = | |
Constraint.create | |
"Sent from factory1" | |
(suppliesF1ToS1 + suppliesF1ToS2 + suppliesF1ToS3 | |
<== factory1Capacity) | |
let SentFromFactory2 = | |
Constraint.create | |
"Sent from factory2" | |
(suppliesF2ToS1 + suppliesF2ToS2 + suppliesF2ToS3 | |
<== factory2Capacity) | |
// تامین نیاز انبارها | |
// Supplying demands of storages | |
let deliveredToStorage1 = | |
Constraint.create | |
"Delivered to storage1" | |
(suppliesF1ToS1 + suppliesF2ToS1 | |
== storage1Demand) | |
let deliveredToStorage2 = | |
Constraint.create | |
"Delivered to storage2" | |
(suppliesF1ToS2 + suppliesF2ToS2 | |
== storage2Demand) | |
let deliveredToStorage3 = | |
Constraint.create | |
"Delivered to storage3" | |
(suppliesF1ToS3 + suppliesF2ToS3 | |
== storage3Demand) | |
// ایجاد مدل | |
// Creating model | |
let model = | |
Model.create objective | |
|> Model.addConstraint SentFromFactory1 | |
|> Model.addConstraint SentFromFactory2 | |
|> Model.addConstraint deliveredToStorage1 | |
|> Model.addConstraint deliveredToStorage2 | |
|> Model.addConstraint deliveredToStorage3 | |
// تنظیمات | |
// Settings of solver | |
let settings = | |
{ SolverType = CBC | |
MaxDuration = 10_000L | |
WriteLPFile = None | |
WriteMPSFile = None } | |
// حل کردن | |
// Solving | |
let solutionOpt = | |
match Solver.solve settings model with | |
| Optimal s -> Some s | |
| Infeasible _ | |
| Unbounded _ | |
| Unknown _ -> None | |
// شاید مساله را پاسخ داشته باشد | |
// Maybe we found minimized cost | |
let minimizedCost solutionOpt objectiveExpr = | |
Option.map | |
(fun solution -> Solution.evaluate solution objectiveExpr) | |
solutionOpt | |
// این ماژول برای گزارش انتقال ها می باشد | |
// This module is for printing transport reports | |
module Functions = | |
// تمام تصمیم ها | |
// All the decisions | |
let allDecisions = | |
[ suppliesF1ToS1 | |
suppliesF1ToS2 | |
suppliesF1ToS3 | |
suppliesF2ToS1 | |
suppliesF2ToS2 | |
suppliesF2ToS3 ] | |
// فیلتر کردن مسیرهای بدون عبور | |
// filter the ways without transport | |
let filterNoneOrZero (allDeciscions: Decision list) | |
(deciscionsResult: Map<Decision, float>) = | |
allDeciscions | |
|> List.choose | |
(fun d -> | |
let r = deciscionsResult.TryFind d | |
match r with | |
| Some 0.0 | |
| None -> None | |
| Some r -> Some(d, r)) | |
// گزارش کردن هر ارسال | |
// print each report | |
let decisionsToString (decisions: (Decision * float) list) = | |
decisions | |
|> List.map | |
(fun (d, r) -> | |
let (DecisionName name) = d.Name | |
$"{name}: {r}\n") | |
|> List.reduce (fun s acc -> acc + s) | |
// گزارش حمل و نقل ها | |
// print the report | |
match minimizedCost solutionOpt objectiveExpression with | |
| Some minimum -> | |
printfn "Objective result: %f" minimum | |
let solution = solutionOpt |> Option.get | |
Functions.filterNoneOrZero Functions.allDecisions solution.DecisionResults | |
|> Functions.decisionsToString | |
|> printfn "%s" | |
| _ -> | |
() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment