using System;
using System.Collections.Generic;
using System.Reflection;
using ILOG.Concert;
using ILOG.CPLEX;
class Program
{
static void Main()
{
// 初始化数据
int[] table1 = { 1, 2, 3, 4, 5, 6, 7, 8 };
int[] table2 = { 4, 5, 6, 7, 8, 9 };
int[] table3 = { 1, 2, 3, 2, 3, 1, 2, 3 };
int n = table1.Length;
int m = table2.Length;
// 创建 CPLEX 模型
Cplex cplex = new Cplex();
// 创建变量
INumVar[] var1 = new INumVar[n];
INumVar[] var2 = new INumVar[m];
//定义决策变量1为整数并且是递增
var1[0] = cplex.IntVar(0, 8, "Var1_0");
for (int i = 1; i < n; i++)
{
var1[i] = cplex.IntVar(3, 9, "Var1_" + i);
cplex.AddGe(cplex.Diff(var1[i], var1[i-1]), 1); // var1[i] > var1[i - 1]
}
//定义决策变量2为整数并且是递增
var2[0] = cplex.IntVar(1, 10, "Var2_0");
for (int i = 1; i < m; i++)
{
var2[i] = cplex.IntVar(1, 10, "Var2_" + i);
cplex.AddGe(cplex.Diff(var2[i], var2[i-1]), 1); // var1[i] > var1[i - 1]
}
// 添加约束:确保每个差值变量是var1中第i个数据在var2中找到比它大并且离它最近的数字与该数据的差值
INumVar[] diffVars = new INumVar[n]; // 存储差值大于0且最小的数
for (int i = 0; i < n; i++)
{
INumVar[] diffExprs = new INumVar[m]; // 创建一个表达式数组,用于存储 var2[j] - var1[i] 的差值表达式
//INumExpr[] diffExprs = new INumExpr[m]; // 创建一个表达式数组,用于存储 var2[j] - var1[i] 的差值表达式
for (int j = 0;j<m; j++)
{
// 计算 var2[j] - var1[i] 的差值
ILinearNumExpr diffExpr = cplex.LinearNumExpr();
diffExpr.AddTerm(1.0, var2[j]);
diffExpr.AddTerm(-1.0, var1[i]);
// 创建一个新的变量用于存储差值
diffExprs[j] = cplex.NumVar(Double.NegativeInfinity, Double.PositiveInfinity, "diffExprs_" + i);
// 添加等式约束,将计算结果赋给新变量
cplex.AddEq(diffExprs[j], diffExpr);
}
// 初始化为一个较大的值
INumVar minPositive = cplex.NumVar(1e20, double.PositiveInfinity, "minPositive");
for (int k = 0; k < m; k++)
{
INumVar expr = diffExprs[k];
if (cplex.GetValue(expr) > 0 && cplex.GetValue(expr) < cplex.GetValue(minPositive))
{
minPositive = expr;
}
}
diffVars[i] = minPositive; // 将最小的差值存储到 diffVars 中
//Console.WriteLine(diffVars[i]);
//Console.ReadLine();
}
//目标函数描述
ILinearNumExpr objExpr = cplex.LinearNumExpr();
for (int i = 0; i < n; i++)
{
objExpr.AddTerm(table3[i], diffVars[i]);
}
//目标函数求解
cplex.AddMinimize(objExpr);
// 求解优化问题
if (cplex.Solve())
{
Console.WriteLine("Objective Value: " + cplex.ObjValue);
Console.ReadLine();
//更新后的表格1
Console.WriteLine("Optimized Table 1:");
for (int i = 0; i < n; i++)
{
Console.WriteLine("x" + i + " = " + cplex.GetValue(var1[i]));
}
//更新后的diffvars
Console.WriteLine("diffvars:");
for (int k = 0; k < n; k++)
{
Console.WriteLine("x" + k + " = " + cplex.GetValue(diffVars[k]));
}
//更新后的diffExprs
//Console.WriteLine("diffExprs:");
//for (int p = 0; p < m; p++)
//{
// Console.WriteLine("x" + p + " = " + cplex.GetValue(diffExprs[p]));
//}
//更新后的表格2
Console.WriteLine("Optimized Table 2:");
for (int j = 0; j < m; j++)
{
Console.WriteLine("x" + j + " = " + cplex.GetValue(var2[j]));
}
}
else
{
Console.WriteLine("No solution found.");
Console.ReadLine();
}
cplex.End();
Console.ReadLine();
}
}