Java, Android Backpack Problem - Dynamic Planning

Posted by lhaynes on Mon, 06 Dec 2021 07:04:06 +0100

Preface

Following the previous backpack problem, Greedy Algorithms, this time let's look at dynamic planning
For dynamic planning, it is dynamic planning that comes into direct contact when you first look at the backpack problem
Feeling is also simpler

Specific requirements of the topic, see the previous one in detail, this one tells us another way

1. Dynamic Planning

Dynamic planning requires us to find the best solution, avoid duplicate calculations and save time

Dynamic programming analysis

** Let's start by defining some declarations and variables
Vi denotes the value of item i I and Wi denotes the volume of item i I
Define V(i,j): current backpack j, the value corresponding to the best combination of the first I items
**
Dynamic planning of the backpack problem, which considers the problem of installing and not installing, is the 01 backpack problem

So there are two cases:
When not installed (the backpack is smaller than the weight of the object), the value is the same as that of the first i-1, that is, V(i,j)=V(i-1,j)
When loading a backpack, but may not be optimal, also consider loading and not installing
That is, V(i,j)=max V(i-1,j), V(i-1, j-w(i)+v(i)
Select the maximum value to ensure optimum
V(i-1,j) means no, V(i-1, j-w(i)+v(i) means that the second item is loaded, the backpack volume decreases w(i), but the value increases v(i)

2. Code implementation

1. Main Layout

Dynamic planning has been added this time, relative to the layout of the last greedy algorithm

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <com.google.android.material.textfield.TextInputLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="10dp">

        <com.google.android.material.textfield.TextInputEditText
            android:id="@+id/number"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="Back Containment"
            android:imeOptions="actionDone"
            android:inputType="number" />
    </com.google.android.material.textfield.TextInputLayout>

    <!--
    <com.google.android.material.textfield.TextInputLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="10dp">

        <com.google.android.material.textfield.TextInputEditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:imeOptions="actionDone"
            android:inputType="number"
            android:hint="Number of items"/>
    </com.google.android.material.textfield.TextInputLayout>
    -->

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <com.google.android.material.textfield.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:layout_weight="1">

            <com.google.android.material.textfield.TextInputEditText
                android:id="@+id/weight"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="Item weight"
                android:imeOptions="actionNext"
                android:inputType="number" />
        </com.google.android.material.textfield.TextInputLayout>

        <com.google.android.material.textfield.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:layout_weight="1">

            <com.google.android.material.textfield.TextInputEditText
                android:id="@+id/values"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="Item value"
                android:imeOptions="actionNone"
                android:inputType="number" />
        </com.google.android.material.textfield.TextInputLayout>
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <com.google.android.material.button.MaterialButton
            android:id="@+id/define"
            style="@style/materialButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Determine"
            android:textColor="#CC9933"
            app:cornerRadius="12dp"
            app:strokeColor="#CC9933"
            app:strokeWidth="2dp" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="40dp"
            android:layout_marginRight="10dp"
            android:text="Current number of items:"
            android:textColor="@color/black"
            android:textSize="17sp" />

        <TextView
            android:id="@+id/amount"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="0"
            android:textColor="@color/black"
            android:textSize="17sp" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <com.google.android.material.button.MaterialButton
            android:id="@+id/greed"
            style="@style/materialButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Greedy Algorithm"
            android:textColor="#CC9933"
            app:cornerRadius="12dp"
            app:strokeColor="#CC9933"
            app:strokeWidth="2dp" />

        <com.google.android.material.button.MaterialButton
            android:id="@+id/dynamic"
            style="@style/materialButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="dynamic programming"
            android:textColor="#CC9933"
            app:cornerRadius="12dp"
            app:strokeColor="#CC9933"
            app:strokeWidth="2dp" />

        
    </LinearLayout>

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/goodsRecycler"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

This time I added a display of the number of items to help you remember how many items there are now.

2. Layout

This layout is to jump to the active layout after clicking the button
This time dynamic planning, I'm a little more complex about what the layout shows
Write two RecyclerView s, but they're about the same thing

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".page.DynamicProgramming">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <TextView

            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="20dp"
            android:layout_marginTop="20dp"
            android:layout_marginRight="20dp"
            android:text="Backpack volume:"
            android:textColor="@color/black"
            android:textSize="18sp" />

        <TextView
            android:id="@+id/dynamicBackpack"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="20dp"
            android:layout_marginTop="20dp"
            android:layout_marginRight="20dp"
            android:text="" />
    </LinearLayout>

    <com.google.android.material.textview.MaterialTextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="15dp"
        android:layout_marginTop="15dp"
        android:background="#FFF"
        android:text="Items put in the backpack are:"
        android:textColor="@color/black"
        android:textSize="18sp" />

    <com.google.android.material.textview.MaterialTextView
        android:id="@+id/goodDynamic"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="15dp"
        android:layout_marginTop="5dp"
        android:background="#FFF"
        android:text=""
        android:textColor="@color/black"
        android:textSize="18sp" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="10dp"
        android:orientation="horizontal">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1">

            <androidx.recyclerview.widget.RecyclerView
                android:id="@+id/dynamic_full"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1">

            <androidx.recyclerview.widget.RecyclerView
                android:id="@+id/dynamic_best"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />
        </LinearLayout>
    </LinearLayout>
</LinearLayout>


The RecyclerView on the left shows the information I want to use for all items, and the RecyclerView on the right shows the information for items loaded into my backpack, which is the so-called optimal solution.

Left:

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/dynamicFullCard"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginLeft="10dp"
    android:layout_marginRight="10dp"
    android:layout_marginBottom="3dp"
    app:cardCornerRadius="15dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="5dp"
        android:layout_marginBottom="5dp"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginBottom="10dp"
                android:paddingLeft="10dp"
                android:text="Weight of item:" />

            <TextView
                android:id="@+id/dynamicWeight"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:paddingLeft="10dp"
                android:text=""
                android:textSize="15sp" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginBottom="10dp"
                android:paddingLeft="10dp"
                android:text="Value of the item:" />

            <TextView
                android:id="@+id/dynamicValues"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:paddingLeft="10dp"
                android:text=""
                android:textSize="15sp" />
        </LinearLayout>
    </LinearLayout>

</androidx.cardview.widget.CardView>

Right:

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/dynamicBestCard"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginLeft="10dp"
    android:layout_marginRight="10dp"
    android:layout_marginBottom="3dp"
    app:cardCornerRadius="15dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:orientation="vertical"
            android:layout_marginTop="10dp">

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginBottom="10dp"
                android:paddingLeft="10dp"
                android:text="Weight of item:" />

            <TextView
                android:id="@+id/dynamicWeight"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:paddingLeft="10dp"
                android:text=""
                android:textSize="15sp" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:orientation="vertical">

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginBottom="10dp"
                android:paddingLeft="10dp"
                android:text="Value of the item:" />

            <TextView
                android:id="@+id/dynamicValues"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:paddingLeft="10dp"
                android:text=""
                android:textSize="15sp" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:orientation="vertical">

            <com.google.android.material.textview.MaterialTextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginBottom="10dp"
                android:paddingLeft="10dp"
                android:lineHeight="20dp"
                android:text="Number one in backpack\n(optimum solution): " />

            <TextView
                android:id="@+id/dynamicBest"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:paddingLeft="10dp"
                android:text=""
                android:textSize="15sp"
                android:layout_marginBottom="10dp"/>
        </LinearLayout>
    </LinearLayout>


</androidx.cardview.widget.CardView>

3.bean data

Because we want to find the best solution, we have an attribute to represent the best solution in addition to weight and value. Here I'll use best to represent it.

public class DynamicGood {

    private int weight;
    private int values;
    private int best;

    public DynamicGood() {
    }

    public DynamicGood(int weight, int values) {
        this.weight = weight;
        this.values = values;
    }

    public DynamicGood(int weight, int values, int best) {
        this.weight = weight;
        this.values = values;
        this.best = best;
    }
    //The get and set of the three properties are not given

Why do I write two constructors here?
The reason is: because one of the two RecyclerView s we wrote is all the items and the other is the best solution. The parameters needed are different!

4. Adapters

Because the two are just one best attribute apart, the adapters are virtually identical

public class DynamicBestAdapter extends RecyclerView.Adapter<DynamicBestAdapter.ViewHolder> {

    private Context context;
    private List<DynamicGood> list = new ArrayList<>();

    public DynamicBestAdapter(List<DynamicGood> list) {
        this.list = list;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        if (context == null) {
            context = parent.getContext();
        }
        
        //The cardView used on the left is different
        View view = LayoutInflater.from(context).inflate(R.layout.recy_dynamic_best, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        DynamicGood dynamicGoodBest = list.get(position + 1);
        holder.dynamicWeight.setText(String.valueOf(dynamicGoodBest.getWeight()));
        holder.dynamicValues.setText(String.valueOf(dynamicGoodBest.getValues()));
 
		//RecyclerView on the left does not use the optimal solution, eliminating
       holder.dynamicBest.setText(String.valueOf(dynamicGoodBest.getBest()));
    }

    @Override
    public int getItemCount() {
        return list.size() - 1;
    }

    static class ViewHolder extends RecyclerView.ViewHolder {
        CardView cardView;
        TextView dynamicWeight;
        TextView dynamicValues;

		//Left RecyclerView removes dynamicBest
        TextView dynamicBest;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            cardView = (CardView) itemView.findViewById(R.id.dynamicBestCard);
            dynamicWeight = (TextView) itemView.findViewById(R.id.dynamicWeight);
            dynamicValues = (TextView) itemView.findViewById(R.id.dynamicValues);

			//Remove to the left
            dynamicBest = (TextView) itemView.findViewById(R.id.dynamicBest);
        }
    }
}

So we've written both adapters and we're in our Activity

5.DynamicProgramming Activity

Establish a model, that is, find max(V1X1+V2X2+...+VnXn);
Looking for constraints, W1X1+W2X2+...+WnXn<capacity;
Dynamic Planning 01 Backpack Problem to ensure that the weight of loaded items is less than the amount of backpack, and the value is the largest, with the best solution

public class DynamicProgramming extends AppCompatActivity {
    private RecyclerView recyclerViewFull, recyclerViewBest;
    private DynamicFullAdapter dynamicFullAdapter;
    private DynamicBestAdapter dynamicBestAdapter;
    private List<DynamicGood> fullList = new ArrayList<>();
    private List<DynamicGood> bestList = new ArrayList<>();
    private TextView goodDynamic, dynamicBackpack;
    private int volume;     //Backpack size, backpack volume
    private int bestNumber = 0; //Count how many backpacks are loaded

    private int[][] dynamicProgramming;    //Dynamic Planning Table

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_dynamic_programming);

        init();     //Initialization
        programming();  //dynamic programming
 
        bestSituation(goodsWeight.size() - 1, volume); //Optimal Solution
        print();
    }

    //Print
    private void print() {
        dynamicBackpack.setText(String.valueOf(volume));
        for (int i = 1; i <= goodsBest.size() - 1; i++) {
            if (goodsBest.get(i) == 1) {
                bestNumber++;   //Number of Statistical Optimal Solutions
                //Shows the subscript for the best solution
               
                goodDynamic.append(String.valueOf(i));
               
                goodDynamic.append(" ");
            }
        }
        //Initialize Array
        DynamicGood[] fullDynamic;  //Display of all items
        DynamicGood[] bestDynamic;  //Display of items loaded in backpack

        fullDynamic = new DynamicGood[goodsWeight.size()];
        fullDynamic[0] = new DynamicGood(0, 0);
        for (int i = 1; i <= goodsWeight.size() - 1; i++) {
            fullDynamic[i] = new DynamicGood(goodsWeight.get(i), goodsValues.get(i));
        }
        fullList.clear();
        for (int x = 0; x < fullDynamic.length; x++) {
            fullList.add(fullDynamic[x]);
        }

        bestDynamic = new DynamicGood[goodsBest.size()];    //size 5 so bestDynamic.length = 5
        int temp = 0;     //The number of temp statistical optimal solutions is initialized to 0 Array The first boundary is 0 temp++ when best == 1
        bestDynamic[temp] = new DynamicGood(0, 0, 0);
        for (int i = 1; i <= goodsBest.size() - 1; i++) {
         
            //Traverse first to find the loaded item with a goodsBest value of 1
            //Subscript for weight values best
            if (goodsBest.get(i) == 1) {
                bestDynamic[temp += 1] = new DynamicGood(goodsWeight.get(i), goodsValues.get(i), i);
//                for (int j = 1; j <= bestNumber; j++) {
//                    bestDynamic[j] = new DynamicGood(goodsWeight.get(i), goodsValues.get(i), goodsBest.get(i));
//                }
            }
        }
        bestList.clear();
        for (int x = 0; x <= temp; x++) {
            bestList.add(bestDynamic[x]);
        }

        GridLayoutManager gridLayoutManagerFull = new GridLayoutManager(this, 1);
        GridLayoutManager gridLayoutManagerBest = new GridLayoutManager(this, 1);
        recyclerViewFull.setLayoutManager(gridLayoutManagerFull);
        recyclerViewBest.setLayoutManager(gridLayoutManagerBest);
        dynamicFullAdapter = new DynamicFullAdapter(fullList);
        dynamicBestAdapter = new DynamicBestAdapter(bestList);
        recyclerViewFull.setAdapter(dynamicFullAdapter);
        recyclerViewBest.setAdapter(dynamicBestAdapter);
    }

    //Initialization
    private void init() {
        volume = getIntent().getIntExtra("goodsVolume", 0);      //Back Containment Value Transfer
        //volume = getIntent().getDoubleExtra("goodsVolume",0);
        dynamicProgramming = new int[goodsWeight.size()][volume + 1];             //Dynamic Planning Table
     
        goodDynamic = (TextView) findViewById(R.id.goodDynamic);
        dynamicBackpack = (TextView) findViewById(R.id.dynamicBackpack);
        recyclerViewFull = (RecyclerView) findViewById(R.id.dynamic_full);
        recyclerViewBest = (RecyclerView) findViewById(R.id.dynamic_best);

        //First guarantee that the optimal solution dynamic array is all zero
        for (int i = 1; i <= goodsWeight.size() - 1; i++) {
            goodsBest.add(0);
         
        }
    }

    //dynamic programming
    private void programming() {
        for (int i = 1; i <= goodsWeight.size() - 1; i++) {  //i is the number of items
            for (int j = 1; j <= volume; j++) {       //j The current amount of backpack, which is equivalent to the amount of backpack added bit by bit, starts to judge if the items can be loaded when they are satisfied
                if (j < goodsWeight.get(i)) {
                    //Because the capacity is not enough to load the item, the dynamic planning table is the same as the previous item, [value corresponding to the best combination of the first i items] [current backload]
                    //Since no items are loaded, the best combinations of the first i items have the same value
                    dynamicProgramming[i][j] = dynamicProgramming[i - 1][j];
                  
                } else {
                    //When loading an item, determine whether the previous item is of great value or of great value after loading to find the best solution
                    dynamicProgramming[i][j] = Math.max(dynamicProgramming[i - 1][j], dynamicProgramming[i - 1][j - goodsWeight.get(i)] + goodsValues.get(i));
                 
                }
            }
        }
    }

    //Find the best solution
    private void bestSituation(int i, int j) {
    
        if (i - 1 >= 0) {
          
            //The parameter passed in is the last item's serial number iCapacity j
            if (dynamicProgramming[i][j] == dynamicProgramming[i - 1][j]) {    //If the value of the current item is equal to that of the previous item in the dynamic planning table
                // Is not loaded
               
                goodsBest.set(i, 0);             //Optimal solution marked 0 means no load
              
                bestSituation(i - 1, j);           //Recursively see if the next item is the best solution
            } else if (j - goodsWeight.get(i) >= 0 && dynamicProgramming[i][j] == dynamicProgramming[i - 1][j - goodsWeight.get(i)] + goodsValues.get(i)) {
                //If the backpack is large enough and optimal value is achieved after loading
              
                goodsBest.set(i, 1);     //Marked as the best solution
              
                bestSituation(i - 1, j - goodsWeight.get(i));    //Next Item
            }
        }
    }
}

Initialization is the first step. These are binding instances, some code for binding controls, and passing in the amount of backspace from Mainactivity, just like previous greedy algorithms
Then the optimal solution is also stored in a dynamic array, as previously mentioned in the Greedy Algorithms article, the first element at the beginning of a dynamic array is 0, for dynamic planning purposes
Define a dynamic array Best in the previous Goods class

//Goods
    //For dynamic planning, save the best solution, see which item is put in, the best solution
    public static ArrayList<Integer> goodsBest = new ArrayList<Integer>();

Then do a dynamic programming() to compare whether or not items are loaded and whether they are most valuable when loaded

Then, to find the best solution, we'll mark the loaded item as 1 in Best and the unloaded item as 0, and wait until the print() function also displays it in RecyclerView on the right side we wrote earlier, depending on whether it's 1 in Best.
The best solution is to go back and look for the dynamic programming table from the last place
If the value of the current item is equal to that of the previous item, it is not loaded and the next item is recursively loaded
Optimal solution if backpack is large enough and optimal value is achieved after loading

For the print part, add the new object to the list as before
However, in the section where the optimal solution is added to the list, because to consider whether it is the optimal solution, you need to determine if the element of goodsBest is equal to 1.
And notice that we are returning the subscript of the optimal solution so that we know the first item is the optimal solution

6.MainActivity

We've added an array of optimal solutions, and we need to start with 0
Nothing changed in general except click events

public class MainActivity extends AppCompatActivity implements View.OnClickListener {


    private RecyclerView recyclerView;
    private RecyclerViewAdapter recyclerViewAdapter;
    private List<Data> dataList = new ArrayList<>();

    private TextInputEditText number;       //capacity
    private TextInputEditText weight;       //weight
    private TextInputEditText values;       //value
    private Button define;
    private TextView amount;                //Number of items (use int type)
    private int goodsAmount = 0;                //Number of items (use int type)

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        init();
        GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 1);
        recyclerView.setLayoutManager(gridLayoutManager);
        recyclerViewAdapter = new RecyclerViewAdapter(dataList);
        recyclerView.setAdapter(recyclerViewAdapter);
    }

    private void init() {
        goodsWeight.add(0);
        goodsValues.add(0);
        goodsScale.add(0.0);           //Initialize the boundary condition, regarding the array boundary overflow after
        goodsBest.add(0);
        Log.d("size","size :"+goodsBest.size());
        recyclerView = (RecyclerView) findViewById(R.id.goodsRecycler);
        number = (TextInputEditText) findViewById(R.id.number);
        weight = (TextInputEditText) findViewById(R.id.weight);
        values = (TextInputEditText) findViewById(R.id.values);
        amount = (TextView) findViewById(R.id.amount);
        define = (Button) findViewById(R.id.define);
        define.setOnClickListener(this);
        Button greed = (Button) findViewById(R.id.greed);
        greed.setOnClickListener(this);
        Button dynamic = (Button) findViewById(R.id.dynamic);
        dynamic.setOnClickListener(this);
      
        amount.setText(String.valueOf(goodsAmount));
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.define:
                //Make a judgement that both input boxes have values
                if (weight.getText() == null || weight.getText().length() == 0 || values.getText() == null || values.getText().length() == 0) {
                    //Not fully entered prompts incomplete input
                    Toast.makeText(this, "Please enter the weight and value of the item in its entirety", Toast.LENGTH_SHORT).show();
                } else {
                    int n = Integer.parseInt(weight.getText().toString());  //Get item weight input value
                    int m = Integer.parseInt(values.getText().toString());  //Get item value input value
                    Data goods = new Data(n, m);        //Create Data Object

                    //dataList.add(goods);
                    recyclerViewAdapter.add(goods);     //Join Adapter adapter for display
                    goodsWeight.add(n);                 //Save Value to Dynamic Array
                    goodsValues.add(m);                 //Save Value to Dynamic Array
                    Log.d("111", "...." + goodsWeight.size());    //Testing guarantees dynamic array length usage
                    Log.d("111", "......" + goodsWeight.get(1));   //Testing guarantees the use of dynamic array values
                    weight.setText("");
                    values.setText("");                 //Ensure that after each input, the values in the input box are cleared to ensure the next input
                    goodsAmount++;
                    amount.setText(String.valueOf(goodsAmount));

                    //Ensure that after each input, the input box cursor is cancelled

                    weight.setImeOptions(EditorInfo.IME_ACTION_NONE);
                    values.setImeOptions(EditorInfo.IME_ACTION_NONE);
                }
                break;
            case R.id.greed:
                //Judgment guarantees input backspace without null backspace at calculation time
                //The boundaries of the two dynamic arrays have been initialized above, so the length of the array is already 1
                if (number.getText() == null || number.getText().length() == 0 || goodsWeight.size() == 1 || goodsValues.size() == 1) {
                    //Information Tips
                    Toast.makeText(this, "Please enter full backpack volume or item weight and value", Toast.LENGTH_SHORT).show();
                } else {
                    //Go to Next Activity to Solve Greedy Algorithms
                    Intent pageGreed = new Intent(MainActivity.this, PageGreed.class);

                    //The activity of passing a backspace value into a greedy algorithm
                    int volume = Integer.parseInt(number.getText().toString());     //Gets the value of the backspace input box
                    pageGreed.putExtra("goodsVolume", volume);       //Intent object.putExtra (key value, actual value)
                    //Key values are similar to pointers used to find values

                    startActivity(pageGreed);
                }
                break;
            case R.id.dynamic:
                if (number.getText() == null || number.getText().length() == 0 || goodsWeight.size() == 1 || goodsValues.size() == 1) {
                    //Information Tips
                    Toast.makeText(this, "Please enter full backpack volume or item weight and value", Toast.LENGTH_SHORT).show();
                } else {
                    Intent dynamicProgramming = new Intent(MainActivity.this, DynamicProgramming.class);

                    int volume = Integer.parseInt(number.getText().toString());
                    dynamicProgramming.putExtra("goodsVolume", volume);

                    startActivity(dynamicProgramming);
                }
                break;
          
        }
    }
}

It also guarantees complete input and then passes values
The difficulty lies in understanding the optimal solution of dynamic programming and the dynamic planning table
Because visualization is required, it is also difficult to print and display dynamic planning

For dynamic programming, the algorithm itself is not difficult. I feel that writing Android code myself is still a bit difficult for visualization.

Finally, there's an ugly running result:

summary

Now there are greedy algorithms and dynamic planning for the backpack problem

I am a bit confused when writing code, that is, about the best solution
The most interesting thing about adding list s to RecyclerView is
Because newnewnewnew add s to the list, there is a limitation that best needs to be equal to 1

PS: When writing this part of the list, it is really written that the mind is confused, a little dizzy, it is very around

Then there will be brutal force, greedy algorithm to solve the approximate solution of 01 knapsack problem, and so on.
(Specifically, they can learn from each other and communicate with each other)

The coming days would be long
to be continued......

Topics: Java Android Algorithm data structure Dynamic Programming