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......
❤