Compare commits
60 Commits
b791a80128
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 3998caf079 | |||
| aec9898091 | |||
| 3c8bed290d | |||
| 13ab972fdc | |||
| 4ca1da90fb | |||
| 6bab964dd5 | |||
| d7d9d5e6ea | |||
| 46d3a584b4 | |||
| f5a8420025 | |||
| 1e7ad317b8 | |||
| 0a47e5ffcb | |||
| 5f153a71d3 | |||
| 901e3a00ff | |||
| 10b10a4f61 | |||
| 7b3b1eb23e | |||
| 2f3c0c82b7 | |||
| caac7b03f9 | |||
| 87528c097e | |||
| dcafbce924 | |||
| cb6d8ced33 | |||
| 5e1de21a22 | |||
| 11d8f8e757 | |||
| de7d671411 | |||
| 41245cae8f | |||
| 6dc06d021a | |||
| ad5aedd454 | |||
| 2f53e5de27 | |||
| 6fb7e5bf68 | |||
| a1d6ed7d75 | |||
| 07cea8fa77 | |||
| d3b3e682db | |||
| 5c9ba9cfdf | |||
| 40f7dc5b49 | |||
| 6c7ba28320 | |||
| d3871084e6 | |||
| dd2aacb284 | |||
| 19ece6f700 | |||
| 7aad87810f | |||
| 65aed86783 | |||
| 01d9f25220 | |||
| 93d580a299 | |||
| 64d4d6c71c | |||
| 70f0125d13 | |||
| 859b34308c | |||
| d8086caa18 | |||
| cd382540a4 | |||
| 41797a07b8 | |||
| 3b35123d0d | |||
| e045407993 | |||
| 877ad0ad1a | |||
| 510415982d | |||
| 1b976d4d32 | |||
| 0a8d951cfa | |||
| f536ca37fe | |||
| e6d4434e69 | |||
| f538278232 | |||
| 52327fd62e | |||
| adea6477d8 | |||
| 81c579bbe1 | |||
| dbf36badbf |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -32,3 +32,4 @@
|
||||
*.out
|
||||
*.app
|
||||
|
||||
build
|
||||
|
||||
BIN
Docs/Documento_entrega.odt
Normal file
BIN
Docs/Documento_entrega.odt
Normal file
Binary file not shown.
44
README.md
44
README.md
@@ -1,3 +1,43 @@
|
||||
# Bin-packing-SA-solution
|
||||
# Solução para o problema Bin Packing
|
||||
|
||||
Tentativa de fazer o bin-packing com SA
|
||||
Este projeto é a solução do Danilo Barcelos e do Allann Cintra para o 2º Desafio em Otimização com Meta-heurística. Ele segue esta seguinte estrutura de arquivos:
|
||||
|
||||
- A pasta "src" contém o código-fonte do programa da solução
|
||||
- A pasta "Docs" contém o arquivo do Writer que foi convertido em PDF para submissão
|
||||
- A pasta "test" contém os casos de teste utilizados. Ela contém o conjunto completo de casos de teste, o conjunto reduzido para debugging, e o arquivo contendo as soluções ótimas de todos os casos
|
||||
- Na pasta raiz você encontrará os scripts que ajudam a testar vários casos de teste de forma rápida
|
||||
|
||||
# Modo de Usar
|
||||
|
||||
## No Linux
|
||||
|
||||
Compile o programa usando makefile `> make`, ou manualmente `> g++ src/main.cpp src/random.cpp src/sa.cpp -o build/sabp`. Após isso você pode rodar o programa manualmente `> build/sabp`, digitando o caso de teste no terminal, ou usando o script "run.sh".
|
||||
|
||||
Para usar ele, basta chamá-lo, por padrão ele busca o executável no lugar onde o makefile compila, e os testes em `test/reduced`. Caso queira mudar onde ele busca as coisas, pode-se usar estas variáveis:
|
||||
|
||||
- EXEC: Caminho do executável
|
||||
- TEST_FOLDER: Caminho da pasta que contém casos de teste. Cada caso deve ser um arquivo de texto
|
||||
- SOLUTIONS_FILE: Caminho do arquivo de soluções
|
||||
|
||||
Aqui vai um exemplo de comando para usar o script, supondo que todos os arquivos necessários estão em `/tmp/files`:
|
||||
|
||||
`EXEC=/tmp/files/exec.out TEST_FOLDER=/tmp/files/tests SOLUTIONS_FILE=/tmp/files/solucoes.txt ./run.sh`
|
||||
|
||||
NOTA: O script bash não diz quanto tempo cada caso de teste levou
|
||||
|
||||
## No Windows
|
||||
|
||||
Compile o programa manualmente, pois o makefile não funciona no Windows `> g++ src/main.cpp src/random.cpp src/sa.cpp -o build/sabp.exe`. Após isso você pode rodar o programa manualmente `> build\sabp.exe`, digitando o caso de teste no terminal, ou usando o script "run.bat".
|
||||
|
||||
Para usar ele, basta chamálo, por padrão ele busca o executável no lugar onde ele estaria se o makefile funcionasse no Windows (`build\sabp.exe`), e os testes em `test\reduced`. Caso queira mudar seu comportamento, pode-se usar estas variáveis:
|
||||
|
||||
- EXEC: Caminho do executável (Parece que precisa estar em aspas? Batch é estranho)
|
||||
- TEST_FOLDER: Caminho da pasta que contém casos de teste. Cada caso deve ser um arquivo de texto
|
||||
- ARGS: Define os argumentos a se passar para o programa. O programa suporta 2 argumentos: i=Não imprimir informações sobre as iterações; c=Não imprimir conteúdos das caixas
|
||||
- SOLUTIONS_FILE: Caminho do arquivo de soluções
|
||||
|
||||
Aqui vai um exemplo de comando para usar o script, supondo que todos os arquivos necessários estão em `C:\arquivos`, e que você está interessado no conteúdo das caixas, mas não nas informações sobre iterações:
|
||||
|
||||
`set EXEC="C:\arquivos\prog.exe"&& set TEST_FOLDER=C:\arquivos\testes&& set SOLUTIONS_FILE=C:\arquivos\testes\Solucoes.txt&& set ARGS=i&& run.bat`
|
||||
|
||||
Este script não procura o arquivo de soluções por padrão, mas diz quantos segundos cada caso de teste levou para ser processado. Se a saída deste script for redirecionada para um arquivo, e um arquivo de soluções foi especificado, pode-se usar o script getstats.py para obter estatísticas do teste.
|
||||
|
||||
32
getstats.py
Normal file
32
getstats.py
Normal file
@@ -0,0 +1,32 @@
|
||||
arqname = input("Escreva o nome do arquivo de saída (Deve estar no formato de saída dos scripts, com arquivo de resposta ótima, e com os argumentos -i e -c)\n> ")
|
||||
arq = open(arqname, "r", -1, "UTF-8")
|
||||
|
||||
caseqtd = 0
|
||||
accuracy = 1.0
|
||||
timetot = 0
|
||||
largesterr = 0
|
||||
|
||||
while True:
|
||||
arq.readline()
|
||||
l2 = arq.readline().split(" ")
|
||||
l3 = arq.readline().split(" ")
|
||||
arq.readline()
|
||||
l5 = arq.readline().split(" ")
|
||||
|
||||
if len(l5) < 5: break
|
||||
|
||||
progres = int(l2[len(l2)-1])
|
||||
optires = int(l3[len(l3)-1])
|
||||
extime = int(l5[len(l5)-2])
|
||||
|
||||
caseqtd += 1
|
||||
timetot += extime
|
||||
diff = progres-optires
|
||||
if diff > largesterr: largesterr = diff
|
||||
accuracy = (accuracy + 1 - (progres-optires)/optires)/2.0
|
||||
|
||||
print("----------Statistics----------")
|
||||
print("Cases parsed...........: %d" %caseqtd)
|
||||
print("Average execution time.: %f" %(timetot/caseqtd))
|
||||
print("Average answer accuracy: %f%%" %(accuracy*100.0))
|
||||
print("Largest error..........: %d" %largesterr)
|
||||
21
main.cpp
21
main.cpp
@@ -1,21 +0,0 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
#include "sa.hpp"
|
||||
|
||||
int main()
|
||||
{
|
||||
int number_of_items = 0;
|
||||
int capacity = 0;
|
||||
std::cin >> number_of_items >> capacity;
|
||||
|
||||
std::vector<long long> items(number_of_items);
|
||||
for (auto &i : items) {
|
||||
std::cin >> i;
|
||||
}
|
||||
|
||||
sa::solution act = sa::solution::simulated_annealing(capacity, items,
|
||||
1000, 0.99);
|
||||
|
||||
act.print_sol();
|
||||
}
|
||||
47
makefile
Normal file
47
makefile
Normal file
@@ -0,0 +1,47 @@
|
||||
# Flag para alterar o padrão do compilador
|
||||
standart = -std=c++17
|
||||
|
||||
# Flags para otimizar o arquivo executável
|
||||
optimize_flags = -O3 -pipe -flto
|
||||
|
||||
# Flags para ativar todos os avisos do compilador
|
||||
warnings = -Wall -Wextra -Werror -Wformat=2 -Wno-maybe-uninitialized \
|
||||
-Wformat-overflow=2 -Wundef -Wconversion -Wwrite-strings
|
||||
|
||||
# Flags para depurar o código
|
||||
sanitize = -fsanitize=address,undefined,pointer-compare,pointer-subtract
|
||||
debug_flags = -ggdb3 -Og -DDEBUG -Wformat-truncation=2 $(sanitize)
|
||||
|
||||
CC := /usr/bin/gcc
|
||||
CXX := /usr/bin/g++
|
||||
|
||||
builddir := build
|
||||
objectname = sabp
|
||||
objectdir = $(builddir)/$(objectname)
|
||||
|
||||
.PHONY: all debug
|
||||
|
||||
all:set_flags $(objectdir)
|
||||
|
||||
debug:set_debug_flags $(objectdir)
|
||||
|
||||
$(objectdir):$(builddir) $(builddir)/random.o $(builddir)/sa.o src/main.cpp
|
||||
$(CXX) $(CPPFLAGS) $(builddir)/random.o $(builddir)/sa.o src/main.cpp -o $(objectdir)
|
||||
|
||||
$(builddir)/random.o:src/random.cpp
|
||||
$(CXX) $(CPPFLAGS) src/random.cpp -o $(builddir)/random.o -c
|
||||
|
||||
$(builddir)/sa.o:src/sa.cpp
|
||||
$(CXX) $(CPPFLAGS) src/sa.cpp -o $(builddir)/sa.o -c
|
||||
|
||||
$(builddir):
|
||||
mkdir -p $(builddir)
|
||||
|
||||
set_flags:
|
||||
$(eval override CPPFLAGS += $(warnings) $(optimize_flags) $(standart))
|
||||
|
||||
set_debug_flags:
|
||||
$(eval override CPPFLAGS += $(warnings) $(sanitize) $(debug_flags))
|
||||
|
||||
clean:
|
||||
rm -rf $(builddir)
|
||||
77
run.bat
Normal file
77
run.bat
Normal file
@@ -0,0 +1,77 @@
|
||||
:: Uso: [set EXEC="caminho\do\executavel.exe"]&&[set TEST_FOLDER=caminho\dos\casetests]&&[set ARGS=ic]&&[set SOLUTIONS_FILE=arquivo\de\solucoes.txt]&&run.bat [> arq\de\saida.txt]
|
||||
@ECHO off
|
||||
setlocal enabledelayedexpansion
|
||||
|
||||
if not defined EXEC (
|
||||
set EXEC="build\sabp.exe"
|
||||
)
|
||||
|
||||
if not defined TEST_FOLDER (
|
||||
set TEST_FOLDER=test\reduced
|
||||
)
|
||||
|
||||
rem I need to fix this later, dear God...
|
||||
set ARGS=-ic
|
||||
|
||||
if defined SOLUTIONS_FILE (
|
||||
for /f "tokens=1,2 skip=1" %%a in (%SOLUTIONS_FILE%) do (
|
||||
set solutions[%%a]=%%b
|
||||
)
|
||||
)
|
||||
|
||||
for %%g in (%TEST_FOLDER%\*) do (
|
||||
for %%h in (%%g) do set testname=%%~nxh
|
||||
for /f "delims=" %%h in ("!testname!") do set optimal=!solutions[%%h]!
|
||||
|
||||
echo Arquivo de teste: %%g
|
||||
|
||||
set start_t=!TIME!
|
||||
for /f "tokens=4" %%h in ('!EXEC! !ARGS! ^< %%g') do set res=%%h
|
||||
set end_t=!TIME!
|
||||
call :difftime !start_t! !end_t! difference
|
||||
|
||||
echo Resultado do programa: !res!
|
||||
if defined optimal (
|
||||
echo Resultado ótimo: !optimal!
|
||||
if !res! EQU !optimal! (
|
||||
echo Resultado ótimo^^!
|
||||
) else (
|
||||
set /a diff= !res!-!optimal!
|
||||
echo Diferença de !diff!
|
||||
)
|
||||
)
|
||||
echo Tempo de execução: !difference! segundos
|
||||
)
|
||||
|
||||
endlocal
|
||||
set EXEC=
|
||||
set TEST_FOLDER=
|
||||
set SOLUTIONS_FILE=
|
||||
set ARGS=
|
||||
goto :eof
|
||||
|
||||
rem Function that gets the difference between two %TIME% variables, expects args= start(VAL), end(VAL), ret(VARNAME)
|
||||
rem This function assumes that the difference in time is LESS THAN 24 HOURS; If the difference is larger, return is incorrect
|
||||
:difftime
|
||||
setlocal
|
||||
|
||||
for /f "tokens=1-3 delims=:" %%a in ("%~1") do (
|
||||
set /a start_h= ^(1%%a-100^) * 3600
|
||||
set /a start_m= ^(1%%b-100^) * 60
|
||||
set /a start_s= ^(1%%c-100^)
|
||||
)
|
||||
|
||||
for /f "tokens=1-3 delims=:" %%a in ("%~3") do (
|
||||
set /a end_h= ^(1%%a-100^) * 3600
|
||||
set /a end_m= ^(1%%b-100^) * 60
|
||||
set /a end_s= ^(1%%c-100^)
|
||||
)
|
||||
|
||||
set /a start_i= %start_h% + %start_m% + %start_s%
|
||||
set /a end_i= %end_h% + %end_m% + %end_s%
|
||||
set /a diff_t= %end_i% - %start_i%
|
||||
|
||||
if diff_t LSS 0 set /a diff_t= %diff_t%+86400
|
||||
|
||||
endlocal & set %~5=%diff_t%
|
||||
goto :eof
|
||||
37
run.sh
Executable file
37
run.sh
Executable file
@@ -0,0 +1,37 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
IFS=$'\n'
|
||||
|
||||
if [[ -z $EXEC ]]; then
|
||||
EXEC="build/sabp"
|
||||
fi
|
||||
|
||||
if [[ -z $TEST_FOLDER ]]; then
|
||||
TEST_FOLDER="test/reduced"
|
||||
fi
|
||||
|
||||
if [[ -z $SOLUTIONS_FILE ]]; then
|
||||
SOLUTIONS_FILE=test/solucoes.txt
|
||||
fi
|
||||
|
||||
declare -A solutions
|
||||
if [[ -f "$SOLUTIONS_FILE" ]]; then
|
||||
while read line; do
|
||||
solutions[$(awk '{print $1}' <<< "$line")]=$(awk '{print $2}' <<< "$line")
|
||||
done < "$SOLUTIONS_FILE"
|
||||
fi
|
||||
|
||||
for file in $(find "$TEST_FOLDER" -type f); do
|
||||
echo "Arquivo de teste: $file"
|
||||
res=$("$EXEC" -i -c < "$file" | awk '{print $4}')
|
||||
optimal=${solutions[$(basename "$file")]}
|
||||
echo "Resultado do programa: ${res}"
|
||||
if [[ ! -z $optimal ]]; then
|
||||
echo "Resultado ótimo: ${optimal}"
|
||||
if [[ $res = $optimal ]]; then
|
||||
echo "Resultado ótimo!"
|
||||
else
|
||||
echo "Diferença de $(bc <<< "${res} - ${optimal}")"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
33
sa.cpp
33
sa.cpp
@@ -1,33 +0,0 @@
|
||||
#include "sa.hpp"
|
||||
#include <cmath>
|
||||
|
||||
auto sa::solution::simulated_annealing(int capacity, const std::vector<long long> &items,
|
||||
const double alpha, double temp)->sa::solution
|
||||
{
|
||||
sa::solution best(items, capacity);
|
||||
best.randomize();
|
||||
|
||||
sa::solution prev = best;
|
||||
std::random_device rdevice;
|
||||
std::default_random_engine eng(rdevice());
|
||||
std::uniform_real_distribution<> rand(0, 1);
|
||||
|
||||
const double temp_min = 0.30;
|
||||
while (temp < temp_min) {
|
||||
sa::solution neighbor(prev);
|
||||
neighbor.setneighbor();
|
||||
|
||||
int diff = prev.fitness - neighbor.fitness;
|
||||
if (diff <= 0 || std::exp(-diff / temp) > rand(eng)) {
|
||||
prev.swap(neighbor);
|
||||
}
|
||||
|
||||
temp *= alpha;
|
||||
|
||||
if (prev.fitness < best.fitness) {
|
||||
best = prev;
|
||||
}
|
||||
}
|
||||
|
||||
return best;
|
||||
}
|
||||
101
sa.hpp
101
sa.hpp
@@ -1,101 +0,0 @@
|
||||
#ifndef SIMULATED_ANNEALING_HEADER_12647_H
|
||||
#define SIMULATED_ANNEALING_HEADER_12647_H
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <queue>
|
||||
#include <random>
|
||||
#include <vector>
|
||||
|
||||
namespace sa {
|
||||
|
||||
class solution {
|
||||
std::vector<long long> items;
|
||||
std::default_random_engine gen;
|
||||
int capacity;
|
||||
int fitness;
|
||||
|
||||
auto calculate_boxes()->int {
|
||||
int count = 1;
|
||||
long long now = 0;
|
||||
|
||||
for (auto i : items) {
|
||||
if (now + i > capacity) {
|
||||
count++;
|
||||
now = i;
|
||||
continue;
|
||||
}
|
||||
now += i;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static void print_box(int box, std::queue<long long> &stored) {
|
||||
std::cout << "Caixa " << box << ":";
|
||||
while (!stored.empty()) {
|
||||
std::cout << ' ' << stored.front();
|
||||
stored.pop();
|
||||
}
|
||||
std::cout << '\n';
|
||||
}
|
||||
|
||||
public:
|
||||
solution() = default;
|
||||
|
||||
solution(const std::vector<long long> &items, int capacity): // Gera a solução inicial
|
||||
items(items), gen(std::random_device()()), capacity(capacity),
|
||||
fitness(calculate_boxes()) {}
|
||||
|
||||
void setneighbor() { // Gera um vizinho da solução
|
||||
std::uniform_int_distribution<> dist(0, items.size() - 1);
|
||||
int first = dist(gen);
|
||||
int second = 0;
|
||||
while ((second = dist(gen)) == first) {}
|
||||
|
||||
std::swap(items[first], items[second]);
|
||||
fitness = calculate_boxes();
|
||||
}
|
||||
|
||||
void randomize() {
|
||||
std::shuffle(items.begin(), items.end(), gen);
|
||||
|
||||
fitness = calculate_boxes();
|
||||
}
|
||||
|
||||
void swap(solution &other) {
|
||||
std::swap(fitness, other.fitness);
|
||||
std::swap(items, other.items);
|
||||
std::swap(capacity, other.capacity);
|
||||
std::swap(gen, other.gen);
|
||||
}
|
||||
|
||||
void print_sol() const {
|
||||
std::cout << "Número de caixas: " << fitness << '\n';
|
||||
|
||||
int box_now = 1;
|
||||
long long now = 0;
|
||||
std::queue<long long> items_stored;
|
||||
|
||||
for (auto i : items) {
|
||||
if (now + i > capacity) {
|
||||
print_box(box_now, items_stored);
|
||||
std::cout << '\n';
|
||||
box_now++;
|
||||
now = i;
|
||||
} else {
|
||||
now += i;
|
||||
}
|
||||
items_stored.push(i);
|
||||
}
|
||||
|
||||
print_box(box_now, items_stored);
|
||||
}
|
||||
|
||||
static auto simulated_annealing(int capacity, const std::vector<long long> &items,
|
||||
double alpha, double temp)->solution;
|
||||
};
|
||||
|
||||
} // namespace sa
|
||||
|
||||
#endif
|
||||
51
src/main.cpp
Normal file
51
src/main.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
#include "sa.hpp"
|
||||
|
||||
#ifndef TEMP
|
||||
#define TEMP 1000
|
||||
#endif
|
||||
|
||||
#ifndef ALPHA
|
||||
#define ALPHA 0.999
|
||||
#endif
|
||||
|
||||
#ifndef TEMP_MIN
|
||||
#define TEMP_MIN 10
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Função main.
|
||||
* Usada apenas para ler os items, a capacidade máxima e
|
||||
* imprimir os dados da melhor solução encontrada.
|
||||
*/
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char flags = 0;
|
||||
for(int i = 1; i < argc; i++){
|
||||
if(argv[i][0] == '-'){
|
||||
int j = 1;
|
||||
while(argv[i][j] != '\0'){
|
||||
if(argv[i][j] == 'i') flags |= SIMULATED_ANNEALING_DISABLE_SHOWITRNUM;
|
||||
else if(argv[i][j] == 'c') flags |= SIMULATED_ANNEALING_DISABLE_SHOWCRATES;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int number_of_items = 0;
|
||||
int capacity = 0;
|
||||
std::cin >> number_of_items >> capacity;
|
||||
|
||||
std::vector<long long> items(number_of_items);
|
||||
for (auto &i : items) {
|
||||
std::cin >> i;
|
||||
}
|
||||
|
||||
sa::solution act = sa::solution::simulated_annealing(capacity, items,
|
||||
ALPHA, TEMP, TEMP_MIN);
|
||||
|
||||
act.print_sol(flags);
|
||||
}
|
||||
4
src/random.cpp
Normal file
4
src/random.cpp
Normal file
@@ -0,0 +1,4 @@
|
||||
#include "random.hpp"
|
||||
|
||||
std::random_device rdevice;
|
||||
std::mt19937_64 rng::rng(rdevice());
|
||||
24
src/random.hpp
Normal file
24
src/random.hpp
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef RANDOM_HPP_RANDOMNESS_WHATEVER_HEADER_238947837827_H
|
||||
#define RANDOM_HPP_RANDOMNESS_WHATEVER_HEADER_238947837827_H
|
||||
|
||||
#include <random>
|
||||
|
||||
namespace rng {
|
||||
extern std::mt19937_64 rng;
|
||||
|
||||
template<long long start, long long end>
|
||||
auto random_int() -> int
|
||||
{
|
||||
static std::uniform_int_distribution<> rint(start, end);
|
||||
return rint(rng);
|
||||
}
|
||||
|
||||
template<int start, int end>
|
||||
auto random_double() -> double
|
||||
{
|
||||
static std::uniform_real_distribution<> rdouble(start, end);
|
||||
return rdouble(rng);
|
||||
}
|
||||
} // namespace rng
|
||||
|
||||
#endif
|
||||
36
src/sa.cpp
Normal file
36
src/sa.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
#include "sa.hpp"
|
||||
#include <cmath>
|
||||
|
||||
/*
|
||||
* Implementação do algoritmo de SA.
|
||||
*/
|
||||
|
||||
auto sa::solution::simulated_annealing(int capacity, const std::vector<long long> &items,
|
||||
const double alpha, double temp,
|
||||
const double temp_min)->sa::solution
|
||||
{
|
||||
sa::solution best(items, capacity);
|
||||
sa::solution prev = best;
|
||||
|
||||
int iteration = 0;
|
||||
|
||||
while (temp > temp_min) {
|
||||
iteration++;
|
||||
sa::solution neighbor(prev, iteration);
|
||||
neighbor.setneighbor();
|
||||
|
||||
long long diff = neighbor.fitness - prev.fitness;
|
||||
if (diff < 0 || rng::random_double<0, 1>() / temp < 0.05) {
|
||||
swap(prev, neighbor);
|
||||
}
|
||||
|
||||
temp *= alpha;
|
||||
|
||||
if (prev.fitness < best.fitness) {
|
||||
best = prev;
|
||||
}
|
||||
}
|
||||
|
||||
best.setiterations(iteration);
|
||||
return best;
|
||||
}
|
||||
287
src/sa.hpp
Normal file
287
src/sa.hpp
Normal file
@@ -0,0 +1,287 @@
|
||||
#ifndef SIMULATED_ANNEALING_HEADER_12647_H
|
||||
#define SIMULATED_ANNEALING_HEADER_12647_H
|
||||
|
||||
#define SIMULATED_ANNEALING_DISABLE_SHOWCRATES 1
|
||||
#define SIMULATED_ANNEALING_DISABLE_SHOWITRNUM 2
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <queue>
|
||||
#include <random>
|
||||
#include <set>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "random.hpp"
|
||||
|
||||
namespace sa {
|
||||
|
||||
using content = std::priority_queue<long long, std::vector<long long>, std::greater<>>;
|
||||
|
||||
class box {
|
||||
content items;
|
||||
long long fullness{};
|
||||
|
||||
/* Troca uma caixa com a outra. */
|
||||
friend void swap(box &one, box &two) {
|
||||
using std::swap;
|
||||
|
||||
swap(one.items, two.items);
|
||||
swap(one.fullness, two.fullness);
|
||||
}
|
||||
|
||||
/* Remove o menor item da caixa. */
|
||||
void pop() {
|
||||
fullness -= items.top();
|
||||
items.pop();
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
box() = default;
|
||||
|
||||
/*
|
||||
* Inicialia uma caixa a partir de um conjunto de items e da soma total
|
||||
* dos items.
|
||||
*/
|
||||
box(content items, long long fullness):
|
||||
items(std::move(items)), fullness(fullness) {}
|
||||
|
||||
/* Adiciona um item a caixa. */
|
||||
void add_item(long long item) {
|
||||
fullness += item;
|
||||
items.push(item);
|
||||
}
|
||||
|
||||
/* Limpa a caixa. */
|
||||
void clear() {
|
||||
while (!items.empty()) {
|
||||
items.pop();
|
||||
}
|
||||
fullness = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Verifica se é possível move o menor item da caixa atual para a
|
||||
* caixa "other" sem violar as restrições de capacidade.
|
||||
*/
|
||||
auto swappable10(box &other, int capacity) -> bool {
|
||||
return items.top() + other.fullness <= capacity;
|
||||
}
|
||||
|
||||
/*
|
||||
* Move o menor item da caixa atual para a caixa "other".
|
||||
*/
|
||||
void swap10(box &other) {
|
||||
other.add_item(items.top());
|
||||
pop();
|
||||
}
|
||||
|
||||
/*
|
||||
* Verifica se é possivel realizar "swap11" com a caixa "other" sem
|
||||
* violar as restrições de capacidade, também verificando se ambos os menores
|
||||
* items são os mesmos.
|
||||
*/
|
||||
auto swappable11(box &other, int capacity) -> bool {
|
||||
long long choice1 = items.top();
|
||||
long long choice2 = other.items.top();
|
||||
return choice1 != choice2 &&
|
||||
choice1 + other.fullness - choice2 <= capacity &&
|
||||
choice2 + fullness - choice1 <= capacity;
|
||||
}
|
||||
|
||||
/*
|
||||
* Troca o menor item da caixa atual com o menor item da caixa
|
||||
* "other"
|
||||
*/
|
||||
void swap11(box &other) {
|
||||
long long choice1 = items.top();
|
||||
long long choice2 = other.items.top();
|
||||
|
||||
pop();
|
||||
other.pop();
|
||||
add_item(choice2);
|
||||
other.add_item(choice1);
|
||||
}
|
||||
|
||||
/* Imprime todos os items da caixa junto com um identificador. */
|
||||
void print(int ind) {
|
||||
std::cout << "Caixa " << ind << ":";
|
||||
content tmp;
|
||||
while (!items.empty()) {
|
||||
std::cout << ' ' << items.top();
|
||||
items.pop();
|
||||
}
|
||||
std::cout << '\n';
|
||||
}
|
||||
|
||||
/* Retorna um booleano indicando se a caixa está vazia. */
|
||||
[[nodiscard]] auto empty() const -> bool {
|
||||
return fullness == 0;
|
||||
}
|
||||
};
|
||||
|
||||
class solution {
|
||||
std::vector<box> boxes;
|
||||
long long fitness;
|
||||
int capacity;
|
||||
int iterations;
|
||||
int iteration;
|
||||
|
||||
/*
|
||||
* Função para trocar duas soluções.
|
||||
* Overload da função std::swap.
|
||||
*/
|
||||
friend void swap(solution &one, solution &two) {
|
||||
using std::swap;
|
||||
|
||||
swap(one.boxes, two.boxes);
|
||||
swap(one.capacity, two.capacity);
|
||||
swap(one.fitness, two.fitness);
|
||||
swap(one.iterations, two.iterations);
|
||||
swap(one.iteration, two.iteration);
|
||||
}
|
||||
|
||||
/*
|
||||
* Função para usar o swap10 ou swap11 aleatoriamente quando
|
||||
* possível.
|
||||
*/
|
||||
void random_swap(int choice, std::vector<int> &sequence10, std::vector<int> &sequence11) {
|
||||
typedef void (box::*swap)(box&);
|
||||
swap swaps[2] = {
|
||||
&box::swap10,
|
||||
&box::swap11
|
||||
};
|
||||
std::vector<int>* sequences[2] = {
|
||||
&sequence10,
|
||||
&sequence11
|
||||
};
|
||||
|
||||
int now = rng::random_double<0, 1>() > 0.3 ? 0 : 1;
|
||||
|
||||
if (sequences[now]->empty()) {
|
||||
now ^= 1;
|
||||
if (sequences[now]->empty()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
std::uniform_int_distribution<> dist(0, (int)sequences[now]->size() - 1);
|
||||
(boxes[choice].*swaps[now])(boxes[(*sequences[now])[dist(rng::rng)]]);
|
||||
}
|
||||
|
||||
public:
|
||||
solution() = default;
|
||||
|
||||
/* Inicializa uma solução a partir da outra. */
|
||||
solution(const solution &other, int itr): boxes(other.boxes), fitness(other.fitness),
|
||||
capacity(other.capacity), iteration(itr) {}
|
||||
|
||||
/* Gera a solução inicial a partir dos items disponíveis. */
|
||||
solution(const std::vector<long long> &items, int capacity):
|
||||
capacity(capacity), iteration(0) {
|
||||
std::multiset<long long> its; // Items ordenados.
|
||||
for (auto i : items) {
|
||||
its.insert(i);
|
||||
}
|
||||
|
||||
long long cap = capacity; // Capacidade restante da caixa atual.
|
||||
box tmp; // Caixa atual.
|
||||
|
||||
while (!its.empty()) {
|
||||
auto itr = its.upper_bound(cap);
|
||||
if (itr == its.begin()) { // Caixa está cheia, cria-se outra.
|
||||
cap = capacity;
|
||||
cap -= *its.begin();
|
||||
itr = its.begin();
|
||||
this->boxes.emplace_back(tmp);
|
||||
tmp.clear();
|
||||
} else { // Caixa consegue colocar outro elemento.
|
||||
itr--;
|
||||
cap -= *itr;
|
||||
}
|
||||
tmp.add_item(*itr);
|
||||
its.erase(itr);
|
||||
}
|
||||
|
||||
if (!tmp.empty()) {
|
||||
this->boxes.emplace_back(tmp);
|
||||
}
|
||||
fitness = (int)this->boxes.size();
|
||||
}
|
||||
|
||||
/* Muda a solução atual para um de seus vizinhos. */
|
||||
void setneighbor() {
|
||||
int choice = std::uniform_int_distribution<>(0, (int)boxes.size() - 1)(rng::rng);
|
||||
std::vector<int> sequence10; // Possíveis candidatos para swap10
|
||||
std::vector<int> sequence11; // Possíveis candidatos para swap11
|
||||
|
||||
sequence10.reserve(boxes.size());
|
||||
sequence11.reserve(boxes.size());
|
||||
|
||||
for (size_t i = 0; i < (size_t)choice; i++) {
|
||||
if (boxes[choice].swappable10(boxes[i], capacity)) {
|
||||
sequence10.push_back((int)i);
|
||||
}
|
||||
if (boxes[choice].swappable11(boxes[i], capacity)) {
|
||||
sequence11.push_back((int)i);
|
||||
}
|
||||
}
|
||||
for (size_t i = choice + 1; i < boxes.size(); i++) {
|
||||
if (boxes[choice].swappable10(boxes[i], capacity)) {
|
||||
sequence10.push_back((int)i);
|
||||
}
|
||||
if (boxes[choice].swappable11(boxes[i], capacity)) {
|
||||
sequence11.push_back((int)i);
|
||||
}
|
||||
}
|
||||
|
||||
random_swap(choice, sequence10, sequence11);
|
||||
if (boxes[choice].empty()) {
|
||||
/*
|
||||
* Caixa agora está vazia, é possível remove-la.
|
||||
*/
|
||||
swap(boxes[choice], boxes[boxes.size() - 1]);
|
||||
boxes.pop_back();
|
||||
fitness = (int)boxes.size();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Imprime todas as informações da solução:
|
||||
* - Número de caixas
|
||||
* - Items em cada caixa
|
||||
* - Iteração onde foi encontrada a solução
|
||||
* - Iterações totais ate o fim do algoritmo
|
||||
*/
|
||||
void print_sol(char flags = 0) {
|
||||
if(!(flags & SIMULATED_ANNEALING_DISABLE_SHOWITRNUM)){
|
||||
std::cout << "Iteração da solução: " << iteration << '\n';
|
||||
std::cout << "Número de iterações calculadas: " << iterations << '\n';
|
||||
}
|
||||
std::cout << "Número de caixas: " << fitness << '\n';
|
||||
|
||||
if(!(flags & SIMULATED_ANNEALING_DISABLE_SHOWCRATES)){
|
||||
for (size_t i = 0; i < boxes.size(); i++) {
|
||||
boxes[i].print((int)i + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Pôe o número de iterações totais para a solução. */
|
||||
void setiterations(int itr) {
|
||||
iterations = itr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Declaração do algoritmo, sua implementação está no arquivo
|
||||
* sa.cpp.
|
||||
*/
|
||||
static auto simulated_annealing(int capacity, const std::vector<long long> &items,
|
||||
double alpha, double temp,
|
||||
double temp_min) -> solution;
|
||||
};
|
||||
|
||||
} // namespace sa
|
||||
|
||||
#endif
|
||||
1005
test/cases/1002_80000_DI_0.txt
Normal file
1005
test/cases/1002_80000_DI_0.txt
Normal file
File diff suppressed because it is too large
Load Diff
1005
test/cases/1002_80000_DI_1.txt
Normal file
1005
test/cases/1002_80000_DI_1.txt
Normal file
File diff suppressed because it is too large
Load Diff
1005
test/cases/1002_80000_DI_10.txt
Normal file
1005
test/cases/1002_80000_DI_10.txt
Normal file
File diff suppressed because it is too large
Load Diff
1005
test/cases/1002_80000_DI_11.txt
Normal file
1005
test/cases/1002_80000_DI_11.txt
Normal file
File diff suppressed because it is too large
Load Diff
1005
test/cases/1002_80000_DI_12.txt
Normal file
1005
test/cases/1002_80000_DI_12.txt
Normal file
File diff suppressed because it is too large
Load Diff
1005
test/cases/1002_80000_DI_13.txt
Normal file
1005
test/cases/1002_80000_DI_13.txt
Normal file
File diff suppressed because it is too large
Load Diff
1005
test/cases/1002_80000_DI_14.txt
Normal file
1005
test/cases/1002_80000_DI_14.txt
Normal file
File diff suppressed because it is too large
Load Diff
1005
test/cases/1002_80000_DI_15.txt
Normal file
1005
test/cases/1002_80000_DI_15.txt
Normal file
File diff suppressed because it is too large
Load Diff
1005
test/cases/1002_80000_DI_16.txt
Normal file
1005
test/cases/1002_80000_DI_16.txt
Normal file
File diff suppressed because it is too large
Load Diff
1005
test/cases/1002_80000_DI_17.txt
Normal file
1005
test/cases/1002_80000_DI_17.txt
Normal file
File diff suppressed because it is too large
Load Diff
1005
test/cases/1002_80000_DI_18.txt
Normal file
1005
test/cases/1002_80000_DI_18.txt
Normal file
File diff suppressed because it is too large
Load Diff
1005
test/cases/1002_80000_DI_19.txt
Normal file
1005
test/cases/1002_80000_DI_19.txt
Normal file
File diff suppressed because it is too large
Load Diff
1005
test/cases/1002_80000_DI_2.txt
Normal file
1005
test/cases/1002_80000_DI_2.txt
Normal file
File diff suppressed because it is too large
Load Diff
1005
test/cases/1002_80000_DI_20.txt
Normal file
1005
test/cases/1002_80000_DI_20.txt
Normal file
File diff suppressed because it is too large
Load Diff
1005
test/cases/1002_80000_DI_21.txt
Normal file
1005
test/cases/1002_80000_DI_21.txt
Normal file
File diff suppressed because it is too large
Load Diff
1005
test/cases/1002_80000_DI_22.txt
Normal file
1005
test/cases/1002_80000_DI_22.txt
Normal file
File diff suppressed because it is too large
Load Diff
1005
test/cases/1002_80000_DI_23.txt
Normal file
1005
test/cases/1002_80000_DI_23.txt
Normal file
File diff suppressed because it is too large
Load Diff
1005
test/cases/1002_80000_DI_24.txt
Normal file
1005
test/cases/1002_80000_DI_24.txt
Normal file
File diff suppressed because it is too large
Load Diff
1005
test/cases/1002_80000_DI_25.txt
Normal file
1005
test/cases/1002_80000_DI_25.txt
Normal file
File diff suppressed because it is too large
Load Diff
1005
test/cases/1002_80000_DI_26.txt
Normal file
1005
test/cases/1002_80000_DI_26.txt
Normal file
File diff suppressed because it is too large
Load Diff
1005
test/cases/1002_80000_DI_27.txt
Normal file
1005
test/cases/1002_80000_DI_27.txt
Normal file
File diff suppressed because it is too large
Load Diff
1005
test/cases/1002_80000_DI_28.txt
Normal file
1005
test/cases/1002_80000_DI_28.txt
Normal file
File diff suppressed because it is too large
Load Diff
1005
test/cases/1002_80000_DI_29.txt
Normal file
1005
test/cases/1002_80000_DI_29.txt
Normal file
File diff suppressed because it is too large
Load Diff
1005
test/cases/1002_80000_DI_3.txt
Normal file
1005
test/cases/1002_80000_DI_3.txt
Normal file
File diff suppressed because it is too large
Load Diff
1005
test/cases/1002_80000_DI_30.txt
Normal file
1005
test/cases/1002_80000_DI_30.txt
Normal file
File diff suppressed because it is too large
Load Diff
1005
test/cases/1002_80000_DI_31.txt
Normal file
1005
test/cases/1002_80000_DI_31.txt
Normal file
File diff suppressed because it is too large
Load Diff
1005
test/cases/1002_80000_DI_32.txt
Normal file
1005
test/cases/1002_80000_DI_32.txt
Normal file
File diff suppressed because it is too large
Load Diff
1005
test/cases/1002_80000_DI_33.txt
Normal file
1005
test/cases/1002_80000_DI_33.txt
Normal file
File diff suppressed because it is too large
Load Diff
1005
test/cases/1002_80000_DI_34.txt
Normal file
1005
test/cases/1002_80000_DI_34.txt
Normal file
File diff suppressed because it is too large
Load Diff
1005
test/cases/1002_80000_DI_35.txt
Normal file
1005
test/cases/1002_80000_DI_35.txt
Normal file
File diff suppressed because it is too large
Load Diff
1005
test/cases/1002_80000_DI_36.txt
Normal file
1005
test/cases/1002_80000_DI_36.txt
Normal file
File diff suppressed because it is too large
Load Diff
1005
test/cases/1002_80000_DI_37.txt
Normal file
1005
test/cases/1002_80000_DI_37.txt
Normal file
File diff suppressed because it is too large
Load Diff
1005
test/cases/1002_80000_DI_38.txt
Normal file
1005
test/cases/1002_80000_DI_38.txt
Normal file
File diff suppressed because it is too large
Load Diff
1005
test/cases/1002_80000_DI_39.txt
Normal file
1005
test/cases/1002_80000_DI_39.txt
Normal file
File diff suppressed because it is too large
Load Diff
1005
test/cases/1002_80000_DI_4.txt
Normal file
1005
test/cases/1002_80000_DI_4.txt
Normal file
File diff suppressed because it is too large
Load Diff
1005
test/cases/1002_80000_DI_40.txt
Normal file
1005
test/cases/1002_80000_DI_40.txt
Normal file
File diff suppressed because it is too large
Load Diff
1005
test/cases/1002_80000_DI_41.txt
Normal file
1005
test/cases/1002_80000_DI_41.txt
Normal file
File diff suppressed because it is too large
Load Diff
1005
test/cases/1002_80000_DI_42.txt
Normal file
1005
test/cases/1002_80000_DI_42.txt
Normal file
File diff suppressed because it is too large
Load Diff
1005
test/cases/1002_80000_DI_43.txt
Normal file
1005
test/cases/1002_80000_DI_43.txt
Normal file
File diff suppressed because it is too large
Load Diff
1005
test/cases/1002_80000_DI_44.txt
Normal file
1005
test/cases/1002_80000_DI_44.txt
Normal file
File diff suppressed because it is too large
Load Diff
1005
test/cases/1002_80000_DI_45.txt
Normal file
1005
test/cases/1002_80000_DI_45.txt
Normal file
File diff suppressed because it is too large
Load Diff
1005
test/cases/1002_80000_DI_46.txt
Normal file
1005
test/cases/1002_80000_DI_46.txt
Normal file
File diff suppressed because it is too large
Load Diff
1005
test/cases/1002_80000_DI_47.txt
Normal file
1005
test/cases/1002_80000_DI_47.txt
Normal file
File diff suppressed because it is too large
Load Diff
1005
test/cases/1002_80000_DI_48.txt
Normal file
1005
test/cases/1002_80000_DI_48.txt
Normal file
File diff suppressed because it is too large
Load Diff
1005
test/cases/1002_80000_DI_49.txt
Normal file
1005
test/cases/1002_80000_DI_49.txt
Normal file
File diff suppressed because it is too large
Load Diff
1005
test/cases/1002_80000_DI_5.txt
Normal file
1005
test/cases/1002_80000_DI_5.txt
Normal file
File diff suppressed because it is too large
Load Diff
1005
test/cases/1002_80000_DI_6.txt
Normal file
1005
test/cases/1002_80000_DI_6.txt
Normal file
File diff suppressed because it is too large
Load Diff
1005
test/cases/1002_80000_DI_7.txt
Normal file
1005
test/cases/1002_80000_DI_7.txt
Normal file
File diff suppressed because it is too large
Load Diff
1005
test/cases/1002_80000_DI_8.txt
Normal file
1005
test/cases/1002_80000_DI_8.txt
Normal file
File diff suppressed because it is too large
Load Diff
1005
test/cases/1002_80000_DI_9.txt
Normal file
1005
test/cases/1002_80000_DI_9.txt
Normal file
File diff suppressed because it is too large
Load Diff
1004
test/cases/1002_80000_NR_0.txt
Normal file
1004
test/cases/1002_80000_NR_0.txt
Normal file
File diff suppressed because it is too large
Load Diff
1004
test/cases/1002_80000_NR_1.txt
Normal file
1004
test/cases/1002_80000_NR_1.txt
Normal file
File diff suppressed because it is too large
Load Diff
1004
test/cases/1002_80000_NR_10.txt
Normal file
1004
test/cases/1002_80000_NR_10.txt
Normal file
File diff suppressed because it is too large
Load Diff
1004
test/cases/1002_80000_NR_11.txt
Normal file
1004
test/cases/1002_80000_NR_11.txt
Normal file
File diff suppressed because it is too large
Load Diff
1004
test/cases/1002_80000_NR_12.txt
Normal file
1004
test/cases/1002_80000_NR_12.txt
Normal file
File diff suppressed because it is too large
Load Diff
1004
test/cases/1002_80000_NR_13.txt
Normal file
1004
test/cases/1002_80000_NR_13.txt
Normal file
File diff suppressed because it is too large
Load Diff
1004
test/cases/1002_80000_NR_14.txt
Normal file
1004
test/cases/1002_80000_NR_14.txt
Normal file
File diff suppressed because it is too large
Load Diff
1004
test/cases/1002_80000_NR_15.txt
Normal file
1004
test/cases/1002_80000_NR_15.txt
Normal file
File diff suppressed because it is too large
Load Diff
1004
test/cases/1002_80000_NR_16.txt
Normal file
1004
test/cases/1002_80000_NR_16.txt
Normal file
File diff suppressed because it is too large
Load Diff
1004
test/cases/1002_80000_NR_17.txt
Normal file
1004
test/cases/1002_80000_NR_17.txt
Normal file
File diff suppressed because it is too large
Load Diff
1004
test/cases/1002_80000_NR_18.txt
Normal file
1004
test/cases/1002_80000_NR_18.txt
Normal file
File diff suppressed because it is too large
Load Diff
1004
test/cases/1002_80000_NR_19.txt
Normal file
1004
test/cases/1002_80000_NR_19.txt
Normal file
File diff suppressed because it is too large
Load Diff
1004
test/cases/1002_80000_NR_2.txt
Normal file
1004
test/cases/1002_80000_NR_2.txt
Normal file
File diff suppressed because it is too large
Load Diff
1004
test/cases/1002_80000_NR_20.txt
Normal file
1004
test/cases/1002_80000_NR_20.txt
Normal file
File diff suppressed because it is too large
Load Diff
1004
test/cases/1002_80000_NR_21.txt
Normal file
1004
test/cases/1002_80000_NR_21.txt
Normal file
File diff suppressed because it is too large
Load Diff
1004
test/cases/1002_80000_NR_22.txt
Normal file
1004
test/cases/1002_80000_NR_22.txt
Normal file
File diff suppressed because it is too large
Load Diff
1004
test/cases/1002_80000_NR_23.txt
Normal file
1004
test/cases/1002_80000_NR_23.txt
Normal file
File diff suppressed because it is too large
Load Diff
1004
test/cases/1002_80000_NR_24.txt
Normal file
1004
test/cases/1002_80000_NR_24.txt
Normal file
File diff suppressed because it is too large
Load Diff
1004
test/cases/1002_80000_NR_25.txt
Normal file
1004
test/cases/1002_80000_NR_25.txt
Normal file
File diff suppressed because it is too large
Load Diff
1004
test/cases/1002_80000_NR_26.txt
Normal file
1004
test/cases/1002_80000_NR_26.txt
Normal file
File diff suppressed because it is too large
Load Diff
1004
test/cases/1002_80000_NR_27.txt
Normal file
1004
test/cases/1002_80000_NR_27.txt
Normal file
File diff suppressed because it is too large
Load Diff
1004
test/cases/1002_80000_NR_28.txt
Normal file
1004
test/cases/1002_80000_NR_28.txt
Normal file
File diff suppressed because it is too large
Load Diff
1004
test/cases/1002_80000_NR_29.txt
Normal file
1004
test/cases/1002_80000_NR_29.txt
Normal file
File diff suppressed because it is too large
Load Diff
1004
test/cases/1002_80000_NR_3.txt
Normal file
1004
test/cases/1002_80000_NR_3.txt
Normal file
File diff suppressed because it is too large
Load Diff
1004
test/cases/1002_80000_NR_30.txt
Normal file
1004
test/cases/1002_80000_NR_30.txt
Normal file
File diff suppressed because it is too large
Load Diff
1004
test/cases/1002_80000_NR_31.txt
Normal file
1004
test/cases/1002_80000_NR_31.txt
Normal file
File diff suppressed because it is too large
Load Diff
1004
test/cases/1002_80000_NR_32.txt
Normal file
1004
test/cases/1002_80000_NR_32.txt
Normal file
File diff suppressed because it is too large
Load Diff
1004
test/cases/1002_80000_NR_33.txt
Normal file
1004
test/cases/1002_80000_NR_33.txt
Normal file
File diff suppressed because it is too large
Load Diff
1004
test/cases/1002_80000_NR_34.txt
Normal file
1004
test/cases/1002_80000_NR_34.txt
Normal file
File diff suppressed because it is too large
Load Diff
1004
test/cases/1002_80000_NR_35.txt
Normal file
1004
test/cases/1002_80000_NR_35.txt
Normal file
File diff suppressed because it is too large
Load Diff
1004
test/cases/1002_80000_NR_36.txt
Normal file
1004
test/cases/1002_80000_NR_36.txt
Normal file
File diff suppressed because it is too large
Load Diff
1004
test/cases/1002_80000_NR_37.txt
Normal file
1004
test/cases/1002_80000_NR_37.txt
Normal file
File diff suppressed because it is too large
Load Diff
1004
test/cases/1002_80000_NR_38.txt
Normal file
1004
test/cases/1002_80000_NR_38.txt
Normal file
File diff suppressed because it is too large
Load Diff
1004
test/cases/1002_80000_NR_39.txt
Normal file
1004
test/cases/1002_80000_NR_39.txt
Normal file
File diff suppressed because it is too large
Load Diff
1004
test/cases/1002_80000_NR_4.txt
Normal file
1004
test/cases/1002_80000_NR_4.txt
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user