Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » Поиск элементов массива, чья сумма равна заданному числу

Ответить
Настройки темы
Поиск элементов массива, чья сумма равна заданному числу

Старожил


Сообщения: 155
Благодарности: 2


Конфигурация

Профиль | Отправить PM | Цитировать


Может кто знает, как реализовать такую штуку: есть массив чисел, необходимо найти такие элменты этого массива, чтобы сумма этих чисел равнялась определенному значению (либо установить, что такой комбинации элемнтов массива нет). Интересует алгоритм или какие-то общие соображения на эту тему. Я делаю так (для комбинации из, к примеру, 4 чисел): цикл по всем возможным комбинациям. Также еще один очень важный вопрос: это (см. код) действительно все возможные комбинации?

Код: Выделить весь код
int NUM[] = {10,20,30,40,50, <...>};
int COUNT = sizeof(NUM)/sizeof(int);
int SUM = 35;
int i,j,k,n;

<...>

for(i=0;i<COUNT;i++)
	for(j=0;j<COUNT;j++)
		for(k=0;k<COUNT;k++)
			for(n=0;n<COUNT;n++)
			{
				if((i!=j && i!=k && i!=n) && (j!=k && j!=n) && (k!=n))
				{
					if(NUM[i] + NUM[j] + NUM[k] + NUM[n] == SUM)
						printf("%d %d %d %d\n",i,j,k,n);
				}
			}

Отправлено: 00:18, 14-09-2006

 

Ночной странник


Contributor


Сообщения: 4050
Благодарности: 83

Профиль | Сайт | Отправить PM | Цитировать


ivank
собственно ваш алгоритм не всегда корректно работат...
Всё хорошо, путь: 10 2 3 4 5 6 7 8 9 11 12 13 14 15 16 17 18 19 20 = 400

int l = 20;
summ2(m,l, l*l);

-------
можно практически все, но просто мы это еще не знаем.
главный враг програмиста это копипастинг
За хорошее сообщение не забываем нажимать ссылочку "Полезное сообщение"!


Отправлено: 16:25, 24-09-2006 | #21



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля.


редкий гость


Сообщения: 1696
Благодарности: 44

Профиль | Сайт | Отправить PM | Цитировать


Vlad Drakula
Влад. Ты неправильно переделал мой код в C#. И не взял мою исправленную функцию из предыдущего поста. Давай помедитируем над разницей вот этого:
Цитата ivank:
static void summ2(int[] num, int n, int m)
{
int[] way = new int[m+1];
for (int i = 0; i <= m; ++i)
way[i] = 0;
и вот этого:
Цитата Vlad:
static void summ2(int[] num, int n, int size)
{
int m = n*(n+1)/2-1; // сумма всех чисел, кроме первого

int[] way = new int[m+1];
for (int i = 0; i <= m; ++i)
way[i] = 0;
Чуешь разницу? Не вали свои баги на меня. В исправленом коде случае. summ2(m, l, l*l); даёт именно "Всё плохо". Всё за те же 4 секунды. В то время, как твой код на аналогичном тесте вешается (при достаточно больших l, 100 уже более чем достаточно).

Ну и вот очередной тест. Сортировка не поможет. У меня всё те же несколько секунд. (Впредь прошу при тестах моего кода брать мою версию, а не то, что ты криво сконвертировал).

Всего 100 чисел. мой код - 0.08с, понятно что зависимость от l - квадратичная, так что при 1000 числах (в 10 раз больше) уже будет ~10с (в 100 раз дольше). Вуаля:
Код: Выделить весь код
using System;

namespace summ
{
    class Class1
    {
        static bool su(int[] m, int[] s, int i, int p, int l, int size, int corsize)
        {
            for(;i < l; i++)
            {
                if(corsize + m[i] == size)
                {
                    for(int j = 0; j <= p; j ++)
                    {
                        Console.Write("{0} + ", m[s[j]]);
                    }

                    Console.WriteLine("{0} = {1};", m[i], size);

                    return true;
                }
                else if(corsize + m[i] < size)
                {
                    s[p + 1] = i;
                    if(su(m, s, i + 1, p + 1, l, size, corsize + m[i]))
                    {
                        return true;
                    }
                }
            }

            return false;
        }

        static void QSort(int[] ar, int size)
        {
            int left, right, ixLeft, ixRight;
            int[] borderLeft = new int[100];
            int[] borderRight = new int[100];
            int stach = 0;
            int copy;
            int x;
            Random r = new Random();
            borderLeft[0] = 0;
            borderRight[0] = size - 1;
            while(stach >= 0)
            {
                ixLeft = left = borderLeft[stach];
                ixRight = right = borderRight[stach];
                stach--;
                
                while(left < right)
                {
                    x = ar[r.Next(left, right)];
                    ixLeft = left;
                    ixRight = right;

                    while(ixLeft <= ixRight)
                    {
 
                        while(ar[ixLeft] > x)
                        {
                            ixLeft++;
                        }
                        while(ar[ixRight] < x)
                        {
                            ixRight--;
                        }
                    
                        if(ixLeft <= ixRight)
                        {
                            copy = ar[ixLeft];
                            ar[ixLeft] = ar[ixRight];
                            ar[ixRight] = copy;
                            ixLeft++;
                            ixRight--;
                        }
                    }

                    if(ixRight - left < right - ixLeft)
                    {
                        stach++;
                        borderLeft[stach] = ixLeft;
                        borderRight[stach] = right;
                        right = ixRight;
                    }
                    else
                    {
                        stach++;
                        borderLeft[stach] = left;
                        borderRight[stach] = ixRight;
                        left = ixLeft;
                    }
                }                
            }
        }

        static void summ(int[] m, int l, int size)
        {
            QSort(m, l);
            int[] s = new int[l];
            su(m, s, 0, -1, l, size, 0);            
        }

        static void summ2(int[] num, int n, int m)
        {
            int[] way = new int[m+1];
            for (int i = 0; i <= m; ++i)
                way[i] = 0;

            way[0] = 1;

            for (int i = 0; i < n; ++i)
                for (int j = m; j > 0; --j)
                    if (way[j] == 0 && j >= num[i] && way[j-num[i]] != 0)
                        way[j] = num[i];

            if (way[m] == 0)
                Console.WriteLine("Всё плохо");
            else
            {
                Console.Write("Всё хорошо, путь: ");
                for (int i = m; i != 0; i -= way[i])
                    Console.Write("{0} ", way[i]);
                Console.WriteLine("");
            }
        }

        static void Main(string[] args)
        {
            DateTime d1, d2;
            int l = 100;
            int[] m = new int[l];

	    int needed = 0;

            for(int j = 0; j < l; j++)
            {
                m[j] = l+j+1;
                needed += m[j];
            }
            needed -= m[l/2];

            d1 = DateTime.Now;                
            summ2(m, l, needed);
            d2 = DateTime.Now;
            Console.WriteLine("ivank's time: {0}", d2 - d1);

            d1 = DateTime.Now;                
            summ(m, l, needed);
            d2 = DateTime.Now;
            Console.WriteLine("vlad's time: {0}", d2 - d1);
        }
    }
}
Кстати, я вспомнил. Это называется задачей об укладке рюкзака, частный её случай. Это NP-полная задача в общем случае. Её можно решить за "псевдо-полиномиальное" время, что я и делаю. предлагаю просесть всю статью.

Честно гворя, я считал, что в СпбГУ достаточно высокий уровень образования, что бы знать комбинаторику в объёме достаточном для понимания, что для перебора всех комбинаций из n чисел требуется 2^n операций. И что это очень большое число уже при n порядка 30.

-------
http://ivank.ru


Последний раз редактировалось ivank, 24-09-2006 в 21:47.


Отправлено: 20:31, 24-09-2006 | #22


Ночной странник


Contributor


Сообщения: 4050
Благодарности: 83

Профиль | Сайт | Отправить PM | Цитировать


ivank
приношу извинения за недогляд при портировании...

предлагаю перейти в тестах на рандомные наборы чисел...

PHP код: Выделить весь код

using System;


namespace summ
{
    class 
Class1
    
{
        static 
int su(int[] mint[] sint iint pint lint sizeint corsize)
        {
            for(
int r 0;li++, r++)
            {
                if(
corsize m[i] == size)
                {
                    for(
int j 0<= p++)
                    {
                        
Console.Write("{0} + "m[s[j]]);
                    }

                    
Console.WriteLine("{0} = {1};"m[i], size);

                    return 
0;
                }
                else if(
corsize m[i] < size)
                {
                    if(
== l)
                    {
                        return 
== ? -1;
                    }

                    
s[1] = i;

                    switch(
su(ms11lsizecorsize m[i]))
                    {
                        case 
0:
                            return 
0;

                        case -
1:
                            if(
== 0)
                            {
                                return -
1;
                            }
                            break;

                        case 
1:
                            
1;
                            break;
                    }
                }
                else if(
== l)
                {
                    return 
1;
                }                
            }

            return 
1;
        }

        static 
void QSort(int[] arint size)
        {
            
int leftrightixLeftixRight;
            
int[] borderLeft = new int[100];
            
int[] borderRight = new int[100];
            
int stach 0;
            
int copy;
            
int x;
            
Random r = new Random();
            
borderLeft[0] = 0;
            
borderRight[0] = size 1;
            while(
stach >= 0)
            {
                
ixLeft left borderLeft[stach];
                
ixRight right borderRight[stach];
                
stach--;
                
                while(
left right)
                {
                    
ar[r.Next(leftright)];
                    
ixLeft left;
                    
ixRight right;

                    while(
ixLeft <= ixRight)
                    {
 
                        while(
ar[ixLeft] > x)
                        {
                            
ixLeft++;
                        }
                        while(
ar[ixRight] < x)
                        {
                            
ixRight--;
                        }
                    
                        if(
ixLeft <= ixRight)
                        {
                            
copy ar[ixLeft];
                            
ar[ixLeft] = ar[ixRight];
                            
ar[ixRight] = copy;
                            
ixLeft++;
                            
ixRight--;
                        }
                    }

                    if(
ixRight left right ixLeft)
                    {
                        
stach++;
                        
borderLeft[stach] = ixLeft;
                        
borderRight[stach] = right;
                        
right ixRight;
                    }
                    else
                    {
                        
stach++;
                        
borderLeft[stach] = left;
                        
borderRight[stach] = ixRight;
                        
left ixLeft;
                    }
                }                
            }
        }

        static 
bool summ(int[] mint lint size)
        {
            
QSort(ml);
            
int[] = new int[l];
            return 
su(ms0, -1lsize0) == true false;        
        }

        static 
bool summ2(int[] numint nint size)
        {
            
int m size;

            
int[] way = new int[m+1];
            for (
int i 0<= m; ++i)
                
way[i] = 0;

            
way[0] = 1;

            for (
int i 0n; ++i)
                for (
int j m0; --j)
                    if (
way[j] == && >= num[i] && way[j-num[i]] != 0)
                        
way[j] = num[i];

            if (
way[m] == 0)
            {
                
Console.WriteLine("Всё плохо");
                return 
false;
            }
            
Console.Write("Всё хорошо, путь: ");
            for (
int i m!= 0-= way[i])
            {
                
Console.Write("{0} "way[i]);
            }
            
Console.WriteLine(" = {0}"size);
            
            return 
true;
        }

        static 
void Main(string[] args)
        {
            
DateTime d1d2;
            
int l 2000;
            
int[] = new int[l];

            
Random r = new Random();
            for (
int j 0l; ++j)
            {
                
m[j] = r.Next(101000);
            }
            
int needed r.Next(10 31000 3);
    
            
d1 DateTime.Now;                
            
summ2(m,lneeded);
            
d2 DateTime.Now;
            
Console.WriteLine("ivank's time: {0}"d2 d1);

            
d1 DateTime.Now;                
            
summ(m,lneeded);
            
d2 DateTime.Now;
            
Console.WriteLine("vlad's time: {0}"d2 d1);
        }
    }


ivank's time: 00:00:11.3763584
vlad's time: 00:00:00.0200288

-------
можно практически все, но просто мы это еще не знаем.
главный враг програмиста это копипастинг
За хорошее сообщение не забываем нажимать ссылочку "Полезное сообщение"!


Отправлено: 00:38, 25-09-2006 | #23


редкий гость


Сообщения: 1696
Благодарности: 44

Профиль | Сайт | Отправить PM | Цитировать


Vlad Drakula
Цитата:
предлагаю перейти в тестах на рандомные наборы чисел...
Слив засчитан.

Я показал, что твой алгоритм в некоторых случаях подвисает (например, когда требуемой комбинации не существует. А такое в оригинальной поставновке задачи может быть). Этого достаточно, чтобы его нельзя было применять. Мой алгоритм [i]гарантированно[i] работает всегда за O(m*n), что в оригинальной постановке задачи (n ~ 40, m ~300000) означает не более чем секундную задержку. Секундная задержка лучше, чем возможное подвисание.

Более того. Предлагаю просто протестировать на реальных данных оба метода. Реальные данные - пример от автора, в посте номер 8.
Цитата:
ivank's time: 00:00:00.2220340
vlad's time: 00:00:13.5698600
что в общем-то и требовалось доказать: в общем случае твой метод нерпиемлем. Более того, если needed=349963, то он опять же подвисает. Да, у тебя достаточно хорошая эвристика, чтобы при достаточно большом наборе чисел рапределённых равномерно быстро находить требуемую комбинацию. К сожалению, входные наборы далеко не всегда обладают такими характеристиками.

Аналогично мой метод ограничен произведением m*n. Но как раз в исходной постановке - это не проблема. А вот возможное отсутствие требуемой комбинации -- очень даже.

Код: Выделить весь код
using System;

namespace summ
{
    class Class1
    {
        static int su(int[] m, int[] s, int i, int p, int l, int size, int corsize)
        {
            for(int r = 0;i < l; i++, r++)
            {
                if(corsize + m[i] == size)
                {
                    for(int j = 0; j <= p; j ++)
                    {
                        Console.Write("{0} + ", m[s[j]]);
                    }

                    Console.WriteLine("{0} = {1};", m[i], size);

                    return 0;
                }
                else if(corsize + m[i] < size)
                {
                    if(i + 1 == l)
                    {
                        return r == 0 ? -1 : 1;
                    }

                    s[p + 1] = i;

                    switch(su(m, s, i + 1, p + 1, l, size, corsize + m[i]))
                    {
                        case 0:
                            return 0;

                        case -1:
                            if(r == 0)
                            {
                                return -1;
                            }
                            break;

                        case 1:
                            r = 1;
                            break;
                    }
                }
                else if(i + 1 == l)
                {
                    return 1;
                }                
            }

            return 1;
        }

        static void QSort(int[] ar, int size)
        {
            int left, right, ixLeft, ixRight;
            int[] borderLeft = new int[100];
            int[] borderRight = new int[100];
            int stach = 0;
            int copy;
            int x;
            Random r = new Random();
            borderLeft[0] = 0;
            borderRight[0] = size - 1;
            while(stach >= 0)
            {
                ixLeft = left = borderLeft[stach];
                ixRight = right = borderRight[stach];
                stach--;
                
                while(left < right)
                {
                    x = ar[r.Next(left, right)];
                    ixLeft = left;
                    ixRight = right;

                    while(ixLeft <= ixRight)
                    {
 
                        while(ar[ixLeft] > x)
                        {
                            ixLeft++;
                        }
                        while(ar[ixRight] < x)
                        {
                            ixRight--;
                        }
                    
                        if(ixLeft <= ixRight)
                        {
                            copy = ar[ixLeft];
                            ar[ixLeft] = ar[ixRight];
                            ar[ixRight] = copy;
                            ixLeft++;
                            ixRight--;
                        }
                    }

                    if(ixRight - left < right - ixLeft)
                    {
                        stach++;
                        borderLeft[stach] = ixLeft;
                        borderRight[stach] = right;
                        right = ixRight;
                    }
                    else
                    {
                        stach++;
                        borderLeft[stach] = left;
                        borderRight[stach] = ixRight;
                        left = ixLeft;
                    }
                }                
            }
        }

        static bool summ(int[] m, int l, int size)
        {
            QSort(m, l);
            int[] s = new int[l];
            return su(m, s, 0, -1, l, size, 0) == 0 ? true : false;        
        }

        static bool summ2(int[] num, int n, int size)
        {
            int m = size;

            int[] way = new int[m+1];
            for (int i = 0; i <= m; ++i)
                way[i] = 0;

            way[0] = 1;

            for (int i = 0; i < n; ++i)
                for (int j = m; j > 0; --j)
                    if (way[j] == 0 && j >= num[i] && way[j-num[i]] != 0)
                        way[j] = num[i];

            if (way[m] == 0)
            {
                Console.WriteLine("Всё плохо");
                return false;
            }
            Console.Write("Всё хорошо, путь: ");
            for (int i = m; i != 0; i -= way[i])
            {
                Console.Write("{0} ", way[i]);
            }
            Console.WriteLine(" = {0}", size);
            
            return true;
        }

        static void Main(string[] args)
        {
            DateTime d1, d2;
            int l = 42;
            int[] m = {
                197900,70584,65006,39893,27638,
                29448,17220,7750,39032,2870,
                2010,22386,93275,20090,10906,
                36162,4133,40180,64575,34440,
                6027,8754,22960,4879,22960,
                18311,39893,27638,58896,24108,
                22386,2727,36162,4879,4133,
                34440,5740,2727,15355,1665,
                34440,8610
            };

            int needed = 350000; // Попробуй 349963
    
            d1 = DateTime.Now;                
            summ2(m,l, needed);
            d2 = DateTime.Now;
            Console.WriteLine("ivank's time: {0}", d2 - d1);

            d1 = DateTime.Now;                
            summ(m,l, needed);
            d2 = DateTime.Now;
            Console.WriteLine("vlad's time: {0}", d2 - d1);
        }
    }
}

-------
http://ivank.ru


Отправлено: 01:14, 25-09-2006 | #24


редкий гость


Сообщения: 1696
Благодарности: 44

Профиль | Сайт | Отправить PM | Цитировать


P.P.S. последний кусочек статистики.
int[] m = {
197900,70584,65006,39893,27638,
29448,17220,7750,39032,2870,
2010,22386,93275,20090,10906,
36162,4133,40180,64575,34440,
6027,8754,22960,4879,22960,
18311,39893,27638,58896,24108,
22386,2727,36162,4879,4133,
34440,5740,2727,15355,1665,
34440,8610
};
Максимальная сумма - 1233188. При этом невозможно получить 306002 различных сумм с помощью данного набора. То есть, если выбирать needed случайно, с вероятностью 1/4 твоя программа зависнет.

Код: Выделить весь код
using System;

namespace summ
{
    class Class1
    {
        static int su(int[] m, int[] s, int i, int p, int l, int size, int corsize)
        {
            for(int r = 0;i < l; i++, r++)
            {
                if(corsize + m[i] == size)
                {
                    for(int j = 0; j <= p; j ++)
                    {
                        Console.Write("{0} + ", m[s[j]]);
                    }

                    Console.WriteLine("{0} = {1};", m[i], size);

                    return 0;
                }
                else if(corsize + m[i] < size)
                {
                    if(i + 1 == l)
                    {
                        return r == 0 ? -1 : 1;
                    }

                    s[p + 1] = i;

                    switch(su(m, s, i + 1, p + 1, l, size, corsize + m[i]))
                    {
                        case 0:
                            return 0;

                        case -1:
                            if(r == 0)
                            {
                                return -1;
                            }
                            break;

                        case 1:
                            r = 1;
                            break;
                    }
                }
                else if(i + 1 == l)
                {
                    return 1;
                }                
            }

            return 1;
        }

        static void QSort(int[] ar, int size)
        {
            int left, right, ixLeft, ixRight;
            int[] borderLeft = new int[100];
            int[] borderRight = new int[100];
            int stach = 0;
            int copy;
            int x;
            Random r = new Random();
            borderLeft[0] = 0;
            borderRight[0] = size - 1;
            while(stach >= 0)
            {
                ixLeft = left = borderLeft[stach];
                ixRight = right = borderRight[stach];
                stach--;
                
                while(left < right)
                {
                    x = ar[r.Next(left, right)];
                    ixLeft = left;
                    ixRight = right;

                    while(ixLeft <= ixRight)
                    {
 
                        while(ar[ixLeft] > x)
                        {
                            ixLeft++;
                        }
                        while(ar[ixRight] < x)
                        {
                            ixRight--;
                        }
                    
                        if(ixLeft <= ixRight)
                        {
                            copy = ar[ixLeft];
                            ar[ixLeft] = ar[ixRight];
                            ar[ixRight] = copy;
                            ixLeft++;
                            ixRight--;
                        }
                    }

                    if(ixRight - left < right - ixLeft)
                    {
                        stach++;
                        borderLeft[stach] = ixLeft;
                        borderRight[stach] = right;
                        right = ixRight;
                    }
                    else
                    {
                        stach++;
                        borderLeft[stach] = left;
                        borderRight[stach] = ixRight;
                        left = ixLeft;
                    }
                }                
            }
        }

        static bool summ(int[] m, int l, int size)
        {
            QSort(m, l);
            int[] s = new int[l];
            return su(m, s, 0, -1, l, size, 0) == 0 ? true : false;        
        }

        static bool summ2(int[] num, int n, int size)
        {
            int m = size;

            int[] way = new int[m+1];
            for (int i = 0; i <= m; ++i)
                way[i] = 0;

            way[0] = 1;

            for (int i = 0; i < n; ++i)
                for (int j = m; j > 0; --j)
                    if (way[j] == 0 && j >= num[i] && way[j-num[i]] != 0)
                        way[j] = num[i];
        
	    if (way[m] == 0)
            {
                Console.WriteLine("Всё плохо");
                return false;
            }
            Console.Write("Всё хорошо, путь: ");
            for (int i = m; i != 0; i -= way[i])
            {
                Console.Write("{0} ", way[i]);
            }
            Console.WriteLine(" = {0}", size);
            
            return true;
        }

        static void Main(string[] args)
        {
            DateTime d1, d2;
            int l = 42;
            int[] m = {
                197900,70584,65006,39893,27638,
                29448,17220,7750,39032,2870,
                2010,22386,93275,20090,10906,
                36162,4133,40180,64575,34440,
                6027,8754,22960,4879,22960,
                18311,39893,27638,58896,24108,
                22386,2727,36162,4879,4133,
                34440,5740,2727,15355,1665,
                34440,8610
            };
            Random r = new Random();
            while (true)
            {
                int needed = r.Next(1665, 1233188);

                d1 = DateTime.Now;                
                summ2(m,l, needed);
                d2 = DateTime.Now;
                Console.WriteLine("ivank's time: {0}", d2 - d1);

                d1 = DateTime.Now;                
                summ(m,l, needed);
                d2 = DateTime.Now;
               Console.WriteLine("vlad's time: {0}", d2 - d1);
            }
        }
    }
}
Проверил. Реально задумывается гораздо чаще.

-------
http://ivank.ru


Отправлено: 01:29, 25-09-2006 | #25

pva pva вне форума

Аватара для pva

Ветеран


Сообщения: 1180
Благодарности: 279

Профиль | Отправить PM | Цитировать


Постановка задачи про рюкзак (bounded knapsack problem) дико напоминает линейное программирование. Или я не прав? (смотрел ссылку, они решили как задачу дискретного оптимального управления)

Отправлено: 08:04, 25-09-2006 | #26


редкий гость


Сообщения: 1696
Благодарности: 44

Профиль | Сайт | Отправить PM | Цитировать


pva
Честно говоря, не очень представляю как это можно сделать. Все известные мне методы линейного программирования, которые ищут дискретные коэфициенты, в конечном счёте NP-полные (читай: сводятся всё к тому же перебору). Кстати, нашёл описание именно нашего частного случая на википедии: http://en.wikipedia.org/wiki/Subset_sum_problem . Там прямо сказано, что это не задача оптимизации (т.е. линейное программирование не применимо. По крайней мере в чистом виде).

-------
http://ivank.ru


Отправлено: 12:13, 25-09-2006 | #27


Ночной странник


Contributor


Сообщения: 4050
Благодарности: 83

Профиль | Сайт | Отправить PM | Цитировать


ivank
соглашусь что ваш алгоритм для данной задачи (типов наборов чисел) лучьше...(пока я не придумал алгорим быстрее)
но веть и быстрая сортировка имеет шанс работать по n*n, и ничего пользуются...

+ еще одно но:
а как на счет реализации?
если по оптимизировать то можно сократить время работы в 3-7 раз...

-------
можно практически все, но просто мы это еще не знаем.
главный враг програмиста это копипастинг
За хорошее сообщение не забываем нажимать ссылочку "Полезное сообщение"!


Отправлено: 01:42, 26-09-2006 | #28


редкий гость


Сообщения: 1696
Благодарности: 44

Профиль | Сайт | Отправить PM | Цитировать


Vlad Drakula
Цитата:
но веть и быстрая сортировка имеет шанс работать по n*n, и ничего пользуются...
Я не спорю. Есть сортировка с помощью кучи, которая гарантированно работает за n*logn, но ею не пользуются, т.к. в среднем случае она в несколько раз медленнее быстрой сортировки (которая, кстати называется сортировкой Хоара, на самом деле). Средние случаи встречаются значительно чаще, чтобы перевешивать превосходство хип-сорта над кусортом в худшем случае.

Аналогично в среднем случае твой алгоритм значительно лучше. Вот только на предполагаемых наборах чисел (25-50) вероятность влететь в худший случай максимальна (т.к. чем больше чисел (n>50), тем больше вероятность получить требуемую сумму с помощью твоей эвристики. А при малом n (<25), даже если требуеммую сумму получить нельзя, стоимость полного перебора невелика).

Цитата:
а как на счет реализации? если по оптимизировать то можно сократить время работы в 3-7 раз...
Да это вроде не требуется по условию. Человек готов был ждать по пол-часа и более. И вообще, не умею я оптимизировать на "не-алгоритмеческом" уровне, доверяю компилятору.

-------
http://ivank.ru


Отправлено: 03:31, 26-09-2006 | #29



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » Поиск элементов массива, чья сумма равна заданному числу

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
Удаление записей из таблицы по заданному времени на php magwolf Вебмастеру 5 14-08-2009 14:13
[решено] Чему равна скорость 1МБбит/сек ? Rock Хочу все знать 12 30-09-2008 04:50
GF8600gts Asus или др. чья лучше? Ochotnik Видеокарты 5 20-03-2008 19:12
С/С++ | Выбор 10 случайных элементов из массива Vovius Программирование и базы данных 5 29-08-2006 19:37
Решено | XML. DOM. Поиск дочерних элементов. penykov Программирование и базы данных 3 27-04-2006 15:46




 
Переход