我正在学习如何将CPlex与C ++结合使用,因此,我的问题可能看起来很愚蠢。以下算法必须访问SQlite数据库,该数据库包含足球运动员的数据,获取其内容,然后使用CPlex,根据幻想游戏中的平均点数及其成本确定最佳阵容。
以下是代码:
#include <iostream>
#include <stdio.h>
#include <cstdlib>
#include <vector>
#include <iomanip>
#include <sqlite3.h>
#include <string.h>
#include <ilcplex/ilocplex.h>
#define TECNICO 0
#define GOLEIRO 1
#define ZAGUEIRO 2
#define LATERAL 3
#define MEIA 4
#define ATACANTE 5
#define NOME 0
#define TIME 1
#define POSICAO 2
#define SITUACAO 3
#define JOGOS 4
#define PRECO 5
#define PRECO_MEDIO 6
#define PONTUACAO 7
#define PONTUACAO_MEDIA 8
#define FALTAS_SOFRIDAS 9
#define ASSISTENCIAS 10
#define FINALIZACAO_TRAVE 11
#define FINALIZACAO_DEFENDIDA 12
#define FINALIZACAO_FORA 13
#define GOLS 14
#define ROUBADA_BOLA 15
#define SG 16
#define DEFESA_DIFICIL 17
#define DEFESA_PENALTI 18
#define PASSE_ERRADO 19
#define IMPEDIMENTO 20
#define PENALTI_PERDIDO 21
#define FALTA_COMETIDA 22
#define GOL_CONTRA 23
#define CARTAO_AMARELO 24
#define CARTAO_VERMELHO 25
#define GOL_SOFRIDO 26
#define ID 27
#define MAX 855
using namespace std;
struct Jogador{
string nome;
int id;
vector<bool> posicao;
float pontuacao_media;
float custo;
bool provavel;
bool pertinencia;
};
Jogador jogadores[MAX];
int contador = 0;
int callback(void *, int, char **, char **);
int main(){
sqlite3 *db;
sqlite3_stmt *stmt;
char *err_msg;
int rc = sqlite3_open("jogadores.db", &db);
if(rc == SQLITE_OK){
const char *sql = "SELECT * FROM jogador";
rc = sqlite3_exec(db, sql, callback, 0, &err_msg);
}
else{
cout << "falhou ao abrir o banco" << endl;
}
IloEnv env;
IloModel model(env);
IloCplex cplex(env);
cplex.setParam(IloCplex::Threads, 1);
float capacidade_cartoletas;
cout << "Insira a quantidade de cartoletas" << endl;
cin >> capacidade_cartoletas;
//IloNumVarArray itens = IloNumVarArray(env, MAX, 0, 1, ILOBOOL);
bool itens[MAX];
IloExpr obj = IloExpr(env);
int max_posicao[] = {1, 1, 2, 2, 4, 2};
int posicoes_usadas[6];
for(int i = 0; i < MAX; i++){
obj += jogadores[i].pontuacao_media*itens[i];
}
IloExpr cartoletas_totais = IloExpr(env);
for(int i = 0; i < MAX; i++){
cartoletas_totais += jogadores[i].custo*itens[i];
}
for(int i = 0; i < MAX; i++){
for(int j = 0; j < MAX; j++){
posicoes_usadas[j] += jogadores[i].posicao[j]*itens[i];
}
}
model.add(cartoletas_totais <= capacidade_cartoletas);
for(int i = 0; i < 6; i++){
model.add(posicoes_usadas[i] <= max_posicao[i]);
}
model.add(IloMaximize(env,obj));
cplex.extract(model);
cplex.solve();
for(int i = 0; i < MAX; i++){
if(cplex.getValue(itens[i])){
cout << jogadores[i].nome << endl;
}
}
}
int callback(void *NotUsed, int argc, char **argv, char **azColName){
NotUsed = 0;
vector<bool> aux;
aux.assign(6, 0);
if(!strcmp(argv[POSICAO], "Técnico")){
aux[TECNICO] = 1;
}
else if(!strcmp(argv[POSICAO], "Goleiro")){
aux[GOLEIRO] = 1;
}
else if(!strcmp(argv[POSICAO], "Zagueiro")){
aux[ZAGUEIRO] = 1;
}
else if(!strcmp(argv[POSICAO], "Lateral")){
aux[LATERAL] = 1;
}
else if(!strcmp(argv[POSICAO], "Meia")){
aux[MEIA] = 1;
}
else if(!strcmp(argv[POSICAO], "Atacante")){
aux[ATACANTE] = 1;
}
int id = atoi(argv[ID]);
jogadores[id].id = id;
jogadores[id].posicao = aux;
jogadores[id].pontuacao_media = atof(argv[PONTUACAO_MEDIA]);
jogadores[id].custo = atof(argv[PRECO]);
jogadores[id].nome = argv[NOME];
jogadores[id].provavel = !strcmp(argv[SITUACAO], "Provável");
contador++;
return 0;
}
我用g ++编译它,但它给出了一个错误:
cartola.cpp:116:55: error: no matching function for call to ‘IloModel::add(bool)’
model.add(posicoes_usadas[i] <= max_posicao[i]);
另一件事:我对CPlex没有多少经验,该代码基于我的老师使用CPlex与C ++解决的一个更简单的问题
答案 0 :(得分:1)
您没有使用CPLEX建模变量对问题进行建模。对于初学者来说,这是一个非常常见的错误。您需要考虑您所知道的数据(例如在数据库表中)以描述您的问题,以及您希望求解器(例如CPLEX)做出哪些决策。然后,对于您所知道的数据,使用普通的C ++(或C#或Java或其他)变量,并使用建模变量类型(IloNumVar等)和约束对这些决策(尚未知的值)进行建模。然后,将这些约束添加到CPLEX模型中,让CPLEX解析模型并为建模变量选择最佳值。