Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > Задача на алгоритм равномерного распределения


Автор: RokDemon 10.5.2009, 23:55
Здравствуйте! мне нужно решить задачу моделирования, но не могу врубиться. нужен совет.а если кто приведет код, будет просто супер!
Итак, суть задачи:
есть 3-х мерный массив из двух типов чисел - однерок(1) и шестерок(6). размерность массива [1000].
нужно сделать так, чтобы однерки и шестерки равномерно "перемешались" этом массиве.
Мои соображения таковы: надо в цикле от 1 до 1000 рандомно взять один элемент массива, потом рандомно другой и поменять их функцией swap.
Я правильно мыслю? или есть другой, более рациональный подход?
помогите плз с кодом..

Автор: Dmi3ev 11.5.2009, 00:29
Цитата

равномерно "перемешались" этом массиве.

что ты под этим понимаешь? лучше на примере (1000х1000х1000 не надо, 5х5х5 достаточно будет)
1) что за входные данные?
2) что хочешь получить?

Добавлено через 2 минуты и 2 секунды
Цитата

типов чисел - однерок(1) и шестерок(6)

можно доктора защитить  smile 

Автор: RokDemon 11.5.2009, 00:55
ок. я пишу диплом просто. задачу моделирования постараюсь более развернуто объяснить. однерки  и шестерки я ввел для примера...итак:
Магнит(образец) кубической формы условно разделили на 1000 кубиков который назван микрообъемом. Каждый микрообъем характеризуется параметром "коэрцитивная сила". Далее:
1)микрообъемы должны заметно различаться по этому параметру(коэрцитивная сила)
2)слабо и сильно коэрцитивные микрообъемы должны быть распределены равномерно по объему образца.
Вопрос: какой нужен алгоритм для того чтобы получить магнит, в котором коэрцитивная сила у микрообъемов будет подобным образом распределена? и что значит 1-е условие, а именно: микрообъемы должны заметно различаться по этому параметру?это как? - например 1,2,3,4,5...100. или все же как два множества [1..5](слабые) и [8..10](сильные) ?

Исходные данные? 3-х мерный массив с заданными значениями, нижняя половина одних чисел, верхняя других. это как бочка - нижняя половина меда, верхняя воды.надо перемешать.  я так думаю, что надо в цикле от 1 до 1000 рандомно взять один элемент массива, потом рандомно другой, так сделать 1000 раз и поменять их функцией swap.
Я правильно мыслю? или есть другой, более рациональный подход?
если да, то как это можно закодить?

Автор: Dmi3ev 11.5.2009, 02:54
Цитата

однерки  и шестерки я ввел для примера

вот это как раз и интересно, сколько единиц, а сколько шестерок...
Цитата

2)слабо и сильно коэрцитивные микрообъемы должны быть распределены равномерно по объему образца.

потому как это можно понять по разному, вот  допустим
0 - сильные
1 - слабые
если у меня будет одномерный массив, я распределю так
01010101
если 2мерный, то
01010101
10101010
01010101
10101010
тупо через один, вполне равномерно  smile И в принципе, может, тебе так и надо если сильных и слабых одинаковое количество...
несложно догадаться для 3мерного...
это если 1 и 0 одинаковое количество, а если нет, то... вот я и спрашиваю, каким образом формируется этот кубик? 
Код

микрообъемы должны заметно различаться по этому параметру?это как? - например 1,2,3,4,5...100.

может у препода спросишь  smile я хз

Автор: J0ker 11.5.2009, 06:48
Цитата(RokDemon @  11.5.2009,  00:55 Найти цитируемый пост)
ок. я пишу диплом просто. задачу моделирования постараюсь более развернуто объяснить. однерки  и шестерки я ввел для примера...

извините за любопытство
а в дипломе вы тоже будете писАть "однерки"?  smile 

Автор: RokDemon 11.5.2009, 19:17
J0ker, 
у вас наверное нет высшего образования. я прав?)

Автор: zim22 11.5.2009, 19:43
Цитата(RokDemon @  11.5.2009,  19:17 Найти цитируемый пост)
J0ker, у вас наверное нет высшего образования. я прав?)

чего вы хотели добиться этим постом? доказать, что вы самый умный?

Автор: RokDemon 12.5.2009, 06:45
Нет, всего лишь хотел показать что подобный юмор здесь неуместен.
Спасибо за помощь всем, кто хоть как то пытался мне помочь!!!

Автор: math64 12.5.2009, 12:28
Код

const int size = 1000;
int array[size];
int ones = size/2;
int zeros = size - ones;
randomize();
for (int i = 0; i <size; i++) {
   if (zeros == 0)
     array[i] = 1;
   else if (ones == 0)
     array[i] = 0;
   else {
     int r = random(ones+zeros);
     if (r >= ones) {
       array[i] = 0;
       zeros--;
     } else {
       array[i] = 1;
       ones--;
     }
   }
}

Автор: Dov 12.5.2009, 19:16
Цитата(RokDemon @  10.5.2009,  23:55 Найти цитируемый пост)
есть 3-х мерный массив из двух типов чисел - однерок(1) и шестерок(6). размерность массива [1000].

Если это действительно так, и количество  "однерок(1) и шестерок(6)" равное, то тебе ничего перемешивать не нужно. Нужно просто каждому элементу массива присвоить попеременно одно из двух значений и всё. Вот так, например:
Код
#define SIZE 10
#define ONE  1
#define SIX  6 

int  main()
{
    int arr[SIZE][SIZE][SIZE];
    int i, j, k;
    int val = SIX;

    for(i = 0; i < SIZE; i++)
    {
        if(SIZE % 2 == 0)
            val = (val == SIX ? ONE : SIX);

        for(j = 0; j < SIZE; j++)
        {
            if(SIZE % 2 == 0)
                val = (val == SIX ? ONE : SIX);

            for(k = 0; k < SIZE; k++)
            {
                val = (val == SIX ? ONE : SIX);
                arr[i][j][k] = val;
                cout << arr[i][j][k] << ' ';            
            }
            cout << endl;
        }
        cout << endl << endl;
    }

    return 0;
}
 

Автор: Dmi3ev 12.5.2009, 23:16
Dov, тоже так считаю, только код писать не стал, лень  smile 
И думаю, что это вполне логично, единц, допустим 30Х30Х30, а шестерок 60Х60Х60, то тогда посложнее...

Автор: math64 13.5.2009, 08:56
Цитата(Dov @  12.5.2009,  19:16 Найти цитируемый пост)
Если это действительно так, и количество  "однерок(1) и шестерок(6)" равное, то тебе ничего перемешивать не нужно.

Это смотря для чего это нужно. Например, нужно сделать градиентую заливку  из двух цветов - "однерок(1) и шестерок(6)",
в вверху - "однерки(1)", внизу - "шестерки(6)", в середине - в перемежку. Если сделать регулярным способом, получится муар.

Автор: Dov 13.5.2009, 09:09
math64

Цитата(RokDemon @  10.5.2009,  23:55 Найти цитируемый пост)
нужно сделать так, чтобы однерки и шестерки равномерно "перемешались" этом массиве.



Автор: C/L 13.5.2009, 09:20
Цитата(RokDemon @  11.5.2009,  02:55 Найти цитируемый пост)
Магнит(образец) кубической формы условно разделили на 1000 кубиков который назван микрообъемом.

Если всего кубиков 1000 то это по 10 на каждое измерение. А коэрцетивная сила это не дискретная величина, поэтому тип массива более правильно взять float или double, в зависимости от желаемой точности расчета. Типа так
Код

float coercetiv[10][10][10];


Цитата(RokDemon @  11.5.2009,  02:55 Найти цитируемый пост)
Исходные данные? 3-х мерный массив с заданными значениями, нижняя половина одних чисел, верхняя других. это как бочка - нижняя половина меда, верхняя воды.надо перемешать.  я так думаю, что надо в цикле от 1 до 1000 рандомно взять один элемент массива, потом рандомно другой, так сделать 1000 раз и поменять их функцией swap.

А зачем мешать если можно сразу сгенерировать просто функцией random. Или если более точно то задаться средней коэрцетивной силой, среднеквадратичным отклонением и законом распределения (см. статистику) например нормальным.

Автор: C/L 13.5.2009, 11:27
Кроме этого в 3D коэрцетивная сила даже не скалярная, а векторная величина, поэтому для типа массива более правильно взять структуру из 3 float или double
Код

struct vect3d {float x,y,z;};
vect3d coercetiv[10][10][10];

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)