문제

내가 진수(자 전화 다)및 배열의 진수 숫자는(의 배열 고)나는 찾아야 할 모든 숫자의 조합에서 는 금액을 목표입니다.

나는가에 대한 선호 솔루션에서는 C#(.Net2.0)지할 수 있는 최고의 알고리즘에 관계없이 승리.

당신의 방법을 서명은 다음과 같습니다:

public decimal[][] Solve(decimal goal, decimal[] elements)
도움이 되었습니까?

해결책

흥미로운 답변이 있습니다.감사에 대한 포인터 위험하는 동안 재미있다-그들은하지 않는 실제로 문제를 해결하는 명시된 바와 같으로 나를 찾고 있었다 정확히 일치하는-이상의 회계/예약 균형을 잡는 것보다 문제는 전통 패킹/배낭 문제입니다.

나는 다음의 개발 stack overflow 관심과 궁금하는 방법을 유용하게 될 것입니다.이 문제에서 작업과 궁금해했지 여부를 스택의 오버플로우를 제공할 수 있었습니다 준비가 대답(또는 더 나은 대답)보다 더 빨리 내가 쓸 수 있습니다.또한 감사에 대한 의견을 제안이 있 태그제는 내 생각하는 합리적으로 정확한 빛의합니다.

에 대한 관심이있는 사람들,여기에는 나의 솔루션을 사용하는 재귀(자연스럽게)내가 또한 변경 내 마음 방법에 대해 서명하고 갔 목록>보다는 오히려 소수[][]으로 돌아 유형:

public class Solver {

    private List<List<decimal>> mResults;

    public List<List<decimal>> Solve(decimal goal, decimal[] elements) {

        mResults = new List<List<decimal>>();
        RecursiveSolve(goal, 0.0m, 
            new List<decimal>(), new List<decimal>(elements), 0);
        return mResults; 
    }

    private void RecursiveSolve(decimal goal, decimal currentSum, 
        List<decimal> included, List<decimal> notIncluded, int startIndex) {

        for (int index = startIndex; index < notIncluded.Count; index++) {

            decimal nextValue = notIncluded[index];
            if (currentSum + nextValue == goal) {
                List<decimal> newResult = new List<decimal>(included);
                newResult.Add(nextValue);
                mResults.Add(newResult);
            }
            else if (currentSum + nextValue < goal) {
                List<decimal> nextIncluded = new List<decimal>(included);
                nextIncluded.Add(nextValue);
                List<decimal> nextNotIncluded = new List<decimal>(notIncluded);
                nextNotIncluded.Remove(nextValue);
                RecursiveSolve(goal, currentSum + nextValue,
                    nextIncluded, nextNotIncluded, startIndex++);
            }
        }
    }
}

응용 프로그램을 원하는 경우 이를 테스트하기,작동하려고 이 콘솔 응용 프로그램 코드:

class Program {
    static void Main(string[] args) {

        string input;
        decimal goal;
        decimal element;

        do {
            Console.WriteLine("Please enter the goal:");
            input = Console.ReadLine();
        }
        while (!decimal.TryParse(input, out goal));

        Console.WriteLine("Please enter the elements (separated by spaces)");
        input = Console.ReadLine();
        string[] elementsText = input.Split(' ');
        List<decimal> elementsList = new List<decimal>();
        foreach (string elementText in elementsText) {
            if (decimal.TryParse(elementText, out element)) {
                elementsList.Add(element);
            }
        }

        Solver solver = new Solver();
        List<List<decimal>> results = solver.Solve(goal, elementsList.ToArray());
        foreach(List<decimal> result in results) {
            foreach (decimal value in result) {
                Console.Write("{0}\t", value);
            }
            Console.WriteLine();
        }


        Console.ReadLine();
    }
}

이 도움이 되었으면 좋겠습니다 누군가가 다른 사람들이 더 빨리 답변(는지 숙제 또는 그렇지 않으면).

환...

다른 팁

하위 집합이섬 문제,그리고 약간 더 일반적인 배낭 문제를 해결할 수 있는 동적 프로그래밍:brute-force 열거의 모든 조합이 필요하지 않습니다.상담 Wikipedia 또는 당신의 마음에 드는 알고리즘을 참조합니다.

하지만 문제는 NP-complete,그들은 아주 쉽게""NP-complete.알고리즘의 복잡성 요소의 개수가 낮습니다.

내가 생각하는 당신 빈 포장 문제 당신의 손에는(NP-하드),제 생각에는 유일한 솔루션이 될 것을 시도해 가능한 모든 조합 하나를 찾을 때까지 작동합니다.

편집:지적으로 주석에,당신은 하지 않습니다 에 대한 조합 트의 번호입니다.그러나 어떤 방법을 오는 최악의 경우 시나리오 집의 숫자가 당신 조합에서의 하위 집합을 조합하급수적으로 증가의 크기를 설정합니다.

그렇지 않으면,그것은 없을 것이 NP-어렵습니다.

당신이 설명 배낭 문제, 유일한 진정한 해결책은 무력.거기에 몇 가지 근사 솔루션은 더 빨리,하지만 그들은하지 않을 수 있습니다.

지 않는 동안 문제 해결의 무력(다른 사람으로는 이미 언급했)정렬할 수 있습의 숫자는 첫 번째,그리고 이동 통해 가능한 사람이다(왼쪽부터 일단달 합계 값을 추가할 수 없습 숫자보다 큰 목표-Sum).

이 방법을 바꿀 것입을 구현하는 알고리즘(을 정렬하기 위해 한 번만 건너 뛰고 다음 표시된 요소)사용하지만,평균적으로 성능을 향상시킬 수 있습니다.

public class Logic1 {
    static int val = 121;
    public static void main(String[] args)
    {
        f(new int[] {1,4,5,17,16,100,100}, 0, 0, "{");
    }

    static void f(int[] numbers, int index, int sum, String output)
    {
        System.out.println(output + " } = " + sum);
        //System.out.println("Index value1 is "+index);
        check (sum);
        if (index == numbers.length)
        {
            System.out.println(output + " } = " + sum);
            return;
        }

        // include numbers[index]
        f(numbers, index + 1, sum + numbers[index], output + " " + numbers[index]);
        check (sum);
        //System.out.println("Index value2 is "+index);
        // exclude numbers[index]
        f(numbers, index + 1, sum, output);
        check (sum);
    }

    static void check (int sum1)
    {
        if (sum1 == val)
            System.exit(0);
    }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top