Chọn các bữa ăn nhiều calo nhất


9

Giả sử tôi ăn năm bữa một ngày và vì có bảy ngày trong một tuần, tôi có công thức nấu ăn cho bảy mỗi bữa, cho tổng cộng 35 công thức nấu ăn. Mỗi công thức có một lượng calo. Mỗi ngày phải chứa một công thức cho mỗi bữa ăn và mỗi công thức được cố định vào một bữa ăn cụ thể (ví dụ: bạn không thể có bánh kếp cho bữa tối). Tất cả 35 công thức nấu ăn phải có trong giải pháp, vì vậy một công thức không thể được lặp lại trong tuần.

Tôi muốn tìm cách sắp xếp các bữa ăn sẽ cung cấp lượng calo thậm chí nhiều nhất mỗi ngày - đó là tôi muốn giảm thiểu sự khác biệt trong tổng lượng calo tiêu thụ từ ngày này sang ngày khác.

Đây không phải là một vấn đề bài tập về nhà - nó thực sự đúng! Tôi không thể đưa ra một cách tiếp cận tốt hơn so với vũ phu, và có 7! ^ 4 kết hợp, rất nhiều.


3
Tôi có một cảm giác đặc biệt rằng đây là một biến thể của vấn đề cắt cổ phiếu hoặc có thể là vấn đề đóng gói bin .
Doval

Để làm rõ - bạn có 7 công thức cho "bữa ăn đầu tiên trong ngày", 7 cho "bữa ăn thứ 2", 7 cho "bữa ăn thứ 3", v.v. Bạn có bao giờ chỉ định một công thức "bữa ăn đầu tiên" cho "bữa ăn cuối cùng trong ngày" không? (Nói cách khác, bạn sẽ phục vụ bánh kếp cho bữa tối chứ?)
Dan Pichelman

Chính xác; bạn sẽ không.
dfaulken

2
Có phải tất cả 35 công thức nấu ăn có lượng calo khác nhau đáng kể ? Nếu bạn làm tròn số lượng calo đến 10 hoặc 50 calo gần nhất, 7! ^ 4 có thể dễ dàng trở thành 3! ^ 4 - có thể dễ dàng tính toán thông qua lực lượng vũ phu
Dan Pichelman

2
Anh bạn, ăn quá nhiều, ăn 5 bữa / ngày sẽ khiến bạn thừa cân.
Pieter B

Câu trả lời:


1

Để thực hiện một cách tiếp cận chính thức hơn cho vấn đề của bạn:

Bạn có 5 danh sách gồm 7 số. Bạn cần xây dựng 7 danh sách gồm 5 số, và tìm giải pháp có sự khác biệt tối thiểu giữa danh sách có tổng số lớn nhất và số có số nhỏ nhất.

Nếu bạn muốn tìm giải pháp tối ưu không có heuristic, tôi tin rằng bạn không có nhiều lựa chọn ngoài việc liệt kê, nhưng bạn không phải liệt kê tất cả chúng.

Bất cứ giải pháp nào bạn tìm thấy, khi bạn đăng ký nó là "tìm thấy tốt nhất cho đến nay", hãy đăng ký hiệu suất của nó liên quan đến số liệu của bạn (tôi tin rằng đó là sự khác biệt tối thiểu). Sau đó, nếu một nhánh giải pháp rõ ràng không có đường, hãy dừng việc liệt kê nó. Protip: những ngày không được xây dựng sẽ có ít nhất một lượng calo là trung bình của tất cả các bữa ăn còn lại. Vì vậy, hãy tưởng tượng bạn có danh sách [10, 2, 2, 1, 1, 0, 0]cho tất cả 5 bữa ăn và bạn đã xây dựng giải pháp 10 cho mỗi bữa ăn cho ngày 1. Bạn biết những ngày còn lại sẽ trung bình 5 calo mỗi ngày, do đó, sự khác biệt sẽ ít nhất là 45 và nếu bạn đã tìm thấy một giải pháp trước đây max - min = 10, bạn không cần phải đi thêm nữa. Bạn sẽ trực tiếp thử một menu khác cho ngày 1.


Nó không phải là một vấn đề bin. Một vấn đề về thùng không phải là số lượng thùng cố định và số lượng vật phẩm không cố định trên mỗi thùng.
paparazzo

Có bạn đúng. Tôi đã sửa sai.
Arthur Havlicek

0

Đây chỉ là một bản hack nhưng nó sẽ giúp bạn kết thúc
Chỉ 3 bữa ăn
Về cơ bản bạn sẽ bỏ bữa nếu nó làm cho hai ngày gần với mức trung bình của C #

Một cách tiếp cận tốt hơn sẽ là trả lại một boolen trên Flop và lặp đi lặp lại cho đến khi hoàn thành.

Flop có thể trở nên thông minh hơn. Bạn có thể ở trong tư thế không bỏ bữa sáng để bỏ bữa trưa và bữa tối. Có thể hoán vị mã cứng. Điều này giống như một loại sắp xếp các giá trị flop hơn là sắp xếp.

public static void MealEven()
{
    List<Day> Days = new List<Day>();
    Random rnd = new Random();
    decimal sum = 0;
    for(int i = 0; i<7; i ++)
    {
        int b = rnd.Next(100) + 40;
        int l = rnd.Next(100) + 60;
        int d = rnd.Next(100) + 80;
        Meal br = new Meal(enumMeal.b, b);
        Meal lu = new Meal(enumMeal.l, l);
        Meal di = new Meal(enumMeal.d, d);
        Day day = new Day(br, lu, di);
        Days.Add(day);
        sum += day.Calories;
    }
    decimal avg = sum / 7;
    foreach (Day d in Days.OrderBy(x => x.Calories))
        System.Diagnostics.Debug.WriteLine(d.Calories);
    System.Diagnostics.Debug.WriteLine("");

    Day low;
    Day high;
    Day lowLast = null;
    Day highLast = null;
    int count = 0;
    while (true)
    {   // first do high and low
        low = Days.OrderBy(x => x.Calories).FirstOrDefault();
        high = Days.OrderByDescending(x => x.Calories).FirstOrDefault();
        if (lowLast != null && lowLast == low && highLast == high)
            break;
        if (count > 1000)
            break;
        lowLast = low;
        highLast = high;
        count++;               
        Flop(ref high, ref low);
    }
    foreach (Day d in Days.OrderBy(x => x.Calories))
        System.Diagnostics.Debug.WriteLine("{0} {1} {2} {3}", d.Calories, d.B.Calories, d.L.Calories, d.D.Calories);
    System.Diagnostics.Debug.WriteLine("");

    // day a one on one pass
    for (int i = 0; i < 7; i ++)
    {
        for (int j = 0; j < 7; j++)
        {
            if (i == j)
                continue;
            Day d1 = Days[i];
            Day d2 = Days[j];
            Flop(ref d1, ref d2);
        }
    }

    foreach (Day d in Days.OrderBy(x => x.Calories))
        System.Diagnostics.Debug.WriteLine("{0} {1} {2} {3}", d.Calories, d.B.Calories, d.L.Calories, d.D.Calories);
    System.Diagnostics.Debug.WriteLine("");
}
public static void Flop (ref Day high, ref Day low)
{
    if(low.Calories > high.Calories)
    {
        int hold = low.B.Calories;
        low.B.Calories = high.B.Calories;
        high.B.Calories = hold;

        hold = low.L.Calories;
        low.L.Calories = high.L.Calories;
        high.L.Calories = hold;

        hold = low.D.Calories;
        low.D.Calories = high.D.Calories;
        high.D.Calories = hold;

    }
    decimal avg = (low.Calories + high.Calories) / (decimal)2;
    int bDiff = (high.B.Calories - low.B.Calories) < 0 ? 0 : (high.B.Calories - low.B.Calories);
    int lDiff = high.L.Calories - low.L.Calories < 0 ? 0 : (high.L.Calories - low.L.Calories);
    int dDiff = high.D.Calories - low.D.Calories < 0 ? 0 : (high.D.Calories - low.D.Calories);
    // only flop is one does not go past the average  
    if (bDiff > 0 && ((low.Calories + bDiff) < avg || (high.Calories - bDiff) > avg))
    {
        int hold = low.B.Calories;
        low.B.Calories = high.B.Calories;
        high.B.Calories = hold;
    }
    if (lDiff > 0 && ((low.Calories + lDiff) < avg || (high.Calories - lDiff) > avg))
    {
        int hold = low.L.Calories;
        low.L.Calories = high.L.Calories;
        high.L.Calories = hold;
    }
    if (dDiff > 0 && ((low.Calories + dDiff) < avg || (high.Calories - dDiff) > avg))
    {
        int hold = low.D.Calories;
        low.D.Calories = high.D.Calories;
        high.D.Calories = hold;
    }
}
public enum enumMeal {b, l, d};
public class Day
{
    public Meal B { get; set; }
    public Meal L { get; set; }
    public Meal D { get; set; }
    public Decimal Calories { get { return (Decimal)(B.Calories + L.Calories + D.Calories); } }
    public Day (Meal b, Meal l, Meal d )
    {
        B = b;
        L = l;
        D = d;
    }
}
public class Meal
{
    public enumMeal Type { get; set; }
    public int  Calories { get; set; }
    public Meal (enumMeal meal, int calories)
    {
        Type = meal;
        Calories = calories;
    }
}   

1
Có cách nào để bạn có thể thêm một lời giải thích hoặc một số nhận xét vào mã để có được câu trả lời hữu ích hơn / chiếu sáng không? Tôi nghĩ rằng tôi hiểu những gì đang xảy ra trong đó nhưng tôi không thể chắc chắn.
Adam Wells

@AdamWells Tôi đã thêm một vài bình luận. Bạn không hiểu điều gì?
paparazzo

Nó chỉ không nhấp với flop. Làm cho ý nghĩa bây giờ, cảm ơn!
Adam Wells

Tôi thậm chí không thể biết đây có phải là mã Java không. Là nó ? Xin lỗi, ngày Java và Cx của tôi thua xa tôi. Đâu là chính?
Arthur Havlicek

@ArthurHavlicek Mã C #. Họ trông rất giống nhau.
paparazzo

0

Đầu tiên tính toán lượng calo trung bình mỗi bữa ăn. Sau đó tính toán số lượng màu trung bình mỗi ngày. Đây sẽ là những số liệu mà người ta có thể đo lường được. Tiếp theo sắp xếp các bữa ăn.

Bây giờ chỉ cần chọn các bữa ăn cao nhất và thấp nhất trong số các loại. Nếu một bữa ăn nằm trong cùng một khoảng thời gian, bạn sẽ phải đi đến mức thấp nhất hoặc cao nhất tiếp theo cho đến khi bạn tìm thấy một bữa ăn không nằm trong khung thời gian đó (bữa tối, v.v.). Làm điều này trong 4 bữa ăn đầu tiên (hi / thấp). Vào bữa ăn thứ 5, hãy chọn một bữa ăn giúp bạn gần với mức trung bình nhất. Tiết kiệm bữa ăn thứ 5 vào một thùng riêng. Rửa sạch và lặp lại 7 lần.

Đây sẽ là bộ bữa ăn ban đầu của bạn. Điều này sẽ khá đẹp. Nếu bạn muốn phân phối tối ưu, một số tinh chỉnh thêm có thể được thực hiện với bữa ăn thứ 5.

Đi qua xô bữa ăn thứ 5 và thử đổi bữa ăn Bữa thứ 5 giữa các ngày để xem các bữa ăn có còn hơn nữa không. Bạn vẫn sẽ phải áp dụng các quy tắc tương tự (không quá một bữa ăn mỗi lần). Người ta có thể hoặc không thể có được một bộ thậm chí nhiều hơn. Sử dụng các giá trị trung bình được tính toán trước đó để xem có cải thiện hay không. Sẽ có rất ít sự kết hợp vì 4 bữa ăn đầu tiên được cố định dựa trên mức cao / thấp.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.