以不同方式添加惩罚或加权值

时间:2020-12-22 18:18:49

标签: python pandas optimization pulp

我正在尝试解决一个最小化问题,特别是在尝试解决优化问题时,我试图通过设置/首选项更好地理解 Python 中的 PulP。

这是一个虚拟问题。

我们正在努力尽量减少哪些订单使我们达到最低总价值。我们还想尝试获得更多天数较低的订单(即:应选择订单 2 和 3 而不是拣货订单 5)

例如:如果我们的目标是达到总价值 <= 50,那么我更愿意选择订单 2 和 3,而不是订单 5,因为订单 5 的天数更高。

我只是不确定如何将此约束或惩罚添加到 PulP 最小化问题中。

这是我使用的代码:

from pulp import *
import pandas as pd

orders_dict_dummy = {"Orders": [1, 2, 3, 4, 5],
                     "Value": [10, 20, 30, 40, 50],
                     "Days": [1, 2, 2, 3, 5],
                     "Participants": [5, 5, 6, 10, 10]}

new_df = pd.DataFrame(orders_dict_dummy)

orders_ = list(new_df['Orders'])
costs = dict(zip(orders_, orders_dict_dummy["Value"]))
days = dict(zip(orders_, orders_dict_dummy["Days"]))
days_list = list(new_df['Days'])

# setup problem
prob = LpProblem("Simple Orders Problem", LpMinimize)

# create Var
order_vars = LpVariable.dicts("Orders", orders_, lowBound=0, upBound=1, cat="Integer")

#objective function
prob += lpSum([costs[i] * order_vars[i] for i in orders_]

# set constraint
prob += lpSum([costs[f] * order_vars[f] for f in orders_]) >= 50

prob.solve()

谢谢。

1 个答案:

答案 0 :(得分:1)

两种可能的方法:

  1. 最大化一个目标(总值),然后将结果添加为约束并求解另一个目标(总天数)。
  2. 将目标设为加权总和,其中总值具有更大的权重。

编辑:按照第二种方法,您可以对目标进行小幅修改:

#include <ArduinoJson.h>
#include <WiFi.h>
#include <WebServer.h>
#include <DHT.h>

#define DHTPIN 13
#define DHTTYPE DHT11

DHT dht(DHTPIN, DHTTYPE);

const char *ssid = "XXX";
const char *pwd = "XXX";

StaticJsonDocument<250> jsonDocument;
char buffer[250];

float temperature;
float humidity;

WebServer server(80);

void connectToWiFi() {
  Serial.print("Connect to: ");
  Serial.println(ssid);

  WiFi.begin(ssid, pwd);

  while (WiFi.status() !=WL_CONNECTED){
    Serial.print(".");
    delay(1000);
  }

  Serial.print("Connected. IP: ");
  Serial.println(WiFi.localIP());
}



void setup_routing(){
  server.on("/temperature", getTemperature);
  server.on("/humidity", getHumidity);
  server.on("/env", getEnv);
  
  server.begin();
}

void create_json(char *tag, float value, char *unit){
  jsonDocument.clear();
  jsonDocument["type"] = tag;
  jsonDocument["value"] = value;
  jsonDocument["unit"] = unit;
  serializeJson(jsonDocument, buffer);
}

void add_json_object(char *tag, float value, char *unit){
  JsonObject obj = jsonDocument.createNestedObject();
  obj["type"] = tag;
  obj["value"] = value;
  obj["unit"]  = unit;
}

void read_sensor_data(void * parameter) {
     for (;;) {
     temperature = dht.readTemperature();
     humidity = dht.readHumidity();
     }
     delay(2000);  
}

void getTemperature(){
  create_json("temperature", temperature,"°C");
  server.send(200, "application/json", buffer);
  Serial.println(temperature);
}
void getHumidity(){
  create_json("humidty", humidity, "%");
  server.send(200, "application/json", buffer);
  Serial.println(humidity);
}
void getEnv() {
  jsonDocument.clear();
  add_json_object("temperature", temperature, "°C");
  add_json_object("humidity", humidity, "%");
  serializeJson(jsonDocument, buffer);
  server.send(200, "application/json", buffer);
}

void setup() {
dht.begin();
Serial.begin(115200);
Serial.println(WiFi.localIP());  
connectToWiFi();
setup_routing();

}

void loop() {
  // put your main code here, to run repeatedly:
delay(2000);
float temperature = dht.readTemperature();
float humidty = dht.readHumidity();

}

其中 #objective function total_cost = lpSum([costs[i] * order_vars[i] for i in orders_]) total_days = lpSum([days[i] * order_vars[i] for i in orders_]) prob += 100*total_cost + total_days 用于强调最小化总成本。

求解后,您可以显示如下结果:

100

我明白了:

print(f"total_cost = {total_cost.value():.1f}")
print(f"total_days = {total_days.value():.1f}")

for v in prob.variables():
    if v.varValue > 0:
        print(v.name, "=", v.varValue)