saezlab / CARNIVAL

CAusal Reasoning for Network Identification with integer VALue programming in R
https://saezlab.github.io/CARNIVAL/
57 stars 29 forks source link

[BUG] Your bug or feature request #95

Closed LorNic97 closed 1 year ago

LorNic97 commented 1 year ago

Hello,

using the runVanillaCarnival function I received the following error:

Error in phaseI_table[, -1]: ! Can't negate columns past the end. ℹ Location 1 doesn't exist. ℹ There are only 0 columns.

Context

So what I did was trying to find where the problem was, going from function to function: solveCarnival -> processSolution -> result -> solversFunctions$saveDiagnostics(result, carnivalOptions) -> parseCplexLog -> convergenceTextToTable

Here I noticed that "text <- text[-1:-2]" removes the first two rows of the text file. In my case though I think that it deletes rows that shouldn't be deleted.

The text file usually starts like this: ""
[75] " Nodes Cuts/"
[76] " Node Left Objective IInf Best Integer Best Bound ItCnt Gap"
[77] ""
[78] " 0+ 0 167.0036 7.0456 95.78%"
[79] "
0+ 0 82.6018 7.0456 91.47%"
[80] " 0 0 17.2442 41 82.6018 17.2442 174 79.12%"
[81] " 0 0 22.7771 55 82.6018 Cuts: 77 246 72.43%"
[82] " 0 0 23.0862 51 82.6018 Cuts: 29 261 72.05%"
[83] " 0 0 23.4035 55 82.6018 Cuts: 72 296 71.67%"
ecc...

And gets firstly parsed into this:

convergence_text [1] " 0+ 0 167.0036 7.0456 95.78%" [2] " 0+ 0 82.6018 7.0456 91.47%" [3] " 0 0 17.2442 41 82.6018 17.2442 174 79.12%" [4] " 0 0 22.7771 55 82.6018 Cuts: 77 246 72.43%" [5] " 0 0 23.0862 51 82.6018 Cuts: 29 261 72.05%" [6] " 0 0 23.4035 55 82.6018 Cuts: 72 296 71.67%" [7] " 0 0 24.0266 61 82.6018 Cuts: 32 324 70.91%" [8] " 0 0 24.9019 74 82.6018 Cuts: 33 366 69.85%" [9] " 0 0 24.9122 69 82.6018 MIRcuts: 7 389 69.84%" ecc...

and lastly (after the "text <- text[-1:-2]" line) into this:

[3] " 0 0 17.2442 41 82.6018 17.2442 174 79.12%" [4] " 0 0 22.7771 55 82.6018 Cuts: 77 246 72.43%" [5] " 0 0 23.0862 51 82.6018 Cuts: 29 261 72.05%" [6] " 0 0 23.4035 55 82.6018 Cuts: 72 296 71.67%" [7] " 0 0 24.0266 61 82.6018 Cuts: 32 324 70.91%" [8] " 0 0 24.9019 74 82.6018 Cuts: 33 366 69.85%" [9] " 0 0 24.9122 69 82.6018 MIRcuts: 7 389 69.84%"

working fine.

But in my case the file is the following:

""
[132] " Nodes Cuts/"
[133] " Node Left Objective IInf Best Integer Best Bound ItCnt Gap"
[134] ""
[135] " 66 49 30.1073 2 30.1073 29.4993 2515 2.02%"
[136] "Elapsed time = 1.45 sec. (235.84 ticks, tree = 0.06 MB, solutions = 1)"
[137] " 523 232 infeasible 30.1073 30.1073 5617 0.00%"
[138] ""

and gets firstly parsed into this:

convergence_text [1] " 66 49 30.1073 2 30.1073 29.4993 2515 2.02%" [2] "Elapsed time = 1.45 sec. (235.84 ticks, tree = 0.06 MB, solutions = 1)"
[3] " 523 232 infeasible 30.1073 30.1073 5617 0.00%"

and lastly (after the "text <- text[-1:-2]" line) into this:

[3] " 523 232 infeasible 30.1073 30.1073 5617 0.00%"

giving at the end an empty tibble in convergenceTextToTable.

I have done this analysis on 105 samples and this is the only one that gives me this problem.
Is it possible for you to fix the code in order to avoid this type of error?

Code

convergenceTextToTable <- function(text) { text = convergence_text atm we work with hard coded headers: header <- c("Node", "Nodes Left", "Objective", "IInf", "Best Integer", "Best Bound", "ItCnt", "Gap" )

remove header: text <- text[-1:-2]

remove cuts cuts <- grep("Cuts", text) if (length(cuts > 0)) text <- text[-cuts] remove stars and plus sign marked <- grep("[+*]",text) if (length(marked) > 0) text <- text[-marked]

remove node file size reports: node_file_index <- grep("Nodefile size",text) if (length(node_file_index) > 0) text <- text[-node_file_index]

save the lines where elapsed time is reported: time_line_index <- grep("Elapsed time",text) time_text <- text[time_line_index] if (length(time_line_index) > 0) text <- text[-time_line_index]

if (length(text) == 0) return(emptyConvergence())

split lines to values line_list <- strsplit(text," +")

remove lines with less length llength <- lapply(line_list, length) %>% unlist()

phaseI_table <- line_list[llength == 9] %>% do.call(rbind,.) %>% dplyr::as_tibble(., .name_repair = "minimal")

phaseI_table <- phaseI_table[,-1] names(phaseI_table) <- header phaseI_table <- phaseI_table %>% dplyr::mutate(Gap = gsub("%","", Gap)) %>% dplyr::rename(Gap [%] = Gap) %>% dplyr::mutate(dplyr::across(dplyr::everything(),as.numeric)) %>% dplyr::mutate(Gap = Objective - Best Bound)

time_table <- timeStringToTable(time_text) time table is joint to the convergence table based on the position

time_table$index <- time_line_index - (1:length(time_line_index)) + 1

result <- phaseI_table %>% dplyr::mutate(index = 1:dplyr::n()) %>% dplyr::left_join(time_table,by = "index") %>% dplyr::select(-index)

return(result) }

gabora commented 1 year ago

Hi @LorNic97 ,

could you please share the complete cplex log file that caused the error to reproduce your issue? thanks Attila

LorNic97 commented 1 year ago

Hi Attila, sure

cplexLog_t11_36_27d27_03_2023n66.txt cplexCommand_t11_36_27d27_03_2023n66.txt

gabora commented 1 year ago

thanks! It seems to me that the issue was that the headers of the sections were removed twice. This is usually not a probelm, if there are many convergence entries in each section, but in your case we had only 2 lines in the second section.

I dont have logs at hand to test thoroughly, but the parser works on your example now.

please let me know if somehting comes up, best, Attila