Solution for closest string 2
This commit is contained in:
parent
162759abcb
commit
8c1aa032d5
13 changed files with 511707 additions and 54 deletions
|
|
@ -1,8 +1,13 @@
|
|||
use std::path::{Path, PathBuf};
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
use clap::Parser;
|
||||
use gurobi::*;
|
||||
use expr::LinExpr;
|
||||
use grb::*;
|
||||
use itertools::Itertools;
|
||||
use ModelSense::Minimize;
|
||||
|
||||
fn read_input(filename: impl AsRef<Path>) -> Vec<Vec<u8>> {
|
||||
let text = std::fs::read_to_string(filename).unwrap();
|
||||
|
|
@ -19,9 +24,10 @@ fn read_input(filename: impl AsRef<Path>) -> Vec<Vec<u8>> {
|
|||
#[derive(Debug, Parser)]
|
||||
struct Args {
|
||||
filename: PathBuf,
|
||||
outfilename: PathBuf,
|
||||
}
|
||||
|
||||
fn solve(input: &[Vec<u8>], d: usize) {
|
||||
fn solve(input: &[Vec<u8>]) -> String {
|
||||
let mut columns = Vec::new();
|
||||
|
||||
for i in 0..input[0].len() {
|
||||
|
|
@ -42,59 +48,77 @@ fn solve(input: &[Vec<u8>], d: usize) {
|
|||
|
||||
let counts = columns.iter().counts();
|
||||
|
||||
let env = Env::new("logfile.log").unwrap();
|
||||
let mut model = Model::new("model1").unwrap();
|
||||
|
||||
let mut model = Model::new("model1", &env).unwrap();
|
||||
let mut variables = HashMap::new();
|
||||
|
||||
let mut variables = Vec::new();
|
||||
|
||||
for (k, &c) in &counts {
|
||||
for (&k, &c) in &counts {
|
||||
let mut v = Vec::new();
|
||||
let mut sum = LinExpr::new();
|
||||
let mut sum = Expr::Linear(LinExpr::new());
|
||||
for i in 0..=(k.iter().max().copied().unwrap()) {
|
||||
let var = model
|
||||
.add_var(
|
||||
&format!("{:?}:{}", k, i),
|
||||
Integer,
|
||||
0.0,
|
||||
-INFINITY,
|
||||
INFINITY,
|
||||
&[],
|
||||
&[],
|
||||
)
|
||||
.unwrap();
|
||||
let var = add_intvar!(model, name: &format!("{:?}:{}", k, i), bounds: 0..).unwrap();
|
||||
|
||||
sum = sum + &var;
|
||||
sum = sum + var;
|
||||
v.push(var);
|
||||
}
|
||||
|
||||
model
|
||||
.add_constr(&format!("{:?}", k), sum, Equal, c as f64)
|
||||
.unwrap();
|
||||
variables.push(v);
|
||||
model.add_constr(&format!("{:?}", k), c!(sum == c)).unwrap();
|
||||
variables.insert(k, v);
|
||||
}
|
||||
|
||||
for i in 0..input.len() {
|
||||
let mut sum = LinExpr::new();
|
||||
let d = add_intvar!(model, name: "D", bounds: 0..).unwrap();
|
||||
|
||||
for (l, (k, _)) in counts.iter().enumerate() {
|
||||
for j in 0..input.len() {
|
||||
if k[i] != k[j] {
|
||||
sum = sum + &variables[l][k[j] as usize];
|
||||
for i in 0..input.len() {
|
||||
let mut sum = Expr::Linear(LinExpr::new());
|
||||
|
||||
for &k in counts.keys() {
|
||||
for j in 0..=*k.iter().max().unwrap() {
|
||||
if k[i] != j {
|
||||
sum = sum + variables[k][j as usize];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
model
|
||||
.add_constr(&format!("{:?}", i), sum, Less, d as f64)
|
||||
.unwrap();
|
||||
model.add_constr(&format!("{:?}", i), c!(sum <= d)).unwrap();
|
||||
}
|
||||
|
||||
model.set_objective(d, Minimize).unwrap();
|
||||
|
||||
model.update().unwrap();
|
||||
|
||||
// model.write("test.lp").unwrap();
|
||||
|
||||
model.optimize().unwrap();
|
||||
|
||||
dbg!(model.status().unwrap());
|
||||
// for vars in &variables {
|
||||
// for v in vars {
|
||||
// dbg!(model.get_obj_attr(attr::X, v).unwrap());
|
||||
// }
|
||||
// }
|
||||
|
||||
let mut result = String::new();
|
||||
|
||||
for (i, col) in columns.iter().enumerate() {
|
||||
let t = model
|
||||
.get_obj_attr_batch(attr::X, variables[col].clone())
|
||||
.unwrap();
|
||||
|
||||
let mut p = columns[0..i].iter().filter(|&c| c == col).count();
|
||||
|
||||
let mut j = 0;
|
||||
while t[j] as usize <= p {
|
||||
p -= t[j] as usize;
|
||||
j += 1;
|
||||
}
|
||||
|
||||
let l = col.iter().position(|&c| c as usize == j).unwrap();
|
||||
|
||||
// dbg!(i, col, t, j, l, char::from_u32(input[l][i] as u32).unwrap());
|
||||
|
||||
result.push(char::from_u32(input[l][i] as u32).unwrap());
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
|
@ -102,5 +126,7 @@ fn main() {
|
|||
|
||||
let input = read_input(args.filename);
|
||||
|
||||
solve(&input, 6);
|
||||
let r = solve(&input);
|
||||
|
||||
std::fs::write(args.outfilename, r).unwrap();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue