DVD에 기록하려는 미디어 파일이 많이 있지만 각 DVD는 4.5GB에 불과하기 때문에 최소 수의 DVD를 사용하도록 파일을 구성하는 최적의 방법을 찾아야합니다 (그렇지 않으면 각 빈 공간이 남아 있습니다) DVD를 쉽게 추가 할 수 있습니다). 이를 도울 수있는 도구가 있습니까?
몇 년 전에 플로피 디스크로이 작업을 수행하는 DOS 유틸리티가있었습니다.
DVD에 기록하려는 미디어 파일이 많이 있지만 각 DVD는 4.5GB에 불과하기 때문에 최소 수의 DVD를 사용하도록 파일을 구성하는 최적의 방법을 찾아야합니다 (그렇지 않으면 각 빈 공간이 남아 있습니다) DVD를 쉽게 추가 할 수 있습니다). 이를 도울 수있는 도구가 있습니까?
몇 년 전에 플로피 디스크로이 작업을 수행하는 DOS 유틸리티가있었습니다.
답변:
조합 적 최적화 문제 (수학자 쓰기로, 또는 동형) 제프 Shattock의 대답이 동등한 것을 정확하지만, 1 차원과 동등의 빈 패킹 문제 가 아닌 배낭 문제 .
운 좋게도, .NET Framework 버전 3.5 이상이 설치된 Windows 컴퓨터에 액세스 할 수있는 다른 사람과 공유 할 수있는 코드가 있습니다.
먼저 LINQPad를 다운로드하여 설치하십시오 .
둘째, 방금 작성한 LINQPad 쿼리를 다운로드 하십시오. 다음은 raw 파일에 대한 linq (ha)입니다. .linq 파일 로 저장하고 LINQPad에서 엽니 다.
매개 변수를 변경하십시오.
LINQPad 쿼리 코드에서 변경해야 할 부분은 다음과 같습니다.
int binSizeMb = 4476; // This is the (floor of the) total size of a DVD+R reported by CDBurnerXP.
string rootFileFolderPath = @"F:\2006 - Polyester Pimpstrap Intergalactic Extravaganza multicam";
binSizeMb
CD, DVD와 같은 '빈'크기로 변경하십시오 . int binSizeMb = 650;
CD를 위해.
참고 –이 binSizeMb
값은 때때로 mebibyte 라고하는 것으로 해석됩니다 . 내 어린 시절과는 달리 모든 바이트 배수가 '이진'일 때 'MB'는 이제 내 코드에서 사용되는 1,048,576 바이트의 mebibyte (MiB)와 달리 '십진 메가 바이트'또는 정확히 1,000,000 바이트를 나타냅니다. . 이를 변경 const int bytesPerMb = 1048576;
하려면 코드 의 줄을 로 변경하십시오 const int bytesPerMb = 1000000;
.
rootFileFolderPath
'빈에 포장'할 파일이 들어있는 폴더의 전체 경로로 변경하십시오 ( 예 : string rootFileFolderPath = @"C:\MySecretBinFilesFolder";
.
쿼리 탭의 왼쪽 상단에 F5있는 실행 버튼을 누르 거나 클릭하여 쿼리를 실행 하십시오.
쿼리 코드는 rootFileFolderPath
폴더 의 모든 파일을 반복적으로 열거 하므로 모든 하위 폴더의 파일도 포함됩니다.
그런 다음 각 빈에있는 모든 파일의 총 크기가 지정된 빈 크기보다 작거나 같은 파일에 대해 'bins'를 만듭니다.
LINQPad 결과 창에는 두 가지 목록이 있습니다.
첫 번째 목록은 찾은 모든 파일 중 크기에 따라 내림차순으로 나열됩니다.
두 번째 목록은 파일 및 파일 크기 목록과 함께 나머지 파일 크기와 함께 '파일 포장'으로 생성 된 저장소입니다.
다음은 두 번째 목록과 처음 두 개의 저장소가 작성된 스크린 샷입니다.
Wikipedia에 따르면, 내가 사용한 알고리즘 – FFD (First Fit Decreasing) 전략은 그리 나쁘지 않아야합니다. 위키피디아 상태 :
2007 년에는 FFD에 대한 바운드 11/9 OPT + 6/9가 엄격하다는 것이 입증되었습니다.
'OPT'는 최적의 전략을 나타냅니다 (특정 실제 전략이 아닌 잠재적으로 도달 할 수없는 무언가).
관련된 수학적 용어에 대한 다소 희미한 기억을 바탕으로, 이는 FFD 전략이 최악의 경우 아이템을 최적의 전략보다 빈의 수의 ~ 1.22 배로 묶어야한다는 것을 의미합니다. 따라서이 전략은 아이템을 4 개가 아닌 5 개의 빈으로 포장 할 수 있습니다. 특정 '병리학 적'아이템 크기를 제외하고는 그 성능이 최적에 가깝다고 생각합니다.
동일한 Wikipedia 기사에서도 "정확한 알고리즘" 이 있다고 명시하고 있습니다 . 나는 그것을 구현하기로 결정할 수도 있습니다. 먼저 알고리즘을 설명하는 논문을 읽어야합니다.
Hitchhiker의 Haskell 가이드 에서 프로그램의 변형 중 하나를 취할 수 있습니다 . 아마도 해당 튜토리얼의 일부를 수행 한 후에; 이 튜토리얼은 여러 디스크에 물건을 분배하는 문제를 정확하게 해결하기 위해 작성되었으며 , 튜토리얼의 3 장 에 나오는 다음과 같이 솔루션이 점진적으로 개선되었습니다 .
충분한 예비가 이미 있습니다. CD를 싸서 갑시다.
이미 알고 있듯이, 우리의 문제는 고전적인 문제입니다. 그것은이라고합니다 "배낭 문제" ( 그것을 구글 은 그것이 이미 모르는 경우. 더 100,000 이상의 링크가 있습니다).
탐욕스러운 해결책부터 시작합시다 ...
다음은 비슷한 질문입니다 (동일하지는 않지만 최적화가 요청되지 않음). 작업에 더 유용한 솔루션 / 프로그램을 찾을 수 있습니다 (게시 될 경우).
일반적으로 Haskell 코드는 표현력이 뛰어나므로 (Haskell은 추상화 수준이 높은 프로그래밍 언어이므로) 쉽게 파악할 수 있습니다.
솔루션 중 하나의 코드를 볼 때 우리가 작성하려는 프로그램의 최상위 구조 는 튜토리얼의 1 장 에서 설명한 것처럼 매우 간단하다는 것을 기억하십시오 .
이제 프로그램이 어떻게 작동하고 의사 코드로 표현되는지에 대해 잠시 생각해 봅시다.
main = Read list of directories and their sizes. Decide how to fit them on CD-Rs. Print solution.
합리적으로 들리나요? 나는 그렇게 생각했다.
인생을 조금 단순화하고 지금은 프로그램 외부의 디렉토리 크기 (예 : "
du -sb *
")를 계산하고 stdin에서이 정보를 읽겠다고 가정 해 봅시다 .
솔루션의 일부를 더 자세히 살펴보십시오.
오래 전 나는 그러한 작업을 수행하기 위해 PHP 스크립트를 작성했습니다 : https://bitbucket.org/borszczuk/php-backup-maker/
또한 다양한 디스크에 복사 할 파일 및 디렉토리를 선택하는 Discfit을 시도하십시오.