Compare commits
36 Commits
19ece6f700
...
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 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -32,3 +32,4 @@
|
||||
*.out
|
||||
*.app
|
||||
|
||||
build
|
||||
|
||||
Binary file not shown.
55
README.md
55
README.md
@@ -1,46 +1,43 @@
|
||||
# Pontifícia Universidade Católica de Goiás
|
||||
# Solução para o problema Bin Packing
|
||||
|
||||
## Escola Politécnica e de Artes
|
||||
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:
|
||||
|
||||
### Ciência da Computação
|
||||
- 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
|
||||
|
||||
Alunos: Allann Barbosa Cintra, Danilo Matias Barcelos
|
||||
# Modo de Usar
|
||||
|
||||
***
|
||||
## No Linux
|
||||
|
||||
## 2º Desafio em Otimização com Meta-heurística
|
||||
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".
|
||||
|
||||
### Problema do Empacotamento – Solução com Recozimento Simulado
|
||||
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:
|
||||
|
||||
#### Tópicos:
|
||||
- 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
|
||||
|
||||
1. Introdução
|
||||
Aqui vai um exemplo de comando para usar o script, supondo que todos os arquivos necessários estão em `/tmp/files`:
|
||||
|
||||
1.1. Ambiente de Teste & Desenvolvimento
|
||||
`EXEC=/tmp/files/exec.out TEST_FOLDER=/tmp/files/tests SOLUTIONS_FILE=/tmp/files/solucoes.txt ./run.sh`
|
||||
|
||||
1.2. Instâncias Utilizadas
|
||||
NOTA: O script bash não diz quanto tempo cada caso de teste levou
|
||||
|
||||
2. Meta-heurística utilizada
|
||||
## No Windows
|
||||
|
||||
2.1. Descrição
|
||||
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".
|
||||
|
||||
2.2. Implementação
|
||||
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:
|
||||
|
||||
2.3. Variações Testadas
|
||||
- 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
|
||||
|
||||
2.4. Resultados
|
||||
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:
|
||||
|
||||
3. Conclusão
|
||||
`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`
|
||||
|
||||
***
|
||||
|
||||
## Introdução
|
||||
|
||||
Este documento é a entrega única do nosso grupo, ele contém todas as informações requisitadas para a submissão do desafio.
|
||||
|
||||
### Ambiente de Teste & Desenvolvimento
|
||||
|
||||
Os computadores pessoais dos dois integrantes foram utilizados em todos os processos deste desafio.
|
||||
O computador do integrante Danilo Barcelos é um computador de mesa sem modelo, possui o processador Ryzen 5 3400G, a placa-mãe ASUS A320M, e 12 GB de memória RAM com 2666 MHz de velocidade. Não possui GPU dedicada. Usa o sistema operacional Windows 10, e o IDE Visual Studio Code.
|
||||
O integrante Allann Cintra possui ???. Ele usa o sistema operacional Linux, com a distribuição Gentoo, e programa na IDE NeoVim.
|
||||
Os resultados dos testes contidos neste documento foram obtidos executando o algoritmo através do script “launch.bat” contido no diretório raiz do projeto no repositório. Todos os testes foram realizados no computador do Danilo. Para executar o algoritmo em um ambiente Linux, basta executar o script “launch.sh”.
|
||||
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)
|
||||
33
main.cpp
33
main.cpp
@@ -1,33 +0,0 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
#include "sa.hpp"
|
||||
|
||||
#ifndef TEMP
|
||||
#define TEMP 1000
|
||||
#endif
|
||||
|
||||
#ifndef ALPHA
|
||||
#define ALPHA 0.99
|
||||
#endif
|
||||
|
||||
#ifndef TEMP_MIN
|
||||
#define TEMP_MIN 0.01
|
||||
#endif
|
||||
|
||||
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,
|
||||
ALPHA, TEMP, TEMP_MIN);
|
||||
|
||||
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)
|
||||
76
run.bat
76
run.bat
@@ -1,15 +1,77 @@
|
||||
:: Uso: [set EXEC="caminho/do/executavel.exe"] && [set TEST_FOLDER="caminho/dos/casetests"] && run.bat
|
||||
:: 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/solucao.exe"
|
||||
set EXEC="build\sabp.exe"
|
||||
)
|
||||
|
||||
if not defined TEST_FOLDER (
|
||||
set TEST_FOLDER=test
|
||||
set TEST_FOLDER=test\reduced
|
||||
)
|
||||
|
||||
for %%g in (%TEST_FOLDER%/*) do (
|
||||
echo Arquivo de teste: %TEST_FOLDER%/%%g
|
||||
%EXEC% < %TEST_FOLDER%/%%g
|
||||
)
|
||||
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
|
||||
27
run.sh
27
run.sh
@@ -3,14 +3,35 @@
|
||||
IFS=$'\n'
|
||||
|
||||
if [[ -z $EXEC ]]; then
|
||||
EXEC="build/main.out"
|
||||
EXEC="build/sabp"
|
||||
fi
|
||||
|
||||
if [[ -z $TEST_FOLDER ]]; then
|
||||
TEST_FOLDER="test"
|
||||
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"
|
||||
"$EXEC" < "$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
|
||||
|
||||
143
sa.hpp
143
sa.hpp
@@ -1,143 +0,0 @@
|
||||
#ifndef SIMULATED_ANNEALING_HEADER_12647_H
|
||||
#define SIMULATED_ANNEALING_HEADER_12647_H
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <queue>
|
||||
#include <random>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
namespace sa {
|
||||
|
||||
class solution {
|
||||
std::vector<long long> items;
|
||||
std::default_random_engine gen;
|
||||
int capacity;
|
||||
int fitness;
|
||||
int iterations;
|
||||
int iteration;
|
||||
|
||||
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 solution &other, int itr): items(other.items), gen(other.gen),
|
||||
capacity(other.capacity), fitness(other.fitness),
|
||||
iteration(itr) {}
|
||||
|
||||
solution(const std::vector<long long> &items, int capacity): // Gera a solução inicial
|
||||
gen(std::random_device()()), capacity(capacity),
|
||||
iteration(0) {
|
||||
std::multiset<long long> its;
|
||||
for (auto i : items) {
|
||||
its.insert(i);
|
||||
}
|
||||
|
||||
this->items.resize(items.size());
|
||||
size_t i = 0;
|
||||
|
||||
long long cap = capacity;
|
||||
|
||||
while (!its.empty()) {
|
||||
auto itr = its.upper_bound(cap);
|
||||
if (itr == its.begin()) {
|
||||
cap = capacity;
|
||||
cap -= *its.begin();
|
||||
itr = its.begin();
|
||||
} else {
|
||||
itr--;
|
||||
cap -= *itr;
|
||||
}
|
||||
this->items[i] = *itr;
|
||||
its.erase(itr);
|
||||
i++;
|
||||
}
|
||||
|
||||
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);
|
||||
std::swap(iteration, other.iteration);
|
||||
}
|
||||
|
||||
void print_sol() const {
|
||||
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';
|
||||
|
||||
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);
|
||||
box_now++;
|
||||
now = i;
|
||||
} else {
|
||||
now += i;
|
||||
}
|
||||
items_stored.push(i);
|
||||
}
|
||||
|
||||
print_box(box_now, items_stored);
|
||||
std::cout << '\n';
|
||||
}
|
||||
|
||||
void setiterations(int itr) {
|
||||
iterations = itr;
|
||||
}
|
||||
|
||||
static auto simulated_annealing(int capacity, const std::vector<long long> &items,
|
||||
double alpha, double temp,
|
||||
double temp_min)->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
|
||||
@@ -1,16 +1,16 @@
|
||||
#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;
|
||||
std::random_device rdevice;
|
||||
std::default_random_engine eng(rdevice());
|
||||
std::uniform_real_distribution<> rand(0, 1);
|
||||
|
||||
int iteration = 0;
|
||||
|
||||
@@ -19,15 +19,14 @@ auto sa::solution::simulated_annealing(int capacity, const std::vector<long long
|
||||
sa::solution neighbor(prev, iteration);
|
||||
neighbor.setneighbor();
|
||||
|
||||
int diff = neighbor.fitness - prev.fitness;
|
||||
if (diff <= 0 || std::exp(-diff / temp) > rand(eng)) {
|
||||
prev.swap(neighbor);
|
||||
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) {
|
||||
std::cout << prev.fitness << ' ' << best.fitness << '\n';
|
||||
best = prev;
|
||||
}
|
||||
}
|
||||
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
1004
test/cases/1002_80000_NR_40.txt
Normal file
1004
test/cases/1002_80000_NR_40.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