Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 23.09.2010, 16:53   #1
r_yevgeniy
Пользователь
 
Регистрация: 20.03.2010
Сообщений: 21
По умолчанию Задача "Колхозники против мышей" C# ---> Delphi

Доброго всем времени суток! Спасибо, что проявили интерес к теме! Требуется помощь добрых людей (а они здесь есть, я знаю) которые помогут перевести код с Си на Делфи. я сам буду еще пытаться, но защита уже в субботу, а так как я не очень силен в лане кодирования (могу конечно форму с кнопками накидать, по коду разобраться, а фот всякие процедуры и функции самому написать..... ). Я так понимаю там код близок и сильно много переделывть не придеться??

Прилагаю, чтобы было понятно, все задание. (Делал не я, брал с другой работы, преподаватель сказал если уж не сами делаете, то хоть разберитесь в проге. Написана была в Visual Studio 2005)

Формулировка задачи

Жители деревни выращивают пшеницу, которая является для них основным продуктом питания. Собирают N тыс. центнеров пшеницы каждый июль и хранят ее в амбаре. Хотя они потребляют только M тыс. центнеров в месяц, они иногда оказываются без пищи, так как пшеницу съедают мыши. Для борьбы с мышами жители запустили кошек, но это не решило проблему. Жители придумали следующее решение – каждый раз, когда в амбаре остается ¾ всей засыпанной пшеницы – они выгружают всю пшеницу и убивают 80% мышей. Но при этом затрачивается много сил. Нужно дать совет, в какие месяцы нужно выгружать пшеницу, чтобы затратить меньше сил.

Постановка задачи

Каждый год в июле собирается зерно, при этом рассчитывается что этого зерна должно хватить до следующего июля. Каждый месяц потребляется постоянное кол-во зерна. Но при этом надо принимать к сведению тот факт, что в амбаре живут мыши, которые тоже поедают зерно. В амбаре так же живут кошки, которые поедают мышей. Раз в месяц жители деревни могут провести акцию по истреблению мышей, при этом им нужно освободить амбар (это сделать тем тяжелее, чем больше там зерна), но в результате одной такой акции истребляется только 80% мышей, живущих в амбаре. Нужно рассчитать оптимальный набор месяцев, в которые нужно совершать акции, для того, чтобы суммарное кол-во выгруженного (и загруженного обратно) для проведения этих акций зерна было минимальным.

Описание функций вычисления:

private double Check(int[] b, double n0, double e, int k, long m0) – функция вычисляет сумму выгруженного зерна, при заданной конфигурации месяцев выгрузки b и начальных параметрах: n0 – начальное кол-во пшеницы, e – кол-во съедаемой пшеницы, k – кол-во кошек, m0 – начальное кол-во мышей.

private double Compute(double n, double e, int k, int[] minB) – вычисление оптимального решения при заданных: n – начальное кол-во зерна, e – кол- во съедаемого зерна, k – кол-во котов, minB – в массиве сохраняется конфигурация месяцев выгрузки, при которой достигнут оптимальный результат.

private void Solve(double n, double e, int k) – функция осуществляет подбор минимального кол-ва кошек, которое необходимо, чтобы пшеницу можно было сохранить. n – начальное кол-во зерна, e – кол- во съедаемого зерна, k – кол-во котов, которое предполагают запустить в амбар колхозники.

private void Output(int[] b, double n0, double e, int k) – вывод на экран найденного решения. b - найденные месяцы выгрузки, n0 – начальное кол-во зерна, e – кол- во съедаемого зерна, k – кол-во котов.

Заранее всем спасибо за помощь. На Вас последняя надежда.

Последний раз редактировалось r_yevgeniy; 23.09.2010 в 16:56.
r_yevgeniy вне форума Ответить с цитированием
Старый 23.09.2010, 16:54   #2
r_yevgeniy
Пользователь
 
Регистрация: 20.03.2010
Сообщений: 21
По умолчанию

Текст программы:
Код:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace VillagersVSMouses
{    
    public partial class Form1 : Form
    {
        //Кол-во пшеницы съедаемой одной мышью в месяц, в центнерах
        private double mouseEat = 0.02;

        //Кол-во мышей, съедаемых кошкой в месяц
        private int catEat = 40;

        //Коэффициенты роста численности мышей за месяц соответственно без истребления и с истреблением в начале этого месяца
        private double[] mouseGrowRate = { 2.5, 0.5 };

        //Максимальное кол-во кошек, для которого стоит искать решение
        private int maxCats = 1000000;

        //Кол-во мышей, которые заводятся изначально на каждый центр зерна
        private double mouseBegins = 0.1;

        private String[] month = { "Январь", "Февраль", "Март", "Апрель", "Май", "Июнь", "Июль", "Август", "Сентябрь", "Октябрь", "Ноябрь", "Декабрь" };

        //Суммарное кол-во пшеницы, которое предстоит выгрузить и загрузить обратно при заданной конфигурации месяцев выгрузки
        private double Check(int[] b, double n0, double e, int k, long m0)
        {
            double[] n = new double[13];
            long[] m = new long[13];
            double sum = 0;
            n[0] = n0;
            m[0] = m0;

            for (int j = 1; j < 13; j++)
            {
                m[j] = Math.Max((long)Math.Round(m[j - 1] * mouseGrowRate[b[j]]) - k * catEat, (long)0);
                n[j] = n[j - 1] - m[j] * mouseEat - e;
                if (n[j] < 0)
                {
                    return Double.MaxValue;
                }
                sum += b[j] * n[j - 1];
            }

            return sum;
        }

        //Вычисление оптимального решения задачи о сохранении зерна
        private double Compute(double n, double e, int k, int[] minB)
        {
            //Нахождение числа мышей, которые заведутся в амбаре в самом начале
            long m = (long)Math.Round(n * mouseBegins);            
            int[] b = new int[13];
            int i;
            
            for (i = 1; i <= 12; i++)
            {
                b[i] = 0;
            }

            //Первый вариант - совсем не истреблять мышей
            double min = Check(b, n, e, k, m);
            for (i = 1; i < 13; i++) b[i] = 0;

            i = 12;

            //Перебор всех возможных вариантов выгрузки зерна
            while (i > 1)
            {
                if (b[i] == 1)
                {
                    b[i] = 0;
                    i--;
                }
                else
                {
                    b[i] = 1;
                    i = 12;
                    //Проверяем очередной вариант
                    double sum = Check(b, n, e, k, m);
                    //Если он оптимальнее уже найденного - сохраняем конфигурацию месяцев в этом варианте
                    if (sum < min)
                    {
                        min = sum;
                        for (int v = 1; v < 13; v++) minB[v] = b[v]; ;                        
                    }
                }
            }

            return min;
        }

        public Form1()
        {
            InitializeComponent();
        }

        private void выходToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }
r_yevgeniy вне форума Ответить с цитированием
Старый 23.09.2010, 16:55   #3
r_yevgeniy
Пользователь
 
Регистрация: 20.03.2010
Сообщений: 21
По умолчанию продолжение

Код:
private void Output(int[] b, double n0, double e, int k)
        {            
            double[] n = new double[13];
            n[0] = n0;
            long[] m = new long[13];
            m[0]= (long)Math.Round(n0 * mouseBegins);
                        
            int mon = 6;
            dataGridView1.Rows.Add("Июль", n[0], m[0], 0);
            double sum = 0;
            for (int j = 1; j < 13; j++)
            {           
                mon = (mon+1)%12;
                m[j] = Math.Max((long)Math.Round(m[j - 1] * mouseGrowRate[b[j]]) - k * catEat, (long)0);
                n[j] = n[j - 1] - m[j] * mouseEat - e;
                if (b[j] == 1)
                {
                    dataGridView1.Rows.Add(month[mon], n[j], m[j], n[j - 1]);
                    sum += n[j - 1];
                    listView1.Items.Add(month[mon]);
                }
                else
                {
                    dataGridView1.Rows.Add(month[mon], n[j], m[j], 0);
                }
            }
            textBox1.Text = sum.ToString("N3");
        }
 
        private void Solve(double n, double e, int k)
        {
            int kl = k;
            int kr = maxCats;
            int[] minB = new int[13];
            int[] b = new int[13];
            double min = Double.MaxValue;            

            //Двоичным поиском подбираем минимальное кол-во кошек таким образом, чтобы нашлось решение задачи
            while (kl <= kr)
            {
                int mid = (kl + kr) / 2;
                double res = Compute(n, e, mid, b);
                if (res == Double.MaxValue)
                {
                    kl = mid + 1;
                }
                else
                {
                    min = res;
                    minB = b;
                    kr = mid - 1;
                }
            }

            //Если решения нет ни при каких разумных значениях кол-ва кошек
            if (min.Equals(Double.MaxValue))
            {
                MessageBox.Show("Пшеницу не удастся сохранить");
            } else 
            //Если минимальное возможное для наличия решения задачи число кошек больше чем планируют запустить в амбар колхозники, то советуем им другое число кошек
            if (kl > k)
            {
                DialogResult result = MessageBox.Show("Кол-ва кошек не достаточно, чтобы сохранить зерно. Минимальное кол-во кошек для сохранения зерна - " + kl.ToString() + ". Хотите расчитать решение для этого кол-ва кошек?", "Запрос", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                if (result.Equals(DialogResult.Yes))
                {
                    numericUpDown3.Value = (decimal)kl;
                    Output(minB, n, e, kl);
                }
            }
            else
            {
                Output(minB, n, e, k);
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
        }

        private void button1_Click(object sender, EventArgs e)
        {
            dataGridView1.Rows.Clear();
            textBox1.Text = "";
            listView1.Items.Clear();
            Solve((double)numericUpDown1.Value*1000, (double)numericUpDown2.Value*10, (int)numericUpDown3.Value);
        }
//Помощь

        private void ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FormHelp form = new FormHelp();
            form.Show();
        }
// О программе
        private void ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FormAbout form = new FormAbout();
            form.Show();
        }
    }
}
r_yevgeniy вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
при вводе на листе "магазин"- код товара появлялось "описание" товара из "склада" с "продажной ценой" aleksei78 Microsoft Office Excel 13 25.08.2009 12:04
"C против C++" есть вопросы CPU Свободное общение 17 31.01.2009 19:57
"Транспортная задача", "Поиск решения" Perroman Microsoft Office Excel 3 12.12.2007 17:12